jobq graph: state filter on /api/jobq/graph + multi-select checkboxes

GET /api/jobq/graph gains a states query param (comma-separated
hive_jobq::State names): narrows the served root groups to the named
states, keeping a group whole (filtering by a root's own state, which
is already its subtree's rolled-up answer). Absent, empty, or fully
unrecognised is the identity filter, matching prior behaviour.

hive-jobq-graph.js gains a row of per-state checkboxes above the tree,
re-fetching the endpoint with the selection on toggle. Default
selection hides Done and Skipped.

Server-side filtering (not client-side hiding) so hive-jobq-graph-update's
node list, and everything downstream of it in builds.js (count pill,
live-log panel), only ever sees what's actually shown.
This commit is contained in:
iris 2026-08-10 22:50:42 +02:00 committed by mara
commit 1e13b88c8c
6 changed files with 236 additions and 27 deletions

View file

@ -255,6 +255,24 @@ Settled entries render their **full step tree**, not just a bare
summary — unlike the old `DagView` projection, this wire does not
filter `Done` nodes out.
**State filter (hyperhive#2606).** A row of per-state checkboxes above
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
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
kept or dropped whole, never split mid-tree. Default selection is
every state **except** `Done`/`Skipped` — a fresh queue view leads
with what's still moving or needs attention, not the settled tail; the
`states` param is omitted entirely (identical request to before this
filter existed) when every state is checked. Server-side: the query
narrows [`Queue::graph_snapshot`]'s already-bounded (`MAX_HISTORY_DAGS`)
root set — the history cap and the state filter are independent
concerns, so a narrow filter never reaches further back in time to
compensate.
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`