diff --git a/apps/desktop/src/renderer/screens/main/components/Sidebar/components/ModeCarousel/components/AnimatedBackground/AnimatedBackground.tsx b/apps/desktop/src/renderer/screens/main/components/Sidebar/components/ModeCarousel/components/AnimatedBackground/AnimatedBackground.tsx index 91852fe33b3..f878db6c4fc 100644 --- a/apps/desktop/src/renderer/screens/main/components/Sidebar/components/ModeCarousel/components/AnimatedBackground/AnimatedBackground.tsx +++ b/apps/desktop/src/renderer/screens/main/components/Sidebar/components/ModeCarousel/components/AnimatedBackground/AnimatedBackground.tsx @@ -24,7 +24,7 @@ export function AnimatedBackground({ return (
- + {modes.map((mode) => { const Icon = modeIcons[mode]; const isActive = mode === currentMode; return ( - + + + + + +

{modeLabels[mode]}

+
+
); })}
); } - diff --git a/apps/desktop/src/renderer/screens/main/components/Sidebar/components/WorktreeList/WorktreeList.tsx b/apps/desktop/src/renderer/screens/main/components/Sidebar/components/WorktreeList/WorktreeList.tsx index 708abae55ce..470cc04938e 100644 --- a/apps/desktop/src/renderer/screens/main/components/Sidebar/components/WorktreeList/WorktreeList.tsx +++ b/apps/desktop/src/renderer/screens/main/components/Sidebar/components/WorktreeList/WorktreeList.tsx @@ -1,6 +1,5 @@ -import { Button } from "@superset/ui/button"; -import { Tooltip, TooltipContent, TooltipTrigger } from "@superset/ui/tooltip"; -import { Monitor, Plus } from "lucide-react"; +import { ChevronDown, Monitor, Plus, SquareTerminal } from "lucide-react"; +import { useEffect, useRef, useState } from "react"; import type { Workspace, Worktree } from "shared/types"; import { WorkspacePortIndicator } from "../WorkspacePortIndicator"; import { WorktreeItem } from "./components/WorktreeItem"; @@ -20,8 +19,8 @@ interface WorktreeListProps { export function WorktreeList({ currentWorkspace, - expandedWorktrees, - onToggleWorktree, + expandedWorktrees: _expandedWorktrees, + onToggleWorktree: _onToggleWorktree, onTabSelect, onReload, onUpdateWorktree, @@ -30,6 +29,44 @@ export function WorktreeList({ selectedWorktreeId, showWorkspaceHeader = false, }: WorktreeListProps) { + // Hooks must be called before any early returns + const [isDropdownOpen, setIsDropdownOpen] = useState(false); + const [defaultTabType, setDefaultTabType] = useState<"terminal" | "preview">( + () => { + // Load from localStorage or default to "terminal" + const saved = localStorage.getItem("newTabDefaultType"); + return (saved === "preview" ? "preview" : "terminal") as + | "terminal" + | "preview"; + }, + ); + const dropdownRef = useRef(null); + const buttonRef = useRef(null); + const chevronRef = useRef(null); + + // Close dropdown when clicking outside + useEffect(() => { + const handleClickOutside = (event: MouseEvent) => { + if ( + dropdownRef.current && + buttonRef.current && + chevronRef.current && + !dropdownRef.current.contains(event.target as Node) && + !buttonRef.current.contains(event.target as Node) && + !chevronRef.current.contains(event.target as Node) + ) { + setIsDropdownOpen(false); + } + }; + + if (isDropdownOpen) { + document.addEventListener("mousedown", handleClickOutside); + return () => { + document.removeEventListener("mousedown", handleClickOutside); + }; + } + }, [isDropdownOpen]); + if (!currentWorkspace) { return (
No workspace open
@@ -48,11 +85,14 @@ export function WorktreeList({ const hasPortForwarding = currentWorkspace.ports && currentWorkspace.ports.length > 0; - // Get main branch from workspace config, fallback to 'main' - const mainBranch = currentWorkspace.branch || "main"; - - const handleAddTerminal = async () => { + const handleAddTerminal = async (updateDefault = false) => { if (!currentWorkspace || !selectedWorktreeId) return; + setIsDropdownOpen(false); + + if (updateDefault) { + setDefaultTabType("terminal"); + localStorage.setItem("newTabDefaultType", "terminal"); + } try { const result = await window.ipcRenderer.invoke("tab-create", { @@ -74,8 +114,14 @@ export function WorktreeList({ } }; - const handleAddPreview = async () => { + const handleAddPreview = async (updateDefault = false) => { if (!currentWorkspace || !selectedWorktreeId) return; + setIsDropdownOpen(false); + + if (updateDefault) { + setDefaultTabType("preview"); + localStorage.setItem("newTabDefaultType", "preview"); + } try { const worktree = currentWorkspace.worktrees.find( @@ -104,6 +150,19 @@ export function WorktreeList({ } }; + const handleCreateDefault = () => { + if (defaultTabType === "terminal") { + handleAddTerminal(); + } else { + handleAddPreview(); + } + }; + + const handleChevronClick = (e: React.MouseEvent) => { + e.stopPropagation(); + setIsDropdownOpen(!isDropdownOpen); + }; + return ( <> {/* Workspace Header - more minimal */} @@ -113,43 +172,6 @@ export function WorktreeList({ )} - {/* Action Buttons - more subtle, inline */} - {selectedWorktreeId && ( -
- - - - - -

New Terminal

-
-
- - - - - - -

New Preview

-
-
-
- )} - {currentWorkspace.worktrees.map((worktree) => ( onCloneWorktree(worktree.id, worktree.branch)} /> ))} + + {/* Arc-style New Tab Button - styled like a tab at the bottom */} + {selectedWorktreeId && ( +
+
+ + + + {/* Dropdown Menu */} + {isDropdownOpen && ( +
+ + +
+ )} +
+
+ )} ); }