Skip to content

Commit e0718a6

Browse files
1 parent a85351f commit e0718a6

File tree

3 files changed

+78
-20
lines changed

3 files changed

+78
-20
lines changed

site/src/components/DropdownMenu/DropdownMenu.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ export const DropdownMenuItem = forwardRef<
111111
[
112112
"relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-2 text-sm text-content-secondary font-medium outline-none transition-colors",
113113
"focus:bg-surface-secondary focus:text-content-primary data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
114-
"[&>svg]:size-4 [&>svg]:shrink-0 no-underline",
114+
"[&>svg]:size-4 [&>svg]:shrink-0 [&>img]:size-4 [&>img]:shrink-0 no-underline",
115115
inset && "pl-8",
116116
],
117117
className,

site/src/pages/TaskPage/TaskPage.stories.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,9 +131,15 @@ export const Active: Story = {
131131
{
132132
...MockWorkspaceApp,
133133
id: "vscode",
134-
display_name: "VSCode",
134+
display_name: "VS Code Web",
135135
icon: "/icon/code.svg",
136136
},
137+
{
138+
...MockWorkspaceApp,
139+
id: "zed",
140+
display_name: "Zed",
141+
icon: "/icon/zed.svg",
142+
},
137143
],
138144
},
139145
],

site/src/pages/TaskPage/TaskPage.tsx

Lines changed: 70 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@ import { API } from "api/api";
22
import { getErrorDetail, getErrorMessage } from "api/errors";
33
import type { WorkspaceApp, WorkspaceStatus } from "api/typesGenerated";
44
import { Button } from "components/Button/Button";
5+
import {
6+
DropdownMenu,
7+
DropdownMenuContent,
8+
DropdownMenuItem,
9+
DropdownMenuTrigger,
10+
} from "components/DropdownMenu/DropdownMenu";
511
import { ExternalImage } from "components/ExternalImage/ExternalImage";
612
import { Loader } from "components/Loader/Loader";
713
import { Margins } from "components/Margins/Margins";
@@ -14,7 +20,12 @@ import {
1420
TooltipTrigger,
1521
} from "components/Tooltip/Tooltip";
1622
import { useProxy } from "contexts/ProxyContext";
17-
import { ArrowLeftIcon, LayoutGridIcon, RotateCcwIcon } from "lucide-react";
23+
import {
24+
ArrowLeftIcon,
25+
ChevronDownIcon,
26+
LayoutGridIcon,
27+
RotateCcwIcon,
28+
} from "lucide-react";
1829
import { AppStatusIcon } from "modules/apps/AppStatusIcon";
1930
import { getAppHref } from "modules/apps/apps";
2031
import { useAppLink } from "modules/apps/useAppLink";
@@ -312,26 +323,67 @@ const TaskApps: FC<TaskAppsProps> = ({ task }) => {
312323
return src;
313324
});
314325

326+
const embeddedApps = apps.filter((app) => !app.external);
327+
const externalApps = apps.filter((app) => app.external);
328+
315329
return (
316330
<main className="flex-1 flex flex-col">
317331
<div className="border-0 border-b border-border border-solid w-full p-1 flex gap-2">
318-
{apps.map((app) => (
319-
<TaskAppButton
320-
key={app.id}
321-
task={task}
322-
app={app}
323-
active={app.id === activeAppId}
324-
onClick={(e) => {
325-
if (app.external) {
326-
return;
327-
}
328-
329-
e.preventDefault();
330-
setActiveAppId(app.id);
331-
setIframeSrc(e.currentTarget.href);
332-
}}
333-
/>
334-
))}
332+
{embeddedApps
333+
.filter((app) => !app.external)
334+
.map((app) => (
335+
<TaskAppButton
336+
key={app.id}
337+
task={task}
338+
app={app}
339+
active={app.id === activeAppId}
340+
onClick={(e) => {
341+
if (app.external) {
342+
return;
343+
}
344+
345+
e.preventDefault();
346+
setActiveAppId(app.id);
347+
setIframeSrc(e.currentTarget.href);
348+
}}
349+
/>
350+
))}
351+
352+
{externalApps.length > 0 && (
353+
<div className="ml-auto">
354+
<DropdownMenu>
355+
<DropdownMenuTrigger asChild>
356+
<Button size="sm" variant="subtle">
357+
Open in IDE
358+
<ChevronDownIcon />
359+
</Button>
360+
</DropdownMenuTrigger>
361+
<DropdownMenuContent>
362+
{externalApps
363+
.filter((app) => app.external)
364+
.map((app) => {
365+
const link = useAppLink(app, {
366+
agent,
367+
workspace: task.workspace,
368+
});
369+
370+
return (
371+
<DropdownMenuItem key={app.id} asChild>
372+
<RouterLink to={link.href}>
373+
{app.icon ? (
374+
<ExternalImage src={app.icon} />
375+
) : (
376+
<LayoutGridIcon />
377+
)}
378+
{link.label}
379+
</RouterLink>
380+
</DropdownMenuItem>
381+
);
382+
})}
383+
</DropdownMenuContent>
384+
</DropdownMenu>
385+
</div>
386+
)}
335387
</div>
336388

337389
<div className="flex-1">

0 commit comments

Comments
 (0)