Files
Rpa_Skills/rpa-dashboard-ai/templates/reference/web/components/StatsBar.tsx
T

101 lines
3.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { BAND_VAR } from '../bands'
import type { Run } from '../types'
/**
* The batch in one line: how much runs unattended, how much needs a person.
*
* This is the number the whole pipeline exists to produce. Reading it off a list
* of cards means counting, so it is stated once at the top — and stated as
* documents, not fields, because the decision it supports ("what do I have to
* look at today") is made per document.
*/
export function StatsBar({ runs }: { runs: Run[] }) {
const done = runs.filter((r) => r.status === 'done')
const clean = done.filter((r) => flagged(r) === 0)
const needs = done.filter((r) => flagged(r) > 0)
const busy = runs.filter((r) => r.status === 'queued' || r.status === 'running')
const failed = runs.filter((r) => r.status === 'failed')
const fields = done.reduce((n, r) => n + flagged(r), 0)
if (runs.length === 0) return null
return (
<div className="sb-runbar">
<Stat n={clean.length} label="run unattended" tone="accent" />
<Stat n={needs.length} label="need a reviewer" tone="amber" />
{fields > 0 && (
<Stat n={fields} label="fields flagged" tone="slate" />
)}
{busy.length > 0 && <Stat n={busy.length} label="extracting" tone="blue" />}
{failed.length > 0 && <Stat n={failed.length} label="failed" tone="red" />}
<BandLegend />
</div>
)
}
function flagged(run: Run): number {
if (run.review) return run.review.total
const s = run.summary
return s ? s.amber + s.red + s.unscored + s.blank_critical : 0
}
function Stat({
n,
label,
tone,
}: {
n: number
label: string
// "accent" ties to the brand ramp (this stat means "went straight through,"
// the same semantic as the confirm/approve action elsewhere); the rest are
// theme tokens for the state they report.
tone: 'accent' | 'amber' | 'slate' | 'blue' | 'red'
}) {
// `slate` stays on the runbar's own ink — a stat with no state to report
// should not borrow a colour that means one.
const colour = {
accent: 'var(--accent-1)',
amber: 'var(--verify)',
slate: '',
blue: 'var(--accent-2)',
red: 'var(--review)',
}[tone]
return (
<span>
<b style={colour ? { color: colour } : undefined}>{n}</b> {label}
</span>
)
}
/**
* What the colours mean, on the page rather than in a document nobody opens.
* The caveat is part of the legend on purpose: the bands rate how legibly the
* source was printed, and a reviewer who reads them as "verified" will trust a
* confident misread.
*/
export function BandLegend() {
return (
<div className="sb-keys">
<Swatch band="green" label="≥0.95 clean" />
<Swatch band="amber" label="0.90–0.95 sample" />
<Swatch band="red" label="<0.90 review" />
<span
className="cursor-help text-muted"
title="The score rates how legibly the source was printed, not whether the value is correct. A cleanly printed value can still be misread."
>
print clarity, not correctness ⓘ
</span>
</div>
)
}
function Swatch({ band, label }: { band: 'green' | 'amber' | 'red'; label: string }) {
return (
<span className="flex items-center text-ink-2">
<i className="sb-swatch" style={{ backgroundColor: BAND_VAR[band] }} />
{label}
</span>
)
}