Skip to content

Commit f6cc3d7

Browse files
fix: collection for release (#697)
1 parent 5835d79 commit f6cc3d7

File tree

5 files changed

+78
-28
lines changed

5 files changed

+78
-28
lines changed

src/components/MetadataCards.tsx

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { Codesnippet } from "./CodeSnippet";
1010
import { CollapsibleCard } from "./CollapsibleCard";
1111
import { KeyValue } from "./KeyValue";
1212
import { NestedCollapsible } from "./NestedCollapsible";
13+
import { isUrl } from "../lib/url";
1314

1415
type Props = { metadata: MetadataMap };
1516

@@ -18,7 +19,11 @@ export function MetadataCards({ metadata }: Props) {
1819
return (
1920
<>
2021
{dictMetadata.map((metadataObj, idx) => (
21-
<NestedCollapsible key={idx} data={metadataObj} title={Object.keys({ metadataObj })[0]} />
22+
<NestedCollapsible
23+
key={idx}
24+
data={metadataObj as Record<string, unknown>}
25+
title={Object.keys({ metadataObj })[0]}
26+
/>
2227
))}
2328
</>
2429
);
@@ -55,9 +60,21 @@ export function UncategorizedCard({ metadata, title }: Props & { title?: string
5560
{(() => {
5661
if (isString(value) && regex.test(value)) {
5762
return <Codesnippet className="py-1" highlightCode code={value} />;
63+
}
64+
if (isString(value) && isUrl(value)) {
65+
return (
66+
<a
67+
className="underline transition-all duration-200 hover:decoration-transparent"
68+
href={value}
69+
target="_blank"
70+
rel="noopener noreferrer"
71+
>
72+
{value}
73+
</a>
74+
);
5875
} else {
5976
return (
60-
<div className="py-1">
77+
<div className="whitespace-normal">
6178
{isString(value) ? value : JSON.stringify(value)}
6279
</div>
6380
);

src/components/NestedCollapsible.tsx

Lines changed: 54 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
/* eslint-disable @typescript-eslint/no-explicit-any */
2-
import { renderAnyToString } from "@/lib/strings";
1+
import { isArray, isObject, isString } from "@/lib/type-guards";
2+
import { isUrl } from "@/lib/url";
33
import { CollapsibleHeaderProps } from "@zenml-io/react-component-library";
44
import {
55
Tooltip,
@@ -14,7 +14,7 @@ import { KeyValue } from "./KeyValue";
1414

1515
type Props = {
1616
intent?: CollapsibleHeaderProps["intent"];
17-
data?: { [key: string]: any };
17+
data?: { [key: string]: unknown };
1818
title: ReactNode;
1919
contentClassName?: string;
2020
className?: string;
@@ -30,15 +30,15 @@ export function NestedCollapsible({
3030
children,
3131
className
3232
}: PropsWithChildren<Props>) {
33-
const objects: { [key: string]: any } = {};
34-
const nonObjects: { [key: string]: any } = {};
35-
const arrays: { [key: string]: any } = {};
33+
const objects: { [key: string]: Record<string, unknown> } = {};
34+
const nonObjects: { [key: string]: unknown } = {};
35+
const arrays: { [key: string]: unknown[] } = {};
3636
const regex = /^<class\s+'.*'>$/;
3737

3838
for (const [key, value] of Object.entries(data || {})) {
39-
if (typeof value === "object" && value !== null && !Array.isArray(value)) {
40-
objects[key] = value;
41-
} else if (Array.isArray(value)) {
39+
if (isObject(value)) {
40+
objects[key] = value as Record<string, unknown>;
41+
} else if (isArray(value)) {
4242
arrays[key] = value;
4343
} else {
4444
nonObjects[key] = value;
@@ -74,14 +74,23 @@ export function NestedCollapsible({
7474
}
7575
value={
7676
<>
77-
{typeof value === "boolean" ? (
78-
<div className="py-1">{JSON.stringify(value)}</div>
79-
) : regex.test(value) ? (
77+
{isString(value) && regex.test(value) ? (
8078
<Codesnippet className="py-1" highlightCode code={value} />
8179
) : value === null ? (
82-
<div className="overflow-x-auto">null</div>
80+
<div>null</div>
81+
) : isString(value) && isUrl(value) ? (
82+
<a
83+
className="underline transition-all duration-200 hover:decoration-transparent"
84+
href={value}
85+
target="_blank"
86+
rel="noopener noreferrer"
87+
>
88+
{value}
89+
</a>
8390
) : (
84-
<div className="overflow-x-auto py-1">{value}</div>
91+
<div className="whitespace-normal">
92+
{isString(value) ? value : JSON.stringify(value)}
93+
</div>
8594
)}
8695
</>
8796
}
@@ -101,13 +110,11 @@ export function NestedCollapsible({
101110
);
102111
}
103112

104-
function RenderArray({ title, value }: { title: string; value: any }) {
105-
const simpleValues: any[] = value.filter(
106-
(val: any) => (!Array.isArray(val) && typeof val !== "object") || val === null
107-
);
108-
const nestedValues: any[] = value.filter(
109-
(val: any) => Array.isArray(val) || typeof val === "object"
113+
function RenderArray({ title, value }: { title: string; value: unknown[] }) {
114+
const simpleValues: unknown[] = value.filter(
115+
(val) => (!isArray(val) && !isObject(val)) || val === null
110116
);
117+
const nestedValues: unknown[] = value.filter((val) => isArray(val) || isObject);
111118

112119
return (
113120
<>
@@ -125,16 +132,40 @@ function RenderArray({ title, value }: { title: string; value: any }) {
125132
</Tooltip>
126133
</TooltipProvider>
127134
}
128-
value={<div className="py-1">{renderAnyToString(value)}</div>}
135+
value={
136+
<div className="py-1">
137+
{value === null ? (
138+
<div>null</div>
139+
) : isString(value) && isUrl(value) ? (
140+
<a
141+
className="underline transition-all duration-200 hover:decoration-transparent"
142+
href={value}
143+
target="_blank"
144+
rel="noopener noreferrer"
145+
>
146+
{value}
147+
</a>
148+
) : (
149+
<div className="whitespace-normal">
150+
{isString(value) ? value : JSON.stringify(value)}
151+
</div>
152+
)}
153+
</div>
154+
}
129155
/>
130156
))}
131157
</dl>
132158
)}
133159
{nestedValues.length > 0 && (
134160
<ul className="space-y-4">
135-
{nestedValues.map((val: any, index: number) => (
161+
{nestedValues.map((val, index: number) => (
136162
<li key={index}>
137-
<NestedCollapsible intent="secondary" key={index} title={index} data={val} />
163+
<NestedCollapsible
164+
intent="secondary"
165+
key={index}
166+
title={index}
167+
data={val as Record<string, Record<string, unknown> | unknown[]>}
168+
/>
138169
</li>
139170
))}
140171
</ul>

src/components/dag-visualizer/layout/real-data.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ function extractNodes(stepConfig: StepDict) {
3232
id: version.id,
3333
placeholderId,
3434
type: "artifact",
35-
data: { ...version, name: version.body?.artifact.name || outputName }
35+
data: { ...version, name: outputName }
3636
});
3737
});
3838
});

src/lib/url.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,7 @@ export function sanitizeUrl(url = "about:blank"): string {
3232
}
3333

3434
export const urlSchema = z.string().url();
35+
36+
export function isUrl(probe: string) {
37+
return urlSchema.safeParse(probe).success;
38+
}

src/types/pipeline-runs.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,13 @@ type ArtifactNodeDetails = ArtifactVersion & { name: string };
1515
export type ArtifactNode = {
1616
id: string;
1717
placeholderId: string;
18-
helperId?: string;
1918
type: "artifact";
2019
data: ArtifactNodeDetails;
2120
};
2221

2322
export type StepNode = {
2423
id: string;
2524
placeholderId: string;
26-
helperId?: string;
2725
type: "step";
2826
data: Step;
2927
};

0 commit comments

Comments
 (0)