diff --git a/src/components/Item/VisualizationItem/Visualization/IframePlugin.js b/src/components/Item/VisualizationItem/Visualization/IframePlugin.js index f6d8590f6..53dabb176 100644 --- a/src/components/Item/VisualizationItem/Visualization/IframePlugin.js +++ b/src/components/Item/VisualizationItem/Visualization/IframePlugin.js @@ -35,11 +35,12 @@ const IframePlugin = ({ // When this mounts, check if the dashboard is recording const { isCached, recordingState } = useCacheableSection(dashboardId) - const [communicationReceived, setCommunicationReceived] = useState(false) const [recordOnNextLoad, setRecordOnNextLoad] = useState( recordingState === 'recording' ) + const prevPluginRef = useRef() + const onError = () => setError('plugin') const pluginProps = useMemo( @@ -56,7 +57,7 @@ const IframePlugin = ({ // TODO: May also want user ID too for multi-user situations cacheId: `${dashboardId}-${itemId}`, isParentCached: isCached, - recordOnNextLoad: recordOnNextLoad, + recordOnNextLoad, }), [ userSettings, @@ -68,6 +69,31 @@ const IframePlugin = ({ ] ) + const getIframeSrc = useCallback(() => { + const pluginType = [CHART, REPORT_TABLE].includes(activeType) + ? VISUALIZATION + : activeType + + // 1. check if there is an override for the plugin + const pluginOverrides = getPluginOverrides() + + if (pluginOverrides && pluginOverrides[pluginType]) { + return pluginOverrides[pluginType] + } + + // 2. check if there is an installed app for the pluginType + // and use its plugin launch URL + const pluginLaunchUrl = getPluginLaunchUrl(pluginType, d2, baseUrl) + + if (pluginLaunchUrl) { + return pluginLaunchUrl + } + + setError('missing-plugin') + }, [activeType, d2, baseUrl]) + + const iframeSrc = getIframeSrc() + useEffect(() => { // Tell plugin to remove cached data if this dashboard has been removed // from offline storage @@ -88,14 +114,14 @@ const IframePlugin = ({ useEffect(() => { if (iframeRef?.current) { // if iframe has not sent initial request, set up a listener - if (!communicationReceived) { + if (iframeSrc !== prevPluginRef.current) { + prevPluginRef.current = iframeSrc + const listener = postRobot.on( 'getProps', // listen for messages coming only from the iframe rendered by this component { window: iframeRef.current.contentWindow }, () => { - setCommunicationReceived(true) - if (recordOnNextLoad) { // Avoid recording unnecessarily, // e.g. if plugin re-requests props for some reason @@ -107,47 +133,20 @@ const IframePlugin = ({ ) return () => listener.cancel() + } else { + postRobot.send( + iframeRef.current.contentWindow, + 'newProps', + pluginProps + ) } } - - if (communicationReceived && iframeRef.current?.contentWindow) { - postRobot.send( - iframeRef.current.contentWindow, - 'newProps', - pluginProps - ) - } - }, [communicationReceived, recordOnNextLoad, pluginProps]) + }, [recordOnNextLoad, pluginProps, iframeSrc]) useEffect(() => { setError(null) }, [filterVersion, visualization.type]) - const getIframeSrc = useCallback(() => { - const pluginType = [CHART, REPORT_TABLE].includes(activeType) - ? VISUALIZATION - : activeType - - // 1. check if there is an override for the plugin - const pluginOverrides = getPluginOverrides() - - if (pluginOverrides && pluginOverrides[pluginType]) { - return pluginOverrides[pluginType] - } - - // 2. check if there is an installed app for the pluginType - // and use its plugin launch URL - const pluginLaunchUrl = getPluginLaunchUrl(pluginType, d2, baseUrl) - - if (pluginLaunchUrl) { - return pluginLaunchUrl - } - - setError('missing-plugin') - - return - }, [activeType, d2, baseUrl]) - if (error) { return error === 'missing-plugin' ? (
@@ -167,8 +166,6 @@ const IframePlugin = ({ ) } - const iframeSrc = getIframeSrc() - return (
{iframeSrc ? (