feat: setup dataset enrichment app codebase and scripts

This commit is contained in:
asus committed 2026-08-05 11:52:27 +07:00
1 parent b5c28cc98a
commit d07578462e
72 files changed
+11370

No files matched your search

+104
View File
@@ -0,0 +1,104 @@
import { useEffect, useState } from 'react'
import { api } from '../api'
import { navigate } from '../App'
import {
FolderIcon,
DatabaseIcon,
RocketIcon,
TagIcon,
BarChartIcon,
SunIcon,
MoonIcon,
ChevronRightIcon,
} from './Icons'
export default function Sidebar({ route, currentProject, theme, onToggleTheme }) {
const [health, setHealth] = useState(null)
const [collapsed, setCollapsed] = useState(() => localStorage.getItem('sidebar_collapsed') === 'true')
useEffect(() => {
api.health().then(setHealth).catch(() => {})
}, [])
const toggleCollapse = () => {
setCollapsed((prev) => {
const next = !prev
localStorage.setItem('sidebar_collapsed', String(next))
return next
})
}
const pId = currentProject?.id || route.projectId || 1
const handleNav = (e, path) => {
e.preventDefault()
navigate(path)
}
return (
<div className={`roboflow-sidebar ${collapsed ? 'collapsed' : ''}`}>
<div className="sidebar-header">
<div className="sidebar-logo">{collapsed ? 'DE' : 'Dataset Enrichment'}</div>
<button className="sidebar-collapse-btn" onClick={toggleCollapse} title={collapsed ? 'Expand sidebar' : 'Collapse sidebar'}>
{collapsed ? <ChevronRightIcon size={14} /> : '❮'}
</button>
</div>
<div className="sidebar-section">
{!collapsed && <div className="sidebar-section-title">WORKSPACE</div>}
<a href="#/projects" onClick={(e) => handleNav(e, '/projects')} className={`sidebar-item ${route.name === 'projects' ? 'active' : ''}`} title="Projects">
<span className="sidebar-icon"><FolderIcon size={16} /></span>
{!collapsed && <span>Projects</span>}
</a>
</div>
<div className="sidebar-section">
{!collapsed && <div className="sidebar-section-title">DATA</div>}
<a href={`#/projects/${pId}`} onClick={(e) => handleNav(e, `/projects/${pId}`)} className={`sidebar-item ${route.name === 'library' ? 'active' : ''}`} title="Video Archive">
<span className="sidebar-icon"><DatabaseIcon size={16} /></span>
{!collapsed && <span>Video Archive</span>}
</a>
<a
href={route.batchId ? `#/batches/${route.batchId}` : `#/projects/${pId}`}
onClick={(e) => handleNav(e, route.batchId ? `/batches/${route.batchId}` : `/projects/${pId}`)}
className={`sidebar-item ${route.name === 'review' || route.name === 'trim' ? 'active' : ''}`}
title="Annotate / Review"
>
<span className="sidebar-icon"><TagIcon size={16} /></span>
{!collapsed && <span>Annotate / Review</span>}
</a>
<a href={`#/projects/${pId}/models`} onClick={(e) => handleNav(e, `/projects/${pId}/models`)} className={`sidebar-item ${route.name === 'models' ? 'active' : ''}`} title="Master Dataset">
<span className="sidebar-icon"><BarChartIcon size={16} /></span>
{!collapsed && <span>Master Dataset</span>}
</a>
</div>
<div className="sidebar-section">
{!collapsed && <div className="sidebar-section-title">MODELS</div>}
<a href={`#/projects/${pId}/models`} onClick={(e) => handleNav(e, `/projects/${pId}/models`)} className={`sidebar-item ${route.name === 'models' ? 'active' : ''}`} title="Train & Select Engine">
<span className="sidebar-icon"><RocketIcon size={16} /></span>
{!collapsed && <span>Train & Select Engine</span>}
</a>
</div>
<div className="sidebar-spacer" />
<div className="sidebar-footer">
<button className="sidebar-theme-toggle" onClick={onToggleTheme} title={theme === 'dark' ? 'Switch to Light Mode' : 'Switch to Dark Mode'}>
{collapsed ? (theme === 'dark' ? <SunIcon size={14} /> : <MoonIcon size={14} />) : (theme === 'dark' ? 'Light Mode' : 'Dark Mode')}
</button>
{health && !collapsed && (
<div className="sidebar-health">
<div className="health-item" title={health.gpu || ''} style={{ whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis', display: 'block' }}>
<span style={{ float: 'left' }}>GPU:</span>
<span style={{ float: 'right' }}>{health.gpu ? health.gpu.replace('NVIDIA GeForce ', '').replace(' Laptop GPU', '') : 'N/A'}</span>
</div>
<div className="health-item"><span>VRAM:</span> <span>{health.vram_free_gb ? `${health.vram_free_gb.toFixed(1)}GB` : 'N/A'}</span></div>
<div className="health-item"><span>SAM3:</span> <span>{health.sam3_ready ? 'Ready' : 'Not Ready'}</span></div>
<div className="health-item"><span>FFmpeg:</span> <span>{health.ffmpeg ? 'OK' : 'Error'}</span></div>
</div>
)}
</div>
</div>
)
}