Skip to content

Commit

Permalink
Can inspect code for visualizations. Layout shift needs fix. (#8648)
Browse files Browse the repository at this point in the history
* Can inspect code for visualizations. Layout shift needs fix.

* ui improvements

---------

Co-authored-by: Lucas <lucas@Dusts-MacBook-Pro.local>
Co-authored-by: Thomas Draier <thomas@dust.tt>
  • Loading branch information
3 people authored Nov 15, 2024
1 parent 08a0fc9 commit 333a557
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 8 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import { Button, Spinner } from "@dust-tt/sparkle";
import { MarkdownContentContext } from "@dust-tt/sparkle";
import { Markdown } from "@dust-tt/sparkle";
import {
Button,
CodeBlock,
Markdown,
MarkdownContentContext,
Modal,
Page,
Spinner,
} from "@dust-tt/sparkle";
import type {
CommandResultMap,
LightWorkspaceType,
Expand Down Expand Up @@ -58,12 +64,14 @@ function useVisualizationDataHandler({
visualization,
setContentHeight,
setErrorMessage,
setCodeDrawerOpened,
vizIframeRef,
workspaceId,
}: {
visualization: Visualization;
setContentHeight: (v: SetStateAction<number>) => void;
setErrorMessage: (v: SetStateAction<string | null>) => void;
setCodeDrawerOpened: (v: SetStateAction<boolean>) => void;
vizIframeRef: React.MutableRefObject<HTMLIFrameElement | null>;
workspaceId: string;
}) {
Expand Down Expand Up @@ -147,6 +155,10 @@ function useVisualizationDataHandler({
downloadFileFromBlob(data.params.blob, data.params.filename);
break;

case "displayCode":
setCodeDrawerOpened(true);
break;

default:
assertNever(data);
}
Expand All @@ -160,11 +172,36 @@ function useVisualizationDataHandler({
getFileBlob,
setContentHeight,
setErrorMessage,
setCodeDrawerOpened,
visualization.identifier,
vizIframeRef,
]);
}

export function CodeDrawer({
isOpened,
onClose,
code,
}: {
isOpened: boolean;
onClose: () => void;
code: string;
}) {
return (
<Modal
isOpen={isOpened}
onClose={onClose}
title="Code for this visualization"
variant="side-md"
hasChanged={false}
>
<Page variant="modal">
<CodeBlock className="language-jsx">{code}</CodeBlock>
</Page>
</Modal>
);
}

export function VisualizationActionIframe({
owner,
visualization,
Expand All @@ -179,7 +216,7 @@ export function VisualizationActionIframe({
const [contentHeight, setContentHeight] = useState<number>(0);
const [errorMessage, setErrorMessage] = useState<string | null>(null);
const [retryClicked, setRetryClicked] = useState(false);

const [isCodeDrawerOpen, setCodeDrawerOpened] = useState(false);
const vizIframeRef = useRef<HTMLIFrameElement | null>(null);

const isErrored = !!errorMessage || retryClicked;
Expand All @@ -189,6 +226,7 @@ export function VisualizationActionIframe({
workspaceId: owner.sId,
setContentHeight,
setErrorMessage,
setCodeDrawerOpened,
vizIframeRef,
});

Expand Down Expand Up @@ -226,6 +264,13 @@ export function VisualizationActionIframe({
<Spinner size="xl" />
</div>
)}
{code && (
<CodeDrawer
isOpened={isCodeDrawerOpen}
onClose={() => setCodeDrawerOpened(false)}
code={code}
/>
)}
<div
className={classNames(
"relative w-full overflow-hidden",
Expand Down
25 changes: 24 additions & 1 deletion types/src/front/assistant/visualization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export type VisualizationRPCRequestMap = {
setContentHeight: SetContentHeightParams;
setErrorMessage: setErrorMessageParams;
downloadFileRequest: DownloadFileRequestParams;
displayCode: null;
};

// Derive the command type from the keys of the request map
Expand Down Expand Up @@ -60,6 +61,7 @@ export interface CommandResultMap {
downloadFileRequest: { blob: Blob; filename?: string };
setContentHeight: void;
setErrorMessage: void;
displayCode: void;
}

// TODO(@fontanierh): refactor all these guards to use io-ts instead of manual checks.
Expand Down Expand Up @@ -170,6 +172,26 @@ export function isDownloadFileRequest(
);
}

// Type guard for getCodeToExecute.
export function isDisplayCodeRequest(
value: unknown
): value is VisualizationRPCRequest & {
command: "displayCode";
params: null;
} {
if (typeof value !== "object" || value === null) {
return false;
}

const v = value as Partial<VisualizationRPCRequest>;

return (
v.command === "displayCode" &&
typeof v.identifier === "string" &&
typeof v.messageUniqueId === "string"
);
}

export function isVisualizationRPCRequest(
value: unknown
): value is VisualizationRPCRequest {
Expand All @@ -182,6 +204,7 @@ export function isVisualizationRPCRequest(
isGetFileRequest(value) ||
isDownloadFileRequest(value) ||
isSetContentHeightRequest(value) ||
isSetErrorMessageRequest(value)
isSetErrorMessageRequest(value) ||
isDisplayCodeRequest(value)
);
}
23 changes: 20 additions & 3 deletions viz/app/components/VisualizationWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { importCode, Runner } from "react-runner";
import * as rechartsAll from "recharts";
import { useResizeDetector } from "react-resize-detector";
import { ErrorBoundary } from "@viz/app/components/ErrorBoundary";
import { Download } from "lucide-react";
import { Download, SquareTerminal } from "lucide-react";
import { toBlob } from "html-to-image";

export function useVisualizationAPI(
Expand Down Expand Up @@ -83,12 +83,20 @@ export function useVisualizationAPI(
[sendCrossDocumentMessage]
);

const displayCode = useCallback(
async () => {
await sendCrossDocumentMessage("displayCode", null);
},
[sendCrossDocumentMessage]
);

return {
error,
fetchCode,
fetchFile,
sendHeightToParent,
downloadFile,
displayCode,
};
}

Expand Down Expand Up @@ -182,7 +190,7 @@ export function VisualizationWrapper({

const [errored, setErrorMessage] = useState<Error | null>(null);

const { fetchCode, fetchFile, error, sendHeightToParent, downloadFile } = api;
const { fetchCode, fetchFile, error, sendHeightToParent, downloadFile, displayCode } = api;

const memoizedDownloadFile = useDownloadFileCallback(downloadFile);

Expand Down Expand Up @@ -249,6 +257,10 @@ export function VisualizationWrapper({
}
}, [ref, downloadFile]);

const handleDisplayCode = useCallback(async () => {
await displayCode();
}, [displayCode]);

useEffect(() => {
if (error) {
setErrorMessage(error);
Expand All @@ -266,12 +278,17 @@ export function VisualizationWrapper({

return (
<div className="relative group/viz">
<div className="flex flex-row gap-2 absolute top-2 right-2 bg-white rounded transition opacity-0 group-hover/viz:opacity-100 z-50">
<button
onClick={handleScreenshotDownload}
className="absolute top-2 right-2 bg-white p-2 rounded shadow hover:bg-gray-100 transition opacity-0 group-hover/viz:opacity-100 z-50"
className="hover:bg-slate-200 rounded p-2 border border-slate-200"
>
<Download size={20} />
</button>
<button className="hover:bg-slate-200 rounded p-2 border border-slate-200" onClick={handleDisplayCode}>
<SquareTerminal size={20} />
</button>
</div>
<div ref={ref}>
<Runner
code={runnerParams.code}
Expand Down

0 comments on commit 333a557

Please sign in to comment.