From c464c2bcb440cc5a7e367c29182edfe07ad7ea94 Mon Sep 17 00:00:00 2001 From: Mohamed Boudra Date: Tue, 16 Jun 2026 14:12:18 +0700 Subject: [PATCH] Move tab row pins and default-pin terminal and browser --- packages/app/e2e/workspace-pins.spec.ts | 13 +-- .../workspace/workspace-desktop-tabs-row.tsx | 83 +++++++++++-------- .../src/workspace-pins/pinned-targets-row.tsx | 4 +- packages/app/src/workspace-pins/store.ts | 20 +++++ 4 files changed, 79 insertions(+), 41 deletions(-) diff --git a/packages/app/e2e/workspace-pins.spec.ts b/packages/app/e2e/workspace-pins.spec.ts index 1b94daf6e..aafac4e0b 100644 --- a/packages/app/e2e/workspace-pins.spec.ts +++ b/packages/app/e2e/workspace-pins.spec.ts @@ -5,6 +5,7 @@ import { togglePinFromMenu, tabRowPin } from "./helpers/pins"; import { expectTerminalTabOpen } from "./helpers/workspace-tabs"; import type { PinnedTabTarget } from "../src/workspace-pins/target"; +const DRAFT_TARGET: PinnedTabTarget = { kind: "draft" }; const TERMINAL_TARGET: PinnedTabTarget = { kind: "terminal" }; let workspace: SeededWorkspace; @@ -23,13 +24,13 @@ test.describe("Pinned tab targets", () => { }) => { await gotoWorkspace(page, workspace.workspaceId); - await expect(tabRowPin(page, TERMINAL_TARGET)).toHaveCount(0); + await expect(tabRowPin(page, DRAFT_TARGET)).toHaveCount(0); - await togglePinFromMenu(page, TERMINAL_TARGET); - await expect(tabRowPin(page, TERMINAL_TARGET)).toBeVisible({ timeout: 10_000 }); + await togglePinFromMenu(page, DRAFT_TARGET); + await expect(tabRowPin(page, DRAFT_TARGET)).toBeVisible({ timeout: 10_000 }); - await togglePinFromMenu(page, TERMINAL_TARGET); - await expect(tabRowPin(page, TERMINAL_TARGET)).toHaveCount(0, { timeout: 10_000 }); + await togglePinFromMenu(page, DRAFT_TARGET); + await expect(tabRowPin(page, DRAFT_TARGET)).toHaveCount(0, { timeout: 10_000 }); }); test("clicking the pinned quick-launch button in the tab row opens a terminal tab", async ({ @@ -38,7 +39,7 @@ test.describe("Pinned tab targets", () => { test.setTimeout(45_000); await gotoWorkspace(page, workspace.workspaceId); - await togglePinFromMenu(page, TERMINAL_TARGET); + await expect(tabRowPin(page, TERMINAL_TARGET)).toBeVisible({ timeout: 10_000 }); await tabRowPin(page, TERMINAL_TARGET).click(); await expectTerminalTabOpen(page); diff --git a/packages/app/src/screens/workspace/workspace-desktop-tabs-row.tsx b/packages/app/src/screens/workspace/workspace-desktop-tabs-row.tsx index 2c00248cd..ffce77c0f 100644 --- a/packages/app/src/screens/workspace/workspace-desktop-tabs-row.tsx +++ b/packages/app/src/screens/workspace/workspace-desktop-tabs-row.tsx @@ -171,6 +171,44 @@ function PinnableProfileMenuItem({ profile, disabled, onLaunch }: PinnableProfil interface WorkspaceInlineAddTabButtonProps { shortcutKeys: ShortcutKey[][] | null; + onCreateAgentTab: () => void; + onLayout: (event: LayoutChangeEvent) => void; +} + +function WorkspaceInlineAddTabButton({ + shortcutKeys, + onCreateAgentTab, + onLayout, +}: WorkspaceInlineAddTabButtonProps) { + const { t } = useTranslation(); + const tooltipText = t("workspace.tabs.actions.newAgent"); + + return ( + + + + + + + + {tooltipText} + {shortcutKeys ? ( + + ) : null} + + + + + ); +} + +interface WorkspaceTabRowExtrasProps { onCreateAgentTab: () => void; onCreateTerminal: () => void; onCreateBrowser: () => void; @@ -179,11 +217,9 @@ interface WorkspaceInlineAddTabButtonProps { normalizedServerId: string; showCreateBrowserTab: boolean; terminalDisabled: boolean; - onLayout: (event: LayoutChangeEvent) => void; } -function WorkspaceInlineAddTabButton({ - shortcutKeys, +function WorkspaceTabRowExtras({ onCreateAgentTab, onCreateTerminal, onCreateBrowser, @@ -192,8 +228,7 @@ function WorkspaceInlineAddTabButton({ normalizedServerId, showCreateBrowserTab, terminalDisabled, - onLayout, -}: WorkspaceInlineAddTabButtonProps) { +}: WorkspaceTabRowExtrasProps) { const { t } = useTranslation(); const { config } = useDaemonConfig(normalizedServerId); const profiles = useMemo( @@ -220,30 +255,8 @@ function WorkspaceInlineAddTabButton({ const launchers = usePinnedLaunchers({ serverId: normalizedServerId, onLaunch }); - const tooltipText = t("workspace.tabs.actions.newAgent"); - return ( - - - - - - - - {tooltipText} - {shortcutKeys ? ( - - ) : null} - - - - + <> @@ -251,7 +264,7 @@ function WorkspaceInlineAddTabButton({ testID="workspace-new-tab-menu-trigger" accessibilityRole="button" accessibilityLabel={t("workspace.tabs.actions.moreActions")} - style={inlineAddActionButtonStyle} + style={newTabActionButtonStyle} > @@ -301,7 +314,8 @@ function WorkspaceInlineAddTabButton({ - + + ); } @@ -975,6 +989,12 @@ export function WorkspaceDesktopTabsRow({ /> + + + - - {showPaneSplitActions ? ( <> ({ alignItems: "center", }, pinButton: { - width: 28, - height: 28, + width: 22, + height: 22, borderRadius: theme.borderRadius.md, alignItems: "center", justifyContent: "center", diff --git a/packages/app/src/workspace-pins/store.ts b/packages/app/src/workspace-pins/store.ts index ef986d9af..524264b43 100644 --- a/packages/app/src/workspace-pins/store.ts +++ b/packages/app/src/workspace-pins/store.ts @@ -9,6 +9,18 @@ interface PinnedTargetsState { isPinned: (target: PinnedTabTarget) => boolean; } +const DEFAULT_PINNED_TARGETS: PinnedTabTarget[] = [{ kind: "terminal" }, { kind: "browser" }]; + +function applyDefaultPinnedTargets(pinned: PinnedTabTarget[]): PinnedTabTarget[] { + const next = [...DEFAULT_PINNED_TARGETS]; + for (const target of pinned) { + if (!isTargetPinned(next, target)) { + next.push(target); + } + } + return next; +} + export const usePinnedTargetsStore = create()( persist( (set, get) => ({ @@ -18,8 +30,16 @@ export const usePinnedTargetsStore = create()( }), { name: "pinned-tab-targets", + version: 1, storage: createJSONStorage(() => AsyncStorage), partialize: (state) => ({ pinned: state.pinned }), + migrate: (persistedState, version) => { + if (version === 0) { + const pinned = (persistedState as { pinned?: PinnedTabTarget[] } | null)?.pinned ?? []; + return { pinned: applyDefaultPinnedTargets(pinned) }; + } + return persistedState as PinnedTargetsState; + }, }, ), );