fix: make sidebar scrollable so training/predictions panels are always visible

This commit is contained in:
Marko Djordjevic 2026-02-17 22:10:54 +01:00
parent 2faa8879f3
commit d34dc9d729
2 changed files with 52 additions and 48 deletions

View file

@ -760,7 +760,7 @@ export default function Home() {
{/* Sidebar */} {/* Sidebar */}
<div className="flex flex-col bg-sidebar border-r border-sidebar-border w-60 flex-shrink-0 animate-fade-in"> <div className="flex flex-col bg-sidebar border-r border-sidebar-border w-60 flex-shrink-0 animate-fade-in">
{/* Sidebar Header */} {/* Sidebar Header */}
<div className="flex items-center justify-between px-4 py-3 border-b border-sidebar-border"> <div className="flex items-center justify-between px-4 py-3 border-b border-sidebar-border flex-shrink-0">
<div> <div>
<h1 className="text-sm font-semibold text-foreground tracking-tight">Candle Annotator</h1> <h1 className="text-sm font-semibold text-foreground tracking-tight">Candle Annotator</h1>
<p className="text-[10px] text-muted-foreground">Chart annotation tool</p> <p className="text-[10px] text-muted-foreground">Chart annotation tool</p>
@ -771,7 +771,7 @@ export default function Home() {
</div> </div>
{/* Chart Selector */} {/* Chart Selector */}
<div className="px-3 py-2 border-b border-sidebar-border"> <div className="px-3 py-2 border-b border-sidebar-border flex-shrink-0">
<ChartSelector <ChartSelector
charts={charts} charts={charts}
activeChartId={activeChartId} activeChartId={activeChartId}
@ -781,12 +781,12 @@ export default function Home() {
</div> </div>
{/* File Upload */} {/* File Upload */}
<div className="px-3 py-2 border-b border-sidebar-border"> <div className="px-3 py-2 border-b border-sidebar-border flex-shrink-0">
<FileUpload onUploadSuccess={handleUploadSuccess} /> <FileUpload onUploadSuccess={handleUploadSuccess} />
</div> </div>
{/* Toolbox */} {/* Toolbox */}
<div className="px-3 py-2 border-b border-sidebar-border"> <div className="px-3 py-2 border-b border-sidebar-border flex-shrink-0">
<Toolbox <Toolbox
activeTool={activeTool} activeTool={activeTool}
onToolChange={setActiveTool} onToolChange={setActiveTool}
@ -806,28 +806,54 @@ export default function Home() {
/> />
</div> </div>
{/* Annotations List - scrollable */} {/* Scrollable middle: Annotations + TA-Lib + Training + Predictions */}
<div className="flex-1 overflow-y-auto scrollbar-thin px-3 py-2 min-h-0"> <div className="flex-1 overflow-y-auto scrollbar-thin min-h-0">
<SpanAnnotationList {/* Annotations List */}
spanAnnotations={spanAnnotations} <div className="px-3 py-2 border-b border-sidebar-border">
spanLabelTypes={spanLabelTypes} <SpanAnnotationList
selectedSpanId={selectedSpanId} spanAnnotations={spanAnnotations}
onSelectSpan={handleSelectedSpanChange} spanLabelTypes={spanLabelTypes}
onDeleteSpan={handleDeleteSpan} selectedSpanId={selectedSpanId}
/> onSelectSpan={handleSelectedSpanChange}
</div> onDeleteSpan={handleDeleteSpan}
/>
{/* TA-Lib Pattern Panel */} </div>
<div className="px-3 py-2 border-t border-sidebar-border">
<TalibPatternPanel {/* TA-Lib Pattern Panel */}
activeChartId={activeChartId} <div className="px-3 py-2 border-b border-sidebar-border">
onAnnotationsChanged={() => fetchSpanAnnotations(activeChartId)} <TalibPatternPanel
getCandles={() => chartRef.current?.getVisibleCandles()} activeChartId={activeChartId}
/> onAnnotationsChanged={() => fetchSpanAnnotations(activeChartId)}
getCandles={() => chartRef.current?.getVisibleCandles()}
/>
</div>
{/* Training Panel */}
<div className="px-3 py-2 border-b border-sidebar-border">
<TrainingPanel />
</div>
{/* Predictions */}
<div className="px-3 py-2">
<PredictionPanel
predictionState={predictionState}
onToggleVisibility={togglePredictionVisibility}
onFetchPredictions={handleFetchVisiblePredictions}
onFetchBatchPredictions={handleFetchBatchPredictions}
onConfidenceChange={setConfidenceThreshold}
onToggleLabelSelection={toggleLabelSelection}
predictionSummary={predictionSummary}
isModelOnline={isModelOnline}
showOnlyDisagreements={showOnlyDisagreements}
onToggleShowOnlyDisagreements={toggleShowOnlyDisagreements}
onModelLoaded={handleModelLoaded}
/>
</div>
</div> </div>
{/* Fixed bottom actions */}
{/* Delete all annotations */} {/* Delete all annotations */}
<div className="px-3 py-2 border-t border-sidebar-border"> <div className="px-3 py-2 border-t border-sidebar-border flex-shrink-0">
<button <button
onClick={handleDeleteAllAnnotations} onClick={handleDeleteAllAnnotations}
disabled={!activeChartId} disabled={!activeChartId}
@ -837,30 +863,8 @@ export default function Home() {
</button> </button>
</div> </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
predictionState={predictionState}
onToggleVisibility={togglePredictionVisibility}
onFetchPredictions={handleFetchVisiblePredictions}
onFetchBatchPredictions={handleFetchBatchPredictions}
onConfidenceChange={setConfidenceThreshold}
onToggleLabelSelection={toggleLabelSelection}
predictionSummary={predictionSummary}
isModelOnline={isModelOnline}
showOnlyDisagreements={showOnlyDisagreements}
onToggleShowOnlyDisagreements={toggleShowOnlyDisagreements}
onModelLoaded={handleModelLoaded}
/>
</div>
{/* Export */} {/* Export */}
<div className="px-3 py-2 border-t border-sidebar-border"> <div className="px-3 py-2 border-t border-sidebar-border flex-shrink-0">
<button <button
onClick={handleExport} 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" 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"
@ -871,7 +875,7 @@ export default function Home() {
</div> </div>
{/* Settings */} {/* Settings */}
<div className="relative px-3 py-2 border-t border-sidebar-border"> <div className="relative px-3 py-2 border-t border-sidebar-border flex-shrink-0">
<button <button
onClick={() => setSettingsOpen((o) => !o)} onClick={() => setSettingsOpen((o) => !o)}
className="flex items-center gap-1.5 px-2 py-1.5 text-xs rounded text-muted-foreground hover:text-foreground hover:bg-secondary/50 transition-colors" className="flex items-center gap-1.5 px-2 py-1.5 text-xs rounded text-muted-foreground hover:text-foreground hover:bg-secondary/50 transition-colors"

File diff suppressed because one or more lines are too long