'use client'; import type { PredictionState, ModelInfoResponse, PredictionSummary } from '@/types/predictions'; interface PredictionPanelProps { predictionState: PredictionState; onToggleVisibility: () => void; onFetchPredictions: () => void; onFetchBatchPredictions: () => void; onConfidenceChange: (threshold: number) => void; onToggleLabelSelection: (label: string) => void; predictionSummary: PredictionSummary | null; isModelOnline: boolean; showOnlyDisagreements?: boolean; onToggleShowOnlyDisagreements?: () => void; } export default function PredictionPanel({ predictionState, onToggleVisibility, onFetchPredictions, onFetchBatchPredictions, onConfidenceChange, onToggleLabelSelection, predictionSummary, isModelOnline, showOnlyDisagreements = false, onToggleShowOnlyDisagreements, }: PredictionPanelProps) { const { visible, isLoading, error, modelInfo, confidenceThreshold, selectedLabels, spans, } = predictionState; if (!isModelOnline) { return (

Model Server Offline

Prediction service is unavailable. Annotation tools continue to work normally.

); } return (
{/* Header with master toggle */}

Predictions

{/* Model Info */} {modelInfo && (
Model: {modelInfo.model_name}
Version: {modelInfo.model_version || 'N/A'}
Type: {modelInfo.model_type}
)} {/* Action Buttons */}
{/* Error Display */} {error && (
{error}
)} {/* Confidence Slider */}
{(confidenceThreshold * 100).toFixed(0)}%
onConfidenceChange(Number(e.target.value) / 100)} className="w-full h-1 bg-muted rounded-lg appearance-none cursor-pointer" />
{/* Label Filter Checkboxes */} {modelInfo && (
{modelInfo.labels.map((label) => { const metrics = modelInfo.per_class_metrics.find((m) => m.label === label); const isSelected = selectedLabels.has(label); return ( ); })}
)} {/* Disagreement Filter */} {predictionSummary && predictionSummary.disagreements.length > 0 && onToggleShowOnlyDisagreements && (
)} {/* Prediction Summary */} {visible && spans.length > 0 && predictionSummary && (
Predictions: {predictionSummary.total_predictions}
Human annotations: {predictionSummary.total_human_annotations}
Agreements: {predictionSummary.agreements}
Disagreements: {predictionSummary.disagreements.length}
)}
); }