dashboard: replace <hive-jobq-graph> with a shared Preact component
Ports the shadow-DOM <hive-jobq-graph> custom element
(frontend/packages/shared/src/jobq-graph/) to a Preact component
(JobqGraph.js) shared by the dashboard and swarm-ui, per hyperhive#3310.
- JobqGraph.js: written with plain h() calls (no JSX) so the same file
compiles unmodified under both the dashboard's text-loader CSS config
and swarm-ui's JSX config. Exports `JobqGraph` for JSX use and
`mountJobqGraph(container, props)` for the dashboard's non-JSX
imperative mount, returning a `{refresh(), update()}` handle matching
the old custom element's public surface. Same rendering contract as
before: indented state tree, payload.label verbatim, payload.data as
a generic key/value list, "waits on: <label>" text for Node-kind deps,
per-state filter checkboxes, optional cancel button.
- jobq-graph.css: light-DOM adaptation of the old shadow-scoped
stylesheet (:host -> .jg-root, otherwise unchanged).
- dashboard/src/builds.js: local mountJobqGraph() renamed to
mountRebuildQueue() to avoid colliding with the newly-imported shared
mountJobqGraph; cancel handling is now a plain onCancel callback
instead of a DOM CustomEvent listener (no shadow boundary to cross
anymore).
- dashboard + shared package.json: added preact as a dependency (matches
swarm-ui's existing pin, 10.29.8) - the dashboard was a vanilla-JS MPA
with no Preact/JSX pipeline before this.
- Removed the old hive-jobq-graph.js/.css entirely (confirmed via grep
it had exactly one consumer, dashboard/src/builds.js, so this is a
clean swap, not parallel maintenance of two implementations).
- Updated stale doc-comment references to the old element name in
builds.html, tabs.js, swarm.js, docs/web-ui/dashboard.md, and
hive-c0re/src/job_queue/mod.rs.
Verified: npm run build (whole frontend workspace) and npm run
typecheck (swarm-ui) both clean; cargo build/clippy/test -p hive-c0re
all clean (331 tests, 0 failures); headless-chromium screenshot of
/builds.html against a mock GET /api/jobq/graph payload confirms full
visual/behavioral parity with the old custom element (tree, filter
checkboxes, cancel buttons, error text, waits-on line, data list, live
build log panel).
This covers the dashboard-replacement half of hyperhive#3310 only. The
swarm-ui half (rendering the CreateAgent DAG on the agent-creation page)
is downstream of hyperhive#3306/#3124 landing - no swarm-ui page exists
yet to mount it in.
This commit is contained in:
parent
bad5285f2e
commit
37161cd136
13 changed files with 344 additions and 336 deletions
|
|
@ -228,16 +228,18 @@ not the graph.
|
|||
**R3BU1LD QU3U3** — pending, in-flight, and recently-settled container
|
||||
operations: rebuilds, meta-update cascades, and first-spawns. One
|
||||
operation runs at a time; the worker drains FIFO. **Is a mounted
|
||||
`<hive-jobq-graph endpoint="/api/jobq/graph">`** (the shared generic
|
||||
graph-viewer component, `@hive/shared/jobq-graph.js`) — `builds.js`
|
||||
does not render the queue itself; it just mounts the element and
|
||||
listens for its `hive-jobq-graph-update` event to drive the two things
|
||||
below it that the generic view doesn't show. The component owns
|
||||
fetching, cold and live: `GET /api/jobq/graph` on mount, and
|
||||
`.refresh()` on every `rebuild_queue_changed` SSE tick (that event is a
|
||||
bare `{ seq }` trigger — it carried a typed queue snapshot until every
|
||||
consumer had moved to the generic endpoint, and now carries none; both
|
||||
dashboard pages treat the tick as a pure refetch trigger).
|
||||
`JobqGraph`** (the shared generic graph-viewer Preact component,
|
||||
`@hive/shared/jobq-graph.js` — the same one swarm-ui uses, a Preact port
|
||||
of the former shadow-DOM `<hive-jobq-graph>` custom element) — `builds.js`
|
||||
does not render the queue itself; it just mounts the component
|
||||
(`mountJobqGraph(container, props)`, since this page has no JSX
|
||||
pipeline) with an `onUpdate` callback to drive the two things below it
|
||||
that the generic view doesn't show. The component owns fetching, cold
|
||||
and live: `GET /api/jobq/graph` on mount, and a refetch via the mount
|
||||
handle's `.refresh()` on every `rebuild_queue_changed` SSE tick (that
|
||||
event is a bare `{ seq }` trigger — it carried a typed queue snapshot
|
||||
until every consumer had moved to the generic endpoint, and now carries
|
||||
none; both dashboard pages treat the tick as a pure refetch trigger).
|
||||
|
||||
Each row is one root graph node (`parent: null`); a multi-step op's
|
||||
per-agent subgraphs and sub-steps render as nodes within that one
|
||||
|
|
@ -250,10 +252,10 @@ as a plain "waits on: `<label>`" text line under the row rather than a
|
|||
gutter rail — a rail breaks visually whenever a nested subtree sits
|
||||
between the two related rows, since a text line needs no continuous
|
||||
vertical space to draw.
|
||||
`builds.js` mounts the element with `cancellable` set, which turns on
|
||||
`builds.js` mounts the component with `cancellable` set, which turns on
|
||||
a per-node cancel button (`✕`) on any non-terminal row — the button
|
||||
dispatches `hive-jobq-graph-cancel`, and the page does the actual
|
||||
`POST /api/rebuild-queue/{id}/cancel`, matching the wire event as its
|
||||
calls the mount's `onCancel(id)` callback, and the page does the actual
|
||||
`POST /api/rebuild-queue/{id}/cancel`, matching that callback to its
|
||||
own domain concept (the component knows nothing about that endpoint).
|
||||
**Rows carry no source chip, kind label, timing, or build-log
|
||||
deep-link** — the generic graph wire doesn't carry those fields, and
|
||||
|
|
@ -266,7 +268,7 @@ does not filter `Done` nodes out.
|
|||
the tree — one per lifecycle state, matching the row glyphs — lets the
|
||||
operator narrow which root groups render; unchecking a state re-fetches
|
||||
`GET /api/jobq/graph?states=<checked, comma-joined>` rather than
|
||||
hiding rows client-side, so `hive-jobq-graph-update`'s node list (and
|
||||
hiding rows client-side, so the `onUpdate` callback's node list (and
|
||||
everything downstream of it — the count pill, the live-log panel) only
|
||||
ever sees what's actually shown. Filtering is by a **root's own**
|
||||
state, which is already its subtree's rolled-up answer, so a group is
|
||||
|
|
@ -284,16 +286,16 @@ Below the queue, a **live build-log panel** (`#rebuild-live-log`,
|
|||
`renderRebuildLiveLog`) shows the currently-running rebuild's output
|
||||
inline — collapsible, with a live/ok/fail badge and a `↓ raw`
|
||||
download. It's keyed to the first `Running` node (in wire order)
|
||||
whose `payload.data.build_log_id` is set — read from the
|
||||
`hive-jobq-graph-update` event's node list, same source as the count
|
||||
pill, no separate fetch — and **polls** `GET /api/build-log/{id}`
|
||||
every 2s (`fetchAndRenderLiveLog` / `liveLogPollTimer`); not an
|
||||
`EventSource` (that's the BUILD L0GS tab's own per-row expand view
|
||||
below — `GET /api/build-logs/id/{id}/stream`, real SSE, replays
|
||||
accumulated output on connect — a separate mechanism). The live-log
|
||||
panel lives in its own container outside `#rebuild-queue-section` so
|
||||
the mounted `<hive-jobq-graph>`'s own re-renders never disturb the
|
||||
open poll; it hides when nothing is building.
|
||||
whose `payload.data.build_log_id` is set — read from the `onUpdate`
|
||||
callback's node list, same source as the count pill, no separate
|
||||
fetch — and **polls** `GET /api/build-log/{id}` every 2s
|
||||
(`fetchAndRenderLiveLog` / `liveLogPollTimer`); not an `EventSource`
|
||||
(that's the BUILD L0GS tab's own per-row expand view below — `GET
|
||||
/api/build-logs/id/{id}/stream`, real SSE, replays accumulated output
|
||||
on connect — a separate mechanism). The live-log panel lives in its
|
||||
own container outside `#rebuild-queue-section` so the mounted
|
||||
`JobqGraph`'s own re-renders never disturb the open poll; it hides
|
||||
when nothing is building.
|
||||
|
||||
**M3T4 1NPUTS** — inputs in `meta/flake.lock` the operator can
|
||||
selectively `nix flake update`, rendered as an indented tree:
|
||||
|
|
|
|||
Loading…
Reference in a new issue