From 638a1b6845f7a02c43234118a2679f9d0673fa9c Mon Sep 17 00:00:00 2001 From: Joe Numainville Date: Wed, 14 Aug 2024 12:47:47 -0500 Subject: [PATCH 1/4] wip --- packages/embed-widget/src/App.tsx | 76 +++++++++++++++++++++++++------ 1 file changed, 62 insertions(+), 14 deletions(-) diff --git a/packages/embed-widget/src/App.tsx b/packages/embed-widget/src/App.tsx index 817289b5cc..05c00d6b7d 100644 --- a/packages/embed-widget/src/App.tsx +++ b/packages/embed-widget/src/App.tsx @@ -63,12 +63,16 @@ const LAYOUT_SETTINGS = { function App(): JSX.Element { const [error, setError] = useState(); const [definition, setDefinition] = useState(); + const [sharedObject, setSharedObject] = useState(); const searchParams = useMemo( () => new URLSearchParams(window.location.search), [] ); // Get the widget name from the query param `name`. const name = searchParams.get('name'); + // Get the type of shared object from the query param, + // which is necessary if the widget is shared. + const shared = searchParams.get('shared'); const api = useApi(); const connection = useConnection(); const client = useClient(); @@ -115,13 +119,26 @@ function App(): JSX.Element { ) ); - log.debug(`Loading widget definition for ${name}...`); + if (shared != null) { + log.debug(`Loading shared object for ${name}...`); - const newDefinition = await fetchVariableDefinition(connection, name); + const obj = await connection.getSharedObject(name, shared); - setDefinition(newDefinition); + setSharedObject(obj); - log.debug(`Widget definition successfully loaded for ${name}`); + log.debug(`Shared object successfully loaded for ${name}`); + } else { + log.debug(`Loading widget definition for ${name}...`); + + const newDefinition = await fetchVariableDefinition( + connection, + name + ); + + setDefinition(newDefinition); + + log.debug(`Widget definition successfully loaded for ${name}`); + } } catch (e: unknown) { log.error(`Unable to load widget definition for ${name}`, e); setError(`${e}`); @@ -132,17 +149,24 @@ function App(): JSX.Element { [api, client, connection, dispatch, name, serverConfig, user] ); - const isLoaded = definition != null && error == null; - const isLoading = definition == null && error == null; + const isLoaded = + (definition != null || sharedObject != null) && error == null; + const isLoading = definition == null && sharedObject == null && error == null; const fetch = useMemo(() => { - if (definition == null) { + if (definition == null && sharedObject == null) { return async () => { - throw new Error('Definition is null'); + throw new Error('Definition and shared object are null'); }; } - return () => connection.getObject(definition); - }, [connection, definition]); + return () => { + if (sharedObject != null) { + return sharedObject; + } else if (definition != null) { + return connection.getObject(definition); + } + }; + }, [connection, definition, sharedObject]); const [goldenLayout, setGoldenLayout] = useState(null); const [dashboardId, setDashboardId] = useState('default-embed-widget'); // Can't be DEFAULT_DASHBOARD_ID because its dashboard layout is not stored in dashboardData @@ -175,16 +199,40 @@ function App(): JSX.Element { const [hasEmittedWidget, setHasEmittedWidget] = useState(false); const handleDashboardInitialized = useCallback(() => { - if (goldenLayout == null || definition == null || hasEmittedWidget) { + if ( + goldenLayout == null || + (definition == null && sharedObject == null) || + hasEmittedWidget + ) { return; } - setHasEmittedWidget(true); + + let widget = null; + if (sharedObject != null) { + widget = { + type: shared, + name: name, + } as dh.ide.VariableDescriptor; + } else if (definition != null) { + widget = getVariableDescriptor(definition); + } else { + return; + } + emitPanelOpen(goldenLayout.eventHub, { fetch, - widget: getVariableDescriptor(definition), + widget: widget, }); - }, [goldenLayout, definition, fetch, hasEmittedWidget]); + }, [ + goldenLayout, + definition, + fetch, + hasEmittedWidget, + name, + shared, + sharedObject, + ]); const allDashboardData = useSelector(getAllDashboardsData); From b5a10443deb68fe07985c2098a362c47d4a83f13 Mon Sep 17 00:00:00 2001 From: Joe Numainville Date: Wed, 14 Aug 2024 15:10:23 -0500 Subject: [PATCH 2/4] wip --- packages/embed-widget/src/App.tsx | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/packages/embed-widget/src/App.tsx b/packages/embed-widget/src/App.tsx index 05c00d6b7d..b9e7fc965b 100644 --- a/packages/embed-widget/src/App.tsx +++ b/packages/embed-widget/src/App.tsx @@ -63,7 +63,8 @@ const LAYOUT_SETTINGS = { function App(): JSX.Element { const [error, setError] = useState(); const [definition, setDefinition] = useState(); - const [sharedObject, setSharedObject] = useState(); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const [sharedObject, setSharedObject] = useState>(); const searchParams = useMemo( () => new URLSearchParams(window.location.search), [] @@ -123,6 +124,7 @@ function App(): JSX.Element { log.debug(`Loading shared object for ${name}...`); const obj = await connection.getSharedObject(name, shared); + console.log(typeof obj); setSharedObject(obj); @@ -146,7 +148,7 @@ function App(): JSX.Element { } initApp(); }, - [api, client, connection, dispatch, name, serverConfig, user] + [api, client, connection, dispatch, name, serverConfig, user, shared] ); const isLoaded = @@ -162,9 +164,11 @@ function App(): JSX.Element { return () => { if (sharedObject != null) { return sharedObject; - } else if (definition != null) { + } + if (definition != null) { return connection.getObject(definition); } + throw new Error('Definition and shared object are null'); }; }, [connection, definition, sharedObject]); @@ -212,7 +216,7 @@ function App(): JSX.Element { if (sharedObject != null) { widget = { type: shared, - name: name, + name, } as dh.ide.VariableDescriptor; } else if (definition != null) { widget = getVariableDescriptor(definition); @@ -222,7 +226,7 @@ function App(): JSX.Element { emitPanelOpen(goldenLayout.eventHub, { fetch, - widget: widget, + widget, }); }, [ goldenLayout, From dca8e4cfeab72457ea103f94e0e69b0768c5540a Mon Sep 17 00:00:00 2001 From: Joe Numainville Date: Tue, 20 Aug 2024 15:56:06 -0500 Subject: [PATCH 3/4] wip --- packages/embed-widget/src/App.tsx | 78 +++++++++++++++++++++---------- 1 file changed, 54 insertions(+), 24 deletions(-) diff --git a/packages/embed-widget/src/App.tsx b/packages/embed-widget/src/App.tsx index b9e7fc965b..497f240dfb 100644 --- a/packages/embed-widget/src/App.tsx +++ b/packages/embed-widget/src/App.tsx @@ -63,8 +63,7 @@ const LAYOUT_SETTINGS = { function App(): JSX.Element { const [error, setError] = useState(); const [definition, setDefinition] = useState(); - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const [sharedObject, setSharedObject] = useState>(); + const [sharedReady, setSharedReady] = useState(false); const searchParams = useMemo( () => new URLSearchParams(window.location.search), [] @@ -73,7 +72,8 @@ function App(): JSX.Element { const name = searchParams.get('name'); // Get the type of shared object from the query param, // which is necessary if the widget is shared. - const shared = searchParams.get('shared'); + const type = searchParams.get('type'); + const isShared = searchParams.get('isShared'); const api = useApi(); const connection = useConnection(); const client = useClient(); @@ -120,15 +120,18 @@ function App(): JSX.Element { ) ); - if (shared != null) { - log.debug(`Loading shared object for ${name}...`); + console.log('user', user); - const obj = await connection.getSharedObject(name, shared); - console.log(typeof obj); + if (isShared === 'true') { + log.debug(`Checking if shared parameters are valid...`); - setSharedObject(obj); + if (type == null) { + throw new Error('Missing URL parameter "type"'); + } - log.debug(`Shared object successfully loaded for ${name}`); + setSharedReady(true); + + log.debug(`Shared parameters are valid`); } else { log.debug(`Loading widget definition for ${name}...`); @@ -148,29 +151,56 @@ function App(): JSX.Element { } initApp(); }, - [api, client, connection, dispatch, name, serverConfig, user, shared] + [ + api, + client, + connection, + dispatch, + name, + serverConfig, + user, + isShared, + type, + ] ); - const isLoaded = - (definition != null || sharedObject != null) && error == null; - const isLoading = definition == null && sharedObject == null && error == null; + const isLoaded = (definition != null || sharedReady != false) && error == null; + const isLoading = definition == null && sharedReady == false && error == null; + + type ConnectionWithGetSharedObject = dh.IdeConnection & { + getSharedObject(name: string, type: string): Promise; + }; + + function isConnectionWithGetSharedObject( + connection: dh.IdeConnection + ): connection is ConnectionWithGetSharedObject { + return ( + 'getSharedObject' in connection && + typeof connection.getSharedObject === 'function' + ); + } const fetch = useMemo(() => { - if (definition == null && sharedObject == null) { + if (definition == null && !sharedReady) { return async () => { - throw new Error('Definition and shared object are null'); + throw new Error('Definition is null'); }; } return () => { - if (sharedObject != null) { - return sharedObject; + if (name != null && type != null) { + if (isConnectionWithGetSharedObject(connection)) { + return connection.getSharedObject(name, type); + } + throw new Error( + 'Connection does not have getSharedObject method. Cannot fetch shared object.' + ); } if (definition != null) { return connection.getObject(definition); } - throw new Error('Definition and shared object are null'); + throw new Error('Definition is null or shared parameters are not set'); }; - }, [connection, definition, sharedObject]); + }, [connection, definition, sharedReady, name, type]); const [goldenLayout, setGoldenLayout] = useState(null); const [dashboardId, setDashboardId] = useState('default-embed-widget'); // Can't be DEFAULT_DASHBOARD_ID because its dashboard layout is not stored in dashboardData @@ -205,7 +235,7 @@ function App(): JSX.Element { const handleDashboardInitialized = useCallback(() => { if ( goldenLayout == null || - (definition == null && sharedObject == null) || + (definition == null && sharedReady == null) || hasEmittedWidget ) { return; @@ -213,9 +243,9 @@ function App(): JSX.Element { setHasEmittedWidget(true); let widget = null; - if (sharedObject != null) { + if (sharedReady != null) { widget = { - type: shared, + type, name, } as dh.ide.VariableDescriptor; } else if (definition != null) { @@ -234,8 +264,8 @@ function App(): JSX.Element { fetch, hasEmittedWidget, name, - shared, - sharedObject, + type, + sharedReady, ]); const allDashboardData = useSelector(getAllDashboardsData); From a8b79d45dee05c40e87e35bb81781c0bbb52183c Mon Sep 17 00:00:00 2001 From: Joe Numainville Date: Tue, 20 Aug 2024 15:59:04 -0500 Subject: [PATCH 4/4] wip --- packages/embed-widget/src/App.tsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/embed-widget/src/App.tsx b/packages/embed-widget/src/App.tsx index 497f240dfb..75f3c2b83a 100644 --- a/packages/embed-widget/src/App.tsx +++ b/packages/embed-widget/src/App.tsx @@ -120,8 +120,6 @@ function App(): JSX.Element { ) ); - console.log('user', user); - if (isShared === 'true') { log.debug(`Checking if shared parameters are valid...`); @@ -164,7 +162,8 @@ function App(): JSX.Element { ] ); - const isLoaded = (definition != null || sharedReady != false) && error == null; + const isLoaded = + (definition != null || sharedReady != false) && error == null; const isLoading = definition == null && sharedReady == false && error == null; type ConnectionWithGetSharedObject = dh.IdeConnection & {