From a2c5348ca4b1fafbaaa906d0ecc0359009217543 Mon Sep 17 00:00:00 2001 From: iris Date: Tue, 26 May 2026 19:39:27 +0200 Subject: [PATCH] =?UTF-8?q?dashboard:=20rename=20src/app.js=20=E2=86=92=20?= =?UTF-8?q?src/tabs.js=20(closes=20#406)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #406 was the JS-split refactor: pull shared helpers into common.js (step 1), pull the flow-only IIFEs into flow.js (step 2), then rename the legacy combined entry from app.js to tabs.js (step 3 — this commit) to reflect that the bundle now owns the dashboard tabs surface only. What moved: - `frontend/packages/dashboard/src/app.js` → `tabs.js` - `build.mjs` entry: `src('app.js')` → `src('tabs.js')`; output is now `static/tabs.js` - `index.html` ` diff --git a/frontend/packages/dashboard/src/flow.js b/frontend/packages/dashboard/src/flow.js index 41487071..eefe8710 100644 --- a/frontend/packages/dashboard/src/flow.js +++ b/frontend/packages/dashboard/src/flow.js @@ -1,4 +1,6 @@ -// /flow.html entry point (#406 step 2 — flow-specific split from app.js). +// /flow.html entry point (#406 step 2 — flow-specific split from the +// previous combined entry; #406 step 3 renamed that combined entry +// from `app.js` to `tabs.js`). // // Owns the full-page broker terminal, the operator-inbox derived store // (populated from the broker stream), the inbox pill flyout, and the @@ -6,10 +8,10 @@ // panel, OS notifications, path linkification) from `./common.js`. // // Does NOT contain the dashboard's tab renderers, mutation-event -// dispatchers, or refreshState — that's `./app.js` (the legacy entry -// kept until step 3 renames it to `tabs.js`). For now the flow page -// runs purely on the broker stream + an initial /api/state fetch -// (compose autocomplete needs the live container list). +// dispatchers, or refreshState — that's `./tabs.js`, loaded only by +// /index.html. The flow page runs purely on the broker stream + an +// initial /api/state fetch (compose autocomplete needs the live +// container list). import { create as termCreate } from '@hive/shared/terminal.js'; import { diff --git a/frontend/packages/dashboard/src/index.html b/frontend/packages/dashboard/src/index.html index 834ca0b5..a14e24e4 100644 --- a/frontend/packages/dashboard/src/index.html +++ b/frontend/packages/dashboard/src/index.html @@ -173,7 +173,7 @@ @@ -216,9 +216,11 @@ title="clear selection (esc)">✕ clear - - + + diff --git a/frontend/packages/dashboard/src/app.js b/frontend/packages/dashboard/src/tabs.js similarity index 98% rename from frontend/packages/dashboard/src/app.js rename to frontend/packages/dashboard/src/tabs.js index 87fb01a9..11aa7be1 100644 --- a/frontend/packages/dashboard/src/app.js +++ b/frontend/packages/dashboard/src/tabs.js @@ -1,16 +1,18 @@ // /index.html entry point: tab renderers + tab routing + refreshState // + notification deltas. Reads /api/state on cold load and after every // async-form submit; live updates run through `applyXxx` mutation -// handlers triggered by the dashboard event stream. (Live SSE -// subscription on /index.html is still missing — see #406 step 3 / #408.) +// handlers triggered by the dashboard event stream. // // #406 step 1: pure helpers + side panel + OS notifications + path // linkification moved to `./common.js`. // #406 step 2: the flow-only IIFEs (operator inbox, inbox-pill, broker -// terminal, @-mention composer) moved to `./flow.js`. /flow.html now -// loads `flow.js` as its own bundle entry; this file (still named -// `app.js` for the moment; rename to `tabs.js` is the last step -// of #406) is loaded only by /index.html. +// terminal, @-mention composer) moved to `./flow.js`. /flow.html loads +// `flow.js` as its own bundle entry; this file is loaded only by +// /index.html. +// #406 step 3: file renamed from `app.js` → `tabs.js` since it owns +// the dashboard *tabs* surface only (the FL0W page has its own bundle). +// Live SSE subscription is wired through `openStream` from common.js +// (#406 step 3 hookup; see also #408 for stream-side filtering). import { marked } from 'marked'; import { @@ -446,14 +448,17 @@ window.marked = marked; function renderContainers(s) { const root = $('containers-section'); - // #containers-section only exists on /index.html. The same - // bundled app.js runs on /flow.html (which has the broker - // terminal but no container list) and on any future pages — - // `container_state_changed` SSE events arrive on every page and - // route through `applyContainerStateChanged → renderContainersFromState`, - // so without this guard the renderer throws `root is null` on - // every event (#399). Matches the no-op-when-target-absent - // convention the other renderers (renderTombstones, etc.) follow. + // #containers-section only exists on /index.html. tabs.js is the + // bundle for that page only (#406 step 3 — /flow.html loads + // flow.js instead), but historical context: pre-split the + // `container_state_changed` SSE handler routed through + // `applyContainerStateChanged → renderContainersFromState` on + // every page that loaded the single combined bundle, and the + // guard prevented a `root is null` throw on /flow.html (#399). + // Today it's belt-and-suspenders for any future page that adds + // tabs.js without a #containers-section. Matches the + // no-op-when-target-absent convention the other renderers + // (renderTombstones, etc.) follow. if (!root) return; root.innerHTML = ''; @@ -1102,9 +1107,10 @@ window.marked = marked; function renderQuestions() { const root = $('questions-section'); // #questions-section only lives on /index.html (Y3R C4LL tab); - // no-op on /flow.html etc. — the bundled app.js runs everywhere - // and `question_added` / `question_resolved` SSE events route - // through here (#399). + // no-op when missing (#406 step 3 — only /index.html loads + // tabs.js, but kept as belt-and-suspenders for any future page + // adding it without that section). `question_added` / + // `question_resolved` SSE events route through here (#399). if (!root) return; root.innerHTML = ''; const fmt = (n) => new Date(n * 1000).toISOString().replace('T', ' ').slice(0, 19);