diff --git a/src/routes/v2/pages/Editor/components/EditorMenuBar/components/WindowsMenu.tsx b/src/routes/v2/pages/Editor/components/EditorMenuBar/components/WindowsMenu.tsx index c9ee3a524..3f45a87b2 100644 --- a/src/routes/v2/pages/Editor/components/EditorMenuBar/components/WindowsMenu.tsx +++ b/src/routes/v2/pages/Editor/components/EditorMenuBar/components/WindowsMenu.tsx @@ -6,6 +6,7 @@ import { DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, + DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, @@ -13,12 +14,19 @@ import { } from "@/components/ui/dropdown-menu"; import { Icon } from "@/components/ui/icon"; import { MenuTriggerButton } from "@/routes/v2/shared/components/MenuTriggerButton"; +import { ShortcutBadge } from "@/routes/v2/shared/components/ShortcutBadge"; import { useSharedStores } from "@/routes/v2/shared/store/SharedStoreContext"; import { VIEW_PRESETS, type ViewPreset, } from "@/routes/v2/shared/windows/viewPresets"; +const PRESET_SHORTCUT_IDS: Record = { + Default: "layout-default", + Minimal: "layout-minimal", + All: "layout-all", +}; + export const WindowsMenu = observer(function WindowsMenu() { const { windows } = useSharedStores(); const allWindows = windows.getAllWindows(); @@ -61,6 +69,11 @@ export const WindowsMenu = observer(function WindowsMenu() { onSelect={() => applyPreset(preset)} > {preset.label} + {PRESET_SHORTCUT_IDS[preset.label] && ( + + + + )} ))} diff --git a/src/routes/v2/shared/hooks/useFocusMode.ts b/src/routes/v2/shared/hooks/useFocusMode.ts index 1f0ccb2ae..d95699718 100644 --- a/src/routes/v2/shared/hooks/useFocusMode.ts +++ b/src/routes/v2/shared/hooks/useFocusMode.ts @@ -4,24 +4,37 @@ import { useEffect } from "react"; import { CMDALT } from "@/routes/v2/shared/shortcuts/keys"; import { useSharedStores } from "@/routes/v2/shared/store/SharedStoreContext"; import { VIEW_PRESETS } from "@/routes/v2/shared/windows/viewPresets"; +import type { WindowStoreImpl } from "@/routes/v2/shared/windows/windowStore"; class FocusModeStore { @observable accessor active = false; + private previousVisibleIds: string[] = []; constructor() { makeObservable(this); } - @action setActive(value: boolean): void { - this.active = value; + /** Snapshot which windows are currently visible, then enter minimal. */ + @action enterMinimal(windows: WindowStoreImpl): void { + this.previousVisibleIds = windows + .getAllWindows() + .filter((w) => w.state !== "hidden") + .map((w) => w.id); + this.active = true; } - @action toggle(): void { - this.active = !this.active; + /** Restore the windows that were visible before entering minimal. */ + @action exitMinimal(windows: WindowStoreImpl): void { + for (const id of this.previousVisibleIds) { + windows.restoreWindow(id); + } + this.previousVisibleIds = []; + this.active = false; } @action reset(): void { this.active = false; + this.previousVisibleIds = []; } } @@ -29,8 +42,9 @@ export const focusModeStore = new FocusModeStore(); /** * Registers keyboard shortcuts for view presets: - * - Cmd+Alt+/ : Toggle Minimal layout (hide all panels) - * - Cmd+Alt+D : Default layout + * - Cmd+Alt+1 : Default layout + * - Cmd+Alt+2 : Toggle Minimal layout (restores previous state on exit) + * - Cmd+Alt+3 : All windows */ export function useFocusMode(): void { const { keyboard, windows } = useSharedStores(); @@ -42,28 +56,44 @@ export function useFocusMode(): void { }; useEffect(() => { + const unregisterDefault = keyboard.registerShortcut({ + id: "layout-default", + keys: [CMDALT, "1"], + label: "Default layout", + action: () => { + applyPreset("Default"); + focusModeStore.reset(); + }, + }); + const unregisterMinimal = keyboard.registerShortcut({ - id: "focus-mode", - keys: [CMDALT, "/"], + id: "layout-minimal", + keys: [CMDALT, "2"], label: "Minimal layout", action: () => { - const allHidden = windows - .getAllWindows() - .every((w) => w.state === "hidden"); - applyPreset(allHidden ? "Default" : "Minimal"); + if (focusModeStore.active) { + focusModeStore.exitMinimal(windows); + } else { + focusModeStore.enterMinimal(windows); + applyPreset("Minimal"); + } }, }); - const unregisterDefault = keyboard.registerShortcut({ - id: "default-layout", - keys: [CMDALT, "D"], - label: "Default layout", - action: () => applyPreset("Default"), + const unregisterAll = keyboard.registerShortcut({ + id: "layout-all", + keys: [CMDALT, "3"], + label: "All windows", + action: () => { + applyPreset("All"); + focusModeStore.reset(); + }, }); return () => { - unregisterMinimal(); unregisterDefault(); + unregisterMinimal(); + unregisterAll(); }; }, [keyboard, windows]); } diff --git a/src/routes/v2/shared/windows/viewPresets.ts b/src/routes/v2/shared/windows/viewPresets.ts index 2e2cbaf13..ce6dedaaa 100644 --- a/src/routes/v2/shared/windows/viewPresets.ts +++ b/src/routes/v2/shared/windows/viewPresets.ts @@ -23,6 +23,11 @@ export const VIEW_PRESETS: ViewPreset[] = [ visible: new Set(["component-library", "recent-runs", "pipeline-details"]), dockPositions: DEFAULT_DOCK_POSITIONS, }, + { + label: "Minimal", + description: "Hide all panels", + visible: new Set(), + }, { label: "All", description: "All windows visible", @@ -36,9 +41,4 @@ export const VIEW_PRESETS: ViewPreset[] = [ ]), dockPositions: DEFAULT_DOCK_POSITIONS, }, - { - label: "Minimal", - description: "Hide all panels", - visible: new Set(), - }, ];