Skip to content

refactor: update app buttons to use the new button component #17684

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
May 6, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add AgentButton back
  • Loading branch information
BrunoQuaresma committed May 5, 2025
commit 8140292ad539d933d3800cdda874a70a8ff60467
39 changes: 15 additions & 24 deletions site/src/components/ExternalImage/ExternalImage.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,19 @@
import { useTheme } from "@emotion/react";
import { type ImgHTMLAttributes, forwardRef } from "react";
import {
type ExternalImageModeStyles,
getExternalImageStylesFromUrl,
} from "theme/externalImages";
import { getExternalImageStylesFromUrl } from "theme/externalImages";

type ExternalImageProps = ImgHTMLAttributes<HTMLImageElement> & {
mode?: ExternalImageModeStyles;
};
export const ExternalImage = forwardRef<
HTMLImageElement,
ImgHTMLAttributes<HTMLImageElement>
>((props, ref) => {
const theme = useTheme();

export const ExternalImage = forwardRef<HTMLImageElement, ExternalImageProps>(
({ mode, ...imgProps }, ref) => {
const theme = useTheme();

return (
// biome-ignore lint/a11y/useAltText: alt should be passed in as a prop
<img
ref={ref}
css={getExternalImageStylesFromUrl(
mode ?? theme.externalImages,
imgProps.src,
)}
{...imgProps}
/>
);
},
);
return (
// biome-ignore lint/a11y/useAltText: alt should be passed in as a prop
<img
ref={ref}
css={getExternalImageStylesFromUrl(theme.externalImages, props.src)}
{...props}
/>
);
});
8 changes: 8 additions & 0 deletions site/src/modules/resources/AgentButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { Button, type ButtonProps } from "components/Button/Button";
import { forwardRef } from "react";

export const AgentButton = forwardRef<HTMLButtonElement, ButtonProps>(
(props, ref) => {
return <Button variant="outline" ref={ref} {...props} />;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is purpose of keeping AgentButton around instead of removing it and using Button directly?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a good question.

Since we want to have the TerminalLink, AppLink, VSCode buttons, etc. visually consistent, and be sure they are always looking the same, I just decided to keep the AgentButton. Of course, we could just set the variant in all these components, but since they are many (around 5 or 6 I guess) it would be easy to forget to update one of them when changing some of the styles (maybe it is not a problem since we have tests).

I'm going to refactor the apps logic very soon, so If I see it is just ok to remove the AgentButton, I will do.

},
);
6 changes: 3 additions & 3 deletions site/src/modules/resources/AgentDevcontainerCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
TooltipProvider,
TooltipTrigger,
} from "components/Tooltip/Tooltip";
import { Button } from "components/Button/Button";
import { AgentButton } from "./AgentButton";

type AgentDevcontainerCardProps = {
agent: WorkspaceAgent;
Expand Down Expand Up @@ -89,12 +89,12 @@ export const AgentDevcontainerCard: FC<AgentDevcontainerCardProps> = ({
<TooltipProvider key={portLabel}>
<Tooltip>
<TooltipTrigger>
<Button disabled={!hasHostBind} asChild>
<AgentButton disabled={!hasHostBind} asChild>
<a href={linkDest}>
<ExternalLinkIcon />
{portLabel}
</a>
</Button>
</AgentButton>
</TooltipTrigger>
<TooltipContent>{helperText}</TooltipContent>
</Tooltip>
Expand Down
6 changes: 3 additions & 3 deletions site/src/modules/resources/AppLink/AppLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
TooltipProvider,
TooltipTrigger,
} from "components/Tooltip/Tooltip";
import { Button } from "components/Button/Button";
import { AgentButton } from "../AgentButton";

export const DisplayAppNameMap: Record<TypesGen.DisplayApp, string> = {
port_forwarding_helper: "Ports",
Expand Down Expand Up @@ -119,7 +119,7 @@ export const AppLink: FC<AppLinkProps> = ({ app, workspace, agent }) => {
const canShare = app.sharing_level !== "owner";

const button = (
<Button disabled={!canClick} asChild>
<AgentButton disabled={!canClick} asChild>
<a
href={href}
onClick={async (event) => {
Expand Down Expand Up @@ -186,7 +186,7 @@ export const AppLink: FC<AppLinkProps> = ({ app, workspace, agent }) => {
{appDisplayName}
{canShare && <ShareIcon app={app} />}
</a>
</Button>
</AgentButton>
);

if (primaryTooltip) {
Expand Down
5 changes: 0 additions & 5 deletions site/src/modules/resources/AppLink/BaseIcon.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,16 @@
import { useTheme } from "@emotion/react";
import ComputerIcon from "@mui/icons-material/Computer";
import type { WorkspaceApp } from "api/typesGenerated";
import { ExternalImage } from "components/ExternalImage/ExternalImage";
import type { FC } from "react";
import { forDarkThemes, forLightThemes } from "theme/externalImages";

interface BaseIconProps {
app: WorkspaceApp;
onIconPathError?: () => void;
}

export const BaseIcon: FC<BaseIconProps> = ({ app, onIconPathError }) => {
const theme = useTheme();

return app.icon ? (
<ExternalImage
mode={theme.palette.mode === "dark" ? forLightThemes : forDarkThemes}
alt={`${app.display_name} Icon`}
src={app.icon}
style={{ pointerEvents: "none" }}
Expand Down
6 changes: 3 additions & 3 deletions site/src/modules/resources/TerminalLink/TerminalLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { TerminalIcon } from "components/Icons/TerminalIcon";
import type { FC, MouseEvent } from "react";
import { generateRandomString } from "utils/random";
import { DisplayAppNameMap } from "../AppLink/AppLink";
import { Button } from "components/Button/Button";
import { AgentButton } from "../AgentButton";

const Language = {
terminalTitle: (identifier: string): string => `Terminal - ${identifier}`,
Expand Down Expand Up @@ -38,7 +38,7 @@ export const TerminalLink: FC<TerminalLinkProps> = ({
}/terminal?${params.toString()}`;

return (
<Button asChild>
<AgentButton asChild>
<a
href={href}
onClick={(event: MouseEvent<HTMLElement>) => {
Expand All @@ -53,6 +53,6 @@ export const TerminalLink: FC<TerminalLinkProps> = ({
<TerminalIcon />
{DisplayAppNameMap.web_terminal}
</a>
</Button>
</AgentButton>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { VSCodeIcon } from "components/Icons/VSCodeIcon";
import { VSCodeInsidersIcon } from "components/Icons/VSCodeInsidersIcon";
import { type FC, useRef, useState } from "react";
import { DisplayAppNameMap } from "../AppLink/AppLink";
import { Button } from "components/Button/Button";
import { AgentButton } from "../AgentButton";

export interface VSCodeDesktopButtonProps {
userName: string;
Expand Down Expand Up @@ -51,7 +51,7 @@ export const VSCodeDesktopButton: FC<VSCodeDesktopButtonProps> = (props) => {
<VSCodeInsidersButton {...props} />
)}

<Button
<AgentButton
aria-controls={
isVariantMenuOpen ? "vscode-variant-button-menu" : undefined
}
Expand All @@ -64,7 +64,7 @@ export const VSCodeDesktopButton: FC<VSCodeDesktopButtonProps> = (props) => {
css={{ paddingLeft: 0, paddingRight: 0 }}
>
<KeyboardArrowDownIcon css={{ fontSize: 16 }} />
</Button>
</AgentButton>
</ButtonGroup>

<Menu
Expand Down Expand Up @@ -113,7 +113,7 @@ const VSCodeButton: FC<VSCodeDesktopButtonProps> = ({
const [loading, setLoading] = useState(false);

return (
<Button
<AgentButton
disabled={loading}
onClick={() => {
setLoading(true);
Expand Down Expand Up @@ -145,7 +145,7 @@ const VSCodeButton: FC<VSCodeDesktopButtonProps> = ({
>
<VSCodeIcon />
{DisplayAppNameMap.vscode}
</Button>
</AgentButton>
);
};

Expand All @@ -158,7 +158,7 @@ const VSCodeInsidersButton: FC<VSCodeDesktopButtonProps> = ({
const [loading, setLoading] = useState(false);

return (
<Button
<AgentButton
disabled={loading}
onClick={() => {
setLoading(true);
Expand Down Expand Up @@ -189,6 +189,6 @@ const VSCodeInsidersButton: FC<VSCodeDesktopButtonProps> = ({
>
<VSCodeInsidersIcon />
{DisplayAppNameMap.vscode_insiders}
</Button>
</AgentButton>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { VSCodeIcon } from "components/Icons/VSCodeIcon";
import { VSCodeInsidersIcon } from "components/Icons/VSCodeInsidersIcon";
import { type FC, useRef, useState } from "react";
import { DisplayAppNameMap } from "../AppLink/AppLink";
import { Button } from "components/Button/Button";
import { AgentButton } from "../AgentButton";

export interface VSCodeDevContainerButtonProps {
userName: string;
Expand Down Expand Up @@ -54,7 +54,7 @@ export const VSCodeDevContainerButton: FC<VSCodeDevContainerButtonProps> = (
<VSCodeInsidersButton {...props} />
)}

<Button
<AgentButton
aria-controls={
isVariantMenuOpen ? "vscode-variant-button-menu" : undefined
}
Expand All @@ -67,7 +67,7 @@ export const VSCodeDevContainerButton: FC<VSCodeDevContainerButtonProps> = (
css={{ paddingLeft: 0, paddingRight: 0 }}
>
<KeyboardArrowDownIcon css={{ fontSize: 16 }} />
</Button>
</AgentButton>
</ButtonGroup>

<Menu
Expand Down Expand Up @@ -117,7 +117,7 @@ const VSCodeButton: FC<VSCodeDevContainerButtonProps> = ({
const [loading, setLoading] = useState(false);

return (
<Button
<AgentButton
disabled={loading}
onClick={() => {
setLoading(true);
Expand Down Expand Up @@ -147,7 +147,7 @@ const VSCodeButton: FC<VSCodeDevContainerButtonProps> = ({
>
<VSCodeIcon />
{DisplayAppNameMap.vscode}
</Button>
</AgentButton>
);
};

Expand All @@ -161,7 +161,7 @@ const VSCodeInsidersButton: FC<VSCodeDevContainerButtonProps> = ({
const [loading, setLoading] = useState(false);

return (
<Button
<AgentButton
disabled={loading}
onClick={() => {
setLoading(true);
Expand Down Expand Up @@ -191,6 +191,6 @@ const VSCodeInsidersButton: FC<VSCodeDevContainerButtonProps> = ({
>
<VSCodeInsidersIcon />
{DisplayAppNameMap.vscode_insiders}
</Button>
</AgentButton>
);
};