diff --git a/src/frontend/src/components/nav/PanelGroup.tsx b/src/frontend/src/components/nav/PanelGroup.tsx index 720cbc4ded..d4a6d3e57f 100644 --- a/src/frontend/src/components/nav/PanelGroup.tsx +++ b/src/frontend/src/components/nav/PanelGroup.tsx @@ -34,8 +34,9 @@ import { PanelType } from './Panel'; * * @param pageKey - Unique key for this panel group * @param panels - List of panels to display - * @param targetModel - The target model for this panel group - * @param targetId - The target ID for this panel group (set to *null* for groups which do not target a specific model instance) + * @param model - The target model for this panel group (e.g. 'part' / 'salesorder') + * @param id - The target ID for this panel group (set to *null* for groups which do not target a specific model instance) + * @param instance - The target model instance for this panel group * @param selectedPanel - The currently selected panel * @param onPanelChange - Callback when the active panel changes * @param collapsible - If true, the panel group can be collapsed (defaults to true) @@ -43,9 +44,9 @@ import { PanelType } from './Panel'; export type PanelProps = { pageKey: string; panels: PanelType[]; - targetInstance?: any; - targetModel?: ModelType | string; - targetId?: number | null; + instance?: any; + model?: ModelType | string; + id?: number | null; selectedPanel?: string; onPanelChange?: (panel: string) => void; collapsible?: boolean; @@ -56,9 +57,9 @@ function BasePanelGroup({ panels, onPanelChange, selectedPanel, - targetInstance, - targetModel, - targetId, + instance, + model, + id, collapsible = true }: Readonly): ReactNode { const location = useLocation(); @@ -67,9 +68,9 @@ function BasePanelGroup({ // Hook to load plugins for this panel const pluginPanels = usePluginPanels({ - targetModel: targetModel, - targetInstance: targetInstance, - targetId: targetId + model: model, + instance: instance, + id: id }); const allPanels = useMemo( diff --git a/src/frontend/src/components/plugins/PluginElement.tsx b/src/frontend/src/components/plugins/PluginElement.tsx new file mode 100644 index 0000000000..7e14e33afc --- /dev/null +++ b/src/frontend/src/components/plugins/PluginElement.tsx @@ -0,0 +1,26 @@ +import { AxiosInstance } from 'axios'; + +import { ModelType } from '../../enums/ModelType'; + +/* + * A set of properties which are passed to a plugin, + * for rendering an element in the user interface. + * + * @param target - The target HTML element to render the plugin into + * @param model - The model type for the plugin (e.g. 'part' / 'purchaseorder') + * @param id - The ID (primary key) of the model instance for the plugin + * @param instance - The model instance data (if available) + * @param api - The Axios API instance (see ../states/ApiState.tsx) + * @param user - The current user instance (see ../states/UserState.tsx) + * @param navigate - The navigation function (see react-router-dom) + */ +export interface PluginElementProps { + target: HTMLDivElement | undefined; + model?: ModelType | string; + id?: number | null; + instance?: any; + api: AxiosInstance; + user: any; + host: string; + navigate: any; +} diff --git a/src/frontend/src/components/plugins/PluginPanel.tsx b/src/frontend/src/components/plugins/PluginPanel.tsx index c1818d2c82..765d147d84 100644 --- a/src/frontend/src/components/plugins/PluginPanel.tsx +++ b/src/frontend/src/components/plugins/PluginPanel.tsx @@ -9,28 +9,14 @@ import { ModelType } from '../../enums/ModelType'; import { useLocalState } from '../../states/LocalState'; import { useUserState } from '../../states/UserState'; import { PanelType } from '../nav/Panel'; +import { PluginElementProps } from './PluginElement'; interface PluginPanelProps extends PanelType { source?: string; params?: any; - targetInstance?: any; - targetModel?: ModelType | string; - targetId?: string | number | null; -} - -/* - * Definition of what we pass into a plugin panel - */ -interface PluginPanelParameters { - target: HTMLDivElement; - props: PluginPanelProps; - targetModel?: ModelType | string; - targetId?: number | null; - targetInstance?: any; - api: AxiosInstance; - user: any; - host: string; - navigate: any; + instance?: any; + model?: ModelType | string; + id?: number | null; } // Placeholder content for a panel with no content @@ -93,17 +79,19 @@ export default function PluginPanel({ props }: { props: PluginPanelProps }) { module.render_panel && typeof module.render_panel === 'function' ) { - module.render_panel({ + // Set of attributes to pass through to the plugin for rendering + let attributes: PluginElementProps = { target: ref.current, - props: props, + model: props.model, + id: props.id, + instance: props.instance, api: api, - host: host, user: user, - navigate: navigate, - targetModel: props.targetModel, - targetId: props.targetId, - targetInstance: props.targetInstance - }); + host: host, + navigate: navigate + }; + + module.render_panel(attributes); } }; diff --git a/src/frontend/src/hooks/UsePluginPanels.tsx b/src/frontend/src/hooks/UsePluginPanels.tsx index de34be1f7c..e19e435039 100644 --- a/src/frontend/src/hooks/UsePluginPanels.tsx +++ b/src/frontend/src/hooks/UsePluginPanels.tsx @@ -18,13 +18,13 @@ export type PluginPanelState = { }; export function usePluginPanels({ - targetInstance, - targetModel, - targetId + instance, + model, + id }: { - targetInstance?: any; - targetModel?: ModelType | string; - targetId?: string | number | null; + instance?: any; + model?: ModelType | string; + id?: string | number | null; }): PluginPanelState { const globalSettings = useGlobalSettingsState(); @@ -33,20 +33,20 @@ export function usePluginPanels({ [globalSettings] ); - // API query to fetch information on available plugin panels + // API query to fetch initial information on available plugin panels const { isFetching, data } = useQuery({ - enabled: pluginPanelsEnabled && !!targetModel && targetId != undefined, - queryKey: [targetModel, targetId], + enabled: pluginPanelsEnabled && !!model && id != undefined, + queryKey: [model, id], queryFn: async () => { - if (!pluginPanelsEnabled || !targetModel) { + if (!pluginPanelsEnabled || !model) { return Promise.resolve([]); } return api .get(apiUrl(ApiEndpoints.plugin_panel_list), { params: { - target_model: targetModel, - target_id: targetId + target_model: model, + target_id: id } }) .then((response: any) => response.data) @@ -62,23 +62,23 @@ export function usePluginPanels({ data?.map((panel: any) => { const pluginKey = panel.plugin || 'plugin'; return { - name: identifierString(`${pluginKey}-${panel.name}`), + name: identifierString(`pluigin-${pluginKey}-${panel.name}`), label: panel.label || t`Plugin Panel`, icon: , content: ( ) }; }) ?? [] ); - }, [data, targetId, targetModel, targetInstance]); + }, [data, id, model, instance]); return { panels: panels diff --git a/src/frontend/src/pages/build/BuildDetail.tsx b/src/frontend/src/pages/build/BuildDetail.tsx index 5697d1c4a6..9438b39650 100644 --- a/src/frontend/src/pages/build/BuildDetail.tsx +++ b/src/frontend/src/pages/build/BuildDetail.tsx @@ -542,9 +542,9 @@ export default function BuildDetail() { diff --git a/src/frontend/src/pages/company/CompanyDetail.tsx b/src/frontend/src/pages/company/CompanyDetail.tsx index eb1b46da5c..55d1324f35 100644 --- a/src/frontend/src/pages/company/CompanyDetail.tsx +++ b/src/frontend/src/pages/company/CompanyDetail.tsx @@ -334,9 +334,9 @@ export default function CompanyDetail(props: Readonly) { diff --git a/src/frontend/src/pages/company/ManufacturerPartDetail.tsx b/src/frontend/src/pages/company/ManufacturerPartDetail.tsx index 1502f8468e..eb16b2651d 100644 --- a/src/frontend/src/pages/company/ManufacturerPartDetail.tsx +++ b/src/frontend/src/pages/company/ManufacturerPartDetail.tsx @@ -287,9 +287,9 @@ export default function ManufacturerPartDetail() { diff --git a/src/frontend/src/pages/company/SupplierPartDetail.tsx b/src/frontend/src/pages/company/SupplierPartDetail.tsx index 75d75fe21a..375546c771 100644 --- a/src/frontend/src/pages/company/SupplierPartDetail.tsx +++ b/src/frontend/src/pages/company/SupplierPartDetail.tsx @@ -379,9 +379,9 @@ export default function SupplierPartDetail() { diff --git a/src/frontend/src/pages/part/CategoryDetail.tsx b/src/frontend/src/pages/part/CategoryDetail.tsx index cd197a1bb1..25cae51208 100644 --- a/src/frontend/src/pages/part/CategoryDetail.tsx +++ b/src/frontend/src/pages/part/CategoryDetail.tsx @@ -315,9 +315,9 @@ export default function CategoryDetail() { diff --git a/src/frontend/src/pages/part/PartDetail.tsx b/src/frontend/src/pages/part/PartDetail.tsx index 4c0d5c2699..2131886bd4 100644 --- a/src/frontend/src/pages/part/PartDetail.tsx +++ b/src/frontend/src/pages/part/PartDetail.tsx @@ -1098,9 +1098,9 @@ export default function PartDetail() { {transferStockItems.modal} {countStockItems.modal} diff --git a/src/frontend/src/pages/purchasing/PurchaseOrderDetail.tsx b/src/frontend/src/pages/purchasing/PurchaseOrderDetail.tsx index 1a301c7eed..21ddc739e5 100644 --- a/src/frontend/src/pages/purchasing/PurchaseOrderDetail.tsx +++ b/src/frontend/src/pages/purchasing/PurchaseOrderDetail.tsx @@ -446,9 +446,9 @@ export default function PurchaseOrderDetail() { diff --git a/src/frontend/src/pages/sales/ReturnOrderDetail.tsx b/src/frontend/src/pages/sales/ReturnOrderDetail.tsx index f47d3f2dec..5f8c2559cc 100644 --- a/src/frontend/src/pages/sales/ReturnOrderDetail.tsx +++ b/src/frontend/src/pages/sales/ReturnOrderDetail.tsx @@ -434,9 +434,9 @@ export default function ReturnOrderDetail() { diff --git a/src/frontend/src/pages/sales/SalesOrderDetail.tsx b/src/frontend/src/pages/sales/SalesOrderDetail.tsx index 7945078c68..faa53a7c27 100644 --- a/src/frontend/src/pages/sales/SalesOrderDetail.tsx +++ b/src/frontend/src/pages/sales/SalesOrderDetail.tsx @@ -486,9 +486,9 @@ export default function SalesOrderDetail() { diff --git a/src/frontend/src/pages/stock/LocationDetail.tsx b/src/frontend/src/pages/stock/LocationDetail.tsx index fbcce3d3cc..6abdba1382 100644 --- a/src/frontend/src/pages/stock/LocationDetail.tsx +++ b/src/frontend/src/pages/stock/LocationDetail.tsx @@ -396,9 +396,9 @@ export default function Stock() { {transferStockItems.modal} {countStockItems.modal} diff --git a/src/frontend/src/pages/stock/StockDetail.tsx b/src/frontend/src/pages/stock/StockDetail.tsx index 9f0bc68911..bedbb8522f 100644 --- a/src/frontend/src/pages/stock/StockDetail.tsx +++ b/src/frontend/src/pages/stock/StockDetail.tsx @@ -631,9 +631,9 @@ export default function StockDetail() { {editStockItem.modal} {duplicateStockItem.modal}