import { useState } from 'react'; import Box from '@mui/material/Box'; import Button from '@mui/material/Button'; import Chip from '@mui/material/Chip'; 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 TextField from '@mui/material/TextField'; 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 Alert from '@mui/material/Alert'; import CircularProgress from '@mui/material/CircularProgress'; import { DatabaseZap, Play, ShieldQuestion } from 'lucide-react'; import type { DatasetSummary } from '../../types/labeleval'; import { generateDataset, precheckDataset, runPipeline, type PrecheckResponse, } from '../../services/labeleval'; import { SectionCard, StatusChip, GateLineList, fmtInt, fmtPct, EmptyState } from './shared'; import { ExplainTip, HeadCell } from '../help/InfoTip'; import { glossaryKeyForStatus } from '../../content/glossary'; function lineageChips(d: DatasetSummary) { const chips: string[] = []; if (d.lineage.generated_from_model) chips.push(`from ${d.lineage.generated_from_model}`); if (d.lineage.corrected_by_review_batch) chips.push(`corrected by ${d.lineage.corrected_by_review_batch}`); if (d.lineage.validated_by_policy) chips.push(`policy ${d.lineage.validated_by_policy}`); if (d.lineage.parent_dataset) chips.push(`parent ${d.lineage.parent_dataset}`); return chips; } export default function DatasetSelector({ datasets, selectedId, onSelect, onChanged, verificationRates, }: { datasets: DatasetSummary[]; selectedId: string | null; onSelect: (id: string) => void; /** Called after generate / run so the parent can refresh. */ onChanged: () => void; /** Optional map dataset_id -> verification rate (0..1). */ verificationRates?: Record; }) { const [genOpen, setGenOpen] = useState(false); const [genForm, setGenForm] = useState({ name: '', num_sequences: 8, frames_per_sequence: 25, seed: 42 }); const [busy, setBusy] = useState(null); // 'generate' | `precheck:${id}` | `run:${id}` const [precheck, setPrecheck] = useState<{ datasetId: string; result: PrecheckResponse } | null>(null); const [notice, setNotice] = useState(null); const [errorMsg, setErrorMsg] = useState(null); const doGenerate = async () => { setBusy('generate'); setErrorMsg(null); try { const ds = await generateDataset({ ...(genForm.name ? { name: genForm.name } : {}), num_sequences: genForm.num_sequences, frames_per_sequence: genForm.frames_per_sequence, seed: genForm.seed, }); setGenOpen(false); setNotice(`Generated dataset ${ds.name} (${ds.dataset_id})`); onSelect(ds.dataset_id); onChanged(); } catch (err) { setErrorMsg(err instanceof Error ? err.message : String(err)); } finally { setBusy(null); } }; const doPrecheck = async (id: string) => { setBusy(`precheck:${id}`); setErrorMsg(null); try { const result = await precheckDataset(id); setPrecheck({ datasetId: id, result }); } catch (err) { setErrorMsg(err instanceof Error ? err.message : String(err)); } finally { setBusy(null); } }; const doRun = async (id: string) => { setBusy(`run:${id}`); setErrorMsg(null); try { const res = await runPipeline(id); setNotice(`Pipeline run ${res.run_id} started (${res.status}). Watch progress on the Overview / Pipeline pages.`); onChanged(); } catch (err) { setErrorMsg(err instanceof Error ? err.message : String(err)); } finally { setBusy(null); } }; return ( } onClick={() => setGenOpen(true)} > Generate Synthetic Dataset } > {notice ? ( setNotice(null)} sx={{ mb: 1 }}> {notice} ) : null} {errorMsg ? ( setErrorMsg(null)} sx={{ mb: 1 }}> {errorMsg} ) : null} {datasets.length === 0 ? ( } onClick={() => setGenOpen(true)}> Generate Synthetic Dataset } /> ) : ( Name Version Frames Annotations Status Actions {datasets.map((d) => { const rate = verificationRates?.[d.dataset_id]; return ( onSelect(d.dataset_id)} sx={{ cursor: 'pointer' }} > {d.name} {d.version} {fmtInt(d.num_frames)} {fmtInt(d.num_annotations)} {d.gt_availability.has_reference && d.gt_availability.gt_type ? ( ) : ( )} {rate !== undefined ? fmtPct(rate) : '—'} {lineageChips(d).map((c) => ( ))} e.stopPropagation()}> ); })}
)} {/* Generate dialog */} setGenOpen(false)}> Generate Synthetic Dataset setGenForm({ ...genForm, name: e.target.value })} /> setGenForm({ ...genForm, num_sequences: Number(e.target.value) })} /> setGenForm({ ...genForm, frames_per_sequence: Number(e.target.value) })} /> setGenForm({ ...genForm, seed: Number(e.target.value) })} /> {/* Precheck results dialog */} setPrecheck(null)} maxWidth="sm" fullWidth> Precheck — {precheck?.datasetId} {precheck ? ( <> {precheck.result.status} — {precheck.result.message} ) : null}
); }