/** * Live progress card for an in-flight (non-published) evaluation run. * Fed by the SSE stream when available, otherwise by 1.5s polling. */ import Box from '@mui/material/Box'; import LinearProgress from '@mui/material/LinearProgress'; import Typography from '@mui/material/Typography'; import type { RunProgress } from '../../types/megaeval'; import { fmtCompact } from '../../services/megaeval'; import { SectionCard } from '../labeleval/shared'; import { CompactStat, RunStatusChip } from './shared'; function fmtEta(s: number | null): string { if (s === null || Number.isNaN(s)) return '—'; if (s < 60) return `${Math.max(0, Math.round(s))}s`; return `${Math.floor(s / 60)}m ${Math.round(s % 60)}s`; } export default function RunProgressCard({ progress }: { progress: RunProgress }) { // Tolerate either 0..1 or 0..100 percent encodings from the backend. const pct = Math.max(0, Math.min(100, progress.percent <= 1 ? progress.percent * 100 : progress.percent)); return ( Evaluation run {progress.run_id.slice(0, 8)} · {progress.model_version} } helpTerm="sse" > {progress.error ? ( {progress.error} ) : ( Map partitions across workers → reduce partial aggregates → materialize cube & indexes → publish. )} ); }