Skip to content

Commit edd5f41

Browse files
authored
feat(ui): show workspace mode badge in task header (#2953)
1 parent 5f5e43b commit edd5f41

2 files changed

Lines changed: 57 additions & 10 deletions

File tree

packages/ui/src/features/task-detail/components/TaskDetail.tsx

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import { useWorkspaceEvents } from "../../workspace/useWorkspaceEvents";
2323
import { HeaderTitleEditor } from "../HeaderTitleEditor";
2424
import { useTaskData } from "../hooks/useTaskData";
2525
import { ExternalAppsOpener } from "./ExternalAppsOpener";
26+
import { WorkspaceModeBadge } from "./WorkspaceModeBadge";
2627

2728
const MIN_REVIEW_WIDTH = 300;
2829
const log = logger.scope("task-detail");
@@ -117,6 +118,8 @@ export function TaskDetail({
117118
const trailing = openTargetPath ? (
118119
<ExternalAppsOpener targetPath={openTargetPath} />
119120
) : null;
121+
const workspace = useWorkspace(taskId);
122+
const workspaceMode = workspace?.mode;
120123
const headerContent = useMemo(
121124
() =>
122125
// Inside a channel, prefix the editable title with the channel
@@ -125,6 +128,11 @@ export function TaskDetail({
125128
channelName ? (
126129
<ChannelBreadcrumb
127130
channelName={channelName}
131+
leafIcon={
132+
workspaceMode ? (
133+
<WorkspaceModeBadge mode={workspaceMode} />
134+
) : undefined
135+
}
128136
leafLabel={task.title}
129137
onRename={handleTitleEditSubmit}
130138
trailing={trailing}
@@ -138,15 +146,18 @@ export function TaskDetail({
138146
onCancel={handleTitleEditCancel}
139147
/>
140148
) : (
141-
<Tooltip content={task.title} side="bottom" delayDuration={300}>
142-
<Text
143-
truncate
144-
className="no-drag min-w-0 font-medium text-[13px]"
145-
onDoubleClick={() => setIsEditingTitle(true)}
146-
>
147-
{task.title}
148-
</Text>
149-
</Tooltip>
149+
<Flex align="center" gap="2" minWidth="0">
150+
<WorkspaceModeBadge mode={workspaceMode} />
151+
<Tooltip content={task.title} side="bottom" delayDuration={300}>
152+
<Text
153+
truncate
154+
className="no-drag min-w-0 font-medium text-[13px]"
155+
onDoubleClick={() => setIsEditingTitle(true)}
156+
>
157+
{task.title}
158+
</Text>
159+
</Tooltip>
160+
</Flex>
150161
)}
151162
{trailing}
152163
</Flex>
@@ -156,6 +167,7 @@ export function TaskDetail({
156167
task.title,
157168
trailing,
158169
isEditingTitle,
170+
workspaceMode,
159171
handleTitleEditSubmit,
160172
handleTitleEditCancel,
161173
],
@@ -166,7 +178,6 @@ export function TaskDetail({
166178
const reviewMode = useReviewNavigationStore(
167179
(s) => s.reviewModes[taskId] ?? "closed",
168180
);
169-
const workspace = useWorkspace(taskId);
170181
const isCloud =
171182
workspace?.mode === "cloud" || task.latest_run?.environment === "cloud";
172183

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { Cloud, GitFork, HardDrives } from "@phosphor-icons/react";
2+
import type { WorkspaceMode } from "@posthog/shared";
3+
import { Tooltip } from "../../../primitives/Tooltip";
4+
5+
const MODE_META: Record<
6+
WorkspaceMode,
7+
{ Icon: typeof Cloud; label: string; color: string }
8+
> = {
9+
local: {
10+
Icon: HardDrives,
11+
label: "Local — runs on your working copy",
12+
color: "var(--gray-10)",
13+
},
14+
worktree: {
15+
Icon: GitFork,
16+
label: "Worktree — runs in an isolated git worktree",
17+
color: "var(--teal-11)",
18+
},
19+
cloud: {
20+
Icon: Cloud,
21+
label: "Cloud — runs on a remote machine",
22+
color: "var(--accent-11)",
23+
},
24+
};
25+
26+
export function WorkspaceModeBadge({ mode }: { mode?: WorkspaceMode }) {
27+
if (!mode) return null;
28+
const { Icon, label, color } = MODE_META[mode];
29+
return (
30+
<Tooltip content={label} side="bottom" delayDuration={300}>
31+
<span className="no-drag flex shrink-0 items-center justify-center">
32+
<Icon size={13} weight="fill" color={color} />
33+
</span>
34+
</Tooltip>
35+
);
36+
}

0 commit comments

Comments
 (0)