Pure `nix fmt` output from the commit before this one — no hand edits. 203 files: 52 md, 42 tsx, 32 js, 32 css, 21 ts, 13 html, 8 json, 3 mjs. Reproduce with `nix develop -c nix fmt` on the parent commit; the result should be byte-identical to this tree. None of the 13 `.prettierignore` entries appears here — verified by intersecting the changed-file list against the ignore file, with a control proving the intersection finds a match when one exists.
68 lines
3 KiB
TypeScript
68 lines
3 KiB
TypeScript
// <JobsPage> — the swarm-level job graph. Reuses the shared JobqGraph
|
|
// component (originally built for the per-hive dashboard's rebuild
|
|
// queue) pointed at swarm-controller's own GET /api/jobq/graph instead
|
|
// of hive-c0re's — same wire shape (Vec<hive_jobq_wire::GraphNode>),
|
|
// different endpoint, no component fork. swarm-controller's graph has
|
|
// no real node kinds wired in yet (see swarm-controller/src/main.rs's
|
|
// SwarmNodeKind/SwarmResourceKind), so this renders an empty tree today
|
|
// — the page exists so the wiring is in place before the first real
|
|
// swarm-level job (e.g. CreateAgent) lands.
|
|
//
|
|
// JobqRollup sits above the graph, same "N running / M queued" banner
|
|
// the dashboard's SW4RM tab shows — no `queueHref`, since a "view
|
|
// queue →" link back to this same page would be noise.
|
|
//
|
|
// Auto-refresh reuses `HivesPage`'s exact pattern (`RefreshIntervalPicker`
|
|
// in the `Panel`'s `actions` slot, `useRefreshInterval` driving the
|
|
// re-fetch), but ticks a `refreshToken` bump instead of doing its own
|
|
// fetch — both `JobqGraph`/`JobqRollup` already accept that prop
|
|
// (bumping it is their documented "refetch now" lever) since the
|
|
// dashboard's own rebuild-queue view needed the same thing first.
|
|
import { useState } from "preact/hooks";
|
|
import { JobqGraph } from "@hive/shared/jobq-graph.js";
|
|
import { JobqRollup } from "@hive/shared/jobq-rollup.js";
|
|
import { Panel } from "../ui/panel/Panel.js";
|
|
import {
|
|
RefreshIntervalPicker,
|
|
useRefreshInterval,
|
|
type RefreshIntervalMs,
|
|
} from "../ui/refresh-interval/RefreshInterval.js";
|
|
import "./JobsPage.css";
|
|
|
|
// Same 30s default + same reasoning as `HivesPage`: no inputs on this
|
|
// page for a refresh to clobber, so the out-of-the-box behaviour should
|
|
// just solve staleness rather than require an opt-in every visit.
|
|
const DEFAULT_INTERVAL_MS: RefreshIntervalMs = 30_000;
|
|
|
|
export function JobsPage() {
|
|
const [intervalMs, setIntervalMs] =
|
|
useState<RefreshIntervalMs>(DEFAULT_INTERVAL_MS);
|
|
const [refreshToken, setRefreshToken] = useState(0);
|
|
|
|
// `useRefreshInterval` ticks once immediately on mount (by design —
|
|
// see its own doc comment), which lands on top of `JobqGraph`'s /
|
|
// `JobqRollup`'s own unconditional mount-time fetch and costs one
|
|
// harmless duplicate request on page load. Not worth a special case
|
|
// in the shared hook for: the alternative (skip the first tick) would
|
|
// need every other `useRefreshInterval` caller to reason about
|
|
// whether it's the sole fetcher or not, for a one-page, one-time,
|
|
// zero-user-visible-effect cost here.
|
|
useRefreshInterval(intervalMs, () => setRefreshToken((t) => t + 1));
|
|
|
|
return (
|
|
<Panel
|
|
title="jobs"
|
|
icon="🧩"
|
|
actions={
|
|
<RefreshIntervalPicker
|
|
id="jobs-refresh"
|
|
value={intervalMs}
|
|
onChange={setIntervalMs}
|
|
/>
|
|
}
|
|
>
|
|
<JobqRollup endpoint="/api/jobq/rollup" refreshToken={refreshToken} />
|
|
<JobqGraph endpoint="/api/jobq/graph" refreshToken={refreshToken} />
|
|
</Panel>
|
|
);
|
|
}
|