feat: redesign UI to match lovable compact sidebar layout
- Replace green hacker theme with professional blue-toned design - Light theme default, manual toggle only (no system detection) - Compact w-60 sidebar with collapsible sections - New CSS tokens: sidebar, chart, candle, annotation colors - Tools displayed as compact grid buttons - Color swatches as inline bar - Chart top bar with keyboard shortcut hints - Inter + JetBrains Mono font pairing - All components updated for compact styling - Tailwind config extended with sidebar/chart tokens
This commit is contained in:
parent
2bde38d0bf
commit
4605283d2b
13 changed files with 976 additions and 740 deletions
|
|
@ -1,54 +1,103 @@
|
|||
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600;700&family=Inter:wght@400;500;600;700&display=swap');
|
||||
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
@layer base {
|
||||
:root {
|
||||
/* Light theme - off-white backgrounds, green-600 accents, near-black text, gray borders */
|
||||
--background: 120 25% 97%; /* #f8faf8 */
|
||||
--foreground: 240 15% 10%; /* #1a1a2e near-black */
|
||||
--card: 0 0% 100%; /* #ffffff */
|
||||
--card-foreground: 240 15% 10%;
|
||||
--background: 0 0% 98%;
|
||||
--foreground: 220 20% 10%;
|
||||
--card: 0 0% 100%;
|
||||
--card-foreground: 220 20% 10%;
|
||||
--popover: 0 0% 100%;
|
||||
--popover-foreground: 240 15% 10%;
|
||||
--primary: 142 76% 36%; /* #16a34a green-600 */
|
||||
--popover-foreground: 220 20% 10%;
|
||||
--primary: 220 70% 45%;
|
||||
--primary-foreground: 0 0% 100%;
|
||||
--secondary: 120 10% 95%; /* #f0f4f0 */
|
||||
--secondary-foreground: 240 15% 10%;
|
||||
--muted: 120 10% 95%;
|
||||
--muted-foreground: 220 9% 46%; /* #4a5568 gray-600 */
|
||||
--accent: 142 76% 36%; /* green-600 */
|
||||
--accent-foreground: 0 0% 100%;
|
||||
--destructive: 348 100% 50%; /* #ff0040 neon red */
|
||||
--secondary: 220 14% 92%;
|
||||
--secondary-foreground: 220 20% 20%;
|
||||
--muted: 220 14% 94%;
|
||||
--muted-foreground: 215 12% 46%;
|
||||
--accent: 220 14% 90%;
|
||||
--accent-foreground: 220 20% 10%;
|
||||
--destructive: 0 72% 51%;
|
||||
--destructive-foreground: 0 0% 100%;
|
||||
--border: 220 13% 84%; /* #d1d5db gray-300 */
|
||||
--input: 220 13% 84%;
|
||||
--ring: 142 76% 36%;
|
||||
--radius: 0.5rem;
|
||||
--border: 220 13% 87%;
|
||||
--input: 220 13% 87%;
|
||||
--ring: 220 70% 45%;
|
||||
--radius: 0.375rem;
|
||||
|
||||
--candle-bull: 0 0% 100%;
|
||||
--candle-bull-stroke: 0 0% 10%;
|
||||
--candle-bear: 0 0% 10%;
|
||||
--candle-bear-stroke: 0 0% 10%;
|
||||
|
||||
--annotation-blue: 217 91% 60%;
|
||||
--annotation-red: 0 72% 51%;
|
||||
--annotation-green: 152 69% 45%;
|
||||
--annotation-orange: 38 92% 50%;
|
||||
--annotation-purple: 263 70% 58%;
|
||||
|
||||
--sidebar-background: 0 0% 100%;
|
||||
--sidebar-foreground: 220 20% 20%;
|
||||
--sidebar-primary: 220 70% 45%;
|
||||
--sidebar-primary-foreground: 0 0% 100%;
|
||||
--sidebar-accent: 220 14% 94%;
|
||||
--sidebar-accent-foreground: 220 20% 10%;
|
||||
--sidebar-border: 220 13% 90%;
|
||||
--sidebar-ring: 220 70% 45%;
|
||||
|
||||
--chart-bg: 0 0% 100%;
|
||||
--chart-grid: 220 13% 92%;
|
||||
--chart-crosshair: 220 10% 60%;
|
||||
--chart-text: 215 12% 46%;
|
||||
}
|
||||
|
||||
.dark {
|
||||
/* Dark hacker theme - terminal blacks, matrix green #00ff41 accents, neon text */
|
||||
--background: 120 38% 3%; /* #0a0e0a near-black */
|
||||
--foreground: 120 100% 63%; /* #00ff41 matrix green */
|
||||
--card: 120 29% 5%; /* #0d110d */
|
||||
--card-foreground: 120 100% 63%;
|
||||
--popover: 120 29% 5%;
|
||||
--popover-foreground: 120 100% 63%;
|
||||
--primary: 120 100% 63%; /* #00ff41 matrix green */
|
||||
--primary-foreground: 120 38% 3%;
|
||||
--secondary: 120 100% 50%; /* #00cc33 */
|
||||
--secondary-foreground: 120 100% 63%;
|
||||
--muted: 120 82% 10%; /* #003311 */
|
||||
--muted-foreground: 120 100% 50%;
|
||||
--accent: 120 100% 63%; /* #00ff41 */
|
||||
--accent-foreground: 120 38% 3%;
|
||||
--destructive: 348 100% 50%; /* #ff0040 neon red */
|
||||
--destructive-foreground: 120 100% 63%;
|
||||
--border: 120 82% 10%; /* #003311 inactive */
|
||||
--input: 120 82% 10%;
|
||||
--ring: 120 100% 63%;
|
||||
--radius: 0.5rem;
|
||||
--background: 220 20% 7%;
|
||||
--foreground: 210 20% 90%;
|
||||
--card: 220 18% 10%;
|
||||
--card-foreground: 210 20% 90%;
|
||||
--popover: 220 18% 12%;
|
||||
--popover-foreground: 210 20% 90%;
|
||||
--primary: 217 91% 60%;
|
||||
--primary-foreground: 220 20% 7%;
|
||||
--secondary: 220 16% 16%;
|
||||
--secondary-foreground: 210 20% 80%;
|
||||
--muted: 220 14% 14%;
|
||||
--muted-foreground: 215 12% 50%;
|
||||
--accent: 220 16% 18%;
|
||||
--accent-foreground: 210 20% 95%;
|
||||
--destructive: 0 72% 51%;
|
||||
--destructive-foreground: 210 20% 95%;
|
||||
--border: 220 14% 18%;
|
||||
--input: 220 14% 20%;
|
||||
--ring: 217 91% 60%;
|
||||
|
||||
--candle-bull: 0 0% 100%;
|
||||
--candle-bull-stroke: 0 0% 90%;
|
||||
--candle-bear: 0 0% 10%;
|
||||
--candle-bear-stroke: 0 0% 90%;
|
||||
|
||||
--annotation-blue: 217 91% 60%;
|
||||
--annotation-red: 0 72% 51%;
|
||||
--annotation-green: 152 69% 45%;
|
||||
--annotation-orange: 38 92% 50%;
|
||||
--annotation-purple: 263 70% 58%;
|
||||
|
||||
--sidebar-background: 220 20% 8%;
|
||||
--sidebar-foreground: 210 20% 80%;
|
||||
--sidebar-primary: 217 91% 60%;
|
||||
--sidebar-primary-foreground: 220 20% 7%;
|
||||
--sidebar-accent: 220 16% 14%;
|
||||
--sidebar-accent-foreground: 210 20% 90%;
|
||||
--sidebar-border: 220 14% 16%;
|
||||
--sidebar-ring: 217 91% 60%;
|
||||
|
||||
--chart-bg: 220 20% 7%;
|
||||
--chart-grid: 220 14% 14%;
|
||||
--chart-crosshair: 210 20% 30%;
|
||||
--chart-text: 215 12% 50%;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -60,98 +109,55 @@
|
|||
@apply bg-background text-foreground antialiased;
|
||||
font-family: 'Inter', system-ui, -apple-system, sans-serif;
|
||||
}
|
||||
code, .font-mono {
|
||||
font-family: 'JetBrains Mono', ui-monospace, monospace;
|
||||
}
|
||||
}
|
||||
|
||||
@layer base {
|
||||
::selection {
|
||||
@apply bg-primary/20 text-foreground;
|
||||
}
|
||||
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
/* Light mode scrollbar */
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background: hsl(var(--muted));
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: hsl(var(--border));
|
||||
border-radius: 4px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: hsl(var(--muted-foreground) / 0.5);
|
||||
}
|
||||
|
||||
/* Dark mode scrollbar */
|
||||
.dark ::-webkit-scrollbar-track {
|
||||
background: hsl(var(--muted));
|
||||
}
|
||||
|
||||
.dark ::-webkit-scrollbar-thumb {
|
||||
background: hsl(var(--primary));
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.dark ::-webkit-scrollbar-thumb:hover {
|
||||
background: hsl(var(--secondary));
|
||||
}
|
||||
}
|
||||
|
||||
/* CRT effects - dark mode only */
|
||||
@layer utilities {
|
||||
.dark .crt-scanlines {
|
||||
position: relative;
|
||||
.scrollbar-thin {
|
||||
scrollbar-width: thin;
|
||||
}
|
||||
|
||||
.dark .crt-scanlines::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(
|
||||
rgba(0, 0, 0, 0) 50%,
|
||||
rgba(0, 0, 0, 0.05) 50%
|
||||
);
|
||||
background-size: 100% 4px;
|
||||
pointer-events: none;
|
||||
z-index: 1;
|
||||
.scrollbar-thin::-webkit-scrollbar {
|
||||
width: 4px;
|
||||
}
|
||||
|
||||
.dark .neon-glow {
|
||||
text-shadow: 0 0 10px hsl(var(--primary)),
|
||||
0 0 20px hsl(var(--primary) / 0.5),
|
||||
0 0 30px hsl(var(--primary) / 0.3);
|
||||
.scrollbar-thin::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.dark .neon-glow-box {
|
||||
box-shadow: 0 0 10px hsl(var(--primary)),
|
||||
0 0 20px hsl(var(--primary) / 0.5);
|
||||
.scrollbar-thin::-webkit-scrollbar-thumb {
|
||||
background: hsl(var(--border));
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.dark .neon-glow-box:hover {
|
||||
box-shadow: 0 0 15px hsl(var(--primary)),
|
||||
0 0 30px hsl(var(--primary) / 0.6),
|
||||
0 0 45px hsl(var(--primary) / 0.4);
|
||||
|
||||
.animate-fade-in {
|
||||
animation: fadeIn 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
@keyframes pulse-glow {
|
||||
0%, 100% {
|
||||
box-shadow: 0 0 10px hsl(var(--primary)),
|
||||
0 0 20px hsl(var(--primary) / 0.5);
|
||||
}
|
||||
50% {
|
||||
box-shadow: 0 0 20px hsl(var(--primary)),
|
||||
0 0 40px hsl(var(--primary) / 0.7),
|
||||
0 0 60px hsl(var(--primary) / 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
.dark .pulse-glow {
|
||||
animation: pulse-glow 2s ease-in-out infinite;
|
||||
|
||||
@keyframes fadeIn {
|
||||
from { opacity: 0; }
|
||||
to { opacity: 1; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,17 +14,11 @@ export default function RootLayout({
|
|||
}>) {
|
||||
return (
|
||||
<html lang="en" suppressHydrationWarning>
|
||||
<head>
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;700&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
</head>
|
||||
<body className="antialiased">
|
||||
<ThemeProvider
|
||||
attribute="class"
|
||||
defaultTheme="system"
|
||||
enableSystem
|
||||
defaultTheme="light"
|
||||
enableSystem={false}
|
||||
>
|
||||
{children}
|
||||
</ThemeProvider>
|
||||
|
|
|
|||
185
src/app/page.tsx
185
src/app/page.tsx
|
|
@ -6,6 +6,8 @@ import FileUpload from '@/components/FileUpload';
|
|||
import CandleChart, { CandleChartHandle } from '@/components/CandleChart';
|
||||
import ChartSelector from '@/components/ChartSelector';
|
||||
import PredictionPanel from '@/components/PredictionPanel';
|
||||
import SpanAnnotationList from '@/components/SpanAnnotationList';
|
||||
import { ThemeToggle } from '@/components/ThemeToggle';
|
||||
import type { PredictionState, PredictionSpan, ModelInfoResponse, Disagreement, DisagreementType, PredictionSummary } from '@/types/predictions';
|
||||
|
||||
/**
|
||||
|
|
@ -692,29 +694,25 @@ export default function Home() {
|
|||
return () => window.removeEventListener('keydown', handleKeyDown);
|
||||
}, [selectedLabelId]);
|
||||
|
||||
const activeChart = charts.find((c) => c.id === activeChartId);
|
||||
|
||||
return (
|
||||
<div className="flex h-screen bg-background">
|
||||
<div className="flex h-screen w-full overflow-hidden bg-background">
|
||||
{/* Sidebar */}
|
||||
<aside className="w-72 flex-shrink-0 flex flex-col border-r border-border bg-card">
|
||||
<div className="p-6 border-b border-border">
|
||||
<h1 className="text-2xl font-semibold text-foreground">Candle Annotator</h1>
|
||||
<p className="text-sm text-muted-foreground mt-1">Chart annotation tool</p>
|
||||
<div className="mt-3 flex flex-col gap-1">
|
||||
<a
|
||||
href="/annotation-types"
|
||||
className="text-sm text-muted-foreground hover:text-foreground"
|
||||
>
|
||||
Manage Annotation Types
|
||||
</a>
|
||||
<a
|
||||
href="/span-label-types"
|
||||
className="text-sm text-muted-foreground hover:text-foreground"
|
||||
>
|
||||
Manage Span Label Types
|
||||
</a>
|
||||
<div className="flex flex-col bg-sidebar border-r border-sidebar-border w-60 flex-shrink-0 animate-fade-in">
|
||||
{/* Sidebar Header */}
|
||||
<div className="flex items-center justify-between px-4 py-3 border-b border-sidebar-border">
|
||||
<div>
|
||||
<h1 className="text-sm font-semibold text-foreground tracking-tight">Candle Annotator</h1>
|
||||
<p className="text-[10px] text-muted-foreground">Chart annotation tool</p>
|
||||
</div>
|
||||
<div className="flex items-center gap-1">
|
||||
<ThemeToggle />
|
||||
</div>
|
||||
</div>
|
||||
<div className="p-6 pb-3">
|
||||
|
||||
{/* Chart Selector */}
|
||||
<div className="px-3 py-2 border-b border-sidebar-border">
|
||||
<ChartSelector
|
||||
charts={charts}
|
||||
activeChartId={activeChartId}
|
||||
|
|
@ -722,10 +720,14 @@ export default function Home() {
|
|||
onDeleteChart={handleDeleteChart}
|
||||
/>
|
||||
</div>
|
||||
<div className="px-6 pb-3">
|
||||
|
||||
{/* File Upload */}
|
||||
<div className="px-3 py-2 border-b border-sidebar-border">
|
||||
<FileUpload onUploadSuccess={handleUploadSuccess} />
|
||||
</div>
|
||||
<div className="px-6 pb-6">
|
||||
|
||||
{/* Toolbox */}
|
||||
<div className="px-3 py-2 border-b border-sidebar-border">
|
||||
<Toolbox
|
||||
activeTool={activeTool}
|
||||
onToolChange={setActiveTool}
|
||||
|
|
@ -744,58 +746,103 @@ export default function Home() {
|
|||
onDeleteSpan={handleDeleteSpan}
|
||||
/>
|
||||
</div>
|
||||
<PredictionPanel
|
||||
predictionState={predictionState}
|
||||
onToggleVisibility={togglePredictionVisibility}
|
||||
onFetchPredictions={handleFetchVisiblePredictions}
|
||||
onFetchBatchPredictions={handleFetchBatchPredictions}
|
||||
onConfidenceChange={setConfidenceThreshold}
|
||||
onToggleLabelSelection={toggleLabelSelection}
|
||||
predictionSummary={predictionSummary}
|
||||
isModelOnline={isModelOnline}
|
||||
showOnlyDisagreements={showOnlyDisagreements}
|
||||
onToggleShowOnlyDisagreements={toggleShowOnlyDisagreements}
|
||||
/>
|
||||
</aside>
|
||||
|
||||
{/* Annotations List - scrollable */}
|
||||
<div className="flex-1 overflow-y-auto scrollbar-thin px-3 py-2 min-h-0">
|
||||
<SpanAnnotationList
|
||||
spanAnnotations={spanAnnotations}
|
||||
spanLabelTypes={spanLabelTypes}
|
||||
selectedSpanId={selectedSpanId}
|
||||
onSelectSpan={handleSelectedSpanChange}
|
||||
onDeleteSpan={handleDeleteSpan}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Predictions */}
|
||||
<div className="px-3 py-2 border-t border-sidebar-border">
|
||||
<PredictionPanel
|
||||
predictionState={predictionState}
|
||||
onToggleVisibility={togglePredictionVisibility}
|
||||
onFetchPredictions={handleFetchVisiblePredictions}
|
||||
onFetchBatchPredictions={handleFetchBatchPredictions}
|
||||
onConfidenceChange={setConfidenceThreshold}
|
||||
onToggleLabelSelection={toggleLabelSelection}
|
||||
predictionSummary={predictionSummary}
|
||||
isModelOnline={isModelOnline}
|
||||
showOnlyDisagreements={showOnlyDisagreements}
|
||||
onToggleShowOnlyDisagreements={toggleShowOnlyDisagreements}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Export */}
|
||||
<div className="px-3 py-2 border-t border-sidebar-border">
|
||||
<button
|
||||
onClick={handleExport}
|
||||
className="w-full flex items-center justify-center gap-1.5 px-2 py-1.5 text-xs rounded bg-primary/10 hover:bg-primary/20 text-primary transition-colors"
|
||||
>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" x2="12" y1="15" y2="3"/></svg>
|
||||
Export JSON
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Main chart area */}
|
||||
<main className="flex-1 relative bg-background">
|
||||
{/* Loading overlay for predictions */}
|
||||
{predictionState.isLoading && (
|
||||
<div className="absolute inset-0 bg-background/50 backdrop-blur-sm z-50 flex items-center justify-center">
|
||||
<div className="bg-card border border-border rounded-lg p-6 shadow-lg">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="animate-spin rounded-full h-5 w-5 border-2 border-primary border-t-transparent" />
|
||||
<span className="text-sm text-foreground">Loading predictions...</span>
|
||||
<div className="flex-1 flex flex-col min-w-0">
|
||||
{/* Chart top bar */}
|
||||
<div className="flex items-center justify-between px-3 py-1.5 border-b border-border bg-card/50">
|
||||
<div className="flex items-center gap-3">
|
||||
<span className="font-mono text-sm font-semibold text-foreground">
|
||||
{activeChart?.name || 'No chart'}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2 text-[10px] text-muted-foreground font-mono">
|
||||
<span className="px-1.5 py-0.5 rounded bg-secondary/50">R Rect</span>
|
||||
<span className="px-1.5 py-0.5 rounded bg-secondary/50">S Span</span>
|
||||
<span className="px-1.5 py-0.5 rounded bg-secondary/50">L Line</span>
|
||||
<span className="px-1.5 py-0.5 rounded bg-secondary/50">D Del</span>
|
||||
<span className="px-1.5 py-0.5 rounded bg-secondary/50">T Theme</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Chart */}
|
||||
<div className="flex-1 min-h-0 relative">
|
||||
{/* Loading overlay for predictions */}
|
||||
{predictionState.isLoading && (
|
||||
<div className="absolute inset-0 bg-background/50 backdrop-blur-sm z-50 flex items-center justify-center">
|
||||
<div className="bg-card border border-border rounded-lg p-6 shadow-lg">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="animate-spin rounded-full h-5 w-5 border-2 border-primary border-t-transparent" />
|
||||
<span className="text-sm text-foreground">Loading predictions...</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<CandleChart
|
||||
ref={chartRef}
|
||||
activeTool={activeTool}
|
||||
onAnnotationChange={handleAnnotationChange}
|
||||
selectedColor={selectedColor}
|
||||
selectedLabelId={selectedLabelId}
|
||||
onLabelSelect={handleLabelSelect}
|
||||
activeChartId={activeChartId}
|
||||
spanAnnotations={spanAnnotations}
|
||||
spanLabelTypes={spanLabelTypes}
|
||||
selectedSpanId={selectedSpanId}
|
||||
onSpanAnnotationsChange={handleSpanAnnotationsChange}
|
||||
onSelectedSpanChange={handleSelectedSpanChange}
|
||||
predictionVisible={predictionState.visible}
|
||||
perCandlePredictions={predictionState.perCandlePredictions}
|
||||
predictionSpans={predictionState.spans}
|
||||
confidenceThreshold={predictionState.confidenceThreshold}
|
||||
selectedLabels={predictionState.selectedLabels}
|
||||
modelInfo={predictionState.modelInfo}
|
||||
predictionSummary={predictionSummary}
|
||||
showOnlyDisagreements={showOnlyDisagreements}
|
||||
onPredictionClick={handlePredictionClick}
|
||||
onPredictionDismiss={handlePredictionDismiss}
|
||||
/>
|
||||
</main>
|
||||
)}
|
||||
<CandleChart
|
||||
ref={chartRef}
|
||||
activeTool={activeTool}
|
||||
onAnnotationChange={handleAnnotationChange}
|
||||
selectedColor={selectedColor}
|
||||
selectedLabelId={selectedLabelId}
|
||||
onLabelSelect={handleLabelSelect}
|
||||
activeChartId={activeChartId}
|
||||
spanAnnotations={spanAnnotations}
|
||||
spanLabelTypes={spanLabelTypes}
|
||||
selectedSpanId={selectedSpanId}
|
||||
onSpanAnnotationsChange={handleSpanAnnotationsChange}
|
||||
onSelectedSpanChange={handleSelectedSpanChange}
|
||||
predictionVisible={predictionState.visible}
|
||||
perCandlePredictions={predictionState.perCandlePredictions}
|
||||
predictionSpans={predictionState.spans}
|
||||
confidenceThreshold={predictionState.confidenceThreshold}
|
||||
selectedLabels={predictionState.selectedLabels}
|
||||
modelInfo={predictionState.modelInfo}
|
||||
predictionSummary={predictionSummary}
|
||||
showOnlyDisagreements={showOnlyDisagreements}
|
||||
onPredictionClick={handlePredictionClick}
|
||||
onPredictionDismiss={handlePredictionDismiss}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue