dashboard: replace agent-tab transient list with build-queue summary banner

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.
This commit is contained in:
iris 2026-06-21 21:43:05 +02:00 committed by mara
commit 6bb976ec72
3 changed files with 53 additions and 13 deletions

View file

@ -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) {