diff --git a/src/frontend/src/components/panels/PanelGroup.tsx b/src/frontend/src/components/panels/PanelGroup.tsx index 295bb03630..f857cccc33 100644 --- a/src/frontend/src/components/panels/PanelGroup.tsx +++ b/src/frontend/src/components/panels/PanelGroup.tsx @@ -84,10 +84,30 @@ function BasePanelGroup({ id: id }); - const allPanels = useMemo( - () => [...panels, ...pluginPanels], - [panels, pluginPanels] - ); + // Rebuild the list of panels + const allPanels = useMemo(() => { + const _panels = [...panels]; + + // Add plugin panels + pluginPanels?.forEach((panel) => { + let panelKey = panel.name; + + // Check if panel with this name already exists + const existingPanel = _panels.find((p) => p.name === panelKey); + + if (existingPanel) { + // Create a unique key for the panel which includes the plugin slug + panelKey = identifierString(`${panel.pluginName}-${panel.name}`); + } + + _panels.push({ + ...panel, + name: panelKey + }); + }); + + return _panels; + }, [panels, pluginPanels]); const activePanels = useMemo( () => allPanels.filter((panel) => !panel.hidden && !panel.disabled), diff --git a/src/frontend/src/hooks/UsePluginPanels.tsx b/src/frontend/src/hooks/UsePluginPanels.tsx index 6eb43a865b..d7491520d8 100644 --- a/src/frontend/src/hooks/UsePluginPanels.tsx +++ b/src/frontend/src/hooks/UsePluginPanels.tsx @@ -15,7 +15,6 @@ import { } from '../components/plugins/PluginUIFeature'; import { ApiEndpoints } from '../enums/ApiEndpoints'; import type { ModelType } from '../enums/ModelType'; -import { identifierString } from '../functions/conversion'; import { apiUrl } from '../states/ApiState'; import { useGlobalSettingsState } from '../states/SettingsState'; @@ -30,6 +29,14 @@ export type PluginPanelContext = InvenTreeContext & { instance?: any; }; +/** + * Type definition for a plugin panel which extends the standard PanelType + * @param pluginName - The name of the plugin which provides this panel + */ +export type PluginPanelType = PanelType & { + pluginName: string; +}; + export function usePluginPanels({ instance, model, @@ -38,7 +45,7 @@ export function usePluginPanels({ instance?: any; model?: ModelType | string; id?: string | number | null; -}): PanelType[] { +}): PluginPanelType[] { const globalSettings = useGlobalSettingsState(); const pluginPanelsEnabled: boolean = useMemo( @@ -86,13 +93,10 @@ export function usePluginPanels({ }; }, [model, id, instance, inventreeContext]); - const pluginPanels: PanelType[] = useMemo(() => { + const pluginPanels: PluginPanelType[] = useMemo(() => { return ( pluginData?.map((props: PluginUIFeature) => { const iconName: string = props?.icon || 'ti:plug:outline'; - const identifier = identifierString( - `${props.plugin_name}-${props.key}` - ); const pluginContext: any = { ...contextData, @@ -100,7 +104,8 @@ export function usePluginPanels({ }; return { - name: identifier, + name: props.key, + pluginName: props.plugin_name, label: props.title, icon: , content: (