Cleanup code for passing data through to plugin panels

- Define interface type
- Shorten variable names
This commit is contained in:
Oliver Walters 2024-08-13 09:40:02 +00:00
parent 90c497e38a
commit 045f8fe069
15 changed files with 102 additions and 87 deletions

View File

@ -34,8 +34,9 @@ import { PanelType } from './Panel';
* *
* @param pageKey - Unique key for this panel group * @param pageKey - Unique key for this panel group
* @param panels - List of panels to display * @param panels - List of panels to display
* @param targetModel - The target model for this panel group * @param model - The target model for this panel group (e.g. 'part' / 'salesorder')
* @param targetId - The target ID for this panel group (set to *null* for groups which do not target a specific model instance) * @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 selectedPanel - The currently selected panel
* @param onPanelChange - Callback when the active panel changes * @param onPanelChange - Callback when the active panel changes
* @param collapsible - If true, the panel group can be collapsed (defaults to true) * @param collapsible - If true, the panel group can be collapsed (defaults to true)
@ -43,9 +44,9 @@ import { PanelType } from './Panel';
export type PanelProps = { export type PanelProps = {
pageKey: string; pageKey: string;
panels: PanelType[]; panels: PanelType[];
targetInstance?: any; instance?: any;
targetModel?: ModelType | string; model?: ModelType | string;
targetId?: number | null; id?: number | null;
selectedPanel?: string; selectedPanel?: string;
onPanelChange?: (panel: string) => void; onPanelChange?: (panel: string) => void;
collapsible?: boolean; collapsible?: boolean;
@ -56,9 +57,9 @@ function BasePanelGroup({
panels, panels,
onPanelChange, onPanelChange,
selectedPanel, selectedPanel,
targetInstance, instance,
targetModel, model,
targetId, id,
collapsible = true collapsible = true
}: Readonly<PanelProps>): ReactNode { }: Readonly<PanelProps>): ReactNode {
const location = useLocation(); const location = useLocation();
@ -67,9 +68,9 @@ function BasePanelGroup({
// Hook to load plugins for this panel // Hook to load plugins for this panel
const pluginPanels = usePluginPanels({ const pluginPanels = usePluginPanels({
targetModel: targetModel, model: model,
targetInstance: targetInstance, instance: instance,
targetId: targetId id: id
}); });
const allPanels = useMemo( const allPanels = useMemo(

View File

@ -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;
}

View File

@ -9,28 +9,14 @@ import { ModelType } from '../../enums/ModelType';
import { useLocalState } from '../../states/LocalState'; import { useLocalState } from '../../states/LocalState';
import { useUserState } from '../../states/UserState'; import { useUserState } from '../../states/UserState';
import { PanelType } from '../nav/Panel'; import { PanelType } from '../nav/Panel';
import { PluginElementProps } from './PluginElement';
interface PluginPanelProps extends PanelType { interface PluginPanelProps extends PanelType {
source?: string; source?: string;
params?: any; params?: any;
targetInstance?: any; instance?: any;
targetModel?: ModelType | string; model?: ModelType | string;
targetId?: string | number | null; id?: 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;
} }
// Placeholder content for a panel with no content // Placeholder content for a panel with no content
@ -93,17 +79,19 @@ export default function PluginPanel({ props }: { props: PluginPanelProps }) {
module.render_panel && module.render_panel &&
typeof module.render_panel === 'function' 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, target: ref.current,
props: props, model: props.model,
id: props.id,
instance: props.instance,
api: api, api: api,
host: host,
user: user, user: user,
navigate: navigate, host: host,
targetModel: props.targetModel, navigate: navigate
targetId: props.targetId, };
targetInstance: props.targetInstance
}); module.render_panel(attributes);
} }
}; };

View File

@ -18,13 +18,13 @@ export type PluginPanelState = {
}; };
export function usePluginPanels({ export function usePluginPanels({
targetInstance, instance,
targetModel, model,
targetId id
}: { }: {
targetInstance?: any; instance?: any;
targetModel?: ModelType | string; model?: ModelType | string;
targetId?: string | number | null; id?: string | number | null;
}): PluginPanelState { }): PluginPanelState {
const globalSettings = useGlobalSettingsState(); const globalSettings = useGlobalSettingsState();
@ -33,20 +33,20 @@ export function usePluginPanels({
[globalSettings] [globalSettings]
); );
// API query to fetch information on available plugin panels // API query to fetch initial information on available plugin panels
const { isFetching, data } = useQuery({ const { isFetching, data } = useQuery({
enabled: pluginPanelsEnabled && !!targetModel && targetId != undefined, enabled: pluginPanelsEnabled && !!model && id != undefined,
queryKey: [targetModel, targetId], queryKey: [model, id],
queryFn: async () => { queryFn: async () => {
if (!pluginPanelsEnabled || !targetModel) { if (!pluginPanelsEnabled || !model) {
return Promise.resolve([]); return Promise.resolve([]);
} }
return api return api
.get(apiUrl(ApiEndpoints.plugin_panel_list), { .get(apiUrl(ApiEndpoints.plugin_panel_list), {
params: { params: {
target_model: targetModel, target_model: model,
target_id: targetId target_id: id
} }
}) })
.then((response: any) => response.data) .then((response: any) => response.data)
@ -62,23 +62,23 @@ export function usePluginPanels({
data?.map((panel: any) => { data?.map((panel: any) => {
const pluginKey = panel.plugin || 'plugin'; const pluginKey = panel.plugin || 'plugin';
return { return {
name: identifierString(`${pluginKey}-${panel.name}`), name: identifierString(`pluigin-${pluginKey}-${panel.name}`),
label: panel.label || t`Plugin Panel`, label: panel.label || t`Plugin Panel`,
icon: <InvenTreeIcon icon={panel.icon ?? 'plugin'} />, icon: <InvenTreeIcon icon={panel.icon ?? 'plugin'} />,
content: ( content: (
<PluginPanel <PluginPanel
props={{ props={{
...panel, ...panel,
targetId: targetId, id: id,
targetModel: targetModel, model: model,
targetInstance: targetInstance instance: instance
}} }}
/> />
) )
}; };
}) ?? [] }) ?? []
); );
}, [data, targetId, targetModel, targetInstance]); }, [data, id, model, instance]);
return { return {
panels: panels panels: panels

View File

@ -542,9 +542,9 @@ export default function BuildDetail() {
<PanelGroup <PanelGroup
pageKey="build" pageKey="build"
panels={buildPanels} panels={buildPanels}
targetInstance={build} instance={build}
targetModel={ModelType.build} model={ModelType.build}
targetId={build.pk} id={build.pk}
/> />
</Stack> </Stack>
</InstanceDetail> </InstanceDetail>

View File

@ -334,9 +334,9 @@ export default function CompanyDetail(props: Readonly<CompanyDetailProps>) {
<PanelGroup <PanelGroup
pageKey="company" pageKey="company"
panels={companyPanels} panels={companyPanels}
targetInstance={company} instance={company}
targetModel={ModelType.company} model={ModelType.company}
targetId={company.pk} id={company.pk}
/> />
</Stack> </Stack>
</InstanceDetail> </InstanceDetail>

View File

@ -287,9 +287,9 @@ export default function ManufacturerPartDetail() {
<PanelGroup <PanelGroup
pageKey="manufacturerpart" pageKey="manufacturerpart"
panels={panels} panels={panels}
targetInstance={manufacturerPart} instance={manufacturerPart}
targetModel={ModelType.manufacturerpart} model={ModelType.manufacturerpart}
targetId={manufacturerPart.pk} id={manufacturerPart.pk}
/> />
</Stack> </Stack>
</InstanceDetail> </InstanceDetail>

View File

@ -379,9 +379,9 @@ export default function SupplierPartDetail() {
<PanelGroup <PanelGroup
pageKey="supplierpart" pageKey="supplierpart"
panels={panels} panels={panels}
targetInstance={supplierPart} instance={supplierPart}
targetModel={ModelType.supplierpart} model={ModelType.supplierpart}
targetId={supplierPart.pk} id={supplierPart.pk}
/> />
</Stack> </Stack>
</InstanceDetail> </InstanceDetail>

View File

@ -315,9 +315,9 @@ export default function CategoryDetail() {
<PanelGroup <PanelGroup
pageKey="partcategory" pageKey="partcategory"
panels={panels} panels={panels}
targetModel={ModelType.partcategory} model={ModelType.partcategory}
targetInstance={category} instance={category}
targetId={category.pk} id={category.pk}
/> />
</Stack> </Stack>
</InstanceDetail> </InstanceDetail>

View File

@ -1098,9 +1098,9 @@ export default function PartDetail() {
<PanelGroup <PanelGroup
pageKey="part" pageKey="part"
panels={partPanels} panels={partPanels}
targetInstance={part} instance={part}
targetModel={ModelType.part} model={ModelType.part}
targetId={part.pk} id={part.pk}
/> />
{transferStockItems.modal} {transferStockItems.modal}
{countStockItems.modal} {countStockItems.modal}

View File

@ -446,9 +446,9 @@ export default function PurchaseOrderDetail() {
<PanelGroup <PanelGroup
pageKey="purchaseorder" pageKey="purchaseorder"
panels={orderPanels} panels={orderPanels}
targetModel={ModelType.purchaseorder} model={ModelType.purchaseorder}
targetInstance={order} instance={order}
targetId={order.pk} id={order.pk}
/> />
</Stack> </Stack>
</InstanceDetail> </InstanceDetail>

View File

@ -434,9 +434,9 @@ export default function ReturnOrderDetail() {
<PanelGroup <PanelGroup
pageKey="returnorder" pageKey="returnorder"
panels={orderPanels} panels={orderPanels}
targetModel={ModelType.returnorder} model={ModelType.returnorder}
targetInstance={order} instance={order}
targetId={order.pk} id={order.pk}
/> />
</Stack> </Stack>
</InstanceDetail> </InstanceDetail>

View File

@ -486,9 +486,9 @@ export default function SalesOrderDetail() {
<PanelGroup <PanelGroup
pageKey="salesorder" pageKey="salesorder"
panels={orderPanels} panels={orderPanels}
targetModel={ModelType.salesorder} model={ModelType.salesorder}
targetId={order.pk} id={order.pk}
targetInstance={order} instance={order}
/> />
</Stack> </Stack>
</InstanceDetail> </InstanceDetail>

View File

@ -396,9 +396,9 @@ export default function Stock() {
<PanelGroup <PanelGroup
pageKey="stocklocation" pageKey="stocklocation"
panels={locationPanels} panels={locationPanels}
targetModel={ModelType.stocklocation} model={ModelType.stocklocation}
targetId={location.pk} id={location.pk}
targetInstance={location} instance={location}
/> />
{transferStockItems.modal} {transferStockItems.modal}
{countStockItems.modal} {countStockItems.modal}

View File

@ -631,9 +631,9 @@ export default function StockDetail() {
<PanelGroup <PanelGroup
pageKey="stockitem" pageKey="stockitem"
panels={stockPanels} panels={stockPanels}
targetModel={ModelType.stockitem} model={ModelType.stockitem}
targetId={stockitem.pk} id={stockitem.pk}
targetInstance={stockitem} instance={stockitem}
/> />
{editStockItem.modal} {editStockItem.modal}
{duplicateStockItem.modal} {duplicateStockItem.modal}