From 1b4317ec35da7cb4fb416d49f7e2a8673d536d05 Mon Sep 17 00:00:00 2001 From: Julius Marminge <51714798+juliusmarminge@users.noreply.github.com> Date: Fri, 12 Jun 2026 19:54:08 -0700 Subject: [PATCH] Restore terminal drawer header toggle --- apps/web/src/components/ChatView.browser.tsx | 57 +++++--------------- apps/web/src/components/ChatView.tsx | 3 ++ apps/web/src/components/chat/ChatHeader.tsx | 31 ++++++++++- 3 files changed, 47 insertions(+), 44 deletions(-) diff --git a/apps/web/src/components/ChatView.browser.tsx b/apps/web/src/components/ChatView.browser.tsx index 11d1ea121d1da8b9992619b9aa5f1f4f62f4c124..81b9c74231c08c42138181a654808e1a05875f8d 100644 --- a/apps/web/src/components/ChatView.browser.tsx +++ b/apps/web/src/components/ChatView.browser.tsx @@ -23,7 +23,6 @@ import { ServerConfig as ServerConfigSchema, } from "@t3tools/contracts"; import { scopedThreadKey, scopeThreadRef } from "@t3tools/client-runtime"; -import { DEFAULT_RESOLVED_KEYBINDINGS } from "@t3tools/shared/keybindings"; import { createModelCapabilities, createModelSelection } from "@t3tools/shared/model"; import { RouterProvider, createMemoryHistory } from "@tanstack/react-router"; import * as Option from "effect/Option"; @@ -2065,26 +2064,15 @@ describe("ChatView timeline estimator parity (full app)", () => { targetMessageId: "msg-user-open-empty-terminal-drawer" as MessageId, targetText: "open empty terminal drawer", }), - configureFixture: (nextFixture) => { - nextFixture.serverConfig = { - ...nextFixture.serverConfig, - keybindings: DEFAULT_RESOLVED_KEYBINDINGS.filter( - (binding) => binding.command === "terminal.toggle", - ), - }; - }, }); try { - window.dispatchEvent( - new KeyboardEvent("keydown", { - key: "j", - metaKey: isMacPlatform(navigator.platform), - ctrlKey: !isMacPlatform(navigator.platform), - bubbles: true, - cancelable: true, - }), + const terminalToggle = await waitForElement( + () => + document.querySelector('button[aria-label="Toggle terminal drawer"]'), + "Unable to find terminal drawer toggle.", ); + terminalToggle.click(); await vi.waitFor( () => { @@ -2116,28 +2104,14 @@ describe("ChatView timeline estimator parity (full app)", () => { targetMessageId: "msg-user-open-inline-terminal-panel" as MessageId, targetText: "open inline terminal panel", }), - configureFixture: (nextFixture) => { - nextFixture.serverConfig = { - ...nextFixture.serverConfig, - keybindings: DEFAULT_RESOLVED_KEYBINDINGS.filter( - (binding) => - binding.command === "rightPanel.toggle" || binding.command === "terminal.toggle", - ), - }; - }, }); try { - window.dispatchEvent( - new KeyboardEvent("keydown", { - key: "b", - altKey: true, - metaKey: isMacPlatform(navigator.platform), - ctrlKey: !isMacPlatform(navigator.platform), - bubbles: true, - cancelable: true, - }), + const rightPanelToggle = await waitForElement( + () => document.querySelector('button[aria-label="Toggle right panel"]'), + "Unable to find right panel toggle.", ); + rightPanelToggle.click(); const addSurface = await waitForElement( () => document.querySelector('button[aria-label="Add panel surface"]'), @@ -2213,15 +2187,12 @@ describe("ChatView timeline estimator parity (full app)", () => { { timeout: 8_000, interval: 16 }, ); - window.dispatchEvent( - new KeyboardEvent("keydown", { - key: "j", - metaKey: isMacPlatform(navigator.platform), - ctrlKey: !isMacPlatform(navigator.platform), - bubbles: true, - cancelable: true, - }), + const drawerToggle = await waitForElement( + () => + document.querySelector('button[aria-label="Toggle terminal drawer"]'), + "Unable to find terminal drawer toggle.", ); + drawerToggle.click(); await vi.waitFor(() => { expect( diff --git a/apps/web/src/components/ChatView.tsx b/apps/web/src/components/ChatView.tsx index 9b99cc8272f8406d10a6b700a586c271e472663f..bfeff47dec41512d94bab92d42bc11fb91dc8c0b 100644 --- a/apps/web/src/components/ChatView.tsx +++ b/apps/web/src/components/ChatView.tsx @@ -4501,6 +4501,8 @@ export default function ChatView(props: ChatViewProps) { } keybindings={keybindings} availableEditors={availableEditors} + terminalAvailable={Boolean(activeProject)} + terminalOpen={Boolean(terminalUiState.terminalOpen)} rightPanelAvailable={Boolean(activeProject)} rightPanelOpen={rightPanelOpen} gitCwd={gitCwd} @@ -4508,6 +4510,7 @@ export default function ChatView(props: ChatViewProps) { onAddProjectScript={saveProjectScript} onUpdateProjectScript={updateProjectScript} onDeleteProjectScript={deleteProjectScript} + onToggleTerminal={toggleTerminalVisibility} onToggleRightPanel={toggleRightPanel} /> diff --git a/apps/web/src/components/chat/ChatHeader.tsx b/apps/web/src/components/chat/ChatHeader.tsx index 8421fc184648c9902b417783accf9eb2f2d8ba15..787913e7b297a682776dfd1bc4cd5a8cb4118fd1 100644 --- a/apps/web/src/components/chat/ChatHeader.tsx +++ b/apps/web/src/components/chat/ChatHeader.tsx @@ -9,7 +9,7 @@ import { scopeThreadRef } from "@t3tools/client-runtime"; import { memo } from "react"; import GitActionsControl from "../GitActionsControl"; import { type DraftId } from "~/composerDraftStore"; -import { PanelRightIcon } from "lucide-react"; +import { PanelBottomIcon, PanelRightIcon } from "lucide-react"; import { Tooltip, TooltipPopup, TooltipTrigger } from "../ui/tooltip"; import ProjectScriptsControl, { type NewProjectScriptInput } from "../ProjectScriptsControl"; import { Toggle } from "../ui/toggle"; @@ -29,6 +29,8 @@ interface ChatHeaderProps { preferredScriptId: string | null; keybindings: ResolvedKeybindingsConfig; availableEditors: ReadonlyArray; + terminalAvailable: boolean; + terminalOpen: boolean; rightPanelAvailable: boolean; rightPanelOpen: boolean; gitCwd: string | null; @@ -36,6 +38,7 @@ interface ChatHeaderProps { onAddProjectScript: (input: NewProjectScriptInput) => Promise; onUpdateProjectScript: (scriptId: string, input: NewProjectScriptInput) => Promise; onDeleteProjectScript: (scriptId: string) => Promise; + onToggleTerminal: () => void; onToggleRightPanel: () => void; } @@ -62,6 +65,8 @@ export const ChatHeader = memo(function ChatHeader({ preferredScriptId, keybindings, availableEditors, + terminalAvailable, + terminalOpen, rightPanelAvailable, rightPanelOpen, gitCwd, @@ -69,6 +74,7 @@ export const ChatHeader = memo(function ChatHeader({ onAddProjectScript, onUpdateProjectScript, onDeleteProjectScript, + onToggleTerminal, onToggleRightPanel, }: ChatHeaderProps) { const primaryEnvironmentId = usePrimaryEnvironmentId(); @@ -77,6 +83,7 @@ export const ChatHeader = memo(function ChatHeader({ activeThreadEnvironmentId, primaryEnvironmentId, }); + const terminalShortcutLabel = shortcutLabelForCommand(keybindings, "terminal.toggle"); const rightPanelShortcutLabel = shortcutLabelForCommand(keybindings, "rightPanel.toggle"); return ( @@ -123,6 +130,28 @@ export const ChatHeader = memo(function ChatHeader({ {...(draftId ? { draftId } : {})} /> )} + + + + + } + /> + + {terminalAvailable + ? `Toggle terminal drawer${terminalShortcutLabel ? ` (${terminalShortcutLabel})` : ""}` + : "Terminal drawer is unavailable"} + +