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 { 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>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
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