Watch
0
0
Fork
You've already forked hyperhive
0

swarm-ui: pages that only display start from the answer they last saw, then refresh behind it

usePolled takes a cache key: it saves each answer in localStorage and starts
from the saved one, so opening the agents, alerts, builds, review runs or hives
view shows the last data at once and the refresh spinner marks the update. A
saved answer is dropped after a day, when it was saved by another build of the
UI, at log out (a new onLogout of the shared user menu) and when the gateway
ends the login (a new onSessionEnded of the session guard). Pages with an
editor (schedules, notification flows, broadcast) do not use it.
This commit is contained in:
iris 2026-11-05 23:14:25 +01:00
commit fd51cbd19d
5 changed files with 238 additions and 14 deletions

View file

@ -79,8 +79,10 @@ function AlertsBody() {
data: alerts,
error,
refreshing,
} = usePolled(intervalMs, (signal) =>
fetchJson<Alert[]>("/api/alerts", signal),
} = usePolled(
intervalMs,
(signal) => fetchJson<Alert[]>("/api/alerts", signal),
{ cacheKey: "alerts" },
);
const listed = alerts ? listedAlerts(alerts, showAll) : null;
const hidden = alerts && listed ? alerts.length - listed.length : 0;

View file

@ -100,8 +100,10 @@ export function AgentsPage() {
error,
refreshing,
setData: setRows,
} = usePolled(intervalMs, (signal) =>
fetchJson<AgentRow[]>("/api/agents/status", signal),
} = usePolled(
intervalMs,
(signal) => fetchJson<AgentRow[]>("/api/agents/status", signal),
{ cacheKey: "agents" },
);
const [createOpen, setCreateOpen] = useState(false);
// The PUT response is the hive's whole declaration set (every agent's

View file

@ -100,7 +100,9 @@ function BuildsBody() {
data: runs,
error,
refreshing,
} = usePolled(intervalMs, (signal) => fetchJson<BuildRun[]>(RUNS, signal));
} = usePolled(intervalMs, (signal) => fetchJson<BuildRun[]>(RUNS, signal), {
cacheKey: "builds",
});
// Which cards are open. Survives a refresh, so a list that updates under
// you does not fold the card you are reading. A linked build starts open.
const [open, setOpen] = useState<ReadonlySet<string>>(

View file

@ -97,8 +97,10 @@ export function ReviewRuns() {
data: runs,
error,
refreshing,
} = usePolled(intervalMs, (signal) =>
fetchJson<ClassifierRun[]>(RUNS, signal),
} = usePolled(
intervalMs,
(signal) => fetchJson<ClassifierRun[]>(RUNS, signal),
{ cacheKey: "review-runs" },
);
// Which cards are expanded. Survives a refresh, so a list that updates
// under you does not fold the card you are reading.

View file

@ -120,8 +120,10 @@ function HiveRoster() {
data: hives,
error,
refreshing,
} = usePolled(intervalMs, (signal) =>
fetchJson<HiveStatus[]>("/api/hives/status", signal),
} = usePolled(
intervalMs,
(signal) => fetchJson<HiveStatus[]>("/api/hives/status", signal),
{ cacheKey: "hives" },
);
return (