// RunHistory scene: cross-scenario timeline. import { useMemo, useState } from "react"; import { useApp } from "../state/store"; import { Clock, HistoryIcon } from "../components/icons"; const STATUS_FILTERS = ["all", "running", "completed", "errored", "queued"] as const; type Status = (typeof STATUS_FILTERS)[number]; const STATUS_COLOR: Record = { running: "var(--run)", completed: "var(--ok)", done: "var(--ok)", errored: "var(--block)", failed: "var(--block)", queued: "var(--queue)", }; export default function RunHistory() { const [filter, setFilter] = useState("all"); const scenarios = useApp((s) => s.scenarios); const rows = useMemo(() => { const out: Array<{ scenarioId: string; scenarioLabel: string; accent: string; live: boolean; run: (typeof scenarios)[number]["runs"][number] }> = []; for (const s of scenarios) { for (const r of s.runs) { if (filter !== "all" && r.status !== filter && !(filter === "completed" && r.status === "done")) continue; out.push({ scenarioId: s.id, scenarioLabel: s.family.label, accent: s.family.accent, live: s.live, run: r }); } } return out.sort((a, b) => (b.run.startedAt || "").localeCompare(a.run.startedAt || "")); }, [filter]); const maxDuration = useMemo(() => Math.max(60, ...rows.map((r) => r.run.durationSec)), [rows]); return (
Run history

All scenarios · all runs

{rows.length === 0 &&
No runs match the current filter.
} {rows.map((row) => (
{row.run.shortId} {row.live ? "live" : "bp"}
{row.scenarioLabel}
{row.run.activeStep ?? "—"}
{Math.round(row.run.durationSec / 60)}m {row.run.status}
))}
); }