Watch
0
0
Fork
You've already forked hyperhive
0

dashboard: the build pages are tabs of the dashboard

The build lifecycle used to be its own page with three sub-tabs. They are
now dashboard tabs (rebuild, meta, buildlogs) beside SW4RM and
P3RM1SS10NS: builds.js is a module tabs.js imports, so the dashboard's one
tab strip, /api/state snapshot and event stream (plus the meta_inputs_changed
and meta_update_running kinds) serve them, and the page, its bundle entry,
stylesheet and home tile are gone. The SW4RM banner's "view queue" link
points at the #rebuild tab, and the rebuild tab carries a count pill of the
rebuilds in flight.

An empty tab-count pill drew a "0": its display beat the UA [hidden] rule.
This commit is contained in:
iris 2026-10-14 20:18:16 +02:00 • committed by mara
commit ee5c057d8f
22 changed files with 386 additions and 456 deletions

View file

@ -34,6 +34,15 @@ import {
renderContainers,
renderSelectionBar,
} from "./swarm.js";
import {
initBuilds,
onBuildsTabShown,
onMetaInputsChanged,
onMetaUpdateRunning,
onRebuildQueueChanged,
rebuildCount,
syncBuildsFromSnapshot,
} from "./builds.js";
// mdNode (in common.js) reads `window.marked` for the markdown side
// panel preview path. Set it here on the dashboard entry so file
@ -146,6 +155,7 @@ window.marked = marked;
// initJobqRollup mounts once and is a no-op on later calls; the
// mount's own effect handles the actual fetch.
initJobqRollup();
syncBuildsFromSnapshot(s);
renderContainers(s);
restoreOpenDetails(openDetails);
// No periodic refresh timer. Phase 6 covers every container
@ -191,11 +201,15 @@ window.marked = marked;
transient_cleared: applyTransientCleared,
container_state_changed: applyContainerStateChanged,
container_removed: applyContainerRemoved,
// rebuild_queue_changed: refreshes the SW4RM queue-summary banner
// (see swarm.js) — a payload-less push trigger, same treatment
// /builds.html gives it for its JobqGraph mount handle's .refresh()
// (its own separate subscription).
rebuild_queue_changed: applyRebuildQueueChanged,
// rebuild_queue_changed: a payload-less push trigger. Refreshes the
// SW4RM queue-summary banner (see swarm.js) and the R3BU1LD QU3U3
// tab's JobqGraph (see builds.js).
rebuild_queue_changed: () => {
applyRebuildQueueChanged();
onRebuildQueueChanged();
},
meta_inputs_changed: onMetaInputsChanged,
meta_update_running: onMetaUpdateRunning,
capabilities_changed: applyCapabilitiesChanged,
tool_groups_changed: applyToolGroupsChanged,
};
@ -208,11 +222,12 @@ window.marked = marked;
// fallback when SharedWorker isn't supported.
//
// kinds= matches MUTATION_HANDLERS verbatim, so the stream carries
// only the 7 wire kinds this page acts on.
// only the 9 wire kinds this page acts on.
const es = openStream(
"/api/dashboard/stream?kinds=" +
"transient_set,transient_cleared," +
"container_state_changed,container_removed,rebuild_queue_changed," +
"meta_inputs_changed,meta_update_running," +
"capabilities_changed,tool_groups_changed",
);
es.onmessage = (e) => {
@ -245,8 +260,8 @@ window.marked = marked;
})();
// ─── tab routing ───────────────────────────────────────────────────────
// Hash-based: `#swarm` / `#system` / `#permissions` activate the
// matching pane on the dashboard. Empty
// Hash-based: `#swarm` / `#rebuild` / `#meta` / `#buildlogs` /
// `#permissions` activate the matching pane on the dashboard. Empty
// hash defaults to SW4RM. FL0W and ST4TS are NOT tabs —
// they're separate pages (`/flow.html`, `/stats.html`) reached from
// the H0M3 hub. Tab routing only
@ -272,6 +287,7 @@ window.marked = marked;
fetchAndRenderCapabilities();
fetchAndRenderToolGroups();
}
onBuildsTabShown(target);
}
// Wire the shared tab strip now that activateTab + the lazy-load fns it
@ -279,6 +295,9 @@ window.marked = marked;
// (default SW4RM), toggles the active tab/pane + aria-selected, and
// fires activateTab for the per-tab side-effects on every change.
createTabStrip($("tabbar"), { defaultId: "swarm", onShow: activateTab });
// The rebuild queue mounts now, not on first show, so its tab's count pill
// is live from the start.
initBuilds();
// Tab count pills — pure derived data from the existing state
// stores so SSE-driven updates flow through without extra plumbing.
@ -302,6 +321,8 @@ window.marked = marked;
if (c.needs_update) swarm++;
}
setTabCount("swarm", swarm);
// R3BU1LD QU3U3 — rebuilds in flight.
setTabCount("rebuild", rebuildCount());
}
// Poll the state stores on a 1s tick to keep the pill counts in
// sync. The state stores are mutated synchronously by every SSE