Skip to content
File

Blob: src/client/components/terminal-workspace.tsx

typescript43 lines
1import { useWorkspaceStore } from "../workspace/store";
2import { useSharedSessionDetection } from "../terminal/use-shared-session-detection";
3import { BootstrapOverlay } from "./bootstrap-overlay";
4import { SessionControls } from "./session-controls";
5import { TabStrip } from "./tab-strip";
6import { TerminalPane } from "./terminal-pane";
7 
8export function TerminalWorkspace({ workspace }: { workspace: string }) {
9 const activeTab = useWorkspaceStore((s) => s.tabs.find((t) => t.id === s.activeTabId));
10 const reconnectKey = useWorkspaceStore((s) => s.reconnectKeys[s.activeTabId] ?? 0);
11 const setConnectionState = useWorkspaceStore((s) => s.setConnectionState);
12 const connectionState = useWorkspaceStore((s) => s.connectionStates[s.activeTabId] ?? "disconnected");
13 
14 useSharedSessionDetection(activeTab?.sessionId ?? "");
15 
16 if (!activeTab) return null;
17 
18 const showOverlay =
19 connectionState === "disconnected" || connectionState === "connecting" || connectionState === "reconnecting";
20 
21 return (
22 <>
23 <a
24 href="#terminal-content"
25 className="sr-only focus:not-sr-only focus:fixed focus:top-4 focus:left-4 focus:z-[200] focus:rounded-lg focus:bg-zinc-800 focus:px-4 focus:py-2 focus:text-accent-400 focus:ring-2 focus:ring-accent-500/50"
26 >
27 Skip to terminal
28 </a>
29 <SessionControls />
30 <TabStrip />
31 <main id="terminal-content" className="flex-1 overflow-hidden relative p-1" role="tabpanel">
32 <TerminalPane
33 key={`${activeTab.id}-${reconnectKey}`}
34 workspace={workspace}
35 sessionId={activeTab.sessionId}
36 onStateChange={(state) => setConnectionState(activeTab.id, state)}
37 />
38 {showOverlay && <BootstrapOverlay reconnecting={connectionState === "reconnecting"} />}
39 </main>
40 </>
41 );
42}