mirror of
https://github.com/coder/coder.git
synced 2025-07-12 00:14:10 +00:00
feature: Add SSH button in the agent access column (#2931)
This commit is contained in:
@ -9,6 +9,7 @@ import { FC } from "react"
|
||||
import { Workspace, WorkspaceResource } from "../../api/typesGenerated"
|
||||
import { getDisplayAgentStatus } from "../../util/workspace"
|
||||
import { AppLink } from "../AppLink/AppLink"
|
||||
import { SSHButton } from "../SSHButton/SSHButton"
|
||||
import { Stack } from "../Stack/Stack"
|
||||
import { TableHeaderRow } from "../TableHeaders/TableHeaders"
|
||||
import { TerminalLink } from "../TerminalLink/TerminalLink"
|
||||
@ -107,18 +108,17 @@ export const Resources: FC<ResourcesProps> = ({
|
||||
<span style={{ color: agentStatus.color }}>{agentStatus.status}</span>
|
||||
</div>
|
||||
</TableCell>
|
||||
{canUpdateWorkspace && (
|
||||
<TableCell>
|
||||
<div className={styles.accessLinks}>
|
||||
{agent.status === "connected" && (
|
||||
<TableCell>
|
||||
<>
|
||||
{canUpdateWorkspace && agent.status === "connected" && (
|
||||
<div className={styles.accessLinks}>
|
||||
<SSHButton workspaceName={workspace.name} agentName={agent.name} />
|
||||
<TerminalLink
|
||||
workspaceName={workspace.name}
|
||||
agentName={agent.name}
|
||||
userName={workspace.owner_name}
|
||||
/>
|
||||
)}
|
||||
{agent.status === "connected" &&
|
||||
agent.apps.map((app) => (
|
||||
{agent.apps.map((app) => (
|
||||
<AppLink
|
||||
key={app.name}
|
||||
appIcon={app.icon}
|
||||
@ -127,9 +127,10 @@ export const Resources: FC<ResourcesProps> = ({
|
||||
workspaceName={workspace.name}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</TableCell>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
)
|
||||
})
|
||||
|
23
site/src/components/SSHButton/SSHButton.stories.tsx
Normal file
23
site/src/components/SSHButton/SSHButton.stories.tsx
Normal 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,
|
||||
}
|
109
site/src/components/SSHButton/SSHButton.tsx
Normal file
109
site/src/components/SSHButton/SSHButton.tsx
Normal 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,
|
||||
},
|
||||
}))
|
Reference in New Issue
Block a user