Skip to content

Commit ce2a7d4

Browse files
refactor: Refactor template resources (#4789)
1 parent 8282e46 commit ce2a7d4

18 files changed

+642
-504
lines changed
Lines changed: 44 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
import { Story } from "@storybook/react"
2-
import { MockWorkspace } from "../../testHelpers/renderHelpers"
2+
import {
3+
MockWorkspace,
4+
MockWorkspaceAgent,
5+
MockWorkspaceApp,
6+
} from "testHelpers/renderHelpers"
37
import { AppLink, AppLinkProps } from "./AppLink"
48

59
export default {
@@ -11,44 +15,59 @@ const Template: Story<AppLinkProps> = (args) => <AppLink {...args} />
1115

1216
export const WithIcon = Template.bind({})
1317
WithIcon.args = {
14-
username: "developer",
15-
workspaceName: MockWorkspace.name,
16-
appName: "code-server",
17-
appIcon: "/icon/code.svg",
18-
appSharingLevel: "owner",
19-
health: "healthy",
18+
workspace: MockWorkspace,
19+
app: {
20+
...MockWorkspaceApp,
21+
name: "code-server",
22+
icon: "/icon/code.svg",
23+
sharing_level: "owner",
24+
health: "healthy",
25+
},
26+
agent: MockWorkspaceAgent,
2027
}
2128

2229
export const WithoutIcon = Template.bind({})
2330
WithoutIcon.args = {
24-
username: "developer",
25-
workspaceName: MockWorkspace.name,
26-
appName: "code-server",
27-
appSharingLevel: "owner",
28-
health: "healthy",
31+
workspace: MockWorkspace,
32+
app: {
33+
...MockWorkspaceApp,
34+
name: "code-server",
35+
sharing_level: "owner",
36+
health: "healthy",
37+
},
38+
agent: MockWorkspaceAgent,
2939
}
3040

3141
export const HealthDisabled = Template.bind({})
3242
HealthDisabled.args = {
33-
username: "developer",
34-
workspaceName: MockWorkspace.name,
35-
appName: "code-server",
36-
appSharingLevel: "owner",
37-
health: "disabled",
43+
workspace: MockWorkspace,
44+
app: {
45+
...MockWorkspaceApp,
46+
name: "code-server",
47+
sharing_level: "owner",
48+
health: "disabled",
49+
},
50+
agent: MockWorkspaceAgent,
3851
}
3952

4053
export const HealthInitializing = Template.bind({})
4154
HealthInitializing.args = {
42-
username: "developer",
43-
workspaceName: MockWorkspace.name,
44-
appName: "code-server",
45-
health: "initializing",
55+
workspace: MockWorkspace,
56+
app: {
57+
...MockWorkspaceApp,
58+
name: "code-server",
59+
health: "initializing",
60+
},
61+
agent: MockWorkspaceAgent,
4662
}
4763

4864
export const HealthUnhealthy = Template.bind({})
4965
HealthUnhealthy.args = {
50-
username: "developer",
51-
workspaceName: MockWorkspace.name,
52-
appName: "code-server",
53-
health: "unhealthy",
66+
workspace: MockWorkspace,
67+
app: {
68+
...MockWorkspaceApp,
69+
name: "code-server",
70+
health: "unhealthy",
71+
},
72+
agent: MockWorkspaceAgent,
5473
}

site/src/components/AppLink/AppLink.tsx

Lines changed: 27 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,12 @@ import CircularProgress from "@material-ui/core/CircularProgress"
33
import Link from "@material-ui/core/Link"
44
import { makeStyles } from "@material-ui/core/styles"
55
import Tooltip from "@material-ui/core/Tooltip"
6-
import ComputerIcon from "@material-ui/icons/Computer"
7-
import PublicOutlinedIcon from "@material-ui/icons/PublicOutlined"
8-
import LockOutlinedIcon from "@material-ui/icons/LockOutlined"
9-
import GroupOutlinedIcon from "@material-ui/icons/GroupOutlined"
106
import ErrorOutlineIcon from "@material-ui/icons/ErrorOutline"
11-
import { FC, PropsWithChildren } from "react"
7+
import { FC } from "react"
128
import * as TypesGen from "../../api/typesGenerated"
139
import { generateRandomString } from "../../util/random"
10+
import { BaseIcon } from "./BaseIcon"
11+
import { ShareIcon } from "./ShareIcon"
1412

1513
export const Language = {
1614
appTitle: (appName: string, identifier: string): string =>
@@ -19,76 +17,50 @@ export const Language = {
1917

2018
export interface AppLinkProps {
2119
appsHost?: string
22-
username: TypesGen.User["username"]
23-
workspaceName: TypesGen.Workspace["name"]
24-
agentName: TypesGen.WorkspaceAgent["name"]
25-
appName: TypesGen.WorkspaceApp["name"]
26-
appIcon?: TypesGen.WorkspaceApp["icon"]
27-
appCommand?: TypesGen.WorkspaceApp["command"]
28-
appSubdomain: TypesGen.WorkspaceApp["subdomain"]
29-
appSharingLevel: TypesGen.WorkspaceApp["sharing_level"]
30-
health: TypesGen.WorkspaceApp["health"]
20+
workspace: TypesGen.Workspace
21+
app: TypesGen.WorkspaceApp
22+
agent: TypesGen.WorkspaceAgent
3123
}
3224

33-
export const AppLink: FC<PropsWithChildren<AppLinkProps>> = ({
25+
export const AppLink: FC<AppLinkProps> = ({
3426
appsHost,
35-
username,
36-
workspaceName,
37-
agentName,
38-
appName,
39-
appIcon,
40-
appCommand,
41-
appSubdomain,
42-
appSharingLevel,
43-
health,
27+
app,
28+
workspace,
29+
agent,
4430
}) => {
4531
const styles = useStyles()
32+
const username = workspace.owner_name
4633

4734
// The backend redirects if the trailing slash isn't included, so we add it
4835
// here to avoid extra roundtrips.
49-
let href = `/@${username}/${workspaceName}.${agentName}/apps/${encodeURIComponent(
50-
appName,
51-
)}/`
52-
if (appCommand) {
53-
href = `/@${username}/${workspaceName}.${agentName}/terminal?command=${encodeURIComponent(
54-
appCommand,
55-
)}`
36+
let href = `/@${username}/${workspace.name}.${
37+
agent.name
38+
}/apps/${encodeURIComponent(app.name)}/`
39+
if (app.command) {
40+
href = `/@${username}/${workspace.name}.${
41+
agent.name
42+
}/terminal?command=${encodeURIComponent(app.command)}`
5643
}
57-
if (appsHost && appSubdomain) {
58-
const subdomain = `${appName}--${agentName}--${workspaceName}--${username}`
44+
if (appsHost && app.subdomain) {
45+
const subdomain = `${app.name}--${agent.name}--${workspace.name}--${username}`
5946
href = `${window.location.protocol}//${appsHost}/`.replace("*", subdomain)
6047
}
6148

6249
let canClick = true
63-
let icon = appIcon ? (
64-
<img alt={`${appName} Icon`} src={appIcon} />
65-
) : (
66-
<ComputerIcon />
67-
)
68-
69-
let shareIcon = <LockOutlinedIcon />
70-
let shareTooltip = "Private, only accessible by you"
71-
if (appSharingLevel === "authenticated") {
72-
shareIcon = <GroupOutlinedIcon />
73-
shareTooltip = "Shared with all authenticated users"
74-
}
75-
if (appSharingLevel === "public") {
76-
shareIcon = <PublicOutlinedIcon />
77-
shareTooltip = "Shared publicly"
78-
}
50+
let icon = <BaseIcon app={app} />
7951

8052
let primaryTooltip = ""
81-
if (health === "initializing") {
53+
if (app.health === "initializing") {
8254
canClick = false
8355
icon = <CircularProgress size={16} />
8456
primaryTooltip = "Initializing..."
8557
}
86-
if (health === "unhealthy") {
58+
if (app.health === "unhealthy") {
8759
canClick = false
8860
icon = <ErrorOutlineIcon className={styles.unhealthyIcon} />
8961
primaryTooltip = "Unhealthy"
9062
}
91-
if (!appsHost && appSubdomain) {
63+
if (!appsHost && app.subdomain) {
9264
canClick = false
9365
icon = <ErrorOutlineIcon className={styles.notConfiguredIcon} />
9466
primaryTooltip =
@@ -99,11 +71,11 @@ export const AppLink: FC<PropsWithChildren<AppLinkProps>> = ({
9971
<Button
10072
size="small"
10173
startIcon={icon}
102-
endIcon={<Tooltip title={shareTooltip}>{shareIcon}</Tooltip>}
74+
endIcon={<ShareIcon app={app} />}
10375
className={styles.button}
10476
disabled={!canClick}
10577
>
106-
<span className={styles.appName}>{appName}</span>
78+
<span className={styles.appName}>{app.name}</span>
10779
</Button>
10880
)
10981

@@ -120,7 +92,7 @@ export const AppLink: FC<PropsWithChildren<AppLinkProps>> = ({
12092
event.preventDefault()
12193
window.open(
12294
href,
123-
Language.appTitle(appName, generateRandomString(12)),
95+
Language.appTitle(app.name, generateRandomString(12)),
12496
"width=900,height=600",
12597
)
12698
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { makeStyles } from "@material-ui/core/styles"
2+
import { Stack } from "components/Stack/Stack"
3+
import { FC } from "react"
4+
import * as TypesGen from "api/typesGenerated"
5+
import { BaseIcon } from "./BaseIcon"
6+
import { ShareIcon } from "./ShareIcon"
7+
8+
export interface AppPreviewProps {
9+
app: TypesGen.WorkspaceApp
10+
}
11+
12+
export const AppPreviewLink: FC<AppPreviewProps> = ({ app }) => {
13+
const styles = useStyles()
14+
15+
return (
16+
<Stack
17+
className={styles.appPreviewLink}
18+
alignItems="center"
19+
direction="row"
20+
spacing={1}
21+
>
22+
<BaseIcon app={app} />
23+
{app.name}
24+
<ShareIcon app={app} />
25+
</Stack>
26+
)
27+
}
28+
29+
const useStyles = makeStyles((theme) => ({
30+
appPreviewLink: {
31+
padding: theme.spacing(0.25, 1.5),
32+
borderRadius: 9999,
33+
border: `1px solid ${theme.palette.divider}`,
34+
color: theme.palette.text.primary,
35+
background: theme.palette.background.paper,
36+
flexShrink: 0,
37+
width: "fit-content",
38+
39+
"& img, & svg": {
40+
width: 14,
41+
},
42+
},
43+
}))
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { WorkspaceApp } from "api/typesGenerated"
2+
import { FC } from "react"
3+
import ComputerIcon from "@material-ui/icons/Computer"
4+
5+
export const BaseIcon: FC<{ app: WorkspaceApp }> = ({ app }) => {
6+
return app.icon ? (
7+
<img alt={`${app.name} Icon`} src={app.icon} />
8+
) : (
9+
<ComputerIcon />
10+
)
11+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import PublicOutlinedIcon from "@material-ui/icons/PublicOutlined"
2+
import LockOutlinedIcon from "@material-ui/icons/LockOutlined"
3+
import GroupOutlinedIcon from "@material-ui/icons/GroupOutlined"
4+
import { FC } from "react"
5+
import * as TypesGen from "../../api/typesGenerated"
6+
import Tooltip from "@material-ui/core/Tooltip"
7+
import { useTranslation } from "react-i18next"
8+
9+
export interface ShareIconProps {
10+
app: TypesGen.WorkspaceApp
11+
}
12+
13+
export const ShareIcon: FC<ShareIconProps> = ({ app }) => {
14+
const { t } = useTranslation("agent")
15+
16+
let shareIcon = <LockOutlinedIcon />
17+
let shareTooltip = t("shareTooltip.private")
18+
if (app.sharing_level === "authenticated") {
19+
shareIcon = <GroupOutlinedIcon />
20+
shareTooltip = t("shareTooltip.authenticated")
21+
}
22+
if (app.sharing_level === "public") {
23+
shareIcon = <PublicOutlinedIcon />
24+
shareTooltip = t("shareTooltip.public")
25+
}
26+
27+
return <Tooltip title={shareTooltip}>{shareIcon}</Tooltip>
28+
}

site/src/components/BuildsTable/BuildsTable.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ export const Language = {
2222

2323
export interface BuildsTableProps {
2424
builds?: TypesGen.WorkspaceBuild[]
25-
className?: string
2625
}
2726

2827
const groupBuildsByDate = (builds?: TypesGen.WorkspaceBuild[]) => {
@@ -48,13 +47,12 @@ const groupBuildsByDate = (builds?: TypesGen.WorkspaceBuild[]) => {
4847

4948
export const BuildsTable: FC<React.PropsWithChildren<BuildsTableProps>> = ({
5049
builds,
51-
className,
5250
}) => {
5351
const isLoading = !builds
5452
const buildsByDate = groupBuildsByDate(builds)
5553

5654
return (
57-
<TableContainer className={className}>
55+
<TableContainer>
5856
<Table data-testid="builds-table" aria-describedby="builds table">
5957
<TableBody>
6058
{isLoading && <TableLoader />}

0 commit comments

Comments
 (0)