Skip to content

Commit f02561a

Browse files
chore(site): minor refactor to the resource metadata code (#11746)
1 parent 5388a1b commit f02561a

File tree

3 files changed

+148
-84
lines changed

3 files changed

+148
-84
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import { MockWorkspaceResource } from "testHelpers/entities";
2+
import type { Meta, StoryObj } from "@storybook/react";
3+
import { ResourceMetadata } from "./ResourceMetadata";
4+
5+
const meta: Meta<typeof ResourceMetadata> = {
6+
title: "pages/WorkspacePage/ResourceMetadata",
7+
component: ResourceMetadata,
8+
};
9+
10+
export default meta;
11+
type Story = StoryObj<typeof ResourceMetadata>;
12+
13+
export const Markdown: Story = {
14+
args: {
15+
resource: {
16+
...MockWorkspaceResource,
17+
metadata: [
18+
{ key: "text", value: "hello", sensitive: false },
19+
{ key: "link", value: "[hello](#)", sensitive: false },
20+
{ key: "b/i", value: "_hello_, **friend**!", sensitive: false },
21+
{ key: "coder", value: "`beep boop`", sensitive: false },
22+
],
23+
},
24+
},
25+
};
26+
27+
export const WithLongStrings: Story = {
28+
args: {
29+
resource: {
30+
...MockWorkspaceResource,
31+
metadata: [
32+
{
33+
key: "xxxxxxxxxxxx",
34+
value: "14",
35+
sensitive: false,
36+
},
37+
{
38+
key: "Long",
39+
value: "The quick brown fox jumped over the lazy dog",
40+
sensitive: false,
41+
},
42+
{
43+
key: "Really long",
44+
value:
45+
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
46+
sensitive: false,
47+
},
48+
],
49+
},
50+
},
51+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
import { MemoizedInlineMarkdown } from "components/Markdown/Markdown";
2+
import { SensitiveValue } from "components/Resources/SensitiveValue";
3+
import { CopyableValue } from "components/CopyableValue/CopyableValue";
4+
import { WorkspaceResource } from "api/typesGenerated";
5+
import { Children, FC, HTMLAttributes, PropsWithChildren } from "react";
6+
import { Interpolation, Theme } from "@emotion/react";
7+
8+
type ResourceMetadataProps = Omit<HTMLAttributes<HTMLElement>, "resource"> & {
9+
resource: WorkspaceResource;
10+
};
11+
12+
export const ResourceMetadata: FC<ResourceMetadataProps> = ({
13+
resource,
14+
...headerProps
15+
}) => {
16+
const metadata = resource.metadata ? [...resource.metadata] : [];
17+
18+
if (resource.daily_cost > 0) {
19+
metadata.push({
20+
key: "Daily cost",
21+
value: resource.daily_cost.toString(),
22+
sensitive: false,
23+
});
24+
}
25+
26+
if (metadata.length === 0) {
27+
return null;
28+
}
29+
30+
return (
31+
<header css={styles.root} {...headerProps}>
32+
{metadata.map((meta) => {
33+
return (
34+
<div css={styles.item} key={meta.key}>
35+
<div css={styles.value}>
36+
{meta.sensitive ? (
37+
<SensitiveValue value={meta.value} />
38+
) : (
39+
<MemoizedInlineMarkdown components={{ p: MetaValue }}>
40+
{meta.value}
41+
</MemoizedInlineMarkdown>
42+
)}
43+
</div>
44+
<div css={styles.label}>{meta.key}</div>
45+
</div>
46+
);
47+
})}
48+
</header>
49+
);
50+
};
51+
52+
const MetaValue = ({ children }: PropsWithChildren) => {
53+
const childrenArray = Children.toArray(children);
54+
if (childrenArray.every((child) => typeof child === "string")) {
55+
return (
56+
<CopyableValue value={childrenArray.join("")}>{children}</CopyableValue>
57+
);
58+
}
59+
return <>{children}</>;
60+
};
61+
62+
const styles = {
63+
root: (theme) => ({
64+
padding: 24,
65+
display: "flex",
66+
flexWrap: "wrap",
67+
gap: 48,
68+
rowGap: 24,
69+
marginBottom: 24,
70+
fontSize: 14,
71+
background: `linear-gradient(180deg, ${theme.palette.background.default} 0%, rgba(0, 0, 0, 0) 100%)`,
72+
}),
73+
74+
item: () => ({
75+
lineHeight: "1.5",
76+
}),
77+
78+
label: (theme) => ({
79+
fontSize: 13,
80+
color: theme.palette.text.secondary,
81+
textOverflow: "ellipsis",
82+
overflow: "hidden",
83+
whiteSpace: "nowrap",
84+
}),
85+
86+
value: () => ({
87+
textOverflow: "ellipsis",
88+
overflow: "hidden",
89+
whiteSpace: "nowrap",
90+
}),
91+
} satisfies Record<string, Interpolation<Theme>>;

site/src/pages/WorkspacePage/Workspace.tsx

+6-84
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { type Interpolation, type Theme } from "@emotion/react";
22
import Button from "@mui/material/Button";
33
import AlertTitle from "@mui/material/AlertTitle";
4-
import { PropsWithChildren, type FC, Children } from "react";
4+
import { type FC } from "react";
55
import { useNavigate } from "react-router-dom";
66
import type * as TypesGen from "api/typesGenerated";
77
import { Alert, AlertDetail } from "components/Alert/Alert";
@@ -21,9 +21,7 @@ import HubOutlined from "@mui/icons-material/HubOutlined";
2121
import { ResourcesSidebar } from "./ResourcesSidebar";
2222
import { WorkspacePermissions } from "./permissions";
2323
import { resourceOptionValue, useResourcesNav } from "./useResourcesNav";
24-
import { MemoizedInlineMarkdown } from "components/Markdown/Markdown";
25-
import { SensitiveValue } from "components/Resources/SensitiveValue";
26-
import { CopyableValue } from "components/CopyableValue/CopyableValue";
24+
import { ResourceMetadata } from "./ResourceMetadata";
2725

2826
export interface WorkspaceProps {
2927
handleStart: (buildParameters?: TypesGen.WorkspaceBuildParameter[]) => void;
@@ -187,7 +185,10 @@ export const Workspace: FC<WorkspaceProps> = ({
187185
<div css={styles.content}>
188186
<div css={styles.dotBackground}>
189187
{selectedResource && (
190-
<WorkspaceResourceData resource={selectedResource} />
188+
<ResourceMetadata
189+
resource={selectedResource}
190+
css={{ margin: "-48px 0 24px -48px" }}
191+
/>
191192
)}
192193
<div
193194
css={{
@@ -282,55 +283,6 @@ export const Workspace: FC<WorkspaceProps> = ({
282283
);
283284
};
284285

285-
const WorkspaceResourceData: FC<{ resource: TypesGen.WorkspaceResource }> = ({
286-
resource,
287-
}) => {
288-
const metadata = resource.metadata ? [...resource.metadata] : [];
289-
290-
if (resource.daily_cost > 0) {
291-
metadata.push({
292-
key: "Daily cost",
293-
value: resource.daily_cost.toString(),
294-
sensitive: false,
295-
});
296-
}
297-
298-
if (metadata.length === 0) {
299-
return null;
300-
}
301-
302-
return (
303-
<header css={styles.resourceData}>
304-
{metadata.map((meta) => {
305-
return (
306-
<div css={styles.resourceDataItem} key={meta.key}>
307-
<div css={styles.resourceDataItemValue}>
308-
{meta.sensitive ? (
309-
<SensitiveValue value={meta.value} />
310-
) : (
311-
<MemoizedInlineMarkdown components={{ p: MetaValue }}>
312-
{meta.value}
313-
</MemoizedInlineMarkdown>
314-
)}
315-
</div>
316-
<div css={styles.resourceDataItemLabel}>{meta.key}</div>
317-
</div>
318-
);
319-
})}
320-
</header>
321-
);
322-
};
323-
324-
const MetaValue = ({ children }: PropsWithChildren) => {
325-
const childrenArray = Children.toArray(children);
326-
if (childrenArray.every((child) => typeof child === "string")) {
327-
return (
328-
<CopyableValue value={childrenArray.join("")}>{children}</CopyableValue>
329-
);
330-
}
331-
return <>{children}</>;
332-
};
333-
334286
const countAgents = (resource: TypesGen.WorkspaceResource) => {
335287
return resource.agents ? resource.agents.length : 0;
336288
};
@@ -365,34 +317,4 @@ const styles = {
365317
flexDirection: "column",
366318
},
367319
}),
368-
369-
resourceData: (theme) => ({
370-
padding: 24,
371-
margin: "-48px 0 0 -48px",
372-
display: "flex",
373-
flexWrap: "wrap",
374-
gap: 48,
375-
rowGap: 24,
376-
marginBottom: 24,
377-
fontSize: 14,
378-
background: `linear-gradient(180deg, ${theme.palette.background.default} 0%, rgba(0, 0, 0, 0) 100%)`,
379-
}),
380-
381-
resourceDataItem: () => ({
382-
lineHeight: "1.5",
383-
}),
384-
385-
resourceDataItemLabel: (theme) => ({
386-
fontSize: 13,
387-
color: theme.palette.text.secondary,
388-
textOverflow: "ellipsis",
389-
overflow: "hidden",
390-
whiteSpace: "nowrap",
391-
}),
392-
393-
resourceDataItemValue: () => ({
394-
textOverflow: "ellipsis",
395-
overflow: "hidden",
396-
whiteSpace: "nowrap",
397-
}),
398320
} satisfies Record<string, Interpolation<Theme>>;

0 commit comments

Comments
 (0)