feat: port contexts layer and MCP parity

This commit is contained in:
“BeeRad”
2026-04-10 19:41:26 +10:00
parent a8c5506fb7
commit 35f9ecf89c
62 changed files with 4206 additions and 1224 deletions
+80
View File
@@ -8,6 +8,8 @@ import {
LayoutList,
Map,
Folder,
ChevronDown,
ChevronRight,
Table2,
BookOpen,
Settings,
@@ -18,6 +20,7 @@ import {
} from 'lucide-react';
import type { PaneType, NavigablePaneType } from '../panes/types';
import type { Theme } from '@/hooks/useTheme';
import type { ContextSummary } from '@/types/database';
interface LeftToolbarProps {
onSearchClick: () => void;
@@ -31,6 +34,8 @@ interface LeftToolbarProps {
activeTabType: PaneType | null;
theme: Theme;
onThemeToggle: () => void;
contexts?: ContextSummary[];
onContextQuickSelect?: (contextId: number, contextName: string) => void;
}
const NAV_WIDTH_COLLAPSED = 50;
@@ -113,7 +118,11 @@ export default function LeftToolbar({
activeTabType,
theme,
onThemeToggle,
contexts = [],
onContextQuickSelect,
}: LeftToolbarProps) {
const [contextsExpanded, setContextsExpanded] = useState(false);
return (
<div
style={{
@@ -148,6 +157,77 @@ export default function LeftToolbar({
<div style={{ flex: 1, display: 'flex', flexDirection: 'column', justifyContent: 'center', minHeight: 0 }}>
<div style={{ borderTop: '1px solid var(--rah-border)', paddingTop: '14px' }}>
<div style={{ display: 'flex', flexDirection: 'column', gap: '4px' }}>
<div style={{ display: 'flex', flexDirection: 'column', gap: '4px', marginBottom: '6px' }}>
<div style={{ display: 'flex', alignItems: 'center', gap: '4px' }}>
<div style={{ flex: 1, minWidth: 0 }}>
<NavButton
icon={Folder}
label="Contexts"
expanded={isExpanded}
active={activeTabType === 'contexts' || openTabTypes.has('contexts')}
onClick={() => onPaneTypeClick('contexts')}
activeTone="green"
/>
</div>
{isExpanded ? (
<button
type="button"
onClick={() => setContextsExpanded((prev) => !prev)}
style={{
width: '28px',
height: '36px',
borderRadius: '8px',
border: 'none',
background: contextsExpanded ? 'var(--rah-bg-hover)' : 'transparent',
color: contextsExpanded ? 'var(--rah-text-active)' : 'var(--rah-text-muted)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
cursor: 'pointer',
flexShrink: 0,
}}
title="Toggle context list"
>
{contextsExpanded ? <ChevronDown size={16} /> : <ChevronRight size={16} />}
</button>
) : null}
</div>
{isExpanded && contextsExpanded && contexts.length > 0 ? (
<div style={{ marginLeft: '14px', paddingLeft: '12px', borderLeft: '1px solid var(--rah-border)', display: 'flex', flexDirection: 'column', gap: '2px' }}>
{contexts.map((context) => (
<button
key={context.id}
type="button"
onClick={() => onContextQuickSelect?.(context.id, context.name)}
style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
gap: '8px',
width: '100%',
minHeight: '28px',
border: 'none',
background: 'transparent',
color: 'var(--rah-text-secondary)',
cursor: 'pointer',
padding: '0 8px',
borderRadius: '8px',
textAlign: 'left',
}}
>
<span style={{ fontSize: '12px', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
{context.name}
</span>
<span style={{ fontSize: '10px', color: 'var(--rah-text-muted)', flexShrink: 0 }}>
{context.count}
</span>
</button>
))}
</div>
) : null}
</div>
{VIEW_ITEMS.map((item) => (
<NavButton
key={`${item.paneType}-${item.label}`}