diff --git a/site/src/components/Icons/VSCodeIcon.stories.tsx b/site/src/components/Icons/VSCodeIcon.stories.tsx new file mode 100644 index 0000000000000..3656005303789 --- /dev/null +++ b/site/src/components/Icons/VSCodeIcon.stories.tsx @@ -0,0 +1,12 @@ +import { Story } from "@storybook/react" +import { VSCodeIcon } from "./VSCodeIcon" + +export default { + title: "icons/VSCodeIcon", + component: VSCodeIcon, +} + +const Template: Story = (args) => + +export const Example = Template.bind({}) +Example.args = {} diff --git a/site/src/components/Icons/VSCodeIcon.tsx b/site/src/components/Icons/VSCodeIcon.tsx new file mode 100644 index 0000000000000..7231dab0e2c22 --- /dev/null +++ b/site/src/components/Icons/VSCodeIcon.tsx @@ -0,0 +1,134 @@ +import SvgIcon, { SvgIconProps } from "@material-ui/core/SvgIcon" + +export const VSCodeIcon: typeof SvgIcon = (props: SvgIconProps) => ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +) diff --git a/site/src/components/Resources/AgentRow.stories.tsx b/site/src/components/Resources/AgentRow.stories.tsx index a289c3d1bf19f..7a74352db92fc 100644 --- a/site/src/components/Resources/AgentRow.stories.tsx +++ b/site/src/components/Resources/AgentRow.stories.tsx @@ -32,6 +32,15 @@ HideSSHButton.args = { hideSSHButton: true, } +export const HideVSCodeDesktopButton = Template.bind({}) +HideVSCodeDesktopButton.args = { + agent: MockWorkspaceAgent, + workspace: MockWorkspace, + applicationsHost: "", + showApps: true, + hideVSCodeDesktopButton: true, +} + export const NotShowingApps = Template.bind({}) NotShowingApps.args = { agent: MockWorkspaceAgent, diff --git a/site/src/components/Resources/AgentRow.tsx b/site/src/components/Resources/AgentRow.tsx index 553761233b39c..c6174f7f56807 100644 --- a/site/src/components/Resources/AgentRow.tsx +++ b/site/src/components/Resources/AgentRow.tsx @@ -13,6 +13,7 @@ import { Maybe } from "components/Conditionals/Maybe" import { AgentStatus } from "./AgentStatus" import { AppLinkSkeleton } from "components/AppLink/AppLinkSkeleton" import { useTranslation } from "react-i18next" +import { VSCodeDesktopButton } from "components/VSCodeDesktopButton/VSCodeDesktopButton" export interface AgentRowProps { agent: WorkspaceAgent @@ -20,6 +21,7 @@ export interface AgentRowProps { applicationsHost: string | undefined showApps: boolean hideSSHButton?: boolean + hideVSCodeDesktopButton?: boolean serverVersion: string } @@ -29,6 +31,7 @@ export const AgentRow: FC = ({ applicationsHost, showApps, hideSSHButton, + hideVSCodeDesktopButton, serverVersion, }) => { const styles = useStyles() @@ -105,6 +108,13 @@ export const AgentRow: FC = ({ agentName={agent.name} /> )} + {!hideVSCodeDesktopButton && ( + + )} {applicationsHost !== undefined && applicationsHost !== "" && ( = (args) => ( + +) + +export const Default = Template.bind({}) +Default.args = { + userName: MockWorkspace.owner_name, + workspaceName: MockWorkspace.name, + agentName: MockWorkspaceAgent.name, +} diff --git a/site/src/components/VSCodeDesktopButton/VSCodeDesktopButton.tsx b/site/src/components/VSCodeDesktopButton/VSCodeDesktopButton.tsx new file mode 100644 index 0000000000000..b7d9e9f70b618 --- /dev/null +++ b/site/src/components/VSCodeDesktopButton/VSCodeDesktopButton.tsx @@ -0,0 +1,52 @@ +import Button from "@material-ui/core/Button" +import { getApiKey } from "api/api" +import { VSCodeIcon } from "components/Icons/VSCodeIcon" +import { FC, PropsWithChildren, useState } from "react" + +export interface VSCodeDesktopButtonProps { + userName: string + workspaceName: string + agentName?: string +} + +export const VSCodeDesktopButton: FC< + PropsWithChildren +> = ({ userName, workspaceName, agentName }) => { + const [loading, setLoading] = useState(false) + + return ( + + ) +} diff --git a/site/src/components/Workspace/Workspace.tsx b/site/src/components/Workspace/Workspace.tsx index d9f3728976ab4..c1405e4bd079a 100644 --- a/site/src/components/Workspace/Workspace.tsx +++ b/site/src/components/Workspace/Workspace.tsx @@ -50,6 +50,7 @@ export interface WorkspaceProps { builds?: TypesGen.WorkspaceBuild[] canUpdateWorkspace: boolean hideSSHButton?: boolean + hideVSCodeDesktopButton?: boolean workspaceErrors: Partial> buildInfo?: TypesGen.BuildInfoResponse applicationsHost?: string @@ -75,6 +76,7 @@ export const Workspace: FC> = ({ canUpdateWorkspace, workspaceErrors, hideSSHButton, + hideVSCodeDesktopButton, buildInfo, applicationsHost, template, @@ -215,6 +217,7 @@ export const Workspace: FC> = ({ applicationsHost={applicationsHost} showApps={canUpdateWorkspace} hideSSHButton={hideSSHButton} + hideVSCodeDesktopButton={hideVSCodeDesktopButton} serverVersion={serverVersion} /> )} diff --git a/site/src/pages/WorkspacePage/WorkspaceReadyPage.tsx b/site/src/pages/WorkspacePage/WorkspaceReadyPage.tsx index 968b74cd14ebc..7f801b17e8df8 100644 --- a/site/src/pages/WorkspacePage/WorkspaceReadyPage.tsx +++ b/site/src/pages/WorkspacePage/WorkspaceReadyPage.tsx @@ -42,6 +42,10 @@ export const WorkspaceReadyPage = ({ workspaceState.children["scheduleBannerMachine"], ) const xServices = useContext(XServiceContext) + const experimental = useSelector( + xServices.entitlementsXService, + (state) => state.context.entitlements.experimental, + ) const featureVisibility = useSelector( xServices.entitlementsXService, selectFeatureVisibility, @@ -120,6 +124,9 @@ export const WorkspaceReadyPage = ({ builds={builds} canUpdateWorkspace={canUpdateWorkspace} hideSSHButton={featureVisibility[FeatureNames.BrowserOnly]} + hideVSCodeDesktopButton={ + !experimental || featureVisibility[FeatureNames.BrowserOnly] + } workspaceErrors={{ [WorkspaceErrors.GET_RESOURCES_ERROR]: refreshWorkspaceWarning, [WorkspaceErrors.GET_BUILDS_ERROR]: getBuildsError,