import { useState } from 'react'; import { RotateCcw, RefreshCw, AlertCircle, ChevronDown, ShieldCheck } from 'lucide-react'; import Button from '../../ui/Button'; import SuggestionsQueue from '../SuggestionsQueue'; const SCOPE_OPTIONS = [ { value: 'full', label: 'Full Analysis', tier: 'Opus', hint: 'Merges · Deletions · Relations · Relevance' }, { value: 'relations', label: 'Relations Only', tier: 'Sonnet', hint: 'Suggest missing logical connections' }, { value: 'relevance', label: 'Relevance Only', tier: 'Sonnet', hint: 'Re-score learning_relevance for all unlocked topics' }, ]; /** * Sidebar controls panel: the exclude-nodes toggle, the AI analysis button * (with scope selector), the snapshot restore row, and the R42 suggestions queue. * * Kept intentionally thin — all async logic lives in the KnowledgeGraph * orchestrator and is injected via props. * * The scope selector is local state here; it produces a scope string that is * forwarded to onAnalyze(scope). Scope options map to different AI tiers: * full → reasoning (Opus) — expensive full quality pass * relations / relevance → standard (Sonnet) — targeted cheaper sub-task */ export default function GraphControls({ showExcludeNodes, onShowExcludeChange, excludedCount = 0, onAnalyze, isAnalyzing, analyzeError, analyzeNotice, disabled, onApplied, snapshotMeta, onRestore, isRestoring, }) { const [scope, setScope] = useState('full'); const selectedOption = SCOPE_OPTIONS.find(o => o.value === scope) ?? SCOPE_OPTIONS[0]; const snapshotLabel = snapshotMeta ? new Date(snapshotMeta.ts).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }) : null; return (
{/* Scope selector */}

{selectedOption.hint}

{/* Restore row — only visible after a bulkSave has written a snapshot */} {snapshotMeta && ( )} {analyzeError && (

{analyzeError}

)} {analyzeNotice && (

{analyzeNotice}

)}
); }