feat: add TalibPatternPanel, TrainingPanel, ModelSelector UI components (tasks 5-8)

- TalibPatternPanel: pattern checkboxes, detect button, results summary, clear-all and per-pattern delete
- TrainingPanel: model type selector, dataset info, start training, polling, run history
- ModelSelector: dropdown of completed runs, wired into PredictionPanel for model switching
- page.tsx: integrate all three panels into sidebar, wire callbacks (model load, annotations refresh)
- tasks.md: mark all 39 tasks complete
This commit is contained in:
Marko Djordjevic 2026-02-17 18:55:52 +01:00
parent 2a02669222
commit 12a9603fce
7 changed files with 849 additions and 23 deletions

View file

@ -3,6 +3,7 @@
import { useState } from 'react';
import { ChevronDown } from 'lucide-react';
import type { PredictionState, ModelInfoResponse, PredictionSummary } from '@/types/predictions';
import ModelSelector from '@/components/ModelSelector';
interface PredictionPanelProps {
predictionState: PredictionState;
@ -15,6 +16,9 @@ interface PredictionPanelProps {
isModelOnline: boolean;
showOnlyDisagreements?: boolean;
onToggleShowOnlyDisagreements?: () => void;
onModelLoaded?: () => void;
onModelLoadError?: (msg: string) => void;
onModelLoadStart?: () => void;
}
export default function PredictionPanel({
@ -28,8 +32,12 @@ export default function PredictionPanel({
isModelOnline,
showOnlyDisagreements = false,
onToggleShowOnlyDisagreements,
onModelLoaded,
onModelLoadError,
onModelLoadStart,
}: PredictionPanelProps) {
const [expanded, setExpanded] = useState(true);
const [modelLoadError, setModelLoadError] = useState<string | null>(null);
const {
visible,
@ -86,6 +94,28 @@ export default function PredictionPanel({
</div>
)}
{/* Model Selector */}
{onModelLoaded && (
<div>
<ModelSelector
currentModelVersion={modelInfo?.model_version}
onModelLoaded={() => {
setModelLoadError(null);
onModelLoaded();
}}
onLoadError={(msg) => {
setModelLoadError(msg);
onModelLoadError?.(msg);
}}
onLoadStart={() => onModelLoadStart?.()}
disabled={isLoading}
/>
{modelLoadError && (
<p className="text-[10px] text-destructive mt-0.5">{modelLoadError}</p>
)}
</div>
)}
{/* Action Buttons */}
<div className="flex gap-1">
<button