From e03dafbdd627fcbaf3180a44b10729b1ede1ce52 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Tue, 18 Jun 2024 13:17:30 +0000 Subject: [PATCH] Example of plugin panel selection based on page --- src/backend/InvenTree/plugin/api.py | 64 ++++++++++++------- .../src/pages/part/CategoryDetail.tsx | 15 ++++- 2 files changed, 54 insertions(+), 25 deletions(-) diff --git a/src/backend/InvenTree/plugin/api.py b/src/backend/InvenTree/plugin/api.py index b898eb2c98..df737d4eab 100644 --- a/src/backend/InvenTree/plugin/api.py +++ b/src/backend/InvenTree/plugin/api.py @@ -427,29 +427,47 @@ class PluginPanelList(APIView): # TODO: Allow plugins to fill this data out ... - panels = [ - { - 'plugin': 'myplugin', - 'name': 'test-plugin', - 'label': 'My Plugin', - 'icon': 'part', - 'content': '
hello world
', - }, - { - 'plugin': 'myplugin', - 'name': 'test-plugin-2', - 'label': 'My Plugin 2', - 'icon': 'email', - 'content': '
hello world 2
', - }, - { - 'plugin': 'myplugin', - 'name': 'test-plugin-3', - 'label': 'My Plugin 3', - 'icon': 'website', - 'content': '
hello world 3
', - }, - ] + user = request.user + target_model = request.query_params.get('target_model', None) + target_id = request.query_params.get('target_id', None) + + if target_model == 'part' and target_id: + panels = [ + *panels, + { + 'plugin': 'myplugin', + 'name': 'test-plugin', + 'label': 'My Plugin', + 'icon': 'part', + 'content': '
hello world
', + }, + { + 'plugin': 'myplugin', + 'name': 'test-plugin-2', + 'label': 'My Plugin 2', + 'icon': 'email', + 'content': '
hello world 2
', + }, + { + 'plugin': 'myplugin', + 'name': 'test-plugin-3', + 'label': 'My Plugin 3', + 'icon': 'website', + 'content': '
hello world 3
', + }, + ] + + if target_model == 'partcategory': + panels = [ + *panels, + { + 'plugin': 'cat', + 'name': 'demo-cat', + 'label': 'Custom Category', + 'icon': 'customer', + 'content': 'This should only appear for a category', + }, + ] return Response(PluginSerializers.PluginPanelSerializer(panels, many=True).data) diff --git a/src/frontend/src/pages/part/CategoryDetail.tsx b/src/frontend/src/pages/part/CategoryDetail.tsx index a94999e396..ab6c7eeaf1 100644 --- a/src/frontend/src/pages/part/CategoryDetail.tsx +++ b/src/frontend/src/pages/part/CategoryDetail.tsx @@ -20,7 +20,8 @@ import { } from '../../components/items/ActionDropdown'; import NavigationTree from '../../components/nav/NavigationTree'; import { PageDetail } from '../../components/nav/PageDetail'; -import { PanelGroup, PanelType } from '../../components/nav/PanelGroup'; +import { PanelType } from '../../components/nav/Panel'; +import { PanelGroup } from '../../components/nav/PanelGroup'; import { ApiEndpoints } from '../../enums/ApiEndpoints'; import { ModelType } from '../../enums/ModelType'; import { UserRoles } from '../../enums/Roles'; @@ -31,6 +32,7 @@ import { useEditApiFormModal } from '../../hooks/UseForm'; import { useInstance } from '../../hooks/UseInstance'; +import { usePluginPanels } from '../../hooks/UsePluginPanels'; import { useUserState } from '../../states/UserState'; import ParametricPartTable from '../../tables/part/ParametricPartTable'; import { PartCategoryTable } from '../../tables/part/PartCategoryTable'; @@ -260,6 +262,15 @@ export default function CategoryDetail({}: {}) { [category, id] ); + const pluginPanels = usePluginPanels({ + targetModel: ModelType.partcategory, + targetId: id + }); + + const panels: PanelType[] = useMemo(() => { + return [...categoryPanels, ...pluginPanels.panels]; + }, [categoryPanels, pluginPanels]); + const breadcrumbs = useMemo( () => [ { name: t`Parts`, url: '/part' }, @@ -296,7 +307,7 @@ export default function CategoryDetail({}: {}) { }} actions={categoryActions} /> - + );