From b38750f0cf5f46c856ef88208c282c764a0ad4b0 Mon Sep 17 00:00:00 2001 From: catlog22 Date: Fri, 20 Feb 2026 21:31:21 +0800 Subject: [PATCH] refactor(terminal-dashboard): simplify CLI launch to dialog-only mode - Replace dropdown menu with direct dialog button - Remove unused state variables (selectedTool, launchMode, selectedShell) - Update button icon to Plus and label to "New Session" - Clean up i18n keys (remove unused tool/mode/shell options) --- .../terminal-dashboard/DashboardToolbar.tsx | 204 +++--------------- .../src/locales/en/terminal-dashboard.json | 11 +- .../src/locales/zh/terminal-dashboard.json | 11 +- 3 files changed, 39 insertions(+), 187 deletions(-) diff --git a/ccw/frontend/src/components/terminal-dashboard/DashboardToolbar.tsx b/ccw/frontend/src/components/terminal-dashboard/DashboardToolbar.tsx index 98fc0c35..b33999e3 100644 --- a/ccw/frontend/src/components/terminal-dashboard/DashboardToolbar.tsx +++ b/ccw/frontend/src/components/terminal-dashboard/DashboardToolbar.tsx @@ -16,29 +16,15 @@ import { Columns2, Rows2, Square, - Terminal, - ChevronDown, - Zap, - Settings, Loader2, Folder, Maximize2, Minimize2, + Activity, + Plus, } from 'lucide-react'; import { cn } from '@/lib/utils'; import { Badge } from '@/components/ui/Badge'; -import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuRadioGroup, - DropdownMenuRadioItem, - DropdownMenuSub, - DropdownMenuSubContent, - DropdownMenuSubTrigger, - DropdownMenuTrigger, - DropdownMenuSeparator, -} from '@/components/ui/Dropdown'; import { useIssueQueueIntegrationStore, selectAssociationChain, @@ -47,11 +33,12 @@ import { useIssues, useIssueQueue } from '@/hooks/useIssues'; import { useTerminalGridStore, selectTerminalGridFocusedPaneId } from '@/stores/terminalGridStore'; import { useWorkflowStore, selectProjectPath } from '@/stores/workflowStore'; import { toast } from '@/stores/notificationStore'; +import { useExecutionMonitorStore, selectActiveExecutionCount } from '@/stores/executionMonitorStore'; import { CliConfigModal, type CliSessionConfig } from './CliConfigModal'; // ========== Types ========== -export type PanelId = 'issues' | 'queue' | 'inspector'; +export type PanelId = 'issues' | 'queue' | 'inspector' | 'execution'; interface DashboardToolbarProps { activePanel: PanelId | null; @@ -79,12 +66,6 @@ const LAYOUT_PRESETS = [ { id: 'grid-2x2' as const, icon: LayoutGrid, labelId: 'terminalDashboard.toolbar.layoutGrid' }, ]; -type LaunchMode = 'default' | 'yolo'; -type ShellKind = 'bash' | 'pwsh' | 'cmd'; - -const CLI_TOOLS = ['claude', 'gemini', 'qwen', 'codex', 'opencode'] as const; -type CliTool = (typeof CLI_TOOLS)[number]; - // ========== Component ========== export function DashboardToolbar({ activePanel, onTogglePanel, isFileSidebarOpen, onToggleFileSidebar, isSessionSidebarOpen, onToggleSessionSidebar, isFullscreen, onToggleFullscreen }: DashboardToolbarProps) { @@ -109,6 +90,9 @@ export function DashboardToolbar({ activePanel, onTogglePanel, isFileSidebarOpen const associationChain = useIssueQueueIntegrationStore(selectAssociationChain); const hasChain = associationChain !== null; + // Execution monitor count + const executionCount = useExecutionMonitorStore(selectActiveExecutionCount); + // Layout preset handler const resetLayout = useTerminalGridStore((s) => s.resetLayout); const handlePreset = useCallback( @@ -121,14 +105,8 @@ export function DashboardToolbar({ activePanel, onTogglePanel, isFileSidebarOpen // Launch CLI handlers const projectPath = useWorkflowStore(selectProjectPath); const focusedPaneId = useTerminalGridStore(selectTerminalGridFocusedPaneId); - // panes available via: useTerminalGridStore((s) => s.panes) const createSessionAndAssign = useTerminalGridStore((s) => s.createSessionAndAssign); const [isCreating, setIsCreating] = useState(false); - const [selectedTool, setSelectedTool] = useState('gemini'); - const [launchMode, setLaunchMode] = useState('yolo'); - const [selectedShell, setSelectedShell] = useState( - typeof navigator !== 'undefined' && navigator.platform.toLowerCase().includes('win') ? 'cmd' : 'bash' - ); const [isConfigOpen, setIsConfigOpen] = useState(false); // Helper to get or create a focused pane @@ -140,39 +118,12 @@ export function DashboardToolbar({ activePanel, onTogglePanel, isFileSidebarOpen return useTerminalGridStore.getState().focusedPaneId; }, [focusedPaneId]); - const handleQuickCreate = useCallback(async () => { - if (!projectPath) return; - setIsCreating(true); - try { - const targetPaneId = getOrCreateFocusedPane(); - if (!targetPaneId) { - toast.error('无法创建会话', '未能获取或创建窗格'); - return; - } - - await createSessionAndAssign(targetPaneId, { - workingDir: projectPath, - preferredShell: selectedShell, - tool: selectedTool, - launchMode, - }, projectPath); - } catch (error: unknown) { - // Handle both Error instances and ApiError-like objects - const message = error instanceof Error - ? error.message - : (error as { message?: string })?.message - ? (error as { message: string }).message - : String(error); - toast.error(`CLI 会话创建失败 (${selectedTool})`, message); - } finally { - setIsCreating(false); - } - }, [projectPath, createSessionAndAssign, selectedTool, selectedShell, launchMode, getOrCreateFocusedPane]); - - const handleConfigure = useCallback(() => { + // Open config modal + const handleOpenConfig = useCallback(() => { setIsConfigOpen(true); }, []); + // Create session from config modal const handleCreateConfiguredSession = useCallback(async (config: CliSessionConfig) => { if (!projectPath) throw new Error('No project path'); setIsCreating(true); @@ -192,7 +143,6 @@ export function DashboardToolbar({ activePanel, onTogglePanel, isFileSidebarOpen projectPath ); } catch (error: unknown) { - // Handle both Error instances and ApiError-like objects const message = error instanceof Error ? error.message : (error as { message?: string })?.message @@ -208,115 +158,24 @@ export function DashboardToolbar({ activePanel, onTogglePanel, isFileSidebarOpen return ( <>
- {/* Launch CLI dropdown */} - - - - - - - - {formatMessage({ id: 'terminalDashboard.toolbar.tool' })} - ({selectedTool}) - - - setSelectedTool(v as CliTool)} - > - {CLI_TOOLS.map((tool) => ( - - {tool} - - ))} - - - - - - - {formatMessage({ id: 'terminalDashboard.toolbar.mode' })} - - {launchMode === 'default' - ? formatMessage({ id: 'terminalDashboard.toolbar.modeDefault' }) - : formatMessage({ id: 'terminalDashboard.toolbar.modeYolo' })} - - - - setLaunchMode(v as LaunchMode)} - > - - {formatMessage({ id: 'terminalDashboard.toolbar.modeDefault' })} - - - {formatMessage({ id: 'terminalDashboard.toolbar.modeYolo' })} - - - - - - - - {formatMessage({ id: 'terminalDashboard.toolbar.shell' })} - - {selectedShell === 'cmd' ? 'cmd' : selectedShell === 'pwsh' ? 'pwsh' : 'bash'} - - - - setSelectedShell(v as ShellKind)} - > - - cmd {formatMessage({ id: 'terminalDashboard.toolbar.shellCmdDesc' })} - - - bash (Git Bash/WSL) - - - pwsh (PowerShell) - - - - - - - - - {formatMessage({ id: 'terminalDashboard.toolbar.quickCreate' })} - - - - - {formatMessage({ id: 'terminalDashboard.toolbar.configure' })} - - - + {/* Launch CLI button - opens config dialog */} + {/* Separator */}
@@ -354,6 +213,13 @@ export function DashboardToolbar({ activePanel, onTogglePanel, isFileSidebarOpen onClick={() => onTogglePanel('inspector')} dot={hasChain} /> + onTogglePanel('execution')} + badge={executionCount > 0 ? executionCount : undefined} + />