Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -67,10 +67,20 @@ const ArtifactVisualizer = ({
return (
<Dialog onOpenChange={handleOpenChange}>
<DialogTrigger asChild>
<Button variant="ghost" size="xs">
<Icon name="Eye" />
Preview
</Button>
{value ? (
<Button variant="ghost" size="xs">
<Icon
name="Maximize2"
size="xs"
className="text-muted-foreground"
/>
</Button>
) : (
<Button variant="ghost" size="xs">
<Icon name="Eye" />
Preview
</Button>
)}
</DialogTrigger>
<DialogContent
className={cn(
Expand Down Expand Up @@ -110,34 +120,81 @@ const ArtifactVisualizer = ({
</DialogDescription>
</DialogHeader>
<div className="overflow-auto flex-1 min-h-0">
<PreviewContent
artifactId={artifact.id}
type={normalizedType}
backendUrl={backendUrl}
name={name}
isFullscreen={isFullscreen}
/>
{value ? (
<InlineContent
name={name}
value={value}
type={normalizedType}
isFullscreen={isFullscreen}
/>
) : (
<PreviewContent
name={name}
artifactId={artifact.id}
type={normalizedType}
isFullscreen={isFullscreen}
/>
)}
</div>
</DialogContent>
</Dialog>
);
};

interface InlineContentProps {
type: string;
name: string;
value: string;
isFullscreen: boolean;
}

const InlineContent = ({
type,
name,
value,
isFullscreen,
}: InlineContentProps) => {
switch (type) {
case "csv":
return (
<CsvVisualizer
value={value}
delimiter=","
isFullscreen={isFullscreen}
/>
);
case "tsv":
return (
<CsvVisualizer
value={value}
delimiter={"\t"}
isFullscreen={isFullscreen}
/>
);
case "jsonobject":
case "jsonarray":
return <JsonVisualizer value={value} name={name} />;
case "text":
default:
return <TextVisualizer value={value} />;
}
};

interface PreviewContentProps {
artifactId: string;
type: string;
backendUrl: string;
name: string;
isFullscreen: boolean;
}

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),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.`);
Expand All @@ -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 <Spinner />;

if (error) {
Expand All @@ -43,7 +51,7 @@ const CsvVisualizer = ({
);
}

if (!data || data.headers.length === 0) {
if (!parsed || parsed.headers.length === 0) {
return (
<Paragraph tone="subdued" size="xs">
No data
Expand All @@ -53,7 +61,7 @@ const CsvVisualizer = ({

return (
<TableVisualizer
data={data}
data={parsed}
signedUrl={signedUrl}
isFullscreen={isFullscreen}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.`);
Expand All @@ -24,6 +28,7 @@ const JsonVisualizer = ({ signedUrl, name }: JsonVisualizerProps) => {
},
staleTime: TWENTY_FOUR_HOURS_IN_MS,
retry: false,
enabled: !!signedUrl,
});

if (isLoading) return <Spinner />;
Expand All @@ -36,9 +41,10 @@ const JsonVisualizer = ({ signedUrl, name }: JsonVisualizerProps) => {
);
}

if (!data) return null;
const content = value ?? data;
if (!content) return null;

return <IOCodeViewer title={name} value={data} />;
return <IOCodeViewer title={name} value={content} />;
};

export default JsonVisualizer;
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {

interface TableVisualizerProps {
data: ArtifactTableData;
signedUrl: string;
signedUrl?: string;
isFullscreen: boolean;
}

Expand All @@ -42,7 +42,7 @@ const TableVisualizer = ({
? `Showing all ${displayedRows.length} rows`
: `Showing first ${displayedRows.length} rows`}
</Paragraph>
{!isShowingAllRows && (
{!isShowingAllRows && signedUrl && (
<Link
href={signedUrl}
target="_blank"
Expand Down
Loading
Loading