Remove pinned launchers from workspace rows

This commit is contained in:
Mohamed Boudra
2026-06-15 15:02:38 +07:00
parent e84a3ff574
commit 754f6336c0
6 changed files with 1 additions and 171 deletions
-4
View File
@@ -19,10 +19,6 @@ export function tabRowPin(page: Page, target: PinnedTabTarget) {
return page.getByTestId(`workspace-pinned-target-${pinnedTargetKey(target)}`);
}
export function sidebarPin(page: Page, target: PinnedTabTarget) {
return page.getByTestId(`sidebar-pinned-target-${pinnedTargetKey(target)}`);
}
export async function openNewTabMenu(page: Page): Promise<void> {
const trigger = page
.getByTestId("workspace-new-tab-menu-trigger")
+1 -22
View File
@@ -1,9 +1,7 @@
import { test, expect } from "./fixtures";
import { gotoWorkspace } from "./helpers/launcher";
import { gotoAppShell } from "./helpers/app";
import { getServerId } from "./helpers/server-id";
import { seedWorkspace, type SeededWorkspace } from "./helpers/seed-client";
import { togglePinFromMenu, tabRowPin, sidebarPin } from "./helpers/pins";
import { togglePinFromMenu, tabRowPin } from "./helpers/pins";
import { expectTerminalTabOpen } from "./helpers/workspace-tabs";
import type { PinnedTabTarget } from "../src/workspace-pins/target";
@@ -45,23 +43,4 @@ test.describe("Pinned tab targets", () => {
await expectTerminalTabOpen(page);
});
test("the pinned button is mirrored in the sidebar workspace row and launches a terminal in that workspace", async ({
page,
}) => {
test.setTimeout(45_000);
await gotoWorkspace(page, workspace.workspaceId);
await togglePinFromMenu(page, TERMINAL_TARGET);
await gotoAppShell(page);
const row = page.getByTestId(`sidebar-workspace-row-${getServerId()}:${workspace.workspaceId}`);
await expect(row).toBeVisible({ timeout: 30_000 });
await row.hover();
await expect(sidebarPin(page, TERMINAL_TARGET)).toBeVisible({ timeout: 10_000 });
await sidebarPin(page, TERMINAL_TARGET).click();
await expect(page).toHaveURL(/\/workspace\//, { timeout: 30_000 });
await expectTerminalTabOpen(page);
});
});
@@ -70,11 +70,6 @@ import {
type SidebarWorkspaceEntry,
} from "@/hooks/use-sidebar-workspaces-list";
import { useSidebarOrderStore } from "@/stores/sidebar-order-store";
import { buildWorkspaceTabPersistenceKey } from "@/stores/workspace-tabs-store/state";
import { usePinnedLaunchers } from "@/workspace-pins/launch";
import { useLaunchIntentStore } from "@/workspace-pins/launch-intent-store";
import { PinnedTargetsRow } from "@/workspace-pins/pinned-targets-row";
import type { PinnedTabTarget } from "@/workspace-pins/target";
import { useShowShortcutBadges } from "@/hooks/use-show-shortcut-badges";
import { ContextMenuTrigger, useContextMenu } from "@/components/ui/context-menu";
import {
@@ -667,40 +662,16 @@ function WorkspaceRowRightGroup({
onRename?: () => void;
}) {
const { t } = useTranslation();
const isMobileBreakpoint = useIsCompactFormFactor();
const showShortcut = showShortcutBadge && shortcutNumber !== null;
const showKebab = Boolean(onArchive && (isHovered || isTouchPlatform));
const showKebabInSlot = showKebab && !showShortcut;
const shouldRenderActionSlot = Boolean(onArchive || workspace.diffStat);
const showPinnedTargets = (isHovered || platformIsNative || isMobileBreakpoint) && !showShortcut;
const onLaunch = useCallback(
(target: PinnedTabTarget) => {
const workspaceKey = buildWorkspaceTabPersistenceKey({
serverId: workspace.serverId,
workspaceId: workspace.workspaceId,
});
if (!workspaceKey) return;
navigateToWorkspace(workspace.serverId, workspace.workspaceId);
useLaunchIntentStore.getState().request({ workspaceKey, target });
},
[workspace.serverId, workspace.workspaceId],
);
const launchers = usePinnedLaunchers({ serverId: workspace.serverId, onLaunch });
return (
<>
{isCreating ? (
<Text style={styles.workspaceCreatingText}>{t("sidebar.workspace.status.creating")}</Text>
) : null}
{launchers.length > 0 ? (
<View
style={showPinnedTargets ? undefined : styles.pinnedTargetsHidden}
pointerEvents={showPinnedTargets ? "auto" : "none"}
>
<PinnedTargetsRow launchers={launchers} testIdPrefix="sidebar-pinned-target" />
</View>
) : null}
{shouldRenderActionSlot ? (
<SidebarWorkspaceTrailingActionSlot>
<SidebarWorkspaceTrailingActionBase
@@ -2719,9 +2690,6 @@ const styles = StyleSheet.create((theme) => ({
fontSize: theme.fontSize.xs,
flexShrink: 0,
},
pinnedTargetsHidden: {
opacity: 0,
},
kebabButton: {
padding: 2,
borderRadius: 4,
@@ -185,8 +185,6 @@ import {
resolveTerminalProfiles,
} from "@getpaseo/protocol/terminal-profiles";
import { getProviderIcon } from "@/components/provider-icons";
import { useLaunchIntentStore } from "@/workspace-pins/launch-intent-store";
import { runPinnedTabTarget, type TabTargetHandlers } from "@/workspace-pins/run";
import {
createWorkspaceFileTabTarget,
normalizeWorkspaceFileLocation,
@@ -1720,37 +1718,6 @@ function useWorkspaceCheckoutStatus(input: {
return { checkoutQuery, isCheckoutStatusLoading };
}
interface PinnedTabLaunchConsumerInput {
serverId: string;
persistenceKey: string | null;
isRouteFocused: boolean;
handlers: TabTargetHandlers;
}
function usePinnedTabLaunchConsumer({
serverId,
persistenceKey,
isRouteFocused,
handlers,
}: PinnedTabLaunchConsumerInput) {
const { config } = useDaemonConfig(serverId);
const profiles = useMemo(
() => resolveTerminalProfiles(config?.terminalProfiles),
[config?.terminalProfiles],
);
const pending = useLaunchIntentStore((state) => state.pending);
useEffect(() => {
if (!persistenceKey || !isRouteFocused || pending?.workspaceKey !== persistenceKey) {
return;
}
const target = useLaunchIntentStore.getState().consume(persistenceKey);
if (target) {
runPinnedTabTarget(target, profiles, handlers);
}
}, [handlers, isRouteFocused, pending, persistenceKey, profiles]);
}
function WorkspaceScreenContent({
serverId,
workspaceId,
@@ -2597,28 +2564,6 @@ function WorkspaceScreenContent({
[openWorkspaceTabFocused, persistenceKey],
);
const pinnedTabHandlers = useMemo<TabTargetHandlers>(
() => ({
createDraft: handleCreateDraftTab,
createTerminal: handleCreateTerminal,
createBrowser: handleCreateBrowserTab,
createTerminalWithProfile: handleCreateTerminalWithProfile,
}),
[
handleCreateBrowserTab,
handleCreateDraftTab,
handleCreateTerminal,
handleCreateTerminalWithProfile,
],
);
usePinnedTabLaunchConsumer({
serverId: normalizedServerId,
persistenceKey,
isRouteFocused,
handlers: pinnedTabHandlers,
});
useDesktopBrowserNewTabRequests({
enabled: Boolean(persistenceKey),
workspaceLayout,
@@ -1,32 +0,0 @@
import { beforeEach, describe, expect, it } from "vitest";
import { useLaunchIntentStore } from "./launch-intent-store";
beforeEach(() => {
useLaunchIntentStore.setState({ pending: null });
});
describe("launch intent store", () => {
it("returns the requested target when the workspace key matches", () => {
useLaunchIntentStore.getState().request({ workspaceKey: "ws-1", target: { kind: "terminal" } });
expect(useLaunchIntentStore.getState().consume("ws-1")).toEqual({ kind: "terminal" });
});
it("clears the pending intent once consumed", () => {
useLaunchIntentStore.getState().request({ workspaceKey: "ws-1", target: { kind: "draft" } });
useLaunchIntentStore.getState().consume("ws-1");
expect(useLaunchIntentStore.getState().pending).toBeNull();
});
it("returns null and keeps the intent when the workspace key does not match", () => {
useLaunchIntentStore.getState().request({ workspaceKey: "ws-1", target: { kind: "browser" } });
expect(useLaunchIntentStore.getState().consume("ws-2")).toBeNull();
expect(useLaunchIntentStore.getState().pending).toEqual({
workspaceKey: "ws-1",
target: { kind: "browser" },
});
});
it("returns null when there is no pending intent", () => {
expect(useLaunchIntentStore.getState().consume("ws-1")).toBeNull();
});
});
@@ -1,26 +0,0 @@
import { create } from "zustand";
import type { PinnedTabTarget } from "@/workspace-pins/target";
export interface PendingTabLaunch {
workspaceKey: string;
target: PinnedTabTarget;
}
interface LaunchIntentState {
pending: PendingTabLaunch | null;
request: (intent: PendingTabLaunch) => void;
consume: (workspaceKey: string) => PinnedTabTarget | null;
}
export const useLaunchIntentStore = create<LaunchIntentState>((set, get) => ({
pending: null,
request: (intent) => set({ pending: intent }),
consume: (workspaceKey) => {
const { pending } = get();
if (!pending || pending.workspaceKey !== workspaceKey) {
return null;
}
set({ pending: null });
return pending.target;
},
}));