import { useQuery } from "@tanstack/react-query"
import { Link } from "@tanstack/react-router"
import { type Range, RangePicker } from "@/components/Common/RangePicker"
import { PANEL_SECTION } from "@/components/Flow/SidePanel"
import { runOverviewQueryOptions } from "@/components/Runs/queries"
import { Badge } from "@/components/ui/badge"
import { cn, dur, si } from "@/lib/utils"
import {
ago,
CARD,
failuresQueryOptions,
flowRollupsQueryOptions,
summaryQueryOptions,
} from "./queries"
function Tile({
label,
value,
note,
to,
hash,
}: {
label: string
value: string
note?: string
/** Where this figure is explained further, if anywhere obvious. */
to?: string
hash?: string
}) {
const body = (
<>
{label}
{value}
{note ? (
{note}
) : null}
>
)
return to ? (
{body}
) : (
{body}
)
}
/**
* How the engine is doing: the standing state, as tiles.
*
* The range control sits on this heading because it governs everything under
* it — the flow table, the charts and the lists — rather than this block
* alone. One window, not one per card.
*/
export function HealthOverview({
range,
onRangeChange,
}: {
range: Range
onRangeChange: (range: Range) => void
}) {
const { data: summary } = useQuery(summaryQueryOptions())
const { data: flows } = useQuery(flowRollupsQueryOptions(range))
// Shares the list below's cache entry, for the one tile that dates them.
const { data: failures } = useQuery(failuresQueryOptions(range))
// Shares the Runs screen's cache entry, which already counts by status in
// the database rather than over a page of rows.
const { data: runs } = useQuery(runOverviewQueryOptions())
const queue = (summary?.queue ?? {}) as Record
const degraded = summary?.status === "degraded"
const errors = (flows ?? []).reduce((total, row) => total + row.errors, 0)
// An instance nobody has run a batch flow on has no runs tile at all —
// the same "nothing has been run yet" the Runs screen itself goes by.
const running = (runs ?? []).reduce((total, row) => total + row.running, 0)
const queued = (runs ?? []).reduce((total, row) => total + row.queued, 0)
return (
Health
{degraded ? "Degraded" : "Running normally"}
{summary?.problems.length ? (
{summary.problems.join(" · ")}
) : null}
{runs?.length ? (
) : null}
{/* Backlog leads: what is waiting is what says the engine is
behind. `pending` is work already running, which reads as idle
on an engine hours behind. */}