From 6bb976ec7209fe3fbde132df26e051e26b97a7e2 Mon Sep 17 00:00:00 2001 From: iris Date: Sun, 21 Jun 2026 21:43:05 +0200 Subject: [PATCH] dashboard: replace agent-tab transient list with build-queue summary banner MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The SW4RM tab rendered a per-transient spinner list above the container list, duplicating the running-step badge already shown on each agent card. Replace it with a single compact amber banner that appears when the rebuild queue has active (queued/running) entries — 'build queue — N running / M queued — view queue →', linking to the full queue on /core.html. Per-agent detail stays on the cards; the top of the tab just gives the at-a-glance summary + a jump to the queue. Closes #1817. --- docs/web-ui/dashboard.md | 8 +++++ frontend/packages/dashboard/src/dashboard.css | 25 ++++++++++++++ frontend/packages/dashboard/src/tabs.js | 33 +++++++++++-------- 3 files changed, 53 insertions(+), 13 deletions(-) diff --git a/docs/web-ui/dashboard.md b/docs/web-ui/dashboard.md index e2e36c1a..189aafc8 100644 --- a/docs/web-ui/dashboard.md +++ b/docs/web-ui/dashboard.md @@ -767,6 +767,14 @@ per-agent actions and navigation links. Contents: agent is stale. Banner pulses on each broker SSE event (`pulseBanner` with a 4s grace timer). +**Build-queue summary banner** — when the rebuild queue has any +`queued` / `running` entries, a compact amber banner sits above the +container list: `◐ build queue — N running · M queued — view queue →` +(the link goes to the C0R3 page's R3BU1LD QU3U3). It replaces the +old per-transient spinner list; the actual running step for each +agent is already shown on its card (transient + in-flight-queue +badges), so the top of the tab only needs the at-a-glance summary. + ### Themed dialogs All confirmations, prompts, and transient error notices use an diff --git a/frontend/packages/dashboard/src/dashboard.css b/frontend/packages/dashboard/src/dashboard.css index bf8fcd7f..70be4d8c 100644 --- a/frontend/packages/dashboard/src/dashboard.css +++ b/frontend/packages/dashboard/src/dashboard.css @@ -564,6 +564,31 @@ body.dashboard-shell { } .port-conflict strong { color: var(--red); } +/* Build-queue summary banner on the SW4RM tab: one compact line + when the rebuild queue has active work, with a link to the full queue on + the C0R3 page. Amber to match the in-progress / "rebuilding" card tint. */ +.queue-summary { + display: flex; + align-items: center; + gap: 0.4em; + flex-wrap: wrap; + background: color-mix(in srgb, var(--amber) 8%, transparent); + border: 1px solid color-mix(in srgb, var(--amber) 55%, transparent); + color: var(--amber); + padding: 0.45em 0.8em; + margin-bottom: 0.6em; + border-radius: 4px; +} +.queue-summary strong { color: var(--amber); } +.queue-summary-link { + margin-left: auto; + color: var(--amber); + text-decoration: none; + font-weight: bold; + white-space: nowrap; +} +.queue-summary-link:hover { text-decoration: underline; } + /* .notif-row / .btn-notif moved to settings.css with the S3TT1NGS page. */ diff --git a/frontend/packages/dashboard/src/tabs.js b/frontend/packages/dashboard/src/tabs.js index 6f0b6ecd..0b3325cd 100644 --- a/frontend/packages/dashboard/src/tabs.js +++ b/frontend/packages/dashboard/src/tabs.js @@ -808,19 +808,26 @@ window.marked = marked; )); } - if (transientsState.size) { - const ul = el('ul'); - const nowUnix = Math.floor(Date.now() / 1000); - for (const [name, t] of transientsState) { - const secs = Math.max(0, nowUnix - t.since_unix); - ul.append(el('li', {}, - el('span', { class: 'glyph spinner' }, '◐'), ' ', - el('span', { class: 'agent' }, name), ' ', - el('span', { class: 'role role-pending' }, t.kind + '…'), ' ', - el('span', { class: 'meta' }, `nixos-container create + start (${secs}s)`), - )); - } - root.append(ul); + // Queue-summary banner: when the rebuild queue has active work, + // show one compact at-a-glance line + a link to the full queue on the + // C0R3 page. Replaces the old per-transient spinner list — the actual + // running step is already visible per-agent on each card (transient + + // in-flight-queue badges), so the top of the tab only needs the summary. + const activeQueue = rebuildQueueState.filter( + (e) => e.state === 'queued' || e.state === 'running', + ); + if (activeQueue.length) { + const running = activeQueue.filter((e) => e.state === 'running').length; + const queued = activeQueue.length - running; + const parts = []; + if (running) parts.push(`${running} running`); + if (queued) parts.push(`${queued} queued`); + root.append(el('div', { class: 'queue-summary' }, + el('span', { class: 'glyph spinner' }, '◐'), ' ', + el('strong', {}, 'build queue'), ' — ', + parts.join(' · '), ' ', + el('a', { class: 'queue-summary-link', href: '/core.html' }, 'view queue →'), + )); } if (!containers.length && !transientsState.size) {