interface SettingsSidebarProps { activeSection?: string; onSelectSection: (section: string) => void; isAdmin: boolean; } /** * Settings navigation, restructured to match the * 2026-05-21-settings-ui-and-config-restructure-design.md (Step 3). * * The form components themselves are intentionally not rewritten in this * step — Provider/Workers/etc keep reading `provider.*` for now and will * show as partially empty against the v2 API. Steps 7-9 swap those forms * to read the new `llm.*` / `gateway.*` keys. * * Old sidebar ids (provider, workspace, tools, browser-settings, * search-filter) still parse via `urlState.ts` and are redirected to * their new homes by `LEGACY_SECTION_REDIRECT` in this file. This keeps * old bookmarks/links working through the transition. */ const CONFIG_GROUPS = [ { label: 'User', sections: [ { id: 'preferences', label: 'Preferences' }, { id: 'notifications', label: '🔔 Notifications' }, { id: 'memory-learning', label: '🧠 Memory & Learning' }, ], }, { label: 'System', adminOnly: true, sections: [ { id: 'branding', label: 'Branding' }, { id: 'paths-storage', label: 'Paths & Storage' }, { id: 'execution', label: 'Execution' }, { id: 'auth', label: 'Authentication' }, { id: 'push-notifications', label: 'Web Push (Server)' }, ], }, { label: 'LLM', adminOnly: true, sections: [ { id: 'llm-workers', label: 'Workers' }, // Step 8: Gateway Keys absorbed into Gateway Server as the // "Virtual Keys" section. Bookmarks to `gateway-keys` are // redirected via LEGACY_SECTION_REDIRECT below. { id: 'gateway-server', label: 'Gateway Server' }, { id: 'llm-metrics', label: 'Metrics' }, ], }, { label: 'Agent Runtime', adminOnly: true, sections: [ { id: 'ask-subtasks', label: 'Ask / Subtasks' }, { id: 'context', label: 'Context' }, { id: 'safety', label: 'Safety' }, { id: 'reflection', label: 'Reflection' }, { id: 'notes', label: 'Notes Injection' }, ], }, { label: 'Tools', adminOnly: true, sections: [ { id: 'tools-web', label: 'Web & Search' }, { id: 'tools-browser', label: 'Browser Runtime' }, { id: 'tools-media', label: 'Media & Documents' }, { id: 'tools-external', label: 'External Services' }, { id: 'search-filter', label: 'Search Filter' }, { id: 'tools-legacy-knowledge', label: 'Legacy Knowledge' }, ], }, { label: 'MCP & Connections', adminOnly: true, sections: [ { id: 'mcp', label: 'MCP Runtime' }, ], }, { label: 'SSH', adminOnly: true, sections: [ { id: 'ssh', label: 'Admin SSH' }, ], }, ] as const; /** * Old sidebar id → new id mapping. Used by `SettingsPage` to upgrade * URLs / bookmarks left over from the pre-Step-3 sidebar layout. Keep * each entry until the underlying old id is fully removed from * `SETTINGS_SECTIONS` in `urlState.ts`. * * `tools` (the catch-all tab) maps to the first new Tools sub-section. * Power users coming in via that old URL should land on something * visible rather than a blank screen. */ export const LEGACY_SECTION_REDIRECT: Record = { provider: 'llm-workers', workspace: 'paths-storage', tools: 'tools-web', 'browser-settings': 'tools-browser', // browser-sessions never had a Settings page in the new layout — // it lives in User Folder. Keep mapping so an old URL still goes // somewhere sensible. 'browser-sessions': 'preferences', // Step 8: Gateway Keys folded into Gateway Server. Bookmarks land // on the parent form which now hosts the Virtual Keys section. 'gateway-keys': 'gateway-server', skills: 'preferences', }; /** Sections that any authenticated user (not just admin) can access. */ export const USER_SECTIONS: string[] = CONFIG_GROUPS .filter(g => !('adminOnly' in g) || !g.adminOnly) .flatMap(g => g.sections.map(s => s.id)); export function SettingsSidebar({ activeSection, onSelectSection, isAdmin }: SettingsSidebarProps) { const visibleGroups = CONFIG_GROUPS.filter(g => isAdmin || !('adminOnly' in g) || !g.adminOnly); return (
{visibleGroups.map(group => (
{group.label}
{group.sections.map(s => ( ))}
))}
); }