diff --git a/frontend/packages/dashboard/src/core.css b/frontend/packages/dashboard/src/core.css index bc16c365..f17ac635 100644 --- a/frontend/packages/dashboard/src/core.css +++ b/frontend/packages/dashboard/src/core.css @@ -1,6 +1,21 @@ /* ─── /core.html — C0R3 page ─────────────────────────────────────── - Kept state (tombstones) and container load. Section rules imported - from system-sections.css (shared with dashboard.css + builds.css). */ + Standalone page for kept state (tombstones) and container load. + Same minimal-chrome pattern as /logs.html (a `← home` back-link + + a createTabStrip sub-tab strip; base tab + page-header styling comes + from @hive/shared via common.css, linked by core.html). + + The section renderers (kept state, container load) emit the same + class names as before. Those section-internal rules live in + system-sections.css (shared with dashboard.css and builds.css, which + references `.rqe-source*` from the schedules view). The + `.hive-stats-table` the container-load table reuses lives in + common.css, linked directly by core.html. Importing just the section + rules keeps the C0R3 bundle small instead of dragging in all of + dashboard.css. + + Rebuild queue + meta inputs have moved to /builds.html; the + `.rebuild-live-log-*` styles that used to live here have moved to + system-sections.css so builds.css can share them via @import. */ @import "./system-sections.css"; body.core-shell { diff --git a/frontend/packages/dashboard/src/schedules.js b/frontend/packages/dashboard/src/schedules.js index e81d70b5..168e7d39 100644 --- a/frontend/packages/dashboard/src/schedules.js +++ b/frontend/packages/dashboard/src/schedules.js @@ -683,7 +683,11 @@ function renderScheduleRow(s, agents) { tr.append(el('td', { class: 'meta' }, s.owner)); - // Body cell — truncates with ellipsis; full body + description on hover. + // Body cell — truncates with ellipsis; full body + description (if + // any) on hover. Description used to be a separate visible block on + // the card layout; the table compresses it into the title to keep + // row height tight. Mara nit-flag candidate if she actually wants + // it visible in-table. const bodyCell = el('td', { class: 'schedules-table-body-cell' }); const bodyText = s.body || ''; bodyCell.title = (s.description ? s.description + '\n\n' : '') + bodyText; diff --git a/frontend/packages/dashboard/src/stream-worker.js b/frontend/packages/dashboard/src/stream-worker.js index 06ae6b90..065b0e5a 100644 --- a/frontend/packages/dashboard/src/stream-worker.js +++ b/frontend/packages/dashboard/src/stream-worker.js @@ -1,6 +1,16 @@ // SharedWorker that holds ONE EventSource per stream URL and fans // every server-sent event out to every connected tab via MessagePort. -// Design rationale: docs/web-ui/shape.md (SSE multiplexing paragraph). +// +// Problem this solves: every dashboard / agent tab opens its own +// `EventSource('/api/dashboard/stream')`. Browsers cap concurrent +// connections per host (~6), and Firefox throttles / disconnects +// background tabs when many are open. The result: tabs silently +// drop the SSE, fall behind, and only catch up on focus. +// +// Centralising the connection in a SharedWorker means N tabs share +// ONE backend EventSource regardless of focus state — way under the +// per-host cap, immune to per-tab throttling, and the worker survives +// any individual tab being suspended. // // Wire protocol (port.postMessage payloads): // @@ -32,7 +42,8 @@ // signal to the client). // // Subscriptions are tracked per (port, url): a single port can -// subscribe to multiple URLs (only one is in use today). +// subscribe to multiple URLs (today only one is in use but the shape +// stays open for the per-agent /events/stream multiplexing follow-up). // Unsubscribing the last port for a URL closes the EventSource so we // don't keep idle streams open. diff --git a/frontend/packages/dashboard/src/system-sections.css b/frontend/packages/dashboard/src/system-sections.css index 480eb0c9..c8dc95d2 100644 --- a/frontend/packages/dashboard/src/system-sections.css +++ b/frontend/packages/dashboard/src/system-sections.css @@ -1,7 +1,22 @@ /* ─── SYST3M/BU1LDS section panels — shared by dashboard, /core.html, and /builds.html ────────────────────────────────────────────────── - Rebuild queue, meta inputs, kept state, and container-load panels. - Imported by core.css, dashboard.css, and builds.css. */ + The rebuild queue, meta inputs, kept state, and container-load panels + render on /core.html; rebuild queue + meta inputs + live-log also + render on /builds.html (the build lifecycle hub). These + section-internal rules used to live in dashboard.css and were pulled + in by /core.html via a wholesale `@import "./dashboard.css"`, which + dragged the entire ~39kb dashboard stylesheet into the bundle. + + They now live here and are `@import`ed by core.css, dashboard.css, + and builds.css. Each page gets only this small file instead of all + of dashboard.css; the dashboard keeps the rules (a couple are still + referenced from dashboard JS — `.rqe-source*` by the schedules view, + and `.hive-stats-table`, which already lives in common.css and is + loaded by all pages). Behaviour-preserving: identical rules, same + custom properties from colors.css / theme.css / common.css. + + The selectors here are uniquely named to these panels and are not + redefined elsewhere, so the cascade is unaffected by the move. */ /* ─── meta inputs panel ────────────────────────────────────────────── */ .meta-inputs { diff --git a/frontend/packages/dashboard/src/tabs.js b/frontend/packages/dashboard/src/tabs.js index 1da887f3..6220ac44 100644 --- a/frontend/packages/dashboard/src/tabs.js +++ b/frontend/packages/dashboard/src/tabs.js @@ -129,8 +129,13 @@ window.marked = marked; if (containersState.delete(ev.name)) renderContainersFromState(); } - // Rebuild queue state — drives "building…" / "meta-updating…" badges on - // SW4RM agent cards (see inFlightOpsByAgent + docs/web-ui.md::Container row). + // Derived rebuild queue state — cold-loaded from + // `/api/state.rebuild_queue`, then mutated live by the + // `rebuild_queue_changed` snapshot event. The SYST3M tab that used to + // render this list moved to the standalone /core.html page; the + // dashboard keeps the STATE because it drives the "building…" / + // "meta-updating…" badges on the SW4RM agent cards (see + // inFlightOpsByAgent + docs/web-ui.md::Container row). let rebuildQueueState = []; function syncRebuildQueueFromSnapshot(s) { rebuildQueueState = (s.rebuild_queue || []).slice();