diff --git a/src/components/TabBar.tsx b/src/components/TabBar.tsx index 54d0ab8..26e0d99 100644 --- a/src/components/TabBar.tsx +++ b/src/components/TabBar.tsx @@ -1,24 +1,71 @@ -import { Plus, SlidersHorizontal } from "lucide-react"; +import { Plus, SlidersHorizontal, Grid2X2, Columns2, Split } from "lucide-react"; import { Button } from "./ui/button"; import { useGrimoire } from "@/core/state"; import { cn } from "@/lib/utils"; import { WorkspaceSettings } from "./WorkspaceSettings"; +import { getAllPresets } from "@/lib/layout-presets"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, +} from "./ui/dropdown-menu"; +import { toast } from "sonner"; import { useState } from "react"; export function TabBar() { - const { state, setActiveWorkspace, createWorkspace } = useGrimoire(); + const { state, setActiveWorkspace, createWorkspace, applyPresetLayout } = useGrimoire(); const { workspaces, activeWorkspaceId } = state; - const [settingsWorkspaceId, setSettingsWorkspaceId] = useState( - null, - ); + const [settingsOpen, setSettingsOpen] = useState(false); + + const activeWorkspace = workspaces[activeWorkspaceId]; + const windowCount = activeWorkspace?.windowIds.length || 0; + const presets = getAllPresets(); const handleNewTab = () => { createWorkspace(); }; - const handleSettingsClick = (e: React.MouseEvent, workspaceId: string) => { + const handleSettingsClick = (e: React.MouseEvent) => { e.stopPropagation(); // Prevent workspace switch - setSettingsWorkspaceId(workspaceId); + setSettingsOpen(true); + }; + + const handleApplyPreset = (presetId: string) => { + const preset = presets.find((p) => p.id === presetId); + if (!preset) return; + + if (windowCount < preset.slots) { + toast.error(`Not enough windows`, { + description: `Preset "${preset.name}" requires ${preset.slots} windows, but only ${windowCount} available.`, + }); + return; + } + + try { + applyPresetLayout(preset); + toast.success(`Layout applied`, { + description: `Applied "${preset.name}" preset to workspace ${activeWorkspace.number}`, + }); + } catch (error) { + toast.error(`Failed to apply layout`, { + description: + error instanceof Error ? error.message : "Unknown error occurred", + }); + } + }; + + const getPresetIcon = (presetId: string) => { + switch (presetId) { + case "side-by-side": + return ; + case "main-sidebar": + return ; + case "grid": + return ; + default: + return ; + } }; // Sort workspaces by number @@ -46,19 +93,60 @@ export function TabBar() { : ws.number} ))} + + {/* Layout Preset Dropdown */} + + + + + +
+ Apply Layout Preset +
+ {presets.map((preset) => { + const canApply = windowCount >= preset.slots; + return ( + handleApplyPreset(preset.id)} + disabled={!canApply} + className="flex items-center gap-3 cursor-pointer" + > +
{getPresetIcon(preset.id)}
+
+
{preset.name}
+
+ {canApply + ? `${preset.slots} windows` + : `Needs ${preset.slots} (have ${windowCount})`} +
+
+
+ ); + })} +
+
+