import { useState } from 'react'; import Box from '@mui/material/Box'; import Dialog from '@mui/material/Dialog'; import DialogTitle from '@mui/material/DialogTitle'; import DialogContent from '@mui/material/DialogContent'; import DialogActions from '@mui/material/DialogActions'; import Button from '@mui/material/Button'; import Table from '@mui/material/Table'; import TableBody from '@mui/material/TableBody'; import TableCell from '@mui/material/TableCell'; import TableHead from '@mui/material/TableHead'; import TableRow from '@mui/material/TableRow'; import Typography from '@mui/material/Typography'; import type { ModelSummary } from '../types/labeleval'; import { getModels, usePoll } from '../services/labeleval'; import { SectionCard, StatusChip, LoadingBox, ErrorNote, MetricCard, fmtPct } from '../components/labeleval/shared'; import { HeadCell } from '../components/help/InfoTip'; export default function ModelsPage() { const models = usePoll(getModels, 10000); const [selected, setSelected] = useState(null); return ( {models.loading && !models.data ? : null} {models.error && !models.data ? : null} {!models.data || models.data.models.length === 0 ? ( No models registered yet — train one from the Training page (Training → Train a New Model). Each completed job registers a model version here with its evaluation metrics. ) : ( Version Name Trained on Status {models.data.models.map((m) => ( setSelected(m)}> {m.model_version} {m.name} {m.trained_on_dataset ?? '—'} {fmtPct(m.metrics.precision)} {fmtPct(m.metrics.recall)} {fmtPct(m.metrics.map_3d)} {fmtPct(m.metrics.safety_critical_recall)} {fmtPct(m.metrics.rare_recall)} ))}
)}
setSelected(null)} maxWidth="sm" fullWidth> {selected?.name} — {selected?.model_version} {selected ? ( <> Model id {selected.model_id} · trained on {selected.trained_on_dataset ?? '—'} · created{' '} {new Date(selected.created_at).toLocaleString()} · status {selected.status} ) : null}
); }