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

@ -7,6 +7,8 @@ import CandleChart, { CandleChartHandle } from '@/components/CandleChart';
import ChartSelector from '@/components/ChartSelector';
import PredictionPanel from '@/components/PredictionPanel';
import SpanAnnotationList from '@/components/SpanAnnotationList';
import TalibPatternPanel from '@/components/TalibPatternPanel';
import TrainingPanel from '@/components/TrainingPanel';
import { ThemeToggle } from '@/components/ThemeToggle';
import type { PredictionState, PredictionSpan, ModelInfoResponse, Disagreement, DisagreementType, PredictionSummary } from '@/types/predictions';
@ -566,6 +568,13 @@ export default function Home() {
}
}, [fetchPredictions]);
// Handle model loaded via ModelSelector: refresh model info and clear prediction cache
const handleModelLoaded = useCallback(async () => {
predictionCacheRef.current = new Map();
setPredictionState((prev) => ({ ...prev, spans: [], perCandlePredictions: [], visible: false }));
await fetchModelInfo();
}, [fetchModelInfo]);
// Handle batch prediction for all candles
const handleFetchBatchPredictions = useCallback(async () => {
if (!activeChartId) return;
@ -758,6 +767,20 @@ export default function Home() {
/>
</div>
{/* TA-Lib Pattern Panel */}
<div className="px-3 py-2 border-t border-sidebar-border">
<TalibPatternPanel
activeChartId={activeChartId}
onAnnotationsChanged={() => fetchSpanAnnotations(activeChartId)}
getCandles={() => chartRef.current?.getVisibleCandles()}
/>
</div>
{/* Training Panel */}
<div className="px-3 py-2 border-t border-sidebar-border">
<TrainingPanel />
</div>
{/* Predictions */}
<div className="px-3 py-2 border-t border-sidebar-border">
<PredictionPanel
@ -771,6 +794,7 @@ export default function Home() {
isModelOnline={isModelOnline}
showOnlyDisagreements={showOnlyDisagreements}
onToggleShowOnlyDisagreements={toggleShowOnlyDisagreements}
onModelLoaded={handleModelLoaded}
/>
</div>