Skip to content

Commit 690ba66

Browse files
feat: Add metadata support to the UI (#3431)
1 parent 53400c6 commit 690ba66

File tree

3 files changed

+127
-10
lines changed

3 files changed

+127
-10
lines changed
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
import IconButton from "@material-ui/core/IconButton"
2+
import { makeStyles } from "@material-ui/core/styles"
3+
import Tooltip from "@material-ui/core/Tooltip"
4+
import VisibilityOffOutlined from "@material-ui/icons/VisibilityOffOutlined"
5+
import VisibilityOutlined from "@material-ui/icons/VisibilityOutlined"
6+
import { WorkspaceResource } from "api/typesGenerated"
7+
import { FC, useState } from "react"
8+
import { TableCellData, TableCellDataPrimary } from "../TableCellData/TableCellData"
9+
import { ResourceAvatar } from "./ResourceAvatar"
10+
11+
const Language = {
12+
showLabel: "Show value",
13+
hideLabel: "Hide value",
14+
}
15+
16+
const SensitiveValue: React.FC<{ value: string }> = ({ value }) => {
17+
const [shouldDisplay, setShouldDisplay] = useState(false)
18+
const styles = useStyles()
19+
const displayValue = shouldDisplay ? value : "••••••••"
20+
const buttonLabel = shouldDisplay ? Language.hideLabel : Language.showLabel
21+
const icon = shouldDisplay ? <VisibilityOffOutlined /> : <VisibilityOutlined />
22+
23+
return (
24+
<div className={styles.sensitiveValue}>
25+
{displayValue}
26+
<Tooltip title={buttonLabel}>
27+
<IconButton
28+
className={styles.button}
29+
onClick={() => {
30+
setShouldDisplay((value) => !value)
31+
}}
32+
size="small"
33+
aria-label={buttonLabel}
34+
>
35+
{icon}
36+
</IconButton>
37+
</Tooltip>
38+
</div>
39+
)
40+
}
41+
42+
export interface ResourceAvatarDataProps {
43+
resource: WorkspaceResource
44+
}
45+
46+
export const ResourceAvatarData: FC<ResourceAvatarDataProps> = ({ resource }) => {
47+
const styles = useStyles()
48+
49+
return (
50+
<div className={styles.root}>
51+
<div className={styles.avatarWrapper}>
52+
<ResourceAvatar type={resource.type} />
53+
</div>
54+
55+
<TableCellData>
56+
<TableCellDataPrimary highlight>{resource.name}</TableCellDataPrimary>
57+
<div className={styles.data}>
58+
{resource.metadata?.map((metadata) => (
59+
<div key={metadata.key} className={styles.dataRow}>
60+
<strong>{metadata.key}:</strong>
61+
{metadata.sensitive ? (
62+
<SensitiveValue value={metadata.value} />
63+
) : (
64+
<div>{metadata.value}</div>
65+
)}
66+
</div>
67+
))}
68+
</div>
69+
</TableCellData>
70+
</div>
71+
)
72+
}
73+
74+
const useStyles = makeStyles((theme) => ({
75+
root: {
76+
display: "flex",
77+
},
78+
79+
avatarWrapper: {
80+
marginRight: theme.spacing(3),
81+
paddingTop: theme.spacing(0.5),
82+
},
83+
84+
data: {
85+
color: theme.palette.text.secondary,
86+
fontSize: 14,
87+
marginTop: theme.spacing(0.75),
88+
display: "grid",
89+
gridAutoFlow: "row",
90+
whiteSpace: "nowrap",
91+
gap: theme.spacing(0.75),
92+
},
93+
94+
dataRow: {
95+
display: "flex",
96+
alignItems: "center",
97+
98+
"& strong": {
99+
marginRight: theme.spacing(1),
100+
},
101+
},
102+
103+
sensitiveValue: {
104+
display: "flex",
105+
alignItems: "center",
106+
},
107+
108+
button: {
109+
marginLeft: theme.spacing(0.5),
110+
color: "inherit",
111+
112+
"& .MuiSvgIcon-root": {
113+
width: 16,
114+
height: 16,
115+
},
116+
},
117+
}))

site/src/components/Resources/Resources.tsx

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import useTheme from "@material-ui/styles/useTheme"
99
import { ErrorSummary } from "components/ErrorSummary/ErrorSummary"
1010
import { FC } from "react"
1111
import { Workspace, WorkspaceResource } from "../../api/typesGenerated"
12-
import { AvatarData } from "../../components/AvatarData/AvatarData"
1312
import { getDisplayAgentStatus } from "../../util/workspace"
1413
import { AppLink } from "../AppLink/AppLink"
1514
import { SSHButton } from "../SSHButton/SSHButton"
@@ -18,7 +17,7 @@ import { TableHeaderRow } from "../TableHeaders/TableHeaders"
1817
import { TerminalLink } from "../TerminalLink/TerminalLink"
1918
import { AgentHelpTooltip } from "../Tooltips/AgentHelpTooltip"
2019
import { ResourcesHelpTooltip } from "../Tooltips/ResourcesHelpTooltip"
21-
import { ResourceAvatar } from "./ResourceAvatar"
20+
import { ResourceAvatarData } from "./ResourceAvatarData"
2221

2322
const Language = {
2423
resources: "Resources",
@@ -73,14 +72,7 @@ export const Resources: FC<ResourcesProps> = ({
7372
/* We need to initialize the agents to display the resource */
7473
}
7574
const agents = resource.agents ?? [null]
76-
const resourceName = (
77-
<AvatarData
78-
avatar={<ResourceAvatar type={resource.type} />}
79-
title={resource.name}
80-
subtitle={resource.type}
81-
highlightTitle
82-
/>
83-
)
75+
const resourceName = <ResourceAvatarData resource={resource} />
8476

8577
return agents.map((agent, agentIndex) => {
8678
{

site/src/testHelpers/entities.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,12 +287,20 @@ export const MockWorkspaceResource: TypesGen.WorkspaceResource = {
287287
name: "a-workspace-resource",
288288
type: "google_compute_disk",
289289
workspace_transition: "start",
290+
metadata: [
291+
{ key: "type", value: "a-workspace-resource", sensitive: false },
292+
{ key: "api_key", value: "12345678", sensitive: true },
293+
],
290294
}
291295

292296
export const MockWorkspaceResource2 = {
293297
...MockWorkspaceResource,
294298
id: "test-workspace-resource-2",
295299
name: "another-workspace-resource",
300+
metadata: [
301+
{ key: "type", value: "google_compute_disk", sensitive: false },
302+
{ key: "size", value: "32GB", sensitive: false },
303+
],
296304
}
297305

298306
export const MockUserAgent: Types.UserAgent = {

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy