Files
sencho/docs/features/sidebar.mdx
T
Anso adcd04b01a refactor(auto-update): retire per-stack gate, drive auto-update from schedules only (#1233)
* refactor(auto-update): retire per-stack gate, drive auto-update from schedules only

The per-stack Auto-update toggle in the stack sidebar context menu wrote a
gate row to `stack_auto_update_settings`, but actual updates only ran when a
`scheduled_tasks` row with `action='update'` fired. On a fresh install the
toggle was inert: detection ran every 6h, nothing was applied.

The same context menu already exposes `Schedule task`, which opens
ScheduledOperationsView pre-filled for the stack where the user can pick
`Auto-update Stack` and any cron. Keeping the toggle alongside that flow
duplicated the same action and turned the gate table into a parallel store
of "is a covering schedule active" derivable from `scheduled_tasks` itself.

Drop the gate model entirely:
- Backend: remove the `stack_auto_update_settings` table and its four
  accessors, the three routes under /api/stacks/*/auto-update, the per-stack
  skip in /api/auto-update/execute and SchedulerService.executeUpdate's
  fleet branch, and the clearStackAutoUpdateSetting call on stack delete.
  Dashboard `autoUpdate` count derives from scheduled_tasks (action='update'
  rows pinned to the node, total/enabled split).
- Frontend: drop the Auto-update entry from the sidebar context menu and its
  optimistic toggle plumbing. Drop autoUpdateSettings state, the
  /stacks/auto-update-settings fetch, and the auto-update-settings-changed
  WebSocket branch. Slim useSidebarActivitySummary (just nextRunAt; no
  enabled/total counts). AutoUpdateReadinessView's per-card autoUpdateEnabled
  now means "a covering enabled action='update' schedule exists" (per-stack
  row or fleet row on this node, earliest next_run_at wins, per-stack row
  wins on ties), with the gate-fetch removed.
- New: scheduledTasksRouter broadcasts scope: 'scheduled-tasks' on POST,
  PUT, PATCH /toggle, and DELETE so useConfigurationStatus and
  useNextAutoUpdateRun refetch under the 250ms debounce instead of waiting
  for the 60s poll. The broadcast is wrapped so a broken subscriber socket
  cannot turn a successful mutation into a 500.
- Docs: rewrite the "Per-stack control" section of auto-update-policies.mdx
  to describe the schedule-based model; update the matching troubleshooting
  entry. The misleading fleet-update help text in ScheduledOperationsView
  is corrected to reflect that every stack on the node is covered.

Tier parity: the surviving auto-update path (Schedule task -> Auto-update
Stack / All Stacks) is gated `requirePaid + requireAdmin` backend and
`isPaid + isAdmin` frontend, matching the gate the deleted routes carried.
The pre-commit grep returns no tier-related diff outside this PR's scope.

No data migration is provided: greenfield rules apply, and the leftover
table on already-shipped instances is harmless because no code reads or
writes it after this PR.

* docs: sweep remaining references to the per-stack auto-update toggle

The previous commit retired the per-stack Auto-update gate in favor of
configuring auto-update purely through scheduled tasks. This commit
removes the now-stale mentions of that toggle across the operator docs:

- docs/features/sidebar.mdx: drop the Auto-update entry from the Inspect
  group description, the matching screenshot alt-text, and the Skipper
  Note that listed it. Schedule task now carries the cross-link to
  Auto-Update Policies.
- docs/features/stack-management.mdx: drop the Auto-update list item;
  refresh the Schedule task entry to mention the Auto-update Stack action.
- docs/features/dashboard.mdx: rename the Configuration Status row from
  "Auto-update stacks" to "Auto-update schedules" with the new value
  shape, and rewrite the troubleshooting accordion to describe the
  scheduled-tasks invalidation path.
- docs/features/scheduled-operations.mdx: rewrite the Auto-update All
  Stacks row and helper text to reflect that every stack on the node is
  covered (no per-stack opt-out from this surface anymore).
- docs/features/multi-node.mdx: rewrite the Updates column definition to
  derive the Auto/Off flag from enabled Auto-update Stack / Auto-update
  All Stacks schedules instead of the removed per-stack policy.

The auto-update-policies.mdx rewrite in the previous commit already
covered the main reference page. The sidebar-context-menu.png screenshot
will be refreshed on release once the new menu is live in production;
the alt text is updated in this commit so it accurately describes the
shipping state.

No website edits needed: the Auto-Update Policies feature card description
("Schedule automatic image pulls and redeployments per stack on your own
cadence") and the feature matrix labels ("Auto-update stack schedule",
"Auto-update all stacks schedule") remain accurate under the new model.

* fix(stacks): drop orphaned requireAdmin import after auto-update route removal

CI's backend lint step flagged this PR's earlier deletion of the three
/api/stacks/*/auto-update routes: those handlers were the only callers of
`requireAdmin` inside routes/stacks.ts, leaving the named import on line 15
unreferenced. `requirePaid` and `effectiveTier` from the same line are still
in use elsewhere in the file and stay.

tsc --noEmit does not flag unused named imports; ESLint's no-unused-vars
does. Local backend lint reproduces and now reports 0 errors against the
existing 334-warning baseline.
2026-05-26 11:08:33 -04:00

147 lines
9.5 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: Stack Sidebar
description: Manage, group, pin, and bulk-act on your stacks from the primary sidebar.
---
The stack sidebar is your cockpit for every stack on the active node. Stacks are grouped by label, your most-used stacks can be pinned to the top, a one-click bulk mode lets you act on several at once, and a live activity footer keeps you aware of what just happened.
<Frame>
<img src="/images/sidebar/sidebar-overview.png" alt="Stack sidebar overview with branding header, node switcher, Create Stack button, Bulk mode and Scan icons, search box, ALL/UP/DOWN/UPDATES filter chips, three label groups (MEDIA, UTILITIES, NETWORK) with stack rows and label dots, and a LIVE activity footer at the bottom" />
</Frame>
## Layout
From top to bottom:
1. **Branding header** shows your Sencho build version.
2. **Node switcher** selects which Sencho instance you are managing.
3. **Action row** holds **Create Stack**, the **Bulk mode** toggle (square icon), and **Scan stacks folder** (folder-search icon).
4. **Search** filters the stack list. Start typing into **Search stacks...** to filter in place.
5. **Filter chips** narrow the list by status (described below).
6. **Stack list** shows your stacks grouped by label.
7. **Activity footer** shows the most recent stack event on the node.
## Filter chips
Four chips sit below the search box. Each shows a live count to the right of its label, and counts above 99 render as **99+** to keep the row from overflowing.
- **All**: every stack on the node.
- **Up**: stacks where at least one container is running.
- **Down**: stacks where no container is running.
- **Updates**: stacks with at least one image update available. The chip turns orange when the count is non-zero so you can spot pending updates at a glance.
<Frame>
<img src="/images/sidebar/sidebar-filter-chips.png" alt="Filter chip row with ALL pressed (count 14), UP (count 14), DOWN (count 0), and UPDATES highlighted in orange with count 1" />
</Frame>
Click the **** (minus) icon on the right to collapse the chip row when you need more vertical room; it becomes a **+** (plus) icon you click to bring the chips back. The collapsed state is remembered in your browser.
## Groups
Stacks are grouped by label. Groups are sorted by size (most populated first), then alphabetically. Stacks with multiple labels appear in every matching group so you always see the full fleet membership per label. Stacks without labels appear in an **Unlabeled** group at the bottom. Click a group header to collapse or expand it; the collapsed state is remembered per node.
## Pinning
Right-click a stack and choose **Pin to top**. Pinned stacks sit in a dedicated **★ PINNED** group at the top of the list. Up to 10 stacks can be pinned per node; pinning an 11th evicts the oldest. Right-click a pinned stack and choose **Unpin** to remove it from the group.
<Frame>
<img src="/images/sidebar/sidebar-pinned.png" alt="Sidebar with a starred PINNED group at the top containing plex, sonarr, and cloudflared, followed by the regular MEDIA group below" />
</Frame>
## Stack rows
Each row gives you everything you need to read the stack at a glance, in a fixed column order:
- **Status pill** on the left. Two uppercase letters in mono type, or a spinner while a lifecycle action is in flight. `UP` means at least one container is running; `DN` means the stack is stopped.
- **Stack name** in mono type, truncated with an ellipsis when the row gets tight.
- **Label dots** to the right of the name. Up to three colored dots representing the stack's labels render here. If a stack carries more than three labels, a **+N** counter appears for the extras.
- **Update indicator**. When a stack has an image update pending, an extra colored dot appears alongside the label dots. If only a Git source update is pending (no image update), a small Git branch icon shows instead. The image-update dot takes priority when both apply.
- **Hover kebab** on the right edge. Hover the row to reveal a vertical three-dot menu that opens the same actions as right-clicking the row.
<Frame>
<img src="/images/sidebar/sidebar-row-anatomy.png" alt="Two stack rows shown stacked: dozzle with two label dots (utilities in grey and media in magenta) and a hover kebab, and cloudflared with an orange indicator dot and a hover kebab" />
</Frame>
## Bulk mode
Click the **Bulk mode** icon next to **Create Stack** (or press <kbd>B</kbd>) to enter selection mode. A checkbox appears at the left of every row, and a sticky toolbar slides in just above the list:
- **Start**, **Stop**, **Restart** apply the action to every selected stack.
- **Update** pulls the latest images for every selected stack and requires a **Skipper** or **Admiral** license.
Click rows to toggle their selection. The toolbar header shows a running count. Click the **×** in the corner of the toolbar to clear the selection, and click the icon again (or press <kbd>B</kbd>) to leave bulk mode.
<Frame>
<img src="/images/sidebar/sidebar-bulk-mode.png" alt="Sidebar in bulk mode with the Bulk mode icon highlighted, a sticky toolbar reading 3 selected with Start, Stop, Restart, and Update buttons, and checkboxes visible on every stack row" />
</Frame>
## Context menu
Right-click any stack (or open the kebab that appears on hover) for its context menu. Items are grouped by purpose:
- **Inspect**: **Alerts**, **Auto-Heal**, **Check updates**, and **Open App** (the last only appears when the stack is running and exposes a port).
- **Organize**: **Labels** (a submenu listing every label on the node, with a check next to each label the stack already carries) and **Pin to top** / **Unpin**.
- **Lifecycle**: **Deploy** (when stopped), **Stop**, **Restart**, **Update** (when running), and **Schedule task** (opens the Schedules view pre-filled for this stack, where **Auto-update Stack** sets up unattended updates on your own cadence).
- **Destructive**: **Delete**.
<Note>
**Auto-Heal** and **Schedule task** require a **Skipper** or **Admiral** license.
</Note>
<Frame>
<img src="/images/sidebar/sidebar-context-menu.png" alt="Right-click context menu on a running plex stack with four sections. INSPECT lists Alerts, Auto-Heal, Check updates, and Open App. ORGANIZE lists Labels with a submenu arrow and Pin to top. LIFECYCLE lists Stop, Restart, Update, and Schedule task. DESTRUCTIVE lists Delete in red." />
</Frame>
## Keyboard shortcuts
Shortcuts fire on the currently selected stack. They are blocked while a text input is focused or the global command palette is open.
### Lifecycle
| Shortcut | Action | Condition |
|----------|--------|-----------|
| <kbd>Ctrl</kbd>+<kbd>Enter</kbd> | Deploy | Stack is stopped |
| <kbd>Ctrl</kbd>+<kbd>.</kbd> | Stop | Stack is running |
| <kbd>Ctrl</kbd>+<kbd>R</kbd> | Restart | Stack is running |
| <kbd>Ctrl</kbd>+<kbd>↑</kbd> | Update images | Stack is running |
| <kbd>Ctrl</kbd>+<kbd>Backspace</kbd> | Delete | Stack exists |
On macOS, use <kbd>Cmd</kbd> in place of <kbd>Ctrl</kbd>.
### Inspect and organize
| Key | Action |
|-----|--------|
| <kbd>A</kbd> | Open the alerts sheet |
| <kbd>H</kbd> | Open the auto-heal sheet (Skipper or Admiral) |
| <kbd>U</kbd> | Check for image updates |
| <kbd>P</kbd> | Pin or unpin the stack |
| <kbd>B</kbd> | Toggle bulk mode |
The **↗** and **L ** glyphs inside the context menu are visual hints, not global bindings. Open **Open App** or **Labels** through the menu (or the hover kebab) to use them.
## Activity footer
The footer surfaces the most recent stack lifecycle event on the node. Each ticker shows the stack name in brand color, a short event description, and a relative time. The kicker text below alternates between **LIVE · VIEW ACTIVITY →** when an event is showing and **IDLE · NO RECENT ACTIVITY** when nothing has happened recently. A pulsing dot to the left indicates the WebSocket subscription is healthy. Click anywhere on the footer to open the global activity view.
<Frame>
<img src="/images/sidebar/sidebar-activity.png" alt="Activity footer with a green pulsing dot, the stack name 'cloudflared' in brand color, an event description, and the kicker LIVE · VIEW ACTIVITY" />
</Frame>
## Troubleshooting
<AccordionGroup>
<Accordion title="I can't see my newly created stack in the sidebar">
Confirm the active filter chip is **All** so a status filter is not hiding the row. Clear the **Search stacks...** box in case a stale query is filtering the list. Then click the **Scan stacks folder** icon next to **Create Stack** to re-index the compose directory on disk.
</Accordion>
<Accordion title="Pinning is not sticking past the 10th stack">
Each node has a 10-stack pin limit. When you pin an 11th stack, the oldest pin is automatically evicted so the new one fits. Unpin a stack you no longer need before adding another, or accept that the oldest will roll off.
</Accordion>
<Accordion title="Keyboard shortcuts are not firing">
Shortcuts only fire when a stack row is selected in the sidebar (one row is highlighted). They are intentionally blocked while a text input is focused or the global command palette (<kbd>Ctrl</kbd>+<kbd>K</kbd>) is open, so they do not collide with typing. Click a stack row, then try the shortcut again.
</Accordion>
<Accordion title="The filter chips disappeared from the sidebar">
Click the **+** icon to the right of the search box to bring them back. The chip row collapses to a thin **** / **+** toggle, and the state is remembered in your browser, so an earlier collapse persists across reloads until you expand it again.
</Accordion>
</AccordionGroup>