feat: port contexts layer and MCP parity
This commit is contained in:
@@ -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}`}
|
||||
|
||||
Reference in New Issue
Block a user