2
0
mirror of https://github.com/inventree/InvenTree.git synced 2026-05-17 14:58:36 +00:00

[bug] Bulk edit fix (#11945)

* Prevent editing of items which do not point directly to the part

* Allow table to define which records can be selected
This commit is contained in:
Oliver
2026-05-15 00:24:22 +10:00
committed by GitHub
parent 701a788a6e
commit c931ab6815
3 changed files with 30 additions and 8 deletions
+2
View File
@@ -173,6 +173,7 @@ export type RowViewProps = RowAction & RowModelProps;
* @param barcodeActions : any[] - List of barcode actions
* @param tableFilters : TableFilter[] - List of custom filters
* @param tableActions : any[] - List of custom action groups
* @param isRecordSelectable : (record: any, index: number) => boolean - Callback function to determine if a row is selectable
* @param detailAction: boolean - Enable detail action for each row (default = true)
* @param dataFormatter : (data: any) => any - Callback function to reformat data returned by server (if not in default format)
* @param rowActions : (record: any) => RowAction[] - Callback function to generate row actions
@@ -203,6 +204,7 @@ export type InvenTreeTableProps<T = any> = {
barcodeActions?: React.ReactNode[];
tableFilters?: TableFilter[];
tableActions?: React.ReactNode[];
isRecordSelectable?: (record: T, index: number) => boolean;
rowExpansion?: DataTableRowExpansionProps<T>;
dataFormatter?: (data: any) => any;
rowActions?: (record: T) => RowAction[];
@@ -860,6 +860,7 @@ export function InvenTreeTableInternal<T extends Record<string, any>>({
onSelectedRecordsChange={
enableSelection ? onSelectedRecordsChange : undefined
}
isRecordSelectable={tableProps.isRecordSelectable}
rowExpansion={rowExpansion}
fetching={isFetching}
noRecordsText={missingRecordsText}
+27 -8
View File
@@ -9,7 +9,7 @@ import useTable from '@lib/hooks/UseTable';
import { ActionButton, RowEditAction, UserRoles } from '@lib/index';
import type { TableFilter } from '@lib/types/Filters';
import type { RowAction, TableColumn } from '@lib/types/Tables';
import { IconReplace } from '@tabler/icons-react';
import { IconExclamationCircle, IconReplace } from '@tabler/icons-react';
import { formatDecimal } from '../../defaults/formatters';
import { bomItemFields } from '../../forms/BomForms';
import {
@@ -132,7 +132,10 @@ export function UsedInTable({
return [
RowEditAction({
hidden: locked || !user.hasChangeRole(UserRoles.bom),
hidden:
locked ||
record.sub_part != partId ||
!user.hasChangeRole(UserRoles.bom),
onClick: () => {
setSelectedBomItem(record);
editBomItem.open();
@@ -140,14 +143,19 @@ export function UsedInTable({
})
];
},
[user]
[user, partId]
);
const bulkReplaceParts = useMemo(() => {}, [table.selectedRecords]);
const bulkReplaceRecords: any[] = useMemo(() => {
// Only allow replacements of BomItem entries which point to this part
return table.selectedRecords.filter(
(record: any) => record.sub_part === partId
);
}, [table.selectedRecords, partId]);
const bulkReplace = useBulkEditApiFormModal({
url: ApiEndpoints.bom_list,
items: table.selectedIds,
items: bulkReplaceRecords.map((record: any) => record.pk),
title: t`Replace Component`,
submitText: t`Replace`,
preFormContent: (
@@ -160,8 +168,18 @@ export function UsedInTable({
>
<Text>{t`This action cannot be easily undone, so please ensure you have selected the correct assemblies.`}</Text>
</Alert>
<Text>{t`The selected assemblies will be updated with the new component.`}</Text>
{table.selectedRecords.map((record: any) => {
{bulkReplaceRecords.length ? (
<Text>{t`The selected assemblies will be updated with the new component.`}</Text>
) : (
<Alert
color='red'
icon={<IconExclamationCircle />}
title={t`No valid items selected`}
>
<Text>{t`Please select one or more valid assemblies to replace the component.`}</Text>
</Alert>
)}
{bulkReplaceRecords?.map((record: any) => {
return <RenderPartColumn part={record.part_detail} key={record.pk} />;
})}
<Divider />
@@ -212,7 +230,8 @@ export function UsedInTable({
modelType: ModelType.part,
modelField: 'part',
tableActions: tableActions,
tableFilters: tableFilters
tableFilters: tableFilters,
isRecordSelectable: (record: any) => record.sub_part === partId
}}
/>
</>