feat(ui): implement disagreement detection, prediction summary, loading states, and update documentation

- Add disagreement detection logic comparing human annotations vs predictions
- Display prediction summary in PredictionPanel (agreements/disagreements)
- Wire up 'Show only disagreements' filter toggle
- Add loading overlay during prediction fetching
- Update docker-compose.yml with healthchecks for all services
- Update DEPLOYMENT.md with comprehensive ML service setup instructions
- Update README.md with ML pipeline overview and architecture diagrams
- Update CLAUDE_DESCRIPTION.md with v3.0.0 ML integration details

Remaining tasks (11.2, 11.4, 11.5) deferred - core functionality complete
This commit is contained in:
Marko Djordjevic 2026-02-15 16:34:02 +01:00
parent 952eb7413c
commit 21f184aa8d
8 changed files with 585 additions and 56 deletions

View file

@ -1,6 +1,5 @@
'use client';
import { useState } from 'react';
import type { PredictionState, ModelInfoResponse, PredictionSummary } from '@/types/predictions';
interface PredictionPanelProps {
@ -12,6 +11,8 @@ interface PredictionPanelProps {
onToggleLabelSelection: (label: string) => void;
predictionSummary?: PredictionSummary;
isModelOnline: boolean;
showOnlyDisagreements?: boolean;
onToggleShowOnlyDisagreements?: () => void;
}
export default function PredictionPanel({
@ -23,8 +24,9 @@ export default function PredictionPanel({
onToggleLabelSelection,
predictionSummary,
isModelOnline,
showOnlyDisagreements = false,
onToggleShowOnlyDisagreements,
}: PredictionPanelProps) {
const [showOnlyDisagreements, setShowOnlyDisagreements] = useState(false);
const {
visible,
@ -175,13 +177,13 @@ export default function PredictionPanel({
)}
{/* Disagreement Filter */}
{predictionSummary && predictionSummary.disagreements.length > 0 && (
{predictionSummary && predictionSummary.disagreements.length > 0 && onToggleShowOnlyDisagreements && (
<div className="mb-3">
<label className="flex items-center gap-2 p-2 bg-muted/50 rounded cursor-pointer hover:bg-muted">
<input
type="checkbox"
checked={showOnlyDisagreements}
onChange={(e) => setShowOnlyDisagreements(e.target.checked)}
onChange={onToggleShowOnlyDisagreements}
className="w-3 h-3"
/>
<span className="text-xs text-foreground">Show only disagreements</span>