dashboard: tab-bar restructure + extract FL0W to /flow.html (#369)
Operator: 'option A (tabs)' (#369#issuecomment-3434) + 'yes terminal can be a separate page' (#369#issuecomment-3437). ## Tab framework `index.html` becomes a 3-tab dashboard with a sticky chrome header: - `◆ SW4RM ◆` — containers list (the central thing) - `◆ Y3R C4LL ◆` — pending approvals + operator-targeted questions - `◆ SYST3M ◆` — meta inputs + rebuild queue + reminders + tombstones Hash routing: `#swarm` / `#call` / `#system` (empty → SW4RM). F5-reloadable + back-button-aware without a router framework. SSE stays alive across tab switches — count pills on inactive tabs update live so the operator never loses pulse on what's happening elsewhere: - SW4RM: containers with needs_update - Y3R C4LL: approvals.pending + questions.pending (attn-coloured pill) - SYST3M: rebuild_queue entries in Queued|Running Pills hidden when count is zero. setInterval(1s) polls the existing state stores (cheap, no per-renderer hookup needed). ## FL0W as its own page The all-agents chat moves to /flow.html — full-viewport vibec0re layout mirroring the per-agent live page (#362): - Fixed-overlay frosted-glass header at top (back link + title + notif controls), backdrop-filter blur shows the scrolled chat text behind. - Full-viewport terminal, scroll-padded for the floating chrome so first/last rows stay reachable. - Fixed-overlay frosted composer at the bottom. - Operator inbox surfaces via a pill (📬 inbox · N) in the upper right — click opens the side-panel flyout with the message list. In the dashboard tab strip, FL0W is the right-most entry but renders as a `<a class="tab tab-link" href="/flow.html">` — clicking navigates to the page rather than swapping a pane. Same pattern back from flow.html via the `← d4shb04rd` link. ## Implementation notes - New `/flow.html` page rendered by the same bundled `app.js` — the flow page just doesn't have the dashboard-chrome DOM, so the matching renderers no-op silently (each `if (!el) return`). Avoids splitting the bundle for v1; can extract later if size becomes a concern. - `Panel` module gains `openNamed(name, …)` + `refresh(name, …)` — the legacy untyped `open(title, content)` calls clear the owner, so file-preview / diff / log drill-ins behave unchanged. `refresh` is no-op when a different view owns the panel, so live message events re-render the inbox flyout only when it's actually open. - `renderInbox` updates BOTH the dashboard's inline `#inbox-section` (now living on the flow page) AND the flow page's pill count + side-panel refresh. The dashboard's empty FL0W tab is removed — inbox + message flow + compose box only exist in flow.html. - Banner shrinks to a thin Catppuccin gradient strip at the top of the dashboard chrome (dropped the multi-line ASCII art — affectionate but pure chrome budget in a tabbed layout). - `build.mjs` copies both `index.html` + `flow.html` into dist. ## Validation `npm run build` clean. Dashboard bundle deltas: app.js 150kb → 152kb (tab routing + count pills + named-Panel) dashboard.css 33kb → 38kb (tab chrome + flow page layout) + dist/flow.html 4.4kb Browser smoke test isn't possible from inside iris's container (no JS engine) — drafting as a PR for operator visual review on next deploy. Worth eyeballing: - Tab switching feels right; counts update live across SSE events - FL0W page reads like the agent live page (frosted header + composer) - Inbox pill opens flyout; live message arrivals refresh it - Back link from flow → dashboard returns to last tab via the URL hash (browser remembers the hash across page nav) Closes #369.
This commit is contained in:
parent
8c7bc850f3
commit
9666cb8c3f
5 changed files with 627 additions and 86 deletions
|
|
@ -48,6 +48,8 @@ await build({
|
|||
logLevel: 'info',
|
||||
});
|
||||
|
||||
copyFileSync(src('index.html'), dist('index.html'));
|
||||
for (const html of ['index.html', 'flow.html']) {
|
||||
copyFileSync(src(html), dist(html));
|
||||
}
|
||||
|
||||
console.log('dashboard build ok →', dist(''));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue