From 127b0df7323c77b7acb931c40d6361e05705c335 Mon Sep 17 00:00:00 2001 From: Camiel van Schoonhoven Date: Mon, 23 Mar 2026 12:26:23 -0700 Subject: [PATCH] chore: Simplify IOCell --- .../ArtifactVisualizer/ArtifactVisualizer.tsx | 91 +++++++++-- .../ArtifactVisualizer/CsvVisualizer.tsx | 20 ++- .../ArtifactVisualizer/JsonVisualizer.tsx | 18 +- .../ArtifactVisualizer/TableVisualizer.tsx | 4 +- .../TaskOverview/IOSection/IOCell/IOCell.tsx | 154 +++++------------- 5 files changed, 145 insertions(+), 142 deletions(-) diff --git a/src/components/shared/ReactFlow/FlowCanvas/TaskNode/TaskOverview/IOSection/IOCell/ArtifactVisualizer/ArtifactVisualizer.tsx b/src/components/shared/ReactFlow/FlowCanvas/TaskNode/TaskOverview/IOSection/IOCell/ArtifactVisualizer/ArtifactVisualizer.tsx index 3221d2906..4098f852d 100644 --- a/src/components/shared/ReactFlow/FlowCanvas/TaskNode/TaskOverview/IOSection/IOCell/ArtifactVisualizer/ArtifactVisualizer.tsx +++ b/src/components/shared/ReactFlow/FlowCanvas/TaskNode/TaskOverview/IOSection/IOCell/ArtifactVisualizer/ArtifactVisualizer.tsx @@ -37,19 +37,19 @@ const VISUALIZABLE_TYPES = new Set([ "apacheparquet", ]); -interface ArtifactVisualizerProps { +type ArtifactVisualizerProps = { artifact: ArtifactNodeResponse; name: string; type: string; -} + value?: string; +}; const ArtifactVisualizer = ({ artifact, name, type, + value, }: ArtifactVisualizerProps) => { - const { backendUrl } = useBackend(); - const [isFullscreen, setIsFullscreen] = useState(false); const normalizedType = type?.toLowerCase().replace(/\s/g, "") ?? "text"; @@ -67,10 +67,20 @@ const ArtifactVisualizer = ({ return ( - + {value ? ( + + ) : ( + + )}
- + {value ? ( + + ) : ( + + )}
); }; +interface InlineContentProps { + type: string; + name: string; + value: string; + isFullscreen: boolean; +} + +const InlineContent = ({ + type, + name, + value, + isFullscreen, +}: InlineContentProps) => { + switch (type) { + case "csv": + return ( + + ); + case "tsv": + return ( + + ); + case "jsonobject": + case "jsonarray": + return ; + case "text": + default: + return ; + } +}; + interface PreviewContentProps { artifactId: string; type: string; - backendUrl: string; name: string; isFullscreen: boolean; } @@ -134,10 +190,11 @@ interface PreviewContentProps { const PreviewContent = ({ artifactId, type, - backendUrl, name, isFullscreen, }: PreviewContentProps) => { + const { backendUrl } = useBackend(); + const { data, isLoading, error } = useQuery({ queryKey: ["artifact-signed-url", artifactId], queryFn: () => getArtifactSignedUrl(artifactId, backendUrl), diff --git a/src/components/shared/ReactFlow/FlowCanvas/TaskNode/TaskOverview/IOSection/IOCell/ArtifactVisualizer/CsvVisualizer.tsx b/src/components/shared/ReactFlow/FlowCanvas/TaskNode/TaskOverview/IOSection/IOCell/ArtifactVisualizer/CsvVisualizer.tsx index 0a8be3582..b88c9d4dd 100644 --- a/src/components/shared/ReactFlow/FlowCanvas/TaskNode/TaskOverview/IOSection/IOCell/ArtifactVisualizer/CsvVisualizer.tsx +++ b/src/components/shared/ReactFlow/FlowCanvas/TaskNode/TaskOverview/IOSection/IOCell/ArtifactVisualizer/CsvVisualizer.tsx @@ -7,20 +7,25 @@ import { TWENTY_FOUR_HOURS_IN_MS } from "@/utils/constants"; import TableVisualizer from "./TableVisualizer"; import { parseCsvPreview } from "./utils"; -interface CsvVisualizerProps { - signedUrl: string; +type CsvVisualizerProps = { delimiter: string; isFullscreen: boolean; -} +} & ( + | { value: string; signedUrl?: never } + | { value?: never; signedUrl: string } +); const CsvVisualizer = ({ - signedUrl, delimiter, isFullscreen, + value, + signedUrl, }: CsvVisualizerProps) => { const { data, isLoading, error } = useQuery({ queryKey: ["artifact-csv", signedUrl, delimiter], queryFn: async () => { + if (!signedUrl) return null; + const response = await fetch(signedUrl); if (!response.ok) { throw new Error(`(${response.status}) Failed to fetch artifact.`); @@ -31,8 +36,11 @@ const CsvVisualizer = ({ }, staleTime: TWENTY_FOUR_HOURS_IN_MS, retry: false, + enabled: !!signedUrl, }); + const parsed = value ? parseCsvPreview(value, delimiter) : data; + if (isLoading) return ; if (error) { @@ -43,7 +51,7 @@ const CsvVisualizer = ({ ); } - if (!data || data.headers.length === 0) { + if (!parsed || parsed.headers.length === 0) { return ( No data @@ -53,7 +61,7 @@ const CsvVisualizer = ({ return ( diff --git a/src/components/shared/ReactFlow/FlowCanvas/TaskNode/TaskOverview/IOSection/IOCell/ArtifactVisualizer/JsonVisualizer.tsx b/src/components/shared/ReactFlow/FlowCanvas/TaskNode/TaskOverview/IOSection/IOCell/ArtifactVisualizer/JsonVisualizer.tsx index 0cc64517e..dc41be113 100644 --- a/src/components/shared/ReactFlow/FlowCanvas/TaskNode/TaskOverview/IOSection/IOCell/ArtifactVisualizer/JsonVisualizer.tsx +++ b/src/components/shared/ReactFlow/FlowCanvas/TaskNode/TaskOverview/IOSection/IOCell/ArtifactVisualizer/JsonVisualizer.tsx @@ -6,15 +6,19 @@ import { TWENTY_FOUR_HOURS_IN_MS } from "@/utils/constants"; import IOCodeViewer from "../IOCodeViewer"; -interface JsonVisualizerProps { - signedUrl: string; +type JsonVisualizerProps = { name: string; -} +} & ( + | { value: string; signedUrl?: never } + | { value?: never; signedUrl: string } +); -const JsonVisualizer = ({ signedUrl, name }: JsonVisualizerProps) => { +const JsonVisualizer = ({ name, value, signedUrl }: JsonVisualizerProps) => { const { data, isLoading, error } = useQuery({ queryKey: ["artifact-json", signedUrl], queryFn: async () => { + if (!signedUrl) return null; + const response = await fetch(signedUrl); if (!response.ok) { throw new Error(`(${response.status}) Failed to fetch artifact.`); @@ -24,6 +28,7 @@ const JsonVisualizer = ({ signedUrl, name }: JsonVisualizerProps) => { }, staleTime: TWENTY_FOUR_HOURS_IN_MS, retry: false, + enabled: !!signedUrl, }); if (isLoading) return ; @@ -36,9 +41,10 @@ const JsonVisualizer = ({ signedUrl, name }: JsonVisualizerProps) => { ); } - if (!data) return null; + const content = value ?? data; + if (!content) return null; - return ; + return ; }; export default JsonVisualizer; diff --git a/src/components/shared/ReactFlow/FlowCanvas/TaskNode/TaskOverview/IOSection/IOCell/ArtifactVisualizer/TableVisualizer.tsx b/src/components/shared/ReactFlow/FlowCanvas/TaskNode/TaskOverview/IOSection/IOCell/ArtifactVisualizer/TableVisualizer.tsx index 64aaa7ff8..e98371eda 100644 --- a/src/components/shared/ReactFlow/FlowCanvas/TaskNode/TaskOverview/IOSection/IOCell/ArtifactVisualizer/TableVisualizer.tsx +++ b/src/components/shared/ReactFlow/FlowCanvas/TaskNode/TaskOverview/IOSection/IOCell/ArtifactVisualizer/TableVisualizer.tsx @@ -18,7 +18,7 @@ import { interface TableVisualizerProps { data: ArtifactTableData; - signedUrl: string; + signedUrl?: string; isFullscreen: boolean; } @@ -42,7 +42,7 @@ const TableVisualizer = ({ ? `Showing all ${displayedRows.length} rows` : `Showing first ${displayedRows.length} rows`} - {!isShowingAllRows && ( + {!isShowingAllRows && signedUrl && ( { const hasInlineValue = canShowInlineValue(inlineValue); const hasDetails = Boolean(artifactData?.uri || hasInlineValue); - const [isOpen, setIsOpen] = useState(false); - const artifactType = type ?? artifact?.type_name ?? (artifactData?.is_dir ? "Directory" : "Any"); return ( - <> - - - - - {name} - + + + + + {name} + - - - {artifactType} - + + + {artifactType} + - {artifactData?.total_size && ( - - ({formatBytes(artifactData.total_size)}) - - )} - + {artifactData?.total_size && ( + + ({formatBytes(artifactData.total_size)}) + + )} + - {artifact && hasDetails && !hasInlineValue && !!type && ( - - )} + {artifact && (hasDetails || hasInlineValue) && ( + + )} + - {hasInlineValue && ( - - - {inlineValue} - + {hasInlineValue && ( + + {inlineValue} + + )} - {inlineValue.length > 16 && ( - - )} - - )} - - {artifactData?.uri && ( - - )} - - {inlineValue && ( - setIsOpen(false)} - /> + {artifactData?.uri && ( + )} - + ); }; @@ -126,33 +88,3 @@ const canShowInlineValue = ( } return false; }; - -const TextPreview = ({ - open, - title, - value, - artifactData, - onClose, -}: { - open: boolean; - title: string; - value: string; - artifactData?: ArtifactDataResponse; - onClose: () => void; -}) => { - return ( - - - {title} - Complete artifact - {artifactData?.uri && ( - - )} - - - - - - - ); -};