Extension Sidebar: Fix not opening the stored component (#104649)

* Extension Sidebar: Fix not opening the stored component

* empty
This commit is contained in:
Sven Grossmann
2025-05-05 14:25:02 -07:00
committed by GitHub
parent d5e3be1b02
commit 2f41c7c289

View File

@ -1,4 +1,4 @@
import { createContext, ReactNode, useCallback, useContext, useEffect, useState } from 'react';
import { createContext, ReactNode, useCallback, useContext, useEffect, useState, useMemo } from 'react';
import { useLocalStorage } from 'react-use';
import { store, type ExtensionInfo } from '@grafana/data';
@ -92,7 +92,7 @@ export const ExtensionSidebarContextProvider = ({ children }: ExtensionSidebarCo
// that means, a plugin would need to register both, a link and a component to
// `grafana/extension-sidebar/v0-alpha` and the link's `configure` method would control
// whether the component is rendered or not
const { links } = usePluginLinks({
const { links, isLoading } = usePluginLinks({
extensionPointId: EXTENSION_SIDEBAR_EXTENSION_POINT_ID,
context: {
path: currentPath,
@ -102,42 +102,59 @@ export const ExtensionSidebarContextProvider = ({ children }: ExtensionSidebarCo
const isEnabled = !!config.featureToggles.extensionSidebar;
// get all components for this extension point, but only for the permitted plugins
// if the extension sidebar is not enabled, we will return an empty map
const availableComponents = isEnabled
? new Map(
Array.from(getExtensionPointPluginMeta(EXTENSION_SIDEBAR_EXTENSION_POINT_ID).entries()).filter(
([pluginId, pluginMeta]) =>
PERMITTED_EXTENSION_SIDEBAR_PLUGINS.includes(pluginId) &&
links.some(
(link) =>
link.pluginId === pluginId &&
pluginMeta.addedComponents.some((component) => component.title === link.title)
const availableComponents = useMemo(
() =>
isEnabled
? new Map(
Array.from(getExtensionPointPluginMeta(EXTENSION_SIDEBAR_EXTENSION_POINT_ID).entries()).filter(
([pluginId, pluginMeta]) =>
PERMITTED_EXTENSION_SIDEBAR_PLUGINS.includes(pluginId) &&
links.some(
(link) =>
link.pluginId === pluginId &&
pluginMeta.addedComponents.some((component) => component.title === link.title)
)
)
)
)
: new Map<
string,
{
readonly addedComponents: ExtensionInfo[];
readonly addedLinks: ExtensionInfo[];
}
>();
)
: new Map<
string,
{
readonly addedComponents: ExtensionInfo[];
readonly addedLinks: ExtensionInfo[];
}
>(),
[isEnabled, links]
);
// check if the stored docked component is still available
let defaultDockedComponentId: string | undefined;
if (storedDockedPluginId) {
const dockedMeta = getComponentMetaFromComponentId(storedDockedPluginId);
if (dockedMeta) {
const plugin = availableComponents.get(dockedMeta.pluginId);
if (plugin) {
const component = plugin.addedComponents.find((c) => c.title === dockedMeta.componentTitle);
if (component) {
defaultDockedComponentId = storedDockedPluginId;
}
}
defaultDockedComponentId = storedDockedPluginId;
}
}
const [dockedComponentId, setDockedComponentId] = useState<string | undefined>(defaultDockedComponentId);
useEffect(() => {
if (isLoading) {
return;
}
if (dockedComponentId) {
const dockedMeta = getComponentMetaFromComponentId(dockedComponentId);
if (dockedMeta) {
const plugin = availableComponents.get(dockedMeta.pluginId);
if (!plugin || !plugin.addedComponents.some((c) => c.title === dockedMeta.componentTitle)) {
setDockedComponentId(undefined);
}
} else {
// no component found, so we clear the docked component id
setDockedComponentId(undefined);
}
}
}, [isLoading, availableComponents, dockedComponentId]);
const setDockedComponentWithProps = useCallback(
(componentId: string | undefined, props?: Record<string, unknown>) => {
setProps(props);
@ -173,6 +190,10 @@ export const ExtensionSidebarContextProvider = ({ children }: ExtensionSidebarCo
// update the stored docked component id when it changes
useEffect(() => {
// wait for the plugin links to be loaded before we update the stored docked component id
if (isLoading) {
return;
}
const componentMeta = getComponentMetaFromComponentId(dockedComponentId ?? '');
const storedComponentId = store.get(EXTENSION_SIDEBAR_DOCKED_LOCAL_STORAGE_KEY);
const storedComponentMeta = getComponentMetaFromComponentId(storedComponentId ?? '');
@ -191,7 +212,7 @@ export const ExtensionSidebarContextProvider = ({ children }: ExtensionSidebarCo
} else {
store.delete(EXTENSION_SIDEBAR_DOCKED_LOCAL_STORAGE_KEY);
}
}, [dockedComponentId]);
}, [dockedComponentId, isLoading]);
return (
<ExtensionSidebarContext.Provider