feature: Add SSH button in the agent access column (#2931)

This commit is contained in:
Bruno Quaresma
2022-07-12 13:10:38 -03:00
committed by GitHub
parent 0645176e66
commit 166bc273b3
3 changed files with 143 additions and 10 deletions

View File

@ -9,6 +9,7 @@ import { FC } from "react"
import { Workspace, WorkspaceResource } from "../../api/typesGenerated" import { Workspace, WorkspaceResource } from "../../api/typesGenerated"
import { getDisplayAgentStatus } from "../../util/workspace" import { getDisplayAgentStatus } from "../../util/workspace"
import { AppLink } from "../AppLink/AppLink" import { AppLink } from "../AppLink/AppLink"
import { SSHButton } from "../SSHButton/SSHButton"
import { Stack } from "../Stack/Stack" import { Stack } from "../Stack/Stack"
import { TableHeaderRow } from "../TableHeaders/TableHeaders" import { TableHeaderRow } from "../TableHeaders/TableHeaders"
import { TerminalLink } from "../TerminalLink/TerminalLink" import { TerminalLink } from "../TerminalLink/TerminalLink"
@ -107,18 +108,17 @@ export const Resources: FC<ResourcesProps> = ({
<span style={{ color: agentStatus.color }}>{agentStatus.status}</span> <span style={{ color: agentStatus.color }}>{agentStatus.status}</span>
</div> </div>
</TableCell> </TableCell>
{canUpdateWorkspace && (
<TableCell> <TableCell>
<>
{canUpdateWorkspace && agent.status === "connected" && (
<div className={styles.accessLinks}> <div className={styles.accessLinks}>
{agent.status === "connected" && ( <SSHButton workspaceName={workspace.name} agentName={agent.name} />
<TerminalLink <TerminalLink
workspaceName={workspace.name} workspaceName={workspace.name}
agentName={agent.name} agentName={agent.name}
userName={workspace.owner_name} userName={workspace.owner_name}
/> />
)} {agent.apps.map((app) => (
{agent.status === "connected" &&
agent.apps.map((app) => (
<AppLink <AppLink
key={app.name} key={app.name}
appIcon={app.icon} appIcon={app.icon}
@ -128,8 +128,9 @@ export const Resources: FC<ResourcesProps> = ({
/> />
))} ))}
</div> </div>
</TableCell>
)} )}
</>
</TableCell>
</TableRow> </TableRow>
) )
}) })

View File

@ -0,0 +1,23 @@
import { Story } from "@storybook/react"
import { MockWorkspace, MockWorkspaceAgent } from "../../testHelpers/renderHelpers"
import { SSHButton, SSHButtonProps } from "./SSHButton"
export default {
title: "components/SSHButton",
component: SSHButton,
}
const Template: Story<SSHButtonProps> = (args) => <SSHButton {...args} />
export const Closed = Template.bind({})
Closed.args = {
workspaceName: MockWorkspace.name,
agentName: MockWorkspaceAgent.name,
}
export const Opened = Template.bind({})
Opened.args = {
workspaceName: MockWorkspace.name,
agentName: MockWorkspaceAgent.name,
defaultIsOpen: true,
}

View File

@ -0,0 +1,109 @@
import Button from "@material-ui/core/Button"
import Popover from "@material-ui/core/Popover"
import { makeStyles } from "@material-ui/core/styles"
import CloudIcon from "@material-ui/icons/CloudOutlined"
import { useRef, useState } from "react"
import { CodeExample } from "../CodeExample/CodeExample"
import { Stack } from "../Stack/Stack"
import { HelpTooltipLink, HelpTooltipLinksGroup, HelpTooltipText } from "../Tooltips/HelpTooltip"
export interface SSHButtonProps {
workspaceName: string
agentName: string
defaultIsOpen?: boolean
}
export const SSHButton: React.FC<SSHButtonProps> = ({
workspaceName,
agentName,
defaultIsOpen = false,
}) => {
const anchorRef = useRef<HTMLButtonElement>(null)
const [isOpen, setIsOpen] = useState(defaultIsOpen)
const id = isOpen ? "schedule-popover" : undefined
const styles = useStyles()
const onClose = () => {
setIsOpen(false)
}
return (
<>
<Button
startIcon={<CloudIcon />}
size="small"
ref={anchorRef}
onClick={() => {
setIsOpen(true)
}}
>
SSH
</Button>
<Popover
classes={{ paper: styles.popoverPaper }}
id={id}
open={isOpen}
anchorEl={anchorRef.current}
onClose={onClose}
anchorOrigin={{
vertical: "bottom",
horizontal: "left",
}}
transformOrigin={{
vertical: "top",
horizontal: "left",
}}
>
<HelpTooltipText>Run the following commands to connect with SSH:</HelpTooltipText>
<Stack spacing={0.5} className={styles.codeExamples}>
<div>
<HelpTooltipText>
<strong className={styles.codeExampleLabel}>
Configure ssh{" "}
<span className={styles.textHelper}>
- only needs to be run once, or after managing workspaces
</span>
</strong>
</HelpTooltipText>
<CodeExample code="coder config-ssh" />
</div>
<div>
<HelpTooltipText>
<strong className={styles.codeExampleLabel}>Connect to the agent</strong>
</HelpTooltipText>
<CodeExample code={`ssh coder.${workspaceName}.${agentName}`} />
</div>
</Stack>
<HelpTooltipLinksGroup>
<HelpTooltipLink href="#">Install Coder CLI</HelpTooltipLink>
<HelpTooltipLink href="#">Configuring VS Code</HelpTooltipLink>
<HelpTooltipLink href="#">SSH configuration</HelpTooltipLink>
</HelpTooltipLinksGroup>
</Popover>
</>
)
}
const useStyles = makeStyles((theme) => ({
popoverPaper: {
padding: `${theme.spacing(2)}px ${theme.spacing(3)}px ${theme.spacing(3)}px`,
width: theme.spacing(38),
color: theme.palette.text.secondary,
marginTop: theme.spacing(0.25),
},
codeExamples: {
marginTop: theme.spacing(1.5),
},
codeExampleLabel: {
fontSize: 12,
},
textHelper: {
fontWeight: 400,
},
}))