2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-10-14 21:22:20 +00:00

add duplicate part action to parts table (#10481)

Co-authored-by: Oliver <oliver.henry.walters@gmail.com>
This commit is contained in:
Steve Groesz
2025-10-05 07:11:48 -05:00
committed by GitHub
parent 0dd38dbca4
commit 2e7e8d5eee

View File

@@ -4,12 +4,17 @@ import { IconShoppingCart } from '@tabler/icons-react';
import { type ReactNode, useCallback, useMemo, useState } from 'react';
import { AddItemButton } from '@lib/components/AddItemButton';
import { type RowAction, RowEditAction } from '@lib/components/RowActions';
import {
type RowAction,
RowDuplicateAction,
RowEditAction
} from '@lib/components/RowActions';
import { ApiEndpoints } from '@lib/enums/ApiEndpoints';
import { ModelType } from '@lib/enums/ModelType';
import { UserRoles } from '@lib/enums/Roles';
import { apiUrl } from '@lib/functions/Api';
import type { TableFilter } from '@lib/types/Filters';
import type { ApiFormFieldSet } from '@lib/types/Forms';
import type { TableColumn } from '@lib/types/Tables';
import type { InvenTreeTableProps } from '@lib/types/Tables';
import { ActionDropdown } from '../../components/items/ActionDropdown';
@@ -23,6 +28,7 @@ import {
useEditApiFormModal
} from '../../hooks/UseForm';
import { useTable } from '../../hooks/UseTable';
import { useGlobalSettingsState } from '../../states/SettingsStates';
import { useUserState } from '../../states/UserState';
import {
CategoryColumn,
@@ -333,6 +339,7 @@ export function PartListTable({
const table = useTable('part-list');
const user = useUserState();
const globalSettings = useGlobalSettingsState();
const initialPartData = useMemo(() => {
return defaultPartData ?? props.params ?? {};
@@ -347,16 +354,64 @@ export function PartListTable({
modelType: ModelType.part
});
const [selectedPart, setSelectedPart] = useState<number>(-1);
const [selectedPart, setSelectedPart] = useState<any>({});
const editPart = useEditApiFormModal({
url: ApiEndpoints.part_list,
pk: selectedPart,
pk: selectedPart.pk,
title: t`Edit Part`,
fields: usePartFields({ create: false }),
onFormSuccess: table.refreshTable
});
const createPartFields = usePartFields({ create: true });
const duplicatePartFields: ApiFormFieldSet = useMemo(() => {
return {
...createPartFields,
duplicate: {
children: {
part: {
value: selectedPart.pk,
hidden: true
},
copy_image: {
value: true
},
copy_bom: {
value:
selectedPart.assembly && globalSettings.isSet('PART_COPY_BOM'),
hidden: !selectedPart.assembly
},
copy_notes: {
value: true
},
copy_parameters: {
value: globalSettings.isSet('PART_COPY_PARAMETERS')
},
copy_tests: {
value: selectedPart.testable,
hidden: !selectedPart.testable
}
}
}
};
}, [createPartFields, globalSettings, selectedPart]);
const duplicatePart = useCreateApiFormModal({
url: ApiEndpoints.part_list,
title: t`Add Part`,
fields: duplicatePartFields,
initialData: {
...selectedPart,
active: true,
locked: false
},
follow: false,
modelType: ModelType.part,
onFormSuccess: table.refreshTable
});
const setCategory = useBulkEditApiFormModal({
url: ApiEndpoints.part_list,
items: table.selectedIds,
@@ -372,18 +427,26 @@ export function PartListTable({
const rowActions = useCallback(
(record: any): RowAction[] => {
const can_edit = user.hasChangePermission(ModelType.part);
const can_add = user.hasAddPermission(ModelType.part);
return [
RowEditAction({
hidden: !can_edit,
onClick: () => {
setSelectedPart(record.pk);
setSelectedPart(record);
editPart.open();
}
}),
RowDuplicateAction({
hidden: !can_add,
onClick: () => {
setSelectedPart(record);
duplicatePart.open();
}
})
];
},
[user, editPart]
[user, editPart, duplicatePart]
);
const tableActions = useMemo(() => {
@@ -426,6 +489,7 @@ export function PartListTable({
return (
<>
{newPart.modal}
{duplicatePart.modal}
{editPart.modal}
{setCategory.modal}
{orderPartsWizard.wizard}