feat: hide parent apps on devcontainer agents (#18120)

**Demo:**

https://github.com/user-attachments/assets/d68cbc33-5199-426b-8f97-35ee1c3ae133
This commit is contained in:
Bruno Quaresma
2025-05-30 14:59:26 -03:00
committed by GitHub
parent 696d264da8
commit 00502dc653
4 changed files with 43 additions and 25 deletions
@@ -12,13 +12,14 @@ import {
HelpTooltipTitle,
HelpTooltipTrigger,
} from "components/HelpTooltip/HelpTooltip";
import { Spinner } from "components/Spinner/Spinner";
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "components/Tooltip/Tooltip";
import { ExternalLinkIcon, Loader2Icon } from "lucide-react";
import { ExternalLinkIcon } from "lucide-react";
import type { FC } from "react";
import { useEffect, useState } from "react";
import { portForwardURL } from "utils/portForward";
@@ -95,7 +96,8 @@ export const AgentDevcontainerCard: FC<AgentDevcontainerCardProps> = ({
<header className="flex justify-between items-center mb-4">
<div className="flex items-center gap-2">
<h3 className="m-0 text-xs font-medium text-content-secondary">
{container.name}
dev container:{" "}
<span className="font-semibold">{container.name}</span>
</h3>
{container.devcontainer_dirty && (
<HelpTooltip>
@@ -117,18 +119,11 @@ export const AgentDevcontainerCard: FC<AgentDevcontainerCardProps> = ({
<Button
variant="outline"
size="sm"
className="text-xs font-medium"
onClick={handleRecreateDevcontainer}
disabled={isRecreating}
>
{isRecreating ? (
<>
<Loader2Icon className="mr-2 h-4 w-4 animate-spin" />
Recreating...
</>
) : (
"Recreate"
)}
<Spinner loading={isRecreating} />
Recreate
</Button>
<AgentDevcontainerSSHButton
@@ -284,3 +284,11 @@ export const GroupApp: Story = {
await userEvent.click(canvas.getByText("group"));
},
};
export const Devcontainer: Story = {
beforeEach: () => {
spyOn(API, "getAgentContainers").mockResolvedValue({
containers: [M.MockWorkspaceAgentContainer],
});
},
};
+27 -8
View File
@@ -1,5 +1,4 @@
import type { Interpolation, Theme } from "@emotion/react";
import Button from "@mui/material/Button";
import Collapse from "@mui/material/Collapse";
import Divider from "@mui/material/Divider";
import Skeleton from "@mui/material/Skeleton";
@@ -12,6 +11,7 @@ import type {
WorkspaceApp,
} from "api/typesGenerated";
import { isAxiosError } from "axios";
import { Button } from "components/Button/Button";
import { DropdownArrow } from "components/DropdownArrow/DropdownArrow";
import {
DropdownMenu,
@@ -71,7 +71,7 @@ export const AgentRow: FC<AgentRowProps> = ({
const appSections = organizeAgentApps(agent.apps);
const hasAppsToDisplay =
!browser_only || appSections.some((it) => it.apps.length > 0);
const shouldDisplayApps =
const shouldDisplayAgentApps =
(agent.status === "connected" && hasAppsToDisplay) ||
agent.status === "connecting";
const hasVSCodeApp =
@@ -160,6 +160,14 @@ export const AgentRow: FC<AgentRowProps> = ({
},
});
// This is used to show the parent apps of the devcontainer.
const [showParentApps, setShowParentApps] = useState(false);
let shouldDisplayAppsSection = shouldDisplayAgentApps;
if (containers && containers.length > 0 && !showParentApps) {
shouldDisplayAppsSection = false;
}
return (
<Stack
key={agent.id}
@@ -191,7 +199,18 @@ export const AgentRow: FC<AgentRowProps> = ({
)}
</div>
<div css={{ display: "flex" }}>
<div className="flex items-center gap-2">
{containers && containers.length > 0 && (
<Button
variant="outline"
size="sm"
onClick={() => setShowParentApps((show) => !show)}
>
Show parent apps
<DropdownArrow close={showParentApps} margin={false} />
</Button>
)}
{!browser_only && agent.display_apps.includes("ssh_helper") && (
<AgentSSHButton
workspaceName={workspace.name}
@@ -218,9 +237,9 @@ export const AgentRow: FC<AgentRowProps> = ({
</section>
)}
{agent.status === "connected" && (
{shouldDisplayAppsSection && (
<section css={styles.apps}>
{shouldDisplayApps && (
{shouldDisplayAgentApps && (
<>
{showVSCode && (
<VSCodeDesktopButton
@@ -319,11 +338,11 @@ export const AgentRow: FC<AgentRowProps> = ({
<Stack css={{ padding: "12px 16px" }} direction="row" spacing={1}>
<Button
variant="text"
size="small"
startIcon={<DropdownArrow close={showLogs} margin={false} />}
size="sm"
variant="subtle"
onClick={() => setShowLogs((v) => !v)}
>
<DropdownArrow close={showLogs} margin={false} />
Logs
</Button>
<Divider orientation="vertical" variant="middle" flexItem />
@@ -35,13 +35,9 @@ export const AgentSSHButton: FC<AgentSSHButtonProps> = ({
return (
<Popover>
<PopoverTrigger>
<Button
size="sm"
variant="subtle"
css={{ fontSize: 13, padding: "8px 12px" }}
>
<Button size="sm" variant="subtle">
Connect via SSH
<ChevronDownIcon className="size-4 ml-2" />
<ChevronDownIcon />
</Button>
</PopoverTrigger>