Skip to content

Commit ad60b38

Browse files
committed
Replace table
1 parent a1b1f7f commit ad60b38

File tree

1 file changed

+20
-218
lines changed

1 file changed

+20
-218
lines changed

site/src/components/Resources/Resources.tsx

Lines changed: 20 additions & 218 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,12 @@
11
import Button from "@material-ui/core/Button"
2-
import { makeStyles, Theme } from "@material-ui/core/styles"
3-
import Table from "@material-ui/core/Table"
4-
import TableBody from "@material-ui/core/TableBody"
5-
import TableCell from "@material-ui/core/TableCell"
6-
import TableContainer from "@material-ui/core/TableContainer"
7-
import TableHead from "@material-ui/core/TableHead"
8-
import TableRow from "@material-ui/core/TableRow"
2+
import { makeStyles } from "@material-ui/core/styles"
93
import { Skeleton } from "@material-ui/lab"
10-
import useTheme from "@material-ui/styles/useTheme"
114
import {
125
CloseDropdown,
136
OpenDropdown,
147
} from "components/DropdownArrows/DropdownArrows"
158
import { PortForwardButton } from "components/PortForwardButton/PortForwardButton"
16-
import { TableCellDataPrimary } from "components/TableCellData/TableCellData"
179
import { FC, useState } from "react"
18-
import { getDisplayAgentStatus, getDisplayVersionStatus } from "util/workspace"
1910
import {
2011
BuildInfoResponse,
2112
DERPRegion,
@@ -26,28 +17,27 @@ import {
2617
import { AppLink } from "../AppLink/AppLink"
2718
import { SSHButton } from "../SSHButton/SSHButton"
2819
import { Stack } from "../Stack/Stack"
29-
import { TableHeaderRow } from "../TableHeaders/TableHeaders"
3020
import { TerminalLink } from "../TerminalLink/TerminalLink"
31-
import { AgentHelpTooltip } from "../Tooltips/AgentHelpTooltip"
32-
import { AgentOutdatedTooltip } from "../Tooltips/AgentOutdatedTooltip"
33-
import { ResourcesHelpTooltip } from "../Tooltips/ResourcesHelpTooltip"
34-
import { ResourceAgentLatency } from "./ResourceAgentLatency"
35-
import { ResourceAvatarData } from "./ResourceAvatarData"
3621
import { AlertBanner } from "components/AlertBanner/AlertBanner"
3722
import { ResourceAvatar } from "./ResourceAvatar"
3823
import { SensitiveValue } from "./SensitiveValue"
3924
import { AgentLatency } from "./AgentLatency"
4025

41-
const Language = {
42-
resources: "Resources",
43-
resourceLabel: "Resource",
44-
agentsLabel: "Agents",
45-
agentLabel: "Agent",
46-
statusLabel: "status: ",
47-
versionLabel: "version: ",
48-
osLabel: "os: ",
49-
}
26+
const getLatency = (agent: WorkspaceAgent) => {
27+
// Find the right latency to display
28+
const latencyValues = Object.values(agent.latency ?? {})
29+
const latency =
30+
latencyValues.find((derp) => derp.preferred) ??
31+
// Accessing an array index can return undefined as well
32+
// for some reason TS does not handle that
33+
(latencyValues[0] as DERPRegion | undefined)
34+
35+
if (!latency) {
36+
return undefined
37+
}
5038

39+
return latency
40+
}
5141
interface ResourcesProps {
5242
resources: WorkspaceResource[]
5343
getResourcesError?: Error | unknown
@@ -63,50 +53,24 @@ export const Resources: FC<React.PropsWithChildren<ResourcesProps>> = ({
6353
getResourcesError,
6454
workspace,
6555
canUpdateWorkspace,
66-
buildInfo,
6756
hideSSHButton,
6857
applicationsHost,
6958
}) => {
7059
const styles = useStyles()
71-
const theme: Theme = useTheme()
72-
const serverVersion = buildInfo?.version || ""
7360
const [shouldDisplayHideResources, setShouldDisplayHideResources] =
7461
useState(false)
7562
const displayResources = shouldDisplayHideResources
7663
? resources
7764
: resources.filter((resource) => !resource.hide)
7865
const hasHideResources = resources.some((r) => r.hide)
7966

80-
const getDisplayLatency = (agent: WorkspaceAgent) => {
81-
// Find the right latency to display
82-
const latencyValues = Object.values(agent.latency ?? {})
83-
const latency =
84-
latencyValues.find((derp) => derp.preferred) ??
85-
// Accessing an array index can return undefined as well
86-
// for some reason TS does not handle that
87-
(latencyValues[0] as DERPRegion | undefined)
88-
89-
if (!latency) {
90-
return undefined
91-
}
92-
93-
// Get the color
94-
let color = theme.palette.success.light
95-
if (latency.latency_ms >= 150 && latency.latency_ms < 300) {
96-
color = theme.palette.warning.light
97-
} else if (latency.latency_ms >= 300) {
98-
color = theme.palette.error.light
99-
}
100-
101-
return {
102-
...latency,
103-
color,
104-
}
67+
if (getResourcesError) {
68+
return <AlertBanner severity="error" error={getResourcesError} />
10569
}
10670

10771
return (
108-
<Stack direction="column" spacing={1}>
109-
{resources.map((resource) => {
72+
<Stack direction="column" spacing={2}>
73+
{displayResources.map((resource) => {
11074
// Type is already displayed on top of the resource name
11175
const metadataToDisplay =
11276
resource.metadata?.filter((data) => data.key !== "type") ?? []
@@ -144,7 +108,7 @@ export const Resources: FC<React.PropsWithChildren<ResourcesProps>> = ({
144108

145109
<div>
146110
{resource.agents?.map((agent) => {
147-
const latency = getDisplayLatency(agent)
111+
const latency = getLatency(agent)
148112

149113
return (
150114
<Stack
@@ -226,163 +190,6 @@ export const Resources: FC<React.PropsWithChildren<ResourcesProps>> = ({
226190
)
227191
})}
228192

229-
<div aria-label={Language.resources} className={styles.wrapper}>
230-
{getResourcesError ? (
231-
<AlertBanner severity="error" error={getResourcesError} />
232-
) : (
233-
<TableContainer className={styles.tableContainer}>
234-
<Table>
235-
<TableHead>
236-
<TableHeaderRow>
237-
<TableCell>
238-
<Stack direction="row" spacing={0.5} alignItems="center">
239-
{Language.resourceLabel}
240-
<ResourcesHelpTooltip />
241-
</Stack>
242-
</TableCell>
243-
<TableCell className={styles.agentColumn}>
244-
<Stack direction="row" spacing={0.5} alignItems="center">
245-
{Language.agentLabel}
246-
<AgentHelpTooltip />
247-
</Stack>
248-
</TableCell>
249-
{canUpdateWorkspace && <TableCell></TableCell>}
250-
</TableHeaderRow>
251-
</TableHead>
252-
<TableBody>
253-
{displayResources.map((resource) => {
254-
{
255-
/* We need to initialize the agents to display the resource */
256-
}
257-
const agents = resource.agents ?? [null]
258-
const resourceName = (
259-
<ResourceAvatarData resource={resource} />
260-
)
261-
262-
return agents.map((agent, agentIndex) => {
263-
{
264-
/* If there is no agent, just display the resource name */
265-
}
266-
if (
267-
!agent ||
268-
workspace.latest_build.transition === "stop"
269-
) {
270-
return (
271-
<TableRow key={`${resource.id}-${agentIndex}`}>
272-
<TableCell>{resourceName}</TableCell>
273-
<TableCell colSpan={3}></TableCell>
274-
</TableRow>
275-
)
276-
}
277-
const { displayVersion, outdated } =
278-
getDisplayVersionStatus(agent.version, serverVersion)
279-
const agentStatus = getDisplayAgentStatus(theme, agent)
280-
return (
281-
<TableRow key={`${resource.id}-${agent.id}`}>
282-
{/* We only want to display the name in the first row because we are using rowSpan */}
283-
{/* The rowspan should be the same than the number of agents */}
284-
{agentIndex === 0 && (
285-
<TableCell
286-
className={styles.resourceNameCell}
287-
rowSpan={agents.length}
288-
>
289-
{resourceName}
290-
</TableCell>
291-
)}
292-
293-
<TableCell className={styles.agentColumn}>
294-
<TableCellDataPrimary highlight>
295-
{agent.name}
296-
</TableCellDataPrimary>
297-
<div className={styles.data}>
298-
<div className={styles.dataRow}>
299-
<strong>{Language.statusLabel}</strong>
300-
<span
301-
style={{ color: agentStatus.color }}
302-
className={styles.status}
303-
>
304-
{agentStatus.status}
305-
</span>
306-
</div>
307-
<div className={styles.dataRow}>
308-
<strong>{Language.osLabel}</strong>
309-
<span className={styles.operatingSystem}>
310-
{agent.operating_system}
311-
</span>
312-
</div>
313-
<div className={styles.dataRow}>
314-
<strong>{Language.versionLabel}</strong>
315-
<span className={styles.agentVersion}>
316-
{displayVersion}
317-
</span>
318-
<AgentOutdatedTooltip outdated={outdated} />
319-
</div>
320-
<div className={styles.dataRow}>
321-
<ResourceAgentLatency latency={agent.latency} />
322-
</div>
323-
</div>
324-
</TableCell>
325-
<TableCell>
326-
<div className={styles.accessLinks}>
327-
{canUpdateWorkspace &&
328-
agent.status === "connected" && (
329-
<>
330-
{applicationsHost !== undefined && (
331-
<PortForwardButton
332-
host={applicationsHost}
333-
workspaceName={workspace.name}
334-
agentId={agent.id}
335-
agentName={agent.name}
336-
username={workspace.owner_name}
337-
/>
338-
)}
339-
{!hideSSHButton && (
340-
<SSHButton
341-
workspaceName={workspace.name}
342-
agentName={agent.name}
343-
/>
344-
)}
345-
<TerminalLink
346-
workspaceName={workspace.name}
347-
agentName={agent.name}
348-
userName={workspace.owner_name}
349-
/>
350-
{agent.apps.map((app) => (
351-
<AppLink
352-
key={app.name}
353-
appsHost={applicationsHost}
354-
appIcon={app.icon}
355-
appName={app.name}
356-
appCommand={app.command}
357-
appSubdomain={app.subdomain}
358-
appSharingLevel={app.sharing_level}
359-
username={workspace.owner_name}
360-
workspaceName={workspace.name}
361-
agentName={agent.name}
362-
health={app.health}
363-
/>
364-
))}
365-
</>
366-
)}
367-
{canUpdateWorkspace &&
368-
agent.status === "connecting" && (
369-
<>
370-
<Skeleton width={80} height={60} />
371-
<Skeleton width={120} height={60} />
372-
</>
373-
)}
374-
</div>
375-
</TableCell>
376-
</TableRow>
377-
)
378-
})
379-
})}
380-
</TableBody>
381-
</Table>
382-
</TableContainer>
383-
)}
384-
</div>
385-
386193
{hasHideResources && (
387194
<div className={styles.buttonWrapper}>
388195
<Button
@@ -408,11 +215,6 @@ export const Resources: FC<React.PropsWithChildren<ResourcesProps>> = ({
408215
}
409216

410217
const useStyles = makeStyles((theme) => ({
411-
wrapper: {
412-
borderRadius: theme.shape.borderRadius,
413-
border: `1px solid ${theme.palette.divider}`,
414-
},
415-
416218
tableContainer: {
417219
border: 0,
418220
},

0 commit comments

Comments
 (0)