diff --git a/ccw/frontend/src/components/terminal-dashboard/TerminalPane.tsx b/ccw/frontend/src/components/terminal-dashboard/TerminalPane.tsx index 58804d93..e387b952 100644 --- a/ccw/frontend/src/components/terminal-dashboard/TerminalPane.tsx +++ b/ccw/frontend/src/components/terminal-dashboard/TerminalPane.tsx @@ -6,7 +6,7 @@ // Renders within the TerminalGrid recursive layout. // File preview is triggered from right sidebar FileSidebarPanel. -import { useCallback, useMemo, useState } from 'react'; +import { useCallback, useEffect, useMemo, useState } from 'react'; import { useIntl } from 'react-intl'; import { SplitSquareHorizontal, @@ -23,6 +23,7 @@ import { FileText, ArrowLeft, LogOut, + WifiOff, } from 'lucide-react'; import { cn } from '@/lib/utils'; import { TerminalInstance } from './TerminalInstance'; @@ -64,6 +65,7 @@ const statusDotStyles: Record = { error: 'bg-red-500', paused: 'bg-yellow-500', resuming: 'bg-blue-400 animate-pulse', + locked: 'bg-amber-500 animate-pulse', }; // ========== Props ========== @@ -129,6 +131,20 @@ export function TerminalPane({ paneId }: TerminalPaneProps) { const status: TerminalStatus = meta?.status ?? 'idle'; const alertCount = meta?.alertCount ?? 0; + // Check if session exists - handles case where pane references a sessionId + // that no longer exists in cliSessionStore (e.g., after page refresh if backend restarted) + const isSessionNotFound = sessionId && !sessions[sessionId]; + + // Clear invalid sessionId after showing the message + useEffect(() => { + if (isSessionNotFound) { + const timer = setTimeout(() => { + assignSession(paneId, null); + }, 3000); // Clear after 3 seconds to let user see the message + return () => clearTimeout(timer); + } + }, [isSessionNotFound, paneId, assignSession]); + // Build session options for dropdown // Use sessions from cliSessionStore directly (all sessions, not just grouped ones) const sessionOptions = useMemo(() => { @@ -261,7 +277,9 @@ export function TerminalPane({ paneId }: TerminalPaneProps) { ) : ( // Terminal mode header <> - {sessionId && ( + {isSessionNotFound ? ( + + ) : sessionId && ( @@ -314,7 +332,7 @@ export function TerminalPane({ paneId }: TerminalPaneProps) { > - {!isFileMode && sessionId && ( + {!isFileMode && sessionId && !isSessionNotFound && ( <> {/* Restart button */}