Skip to content

Commit a2aabec

Browse files
committed
refactor: extract WorkspaceTitleBar for reuse in header and hover card
Create a shared WorkspaceTitleBar component that displays: - RuntimeBadge - Project name - Branch selector - Git status indicator Used in both WorkspaceHeader (full variant) and WorkspaceListItem hover card (dense variant) to maximize code reuse.
1 parent c7983c7 commit a2aabec

File tree

3 files changed

+97
-28
lines changed

3 files changed

+97
-28
lines changed

src/browser/components/WorkspaceHeader.tsx

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,7 @@ import {
88
getNotifyOnResponseKey,
99
getNotifyOnResponseAutoEnableKey,
1010
} from "@/common/constants/storage";
11-
import { GitStatusIndicator } from "./GitStatusIndicator";
12-
import { RuntimeBadge } from "./RuntimeBadge";
13-
import { BranchSelector } from "./BranchSelector";
11+
import { WorkspaceTitleBar } from "./WorkspaceTitleBar";
1412
import { WorkspaceMCPModal } from "./WorkspaceMCPModal";
1513
import { Tooltip, TooltipTrigger, TooltipContent } from "./ui/tooltip";
1614
import { Popover, PopoverTrigger, PopoverContent } from "./ui/popover";
@@ -211,24 +209,17 @@ export const WorkspaceHeader: React.FC<WorkspaceHeaderProps> = ({
211209
<Menu className="h-3.5 w-3.5" />
212210
</Button>
213211
)}
214-
<RuntimeBadge
212+
<WorkspaceTitleBar
213+
workspaceId={workspaceId}
214+
projectName={projectName}
215+
projectPath={projectPath}
216+
workspaceName={workspaceName}
217+
namedWorkspacePath={namedWorkspacePath}
215218
runtimeConfig={runtimeConfig}
219+
gitStatus={gitStatus}
216220
isWorking={isWorking}
217-
workspacePath={namedWorkspacePath}
218-
workspaceName={workspaceName}
219-
tooltipSide="bottom"
221+
variant="full"
220222
/>
221-
<span className="min-w-0 truncate font-mono text-xs">{projectName}</span>
222-
<div className="flex items-center gap-1">
223-
<BranchSelector workspaceId={workspaceId} workspaceName={workspaceName} />
224-
<GitStatusIndicator
225-
gitStatus={gitStatus}
226-
workspaceId={workspaceId}
227-
projectPath={projectPath}
228-
tooltipPosition="bottom"
229-
isWorking={isWorking}
230-
/>
231-
</div>
232223
</div>
233224
<div className={cn("flex items-center gap-2", isDesktop && "titlebar-no-drag")}>
234225
<WorkspaceLinks workspaceId={workspaceId} />

src/browser/components/WorkspaceListItem.tsx

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { useDrag } from "react-dnd";
1111
import { getEmptyImage } from "react-dnd-html5-backend";
1212
import { GitStatusIndicator } from "./GitStatusIndicator";
1313
import { RuntimeBadge } from "./RuntimeBadge";
14+
import { WorkspaceTitleBar } from "./WorkspaceTitleBar";
1415
import { Tooltip, TooltipTrigger, TooltipContent } from "./ui/tooltip";
1516
import { HoverCard, HoverCardTrigger, HoverCardContent } from "./ui/hover-card";
1617
import { Trash2 } from "lucide-react";
@@ -451,16 +452,17 @@ function RegularWorkspaceListItemInner(props: WorkspaceListItemProps) {
451452
onFocusOutside={preventHoverCardDismissForRadixPortals}
452453
>
453454
<div className="flex flex-col gap-1">
454-
<div className="flex items-center gap-2">
455-
<RuntimeBadge
456-
runtimeConfig={metadata.runtimeConfig}
457-
workspaceName={metadata.name}
458-
workspacePath={namedWorkspacePath}
459-
/>
460-
<span className="text-foreground font-medium break-words whitespace-normal">
461-
{displayTitle}
462-
</span>
463-
</div>
455+
<WorkspaceTitleBar
456+
workspaceId={workspaceId}
457+
projectName={projectName}
458+
projectPath={projectPath}
459+
workspaceName={metadata.name}
460+
namedWorkspacePath={namedWorkspacePath}
461+
runtimeConfig={metadata.runtimeConfig}
462+
gitStatus={gitStatus}
463+
isWorking={isWorking}
464+
variant="dense"
465+
/>
464466
{!isDisabled && (
465467
<div className="text-muted text-xs">Double-click to edit title</div>
466468
)}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import React from "react";
2+
import { cn } from "@/common/lib/utils";
3+
import { GitStatusIndicator } from "./GitStatusIndicator";
4+
import { RuntimeBadge } from "./RuntimeBadge";
5+
import { BranchSelector } from "./BranchSelector";
6+
import type { RuntimeConfig } from "@/common/types/runtime";
7+
import type { GitStatus } from "@/common/types/workspace";
8+
9+
interface WorkspaceTitleBarProps {
10+
workspaceId: string;
11+
projectName: string;
12+
projectPath: string;
13+
workspaceName: string;
14+
namedWorkspacePath: string;
15+
runtimeConfig?: RuntimeConfig;
16+
gitStatus: GitStatus | null;
17+
isWorking: boolean;
18+
/**
19+
* "full" - Used in WorkspaceHeader with larger text and bottom tooltips
20+
* "dense" - Used in HoverCard with smaller text and right tooltips
21+
*/
22+
variant?: "full" | "dense";
23+
className?: string;
24+
}
25+
26+
/**
27+
* Reusable workspace title bar showing runtime badge, project name, branch, and git status.
28+
* Used in both WorkspaceHeader (full variant) and WorkspaceListItem hover card (dense variant).
29+
*/
30+
export function WorkspaceTitleBar({
31+
workspaceId,
32+
projectName,
33+
projectPath,
34+
workspaceName,
35+
namedWorkspacePath,
36+
runtimeConfig,
37+
gitStatus,
38+
isWorking,
39+
variant = "full",
40+
className,
41+
}: WorkspaceTitleBarProps) {
42+
const isDense = variant === "dense";
43+
// RuntimeBadge only supports top/bottom; GitStatusIndicator supports right/bottom
44+
const gitTooltipPosition = isDense ? "right" : "bottom";
45+
46+
return (
47+
<div
48+
className={cn(
49+
"flex min-w-0 items-center gap-2",
50+
isDense ? "text-[11px]" : "gap-2.5",
51+
className
52+
)}
53+
>
54+
<RuntimeBadge
55+
runtimeConfig={runtimeConfig}
56+
isWorking={isWorking}
57+
workspacePath={namedWorkspacePath}
58+
workspaceName={workspaceName}
59+
tooltipSide="bottom"
60+
/>
61+
<span className={cn("min-w-0 truncate font-mono", isDense ? "text-[11px]" : "text-xs")}>
62+
{projectName}
63+
</span>
64+
<div className="flex items-center gap-1">
65+
<BranchSelector workspaceId={workspaceId} workspaceName={workspaceName} />
66+
<GitStatusIndicator
67+
gitStatus={gitStatus}
68+
workspaceId={workspaceId}
69+
projectPath={projectPath}
70+
tooltipPosition={gitTooltipPosition}
71+
isWorking={isWorking}
72+
/>
73+
</div>
74+
</div>
75+
);
76+
}

0 commit comments

Comments
 (0)