From 4739d59c0b6128cda3adb67a1772eb65ae3a8ec2 Mon Sep 17 00:00:00 2001 From: Oliver Date: Tue, 21 Jul 2026 16:12:00 +1000 Subject: [PATCH] [bug] Bom table fix (#12436) * Fix logic for table context menu * Memoize handleCellContextMenu --- .../src/components/tables/InvenTreeTable.tsx | 133 ++++++++++-------- 1 file changed, 73 insertions(+), 60 deletions(-) diff --git a/src/frontend/src/components/tables/InvenTreeTable.tsx b/src/frontend/src/components/tables/InvenTreeTable.tsx index 43f70b70b9..15ef3cde1d 100644 --- a/src/frontend/src/components/tables/InvenTreeTable.tsx +++ b/src/frontend/src/components/tables/InvenTreeTable.tsx @@ -766,69 +766,82 @@ export function InvenTreeTableInternal>({ }, [props.onCellContextMenu, props.rowActions, props.modelType]); // Callback when a cell is right-clicked - const handleCellContextMenu = ({ - record, - column, - event - }: { - record: any; - column: any; - event: any; - }) => { - if (column?.noContext === true) { - return; - } - if (props.onCellContextMenu) { - return props.onCellContextMenu(record, event); - } - - const empty = () => {}; - let items: ContextMenuItemOptions[] = []; - - if (!!props.rowActions) { - items = props.rowActions(record).map((action) => ({ - key: action.title ?? '', - title: action.title ?? '', - color: action.color, - icon: action.icon, - onClick: action.onClick ?? empty, - hidden: action.hidden, - disabled: action.disabled - })); - } - - if (props.modelType && props.detailAction !== false) { - // Add action to navigate to the detail view - const accessor = props.modelField ?? 'pk'; - const pk = resolveItem(record, accessor); - const url = getDetailUrl(props.modelType, pk); - - const model: string | undefined = - ModelInformationDict[props.modelType]?.label?.(); - - let detailsText: string = t`View details`; - - if (!!model) { - detailsText = t`View ${model}`; + const handleCellContextMenu = useCallback( + ({ + record, + column, + event + }: { + record: any; + column: any; + event: any; + }) => { + if (column?.noContext === true) { + return; + } + if (props.onCellContextMenu) { + return props.onCellContextMenu(record, event); } - items.push({ - key: 'detail', - title: detailsText, - icon: , - onClick: (event: any) => { - cancelEvent(event); - if (eventModified(event as any)) { - navigateToLink(url, navigate, event); - } else { - showRowPreview(pk); - } - } - }); - } + const empty = () => {}; + let items: ContextMenuItemOptions[] = []; - return showContextMenu?.(items)(event); - }; + if (!!props.rowActions) { + items = props.rowActions(record).map((action) => ({ + key: action.title ?? '', + title: action.title ?? '', + color: action.color, + icon: action.icon, + onClick: action.onClick ?? empty, + hidden: action.hidden, + disabled: action.disabled + })); + } + + if (props.modelType && props.detailAction !== false) { + // Add action to navigate to the detail view + const accessor = props.modelField ?? 'pk'; + const pk = resolveItem(record, accessor); + const url = getDetailUrl(props.modelType, pk); + + const model: string | undefined = + ModelInformationDict[props.modelType]?.label?.(); + + let detailsText: string = t`View details`; + + if (!!model) { + detailsText = t`View ${model}`; + } + + items.push({ + key: 'detail', + title: detailsText, + icon: , + onClick: (event: any) => { + cancelEvent(event); + if (!showPreviewPanel || eventModified(event as any)) { + navigateToLink(url, navigate, event); + } else { + showRowPreview(pk); + } + } + }); + } + + return showContextMenu?.(items)(event); + }, + [ + props.onCellContextMenu, + props.rowActions, + props.modelType, + props.detailAction, + props.modelField, + showPreviewPanel, + showRowPreview, + showContextMenu, + navigate + ] + ); // Pagination refresh table if pageSize changes const updatePageSize = useCallback((size: number) => {