feat: reorganize global settings navigation into groups

- Refactored the global navigation structure to group settings items into distinct categories for improved organization and usability.
- Updated the settings navigation component to render these groups dynamically, enhancing the user experience.
- Changed the default initial view in the settings hook to 'model-defaults' for better alignment with the new navigation structure.

These changes streamline navigation and make it easier for users to find relevant settings.
This commit is contained in:
webdevcody
2026-01-09 17:09:08 -05:00
parent a01241fabe
commit cadb19d7ed
3 changed files with 75 additions and 49 deletions

View File

@@ -2,8 +2,8 @@ import { useState, useEffect } from 'react';
import { ChevronDown, ChevronRight } from 'lucide-react';
import { cn } from '@/lib/utils';
import type { Project } from '@/lib/electron';
import type { NavigationItem } from '../config/navigation';
import { GLOBAL_NAV_ITEMS, PROJECT_NAV_ITEMS } from '../config/navigation';
import type { NavigationItem, NavigationGroup } from '../config/navigation';
import { GLOBAL_NAV_GROUPS, PROJECT_NAV_ITEMS } from '../config/navigation';
import type { SettingsViewId } from '../hooks/use-settings-view';
const PROVIDERS_DROPDOWN_KEY = 'settings-providers-dropdown-open';
@@ -177,37 +177,45 @@ export function SettingsNavigation({
)}
>
<div className="sticky top-0 p-4 space-y-1">
{/* Global Settings Label */}
<div className="px-3 py-2 text-xs font-semibold text-muted-foreground/70 uppercase tracking-wider">
Global Settings
</div>
{/* Global Settings Groups */}
{GLOBAL_NAV_GROUPS.map((group, groupIndex) => (
<div key={group.label}>
{/* Group divider (except for first group) */}
{groupIndex > 0 && <div className="my-3 border-t border-border/50" />}
{/* Global Settings Items */}
<div className="space-y-1">
{GLOBAL_NAV_ITEMS.map((item) =>
item.subItems ? (
<NavItemWithSubItems
key={item.id}
item={item}
activeSection={activeSection}
onNavigate={onNavigate}
/>
) : (
<NavButton
key={item.id}
item={item}
isActive={activeSection === item.id}
onNavigate={onNavigate}
/>
)
)}
</div>
{/* Group Label */}
<div className="px-3 py-2 text-xs font-semibold text-muted-foreground/70 uppercase tracking-wider">
{group.label}
</div>
{/* Group Items */}
<div className="space-y-1">
{group.items.map((item) =>
item.subItems ? (
<NavItemWithSubItems
key={item.id}
item={item}
activeSection={activeSection}
onNavigate={onNavigate}
/>
) : (
<NavButton
key={item.id}
item={item}
isActive={activeSection === item.id}
onNavigate={onNavigate}
/>
)
)}
</div>
</div>
))}
{/* Project Settings - only show when a project is selected */}
{currentProject && (
<>
{/* Divider */}
<div className="my-4 border-t border-border/50" />
<div className="my-3 border-t border-border/50" />
{/* Project Settings Label */}
<div className="px-3 py-2 text-xs font-semibold text-muted-foreground/70 uppercase tracking-wider">

View File

@@ -31,32 +31,50 @@ export interface NavigationGroup {
items: NavigationItem[];
}
// Global settings - always visible
export const GLOBAL_NAV_ITEMS: NavigationItem[] = [
{ id: 'api-keys', label: 'API Keys', icon: Key },
// Global settings organized into groups
export const GLOBAL_NAV_GROUPS: NavigationGroup[] = [
{
id: 'providers',
label: 'AI Providers',
icon: Bot,
subItems: [
{ id: 'claude-provider', label: 'Claude', icon: AnthropicIcon },
{ id: 'cursor-provider', label: 'Cursor', icon: CursorIcon },
{ id: 'codex-provider', label: 'Codex', icon: OpenAIIcon },
{ id: 'opencode-provider', label: 'OpenCode', icon: Cpu },
label: 'Model & Prompts',
items: [
{ id: 'model-defaults', label: 'Model Defaults', icon: Workflow },
{ id: 'defaults', label: 'Feature Defaults', icon: FlaskConical },
{ id: 'prompts', label: 'Prompt Customization', icon: MessageSquareText },
{ id: 'api-keys', label: 'API Keys', icon: Key },
{
id: 'providers',
label: 'AI Providers',
icon: Bot,
subItems: [
{ id: 'claude-provider', label: 'Claude', icon: AnthropicIcon },
{ id: 'cursor-provider', label: 'Cursor', icon: CursorIcon },
{ id: 'codex-provider', label: 'Codex', icon: OpenAIIcon },
{ id: 'opencode-provider', label: 'OpenCode', icon: Cpu },
],
},
{ id: 'mcp-servers', label: 'MCP Servers', icon: Plug },
],
},
{
label: 'Interface',
items: [
{ id: 'appearance', label: 'Appearance', icon: Palette },
{ id: 'terminal', label: 'Terminal', icon: SquareTerminal },
{ id: 'keyboard', label: 'Keyboard Shortcuts', icon: Settings2 },
{ id: 'audio', label: 'Audio', icon: Volume2 },
],
},
{
label: 'Account & Security',
items: [
{ id: 'account', label: 'Account', icon: User },
{ id: 'security', label: 'Security', icon: Shield },
],
},
{ id: 'mcp-servers', label: 'MCP Servers', icon: Plug },
{ id: 'prompts', label: 'Prompt Customization', icon: MessageSquareText },
{ id: 'model-defaults', label: 'Model Defaults', icon: Workflow },
{ id: 'appearance', label: 'Appearance', icon: Palette },
{ id: 'terminal', label: 'Terminal', icon: SquareTerminal },
{ id: 'keyboard', label: 'Keyboard Shortcuts', icon: Settings2 },
{ id: 'audio', label: 'Audio', icon: Volume2 },
{ id: 'defaults', label: 'Feature Defaults', icon: FlaskConical },
{ id: 'account', label: 'Account', icon: User },
{ id: 'security', label: 'Security', icon: Shield },
];
// Flat list of all global nav items for backwards compatibility
export const GLOBAL_NAV_ITEMS: NavigationItem[] = GLOBAL_NAV_GROUPS.flatMap((group) => group.items);
// Project-specific settings - only visible when a project is selected
export const PROJECT_NAV_ITEMS: NavigationItem[] = [
{ id: 'danger', label: 'Danger Zone', icon: Trash2 },

View File

@@ -24,7 +24,7 @@ interface UseSettingsViewOptions {
initialView?: SettingsViewId;
}
export function useSettingsView({ initialView = 'api-keys' }: UseSettingsViewOptions = {}) {
export function useSettingsView({ initialView = 'model-defaults' }: UseSettingsViewOptions = {}) {
const [activeView, setActiveView] = useState<SettingsViewId>(initialView);
const navigateTo = useCallback((viewId: SettingsViewId) => {