Skip to content

Commit 47d3161

Browse files
authored
fix: give more room to lonely resource metadata items (coder#9832)
1 parent 3757005 commit 47d3161

File tree

8 files changed

+337
-152
lines changed

8 files changed

+337
-152
lines changed

site/src/components/Resources/ResourceCard.stories.tsx

+36-59
Original file line numberDiff line numberDiff line change
@@ -8,41 +8,14 @@ import { AgentRow } from "./AgentRow";
88
import { ResourceCard } from "./ResourceCard";
99
import { ProxyContext, getPreferredProxy } from "contexts/ProxyContext";
1010
import type { Meta, StoryObj } from "@storybook/react";
11+
import { type WorkspaceAgent } from "api/typesGenerated";
1112

1213
const meta: Meta<typeof ResourceCard> = {
13-
title: "components/ResourceCard",
14+
title: "components/Resources/ResourceCard",
1415
component: ResourceCard,
1516
args: {
1617
resource: MockWorkspaceResource,
17-
agentRow: (agent) => (
18-
<ProxyContext.Provider
19-
value={{
20-
proxyLatencies: MockProxyLatencies,
21-
proxy: getPreferredProxy([], undefined),
22-
proxies: [],
23-
isLoading: false,
24-
isFetched: true,
25-
setProxy: () => {
26-
return;
27-
},
28-
clearProxy: () => {
29-
return;
30-
},
31-
refetchProxyLatencies: (): Date => {
32-
return new Date();
33-
},
34-
}}
35-
>
36-
<AgentRow
37-
showApps
38-
key={agent.id}
39-
agent={agent}
40-
workspace={MockWorkspace}
41-
serverVersion=""
42-
onUpdateAgent={action("updateAgent")}
43-
/>
44-
</ProxyContext.Provider>
45-
),
18+
agentRow: getAgentRow,
4619
},
4720
};
4821

@@ -96,34 +69,38 @@ export const BunchOfMetadata: Story = {
9669
},
9770
],
9871
},
99-
agentRow: (agent) => (
100-
<ProxyContext.Provider
101-
value={{
102-
proxyLatencies: MockProxyLatencies,
103-
proxy: getPreferredProxy([], undefined),
104-
proxies: [],
105-
isLoading: false,
106-
isFetched: true,
107-
setProxy: () => {
108-
return;
109-
},
110-
clearProxy: () => {
111-
return;
112-
},
113-
refetchProxyLatencies: (): Date => {
114-
return new Date();
115-
},
116-
}}
117-
>
118-
<AgentRow
119-
showApps
120-
key={agent.id}
121-
agent={agent}
122-
workspace={MockWorkspace}
123-
serverVersion=""
124-
onUpdateAgent={action("updateAgent")}
125-
/>
126-
</ProxyContext.Provider>
127-
),
72+
agentRow: getAgentRow,
12873
},
12974
};
75+
76+
function getAgentRow(agent: WorkspaceAgent): JSX.Element {
77+
return (
78+
<ProxyContext.Provider
79+
value={{
80+
proxyLatencies: MockProxyLatencies,
81+
proxy: getPreferredProxy([], undefined),
82+
proxies: [],
83+
isLoading: false,
84+
isFetched: true,
85+
setProxy: () => {
86+
return;
87+
},
88+
clearProxy: () => {
89+
return;
90+
},
91+
refetchProxyLatencies: (): Date => {
92+
return new Date();
93+
},
94+
}}
95+
>
96+
<AgentRow
97+
showApps
98+
key={agent.id}
99+
agent={agent}
100+
workspace={MockWorkspace}
101+
serverVersion=""
102+
onUpdateAgent={action("updateAgent")}
103+
/>
104+
</ProxyContext.Provider>
105+
);
106+
}

site/src/components/Resources/ResourceCard.tsx

+59-53
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ import {
1010
} from "components/DropdownArrows/DropdownArrows";
1111
import IconButton from "@mui/material/IconButton";
1212
import Tooltip from "@mui/material/Tooltip";
13-
import { Maybe } from "components/Conditionals/Maybe";
1413
import { CopyableValue } from "components/CopyableValue/CopyableValue";
14+
import { type Theme } from "@mui/material/styles";
1515

1616
export interface ResourceCardProps {
1717
resource: WorkspaceResource;
@@ -21,12 +21,20 @@ export interface ResourceCardProps {
2121
export const ResourceCard: FC<ResourceCardProps> = ({ resource, agentRow }) => {
2222
const [shouldDisplayAllMetadata, setShouldDisplayAllMetadata] =
2323
useState(false);
24-
const styles = useStyles();
2524
const metadataToDisplay = resource.metadata ?? [];
2625
const visibleMetadata = shouldDisplayAllMetadata
2726
? metadataToDisplay
2827
: metadataToDisplay.slice(0, 4);
2928

29+
// Add one to `metadataLength` if the resource has a cost, and hide one
30+
// additional metadata item, because cost is displayed in the same grid.
31+
let metadataLength = resource.metadata?.length ?? 0;
32+
if (resource.daily_cost > 0) {
33+
metadataLength += 1;
34+
visibleMetadata.pop();
35+
}
36+
const styles = useStyles({ metadataLength });
37+
3038
return (
3139
<div key={resource.id} className={`${styles.resourceCard} resource-card`}>
3240
<Stack
@@ -49,57 +57,52 @@ export const ResourceCard: FC<ResourceCardProps> = ({ resource, agentRow }) => {
4957
</div>
5058
</Stack>
5159

52-
<Stack alignItems="flex-start" direction="row" spacing={5}>
53-
<div className={styles.metadataHeader}>
54-
{resource.daily_cost > 0 && (
55-
<div className={styles.metadata}>
56-
<div className={styles.metadataLabel}>
57-
<b>cost</b>
58-
</div>
60+
<div className={styles.metadataHeader}>
61+
{resource.daily_cost > 0 && (
62+
<div className={styles.metadata}>
63+
<div className={styles.metadataLabel}>
64+
<b>cost</b>
65+
</div>
66+
<div className={styles.metadataValue}>{resource.daily_cost}</div>
67+
</div>
68+
)}
69+
{visibleMetadata.map((meta) => {
70+
return (
71+
<div className={styles.metadata} key={meta.key}>
72+
<div className={styles.metadataLabel}>{meta.key}</div>
5973
<div className={styles.metadataValue}>
60-
{resource.daily_cost}
74+
{meta.sensitive ? (
75+
<SensitiveValue value={meta.value} />
76+
) : (
77+
<CopyableValue value={meta.value}>
78+
{meta.value}
79+
</CopyableValue>
80+
)}
6181
</div>
6282
</div>
63-
)}
64-
{visibleMetadata.map((meta) => {
65-
return (
66-
<div className={styles.metadata} key={meta.key}>
67-
<div className={styles.metadataLabel}>{meta.key}</div>
68-
<div className={styles.metadataValue}>
69-
{meta.sensitive ? (
70-
<SensitiveValue value={meta.value} />
71-
) : (
72-
<CopyableValue value={meta.value}>
73-
{meta.value}
74-
</CopyableValue>
75-
)}
76-
</div>
77-
</div>
78-
);
79-
})}
80-
</div>
81-
82-
<Maybe condition={metadataToDisplay.length > 4}>
83-
<Tooltip
84-
title={
85-
shouldDisplayAllMetadata ? "Hide metadata" : "Show all metadata"
86-
}
83+
);
84+
})}
85+
</div>
86+
{metadataLength > 4 && (
87+
<Tooltip
88+
title={
89+
shouldDisplayAllMetadata ? "Hide metadata" : "Show all metadata"
90+
}
91+
>
92+
<IconButton
93+
onClick={() => {
94+
setShouldDisplayAllMetadata((value) => !value);
95+
}}
96+
size="large"
8797
>
88-
<IconButton
89-
onClick={() => {
90-
setShouldDisplayAllMetadata((value) => !value);
91-
}}
92-
size="large"
93-
>
94-
{shouldDisplayAllMetadata ? (
95-
<CloseDropdown margin={false} />
96-
) : (
97-
<OpenDropdown margin={false} />
98-
)}
99-
</IconButton>
100-
</Tooltip>
101-
</Maybe>
102-
</Stack>
98+
{shouldDisplayAllMetadata ? (
99+
<CloseDropdown margin={false} />
100+
) : (
101+
<OpenDropdown margin={false} />
102+
)}
103+
</IconButton>
104+
</Tooltip>
105+
)}
103106
</Stack>
104107

105108
{resource.agents && resource.agents.length > 0 && (
@@ -109,7 +112,7 @@ export const ResourceCard: FC<ResourceCardProps> = ({ resource, agentRow }) => {
109112
);
110113
};
111114

112-
const useStyles = makeStyles((theme) => ({
115+
const useStyles = makeStyles<Theme, { metadataLength: number }>((theme) => ({
113116
resourceCard: {
114117
background: theme.palette.background.paper,
115118
borderRadius: theme.shape.borderRadius,
@@ -141,12 +144,15 @@ const useStyles = makeStyles((theme) => ({
141144
},
142145
},
143146

144-
metadataHeader: {
147+
metadataHeader: (props) => ({
148+
flexGrow: 2,
145149
display: "grid",
146-
gridTemplateColumns: "repeat(4, minmax(0, 1fr))",
150+
gridTemplateColumns: `repeat(${
151+
props.metadataLength === 1 ? 1 : 4
152+
}, minmax(0, 1fr))`,
147153
gap: theme.spacing(5),
148154
rowGap: theme.spacing(3),
149-
},
155+
}),
150156

151157
metadata: {
152158
...theme.typography.body2,

0 commit comments

Comments
 (0)