-
Notifications
You must be signed in to change notification settings - Fork 31
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Add shared objects to embed-widget #2189
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -63,12 +63,17 @@ | |||||
function App(): JSX.Element { | ||||||
const [error, setError] = useState<string>(); | ||||||
const [definition, setDefinition] = useState<dh.ide.VariableDefinition>(); | ||||||
const [sharedReady, setSharedReady] = useState<boolean>(false); | ||||||
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 type = searchParams.get('type'); | ||||||
const isShared = searchParams.get('isShared'); | ||||||
const api = useApi(); | ||||||
const connection = useConnection(); | ||||||
const client = useClient(); | ||||||
|
@@ -115,34 +120,86 @@ | |||||
) | ||||||
); | ||||||
|
||||||
log.debug(`Loading widget definition for ${name}...`); | ||||||
if (isShared === 'true') { | ||||||
log.debug(`Checking if shared parameters are valid...`); | ||||||
|
||||||
const newDefinition = await fetchVariableDefinition(connection, name); | ||||||
if (type == null) { | ||||||
throw new Error('Missing URL parameter "type"'); | ||||||
} | ||||||
|
||||||
setDefinition(newDefinition); | ||||||
setSharedReady(true); | ||||||
|
||||||
log.debug(`Widget definition successfully loaded for ${name}`); | ||||||
log.debug(`Shared parameters are valid`); | ||||||
} 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}`); | ||||||
} | ||||||
} | ||||||
initApp(); | ||||||
}, | ||||||
[api, client, connection, dispatch, name, serverConfig, user] | ||||||
[ | ||||||
api, | ||||||
client, | ||||||
connection, | ||||||
dispatch, | ||||||
name, | ||||||
serverConfig, | ||||||
user, | ||||||
isShared, | ||||||
type, | ||||||
] | ||||||
); | ||||||
|
||||||
const isLoaded = definition != null && error == null; | ||||||
const isLoading = definition == null && error == null; | ||||||
const isLoaded = | ||||||
(definition != null || sharedReady != false) && error == null; | ||||||
const isLoading = definition == null && sharedReady == false && error == null; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
||||||
type ConnectionWithGetSharedObject = dh.IdeConnection & { | ||||||
getSharedObject(name: string, type: string): Promise<unknown>; | ||||||
}; | ||||||
|
||||||
function isConnectionWithGetSharedObject( | ||||||
connection: dh.IdeConnection | ||||||
): connection is ConnectionWithGetSharedObject { | ||||||
return ( | ||||||
'getSharedObject' in connection && | ||||||
typeof connection.getSharedObject === 'function' | ||||||
); | ||||||
} | ||||||
Comment on lines
+169
to
+180
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Move the type definition and typePredicate outside of/above this functional component. |
||||||
|
||||||
const fetch = useMemo(() => { | ||||||
if (definition == null) { | ||||||
if (definition == null && !sharedReady) { | ||||||
return async () => { | ||||||
throw new Error('Definition is null'); | ||||||
}; | ||||||
} | ||||||
return () => connection.getObject(definition); | ||||||
}, [connection, definition]); | ||||||
return () => { | ||||||
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) { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd personally put the |
||||||
return connection.getObject(definition); | ||||||
} | ||||||
throw new Error('Definition is null or shared parameters are not set'); | ||||||
}; | ||||||
}, [connection, definition, sharedReady, name, type]); | ||||||
|
||||||
const [goldenLayout, setGoldenLayout] = useState<GoldenLayout | null>(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 +232,40 @@ | |||||
const [hasEmittedWidget, setHasEmittedWidget] = useState(false); | ||||||
|
||||||
const handleDashboardInitialized = useCallback(() => { | ||||||
if (goldenLayout == null || definition == null || hasEmittedWidget) { | ||||||
if ( | ||||||
goldenLayout == null || | ||||||
(definition == null && sharedReady == null) || | ||||||
hasEmittedWidget | ||||||
) { | ||||||
return; | ||||||
} | ||||||
|
||||||
setHasEmittedWidget(true); | ||||||
|
||||||
let widget = null; | ||||||
if (sharedReady != null) { | ||||||
widget = { | ||||||
type, | ||||||
name, | ||||||
} as dh.ide.VariableDescriptor; | ||||||
} else if (definition != null) { | ||||||
widget = getVariableDescriptor(definition); | ||||||
} else { | ||||||
return; | ||||||
} | ||||||
|
||||||
emitPanelOpen(goldenLayout.eventHub, { | ||||||
fetch, | ||||||
widget: getVariableDescriptor(definition), | ||||||
widget, | ||||||
}); | ||||||
}, [goldenLayout, definition, fetch, hasEmittedWidget]); | ||||||
}, [ | ||||||
goldenLayout, | ||||||
definition, | ||||||
fetch, | ||||||
hasEmittedWidget, | ||||||
name, | ||||||
type, | ||||||
sharedReady, | ||||||
]); | ||||||
|
||||||
const allDashboardData = useSelector(getAllDashboardsData); | ||||||
|
||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.