From c7dfde4b79eb5110d7d5420002a0631151401645 Mon Sep 17 00:00:00 2001 From: Anso Date: Mon, 20 Apr 2026 11:24:41 -0400 Subject: [PATCH] fix(sidebar): distinct fuchsia notification dot for update indicator (#708) The pulsing dot signaling an available image update used --info (blue hue 250), the same hue as --label-blue, so the two blended visually when a stack carried a blue label. Introduce a dedicated --update token in vibrant fuchsia (hue 320) sitting outside the label palette, and render both the sidebar StackRow and the fleet NodeManager indicator as a notification-dot pattern (solid stationary core with animate-ping halo). Aligns with the design rule that static state should not pulse. --- docs/features/multi-node.mdx | 2 +- frontend/src/components/NodeManager.tsx | 7 +++++-- frontend/src/components/sidebar/StackRow.tsx | 7 ++++++- frontend/src/index.css | 9 +++++++++ 4 files changed, 21 insertions(+), 4 deletions(-) diff --git a/docs/features/multi-node.mdx b/docs/features/multi-node.mdx index 02295ae3..7746a390 100644 --- a/docs/features/multi-node.mdx +++ b/docs/features/multi-node.mdx @@ -77,7 +77,7 @@ The Nodes table surfaces scheduling and update status at a glance for each node: | Column | What it shows | |--------|---------------| | **Schedules** | Number of active scheduled tasks targeting this node, plus a relative countdown to the next run (e.g. "next 2h") | -| **Updates** | Whether auto-update policies are enabled ("Auto" badge), and how many stacks have pending image updates (pulsing blue dot with count) | +| **Updates** | Whether auto-update policies are enabled ("Auto" badge), and how many stacks have pending image updates (fuchsia notification dot with expanding halo and a count) | Click the **calendar icon** on any node row to jump directly to the Schedules view filtered to that node. From there you can create, edit, or manage scheduled tasks scoped to the selected node. The filter bar shows which node you are viewing, with a **Clear filter** button to return to the full list. diff --git a/frontend/src/components/NodeManager.tsx b/frontend/src/components/NodeManager.tsx index fd417259..17159f15 100644 --- a/frontend/src/components/NodeManager.tsx +++ b/frontend/src/components/NodeManager.tsx @@ -602,8 +602,11 @@ export function NodeManager() { )} {(summary?.stacks_with_updates ?? 0) > 0 && ( - - + + + + + {summary!.stacks_with_updates} diff --git a/frontend/src/components/sidebar/StackRow.tsx b/frontend/src/components/sidebar/StackRow.tsx index 02b6f3af..9dfec7e1 100644 --- a/frontend/src/components/sidebar/StackRow.tsx +++ b/frontend/src/components/sidebar/StackRow.tsx @@ -72,7 +72,12 @@ export function StackRow(props: StackRowProps) { )} {hasUpdate && ( } + trigger={( + + + + + )} label="Update available" /> )} diff --git a/frontend/src/index.css b/frontend/src/index.css index 318191c5..305c1346 100644 --- a/frontend/src/index.css +++ b/frontend/src/index.css @@ -48,6 +48,9 @@ --info: oklch(0.62 0.14 250); --info-foreground: oklch(1 0 0); --info-muted: oklch(0.62 0.14 250 / 0.12); + --update: oklch(0.62 0.22 320); + --update-foreground: oklch(1 0 0); + --update-muted: oklch(0.62 0.22 320 / 0.12); --destructive-muted: oklch(0.63 0.19 23 / 0.12); /* Charts — cyan leads as the primary data color, amber for peaks, rose for errors */ @@ -221,6 +224,9 @@ --info: oklch(0.70 0.14 250); --info-foreground: oklch(0.10 0 0); --info-muted: oklch(0.70 0.14 250 / 0.15); + --update: oklch(0.72 0.20 320); + --update-foreground: oklch(0.10 0 0); + --update-muted: oklch(0.72 0.20 320 / 0.15); --destructive-muted: oklch(0.69 0.20 24 / 0.15); /* Charts — cyan leads as the primary data color, amber for peaks, rose for errors */ @@ -393,6 +399,9 @@ --color-info: var(--info); --color-info-foreground: var(--info-foreground); --color-info-muted: var(--info-muted); + --color-update: var(--update); + --color-update-foreground: var(--update-foreground); + --color-update-muted: var(--update-muted); --color-destructive-muted: var(--destructive-muted); --font-sans: var(--font-sans);