/** * Multi-gate readiness skeleton: Scenario / Coverage / Regression / Safety / Release * (+ quality / launch when wired). */ import Box from '@mui/material/Box'; import Chip from '@mui/material/Chip'; import Typography from '@mui/material/Typography'; import { CheckCircle2, CircleDashed, XCircle } from 'lucide-react'; import { useGateStatus } from '../../services/platform'; import { ErrorNote, LoadingBox, SectionCard } from '../labeleval/shared'; const DISPLAY_ORDER = ['scenario', 'coverage', 'regression', 'safety', 'quality', 'launch', 'release']; function statusChip(passed: boolean | null, ready: boolean) { if (!ready) { return } label="Skeleton" variant="outlined" />; } if (passed === true) { return } label="Pass" />; } if (passed === false) { return } label="Fail" />; } return ; } export default function GateStatusPanel({ candidateRunId, baselineRunId, refreshKey = 0, }: { candidateRunId: string | null; baselineRunId: string | null; refreshKey?: number; }) { const poll = useGateStatus(candidateRunId, baselineRunId, refreshKey); if (poll.error && !poll.data) return ; if (poll.loading && !poll.data) return ; const data = poll.data; if (!data) return null; const byType = Object.fromEntries(data.gates.map((g) => [g.gate_type, g])); return ( {data.summary.release_ready ? 'Release ready' : `${data.summary.unwired_count} gates still Phase 2–6 stubs`} } > {DISPLAY_ORDER.map((type) => { const g = byType[type]; if (!g) return null; return ( {type} {statusChip(g.passed, g.ready)} {g.message} ); })} ); }