diff --git a/apps/frontend/src/renderer/components/ProjectTabBar.tsx b/apps/frontend/src/renderer/components/ProjectTabBar.tsx index d76b34f4..9d89c07c 100644 --- a/apps/frontend/src/renderer/components/ProjectTabBar.tsx +++ b/apps/frontend/src/renderer/components/ProjectTabBar.tsx @@ -6,6 +6,7 @@ import { Button } from './ui/button'; import { SortableProjectTab } from './SortableProjectTab'; import { UsageIndicator } from './UsageIndicator'; import { AuthStatusIndicator } from './AuthStatusIndicator'; +import { useWindowStore } from '../stores/window-store'; import type { Project } from '../../shared/types'; interface ProjectTabBarProps { @@ -29,6 +30,22 @@ export function ProjectTabBar({ onSettingsClick }: ProjectTabBarProps) { const { t } = useTranslation('common'); + const { isProjectPoppedOut, setWindowLoading, addPoppedOutProject } = useWindowStore(); + + // Handler for popping out a project into a new window + const handlePopOutProject = async (projectId: string) => { + try { + setWindowLoading(projectId, true); + const { windowId } = await window.electronAPI.window.popOutProject(projectId); + addPoppedOutProject(projectId); + console.log(`Project ${projectId} popped out to window ${windowId}`); + } catch (error) { + console.error('Failed to pop out project:', error); + // TODO: Show error notification to user + } finally { + setWindowLoading(projectId, false); + } + }; // Keyboard shortcuts for tab navigation useEffect(() => { @@ -107,6 +124,8 @@ export function ProjectTabBar({ }} // Pass control props only for active tab onSettingsClick={isActiveTab ? onSettingsClick : undefined} + onPopOutClick={isActiveTab ? () => handlePopOutProject(project.id) : undefined} + isPoppedOut={isProjectPoppedOut(project.id)} /> ); })} diff --git a/apps/frontend/src/renderer/components/SortableProjectTab.tsx b/apps/frontend/src/renderer/components/SortableProjectTab.tsx index d57cf129..9ffcc4a3 100644 --- a/apps/frontend/src/renderer/components/SortableProjectTab.tsx +++ b/apps/frontend/src/renderer/components/SortableProjectTab.tsx @@ -1,7 +1,7 @@ import { useSortable } from '@dnd-kit/sortable'; import { CSS } from '@dnd-kit/utilities'; import { useTranslation } from 'react-i18next'; -import { Settings2 } from 'lucide-react'; +import { Settings2, ExternalLink } from 'lucide-react'; import { cn } from '../lib/utils'; import { Tooltip, TooltipContent, TooltipTrigger } from './ui/tooltip'; import type { Project } from '../../shared/types'; @@ -15,6 +15,8 @@ interface SortableProjectTabProps { onClose: (e: React.MouseEvent) => void; // Optional control props for active tab onSettingsClick?: () => void; + onPopOutClick?: () => void; + isPoppedOut?: boolean; } // Detect if running on macOS for keyboard shortcut display @@ -28,7 +30,9 @@ export function SortableProjectTab({ tabIndex, onSelect, onClose, - onSettingsClick + onSettingsClick, + onPopOutClick, + isPoppedOut = false }: SortableProjectTabProps) { const { t } = useTranslation('common'); // Build tooltip with keyboard shortcut hint (only for tabs 1-9) @@ -112,9 +116,40 @@ export function SortableProjectTab({ - {/* Active tab controls - settings and archive, always accessible */} + {/* Active tab controls - settings, pop-out, always accessible */} {isActive && (