From 65cd136f52377ac4c8f50fa46bc4e3aa16b8b660 Mon Sep 17 00:00:00 2001 From: Henry Fontanier Date: Thu, 1 Aug 2024 19:12:15 +0200 Subject: [PATCH] enh: make viz responsive, remove extra renders, handle err in main window (#6629) * enh: improve viz responsiveness, remove extra renders, handle error in main * mark last viz as complete on agent message success * naming * nit * remove outdated comment * r --------- Co-authored-by: Henry Fontanier --- .../assistant/conversation/AgentMessage.tsx | 6 ++ .../actions/VisualizationActionIframe.tsx | 79 ++++++++++++------- front/lib/api/assistant/visualization.ts | 12 ++- types/src/front/assistant/visualization.ts | 39 ++++----- viz/app/components/Components.tsx | 49 ------------ viz/app/components/ErrorBoundary.tsx | 61 +------------- viz/app/components/VisualizationWrapper.tsx | 16 +--- viz/package-lock.json | 15 ++-- viz/package.json | 2 +- 9 files changed, 96 insertions(+), 183 deletions(-) diff --git a/front/components/assistant/conversation/AgentMessage.tsx b/front/components/assistant/conversation/AgentMessage.tsx index a8fbf9cb79bd..a7b3afe7ddfe 100644 --- a/front/components/assistant/conversation/AgentMessage.tsx +++ b/front/components/assistant/conversation/AgentMessage.tsx @@ -211,6 +211,12 @@ export function AgentMessage({ ...event.message, }; }); + // Mark the last viz as complete if it is not already. + setVisualizations((v) => + v.map((item, index) => + index === v.length - 1 ? { ...item, complete: true } : item + ) + ); break; } diff --git a/front/components/assistant/conversation/actions/VisualizationActionIframe.tsx b/front/components/assistant/conversation/actions/VisualizationActionIframe.tsx index 0e27c296c686..47091f19bb7b 100644 --- a/front/components/assistant/conversation/actions/VisualizationActionIframe.tsx +++ b/front/components/assistant/conversation/actions/VisualizationActionIframe.tsx @@ -1,4 +1,4 @@ -import { Spinner } from "@dust-tt/sparkle"; +import { Button, Spinner } from "@dust-tt/sparkle"; import type { CommandResultMap, VisualizationRPCCommand, @@ -38,14 +38,14 @@ const sendResponseToIframe = ( // Custom hook to encapsulate the logic for handling visualization messages. function useVisualizationDataHandler({ visualization, - onRetry, setContentHeight, + setIsErrored, vizIframeRef, workspaceId, }: { visualization: Visualization; - onRetry: () => void; setContentHeight: (v: SetStateAction) => void; + setIsErrored: (v: SetStateAction) => void; vizIframeRef: React.MutableRefObject; workspaceId: string; }) { @@ -98,14 +98,14 @@ function useVisualizationDataHandler({ break; - case "retry": - onRetry(); - break; - case "setContentHeight": setContentHeight(data.params.height); break; + case "setErrored": + setIsErrored(true); + break; + default: assertNever(data); } @@ -117,8 +117,8 @@ function useVisualizationDataHandler({ visualization.identifier, code, getFileBlob, - onRetry, setContentHeight, + setIsErrored, vizIframeRef, ]); } @@ -130,45 +130,41 @@ export function VisualizationActionIframe({ }: { owner: WorkspaceType; visualization: Visualization; - onRetry: () => void; }) { - const [contentHeight, setContentHeight] = useState(0); - const [iframeLoaded, setIframeLoaded] = useState(false); - const [showSpinner, setShowSpinner] = useState(true); + const [contentHeight, setContentHeight] = useState(0); + const [isErrored, setIsErrored] = useState(false); const [activeIndex, setActiveIndex] = useState(1); const vizIframeRef = useRef(null); const containerRef = useRef(null); const codeRef = useRef(null); + const errorRef = useRef(null); const workspaceId = owner.sId; useVisualizationDataHandler({ visualization, workspaceId, - onRetry, setContentHeight, + setIsErrored, vizIframeRef, }); const { code, complete: codeFullyGenerated } = visualization; + const iframeLoaded = contentHeight > 0; + const showSpinner = + ((!codeFullyGenerated && !code) || (codeFullyGenerated && !iframeLoaded)) && + !isErrored; + useEffect(() => { if (!codeFullyGenerated) { - // Display spinner over the code block while waiting for code generation. - setShowSpinner(!code); setActiveIndex(0); - } else if (iframeLoaded) { - // Display iframe if code is generated and iframe has loaded. - setShowSpinner(false); - setActiveIndex(1); } else { - // Show spinner while iframe is loading. - setShowSpinner(true); setActiveIndex(1); } - }, [codeFullyGenerated, code, iframeLoaded]); + }, [codeFullyGenerated, code]); useEffect(() => { if (!containerRef.current) { @@ -182,9 +178,13 @@ export function VisualizationActionIframe({ ? `${codeRef.current?.scrollHeight}px` : "100%"; } else if (activeIndex === 1) { - containerRef.current.style.height = `${contentHeight}px`; + if (isErrored && errorRef.current) { + containerRef.current.style.height = `${errorRef.current.scrollHeight}px`; + } else if (!isErrored) { + containerRef.current.style.height = `${contentHeight}px`; + } } - }, [activeIndex, contentHeight, codeFullyGenerated]); + }, [activeIndex, contentHeight, codeFullyGenerated, isErrored]); return (
@@ -202,7 +202,9 @@ export function VisualizationActionIframe({
@@ -219,21 +221,38 @@ export function VisualizationActionIframe({ />
- {codeFullyGenerated && ( + {codeFullyGenerated && !isErrored && (