interface CoverageReport { currentPercent: number; thresholdPercent: number; baselinePercent: number | null; } interface GateState { canAccept: boolean; reasons: string[]; warning: string | null; summary: { total: number; passed: number; failed: number; }; missingCategories: string[]; coverageReport: CoverageReport | null; } interface GatePanelProps { gateState: GateState | null; gateStatusLabel: string; gateStatusColor: string; isGateLoading: boolean; gateError: string | null; coverageError: string | null; lastGateRefresh: Date | null; onRefresh: () => void; onCollectCoverage: () => void; isCollectingCoverage: boolean; } const formatTimestamp = (value: Date | null): string => { if (!value) return "—"; return value.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit", second: "2-digit", }); }; export function GatePanel({ gateState, gateStatusLabel, gateStatusColor, isGateLoading, gateError, coverageError, lastGateRefresh, onRefresh, onCollectCoverage, isCollectingCoverage, }: GatePanelProps) { return (
Workflow Gates
{gateStatusLabel}
Updated {formatTimestamp(lastGateRefresh)}
{isGateLoading ? (
Loading workflow gates...
) : gateError ? (
{gateError}
) : gateState ? (
Summary: {gateState.summary.passed}/{gateState.summary.total}{" "} passing, {gateState.summary.failed} failing
{gateState.coverageReport && (
Coverage: {gateState.coverageReport.currentPercent.toFixed(1)}% (threshold: {gateState.coverageReport.thresholdPercent.toFixed(1)} %)
)} {coverageError && (
Coverage error: {coverageError}
)} {gateState.missingCategories.length > 0 && (
Missing: {gateState.missingCategories.join(", ")}
)} {gateState.warning && (
{gateState.warning}
)} {gateState.reasons.length > 0 && ( )}
) : (
No workflow data yet.
)}
); }