From af6cce3aba66ff3d6109558ea773a339e084872c Mon Sep 17 00:00:00 2001 From: Oliver Date: Wed, 12 Nov 2025 00:08:45 +1100 Subject: [PATCH] [UI] Duplicate supplier part (#10809) * Allow duplication of supplier part * Bug fix for pack quantity display * Allow duplication of ManufacturerPart --- .../purchasing/ManufacturerPartTable.tsx | 33 +++++++++++---- .../tables/purchasing/SupplierPartTable.tsx | 40 ++++++++++++++----- 2 files changed, 55 insertions(+), 18 deletions(-) diff --git a/src/frontend/src/tables/purchasing/ManufacturerPartTable.tsx b/src/frontend/src/tables/purchasing/ManufacturerPartTable.tsx index b3920b9428..01871f0eb4 100644 --- a/src/frontend/src/tables/purchasing/ManufacturerPartTable.tsx +++ b/src/frontend/src/tables/purchasing/ManufacturerPartTable.tsx @@ -5,6 +5,7 @@ import { AddItemButton } from '@lib/components/AddItemButton'; import { type RowAction, RowDeleteAction, + RowDuplicateAction, RowEditAction } from '@lib/components/RowActions'; import { ApiEndpoints } from '@lib/enums/ApiEndpoints'; @@ -88,9 +89,7 @@ export function ManufacturerPartTable({ const manufacturerPartFields = useManufacturerPartFields(); - const [selectedPart, setSelectedPart] = useState( - undefined - ); + const [selectedPart, setSelectedPart] = useState(undefined); const createManufacturerPart = useCreateApiFormModal({ url: ApiEndpoints.manufacturer_part_list, @@ -105,15 +104,25 @@ export function ManufacturerPartTable({ const editManufacturerPart = useEditApiFormModal({ url: ApiEndpoints.manufacturer_part_list, - pk: selectedPart, + pk: selectedPart?.pk, title: t`Edit Manufacturer Part`, - fields: manufacturerPartFields, + fields: useMemo(() => manufacturerPartFields, [manufacturerPartFields]), table: table }); + const duplicateManufacturerPart = useCreateApiFormModal({ + url: ApiEndpoints.manufacturer_part_list, + title: t`Add Manufacturer Part`, + fields: useMemo(() => manufacturerPartFields, [manufacturerPartFields]), + table: table, + initialData: { + ...selectedPart + } + }); + const deleteManufacturerPart = useDeleteApiFormModal({ url: ApiEndpoints.manufacturer_part_list, - pk: selectedPart, + pk: selectedPart?.pk, title: t`Delete Manufacturer Part`, table: table }); @@ -157,14 +166,21 @@ export function ManufacturerPartTable({ RowEditAction({ hidden: !user.hasChangeRole(UserRoles.purchase_order), onClick: () => { - setSelectedPart(record.pk); + setSelectedPart(record); editManufacturerPart.open(); } }), + RowDuplicateAction({ + hidden: !user.hasAddRole(UserRoles.purchase_order), + onClick: () => { + setSelectedPart(record); + duplicateManufacturerPart.open(); + } + }), RowDeleteAction({ hidden: !user.hasDeleteRole(UserRoles.purchase_order), onClick: () => { - setSelectedPart(record.pk); + setSelectedPart(record); deleteManufacturerPart.open(); } }) @@ -176,6 +192,7 @@ export function ManufacturerPartTable({ return ( <> {createManufacturerPart.modal} + {duplicateManufacturerPart.modal} {editManufacturerPart.modal} {deleteManufacturerPart.modal} { const part = record?.part_detail ?? {}; @@ -126,7 +125,7 @@ export function SupplierPartTable({ if (part.units) { extra.push( - + {t`Base units`} : {part.units} ); @@ -134,7 +133,7 @@ export function SupplierPartTable({ return ( @@ -236,19 +235,32 @@ export function SupplierPartTable({ const editSupplierPartFields = useSupplierPartFields({}); - const [selectedSupplierPart, setSelectedSupplierPart] = useState(0); + const [selectedSupplierPart, setSelectedSupplierPart] = + useState(undefined); const editSupplierPart = useEditApiFormModal({ url: ApiEndpoints.supplier_part_list, - pk: selectedSupplierPart, + pk: selectedSupplierPart?.pk, title: t`Edit Supplier Part`, - fields: editSupplierPartFields, + fields: useMemo(() => editSupplierPartFields, [editSupplierPartFields]), table: table }); + const duplicateSupplierPart = useCreateApiFormModal({ + url: ApiEndpoints.supplier_part_list, + title: t`Add Supplier Part`, + fields: useMemo(() => editSupplierPartFields, [editSupplierPartFields]), + initialData: { + ...selectedSupplierPart, + active: true + }, + table: table, + successMessage: t`Supplier part created` + }); + const deleteSupplierPart = useDeleteApiFormModal({ url: ApiEndpoints.supplier_part_list, - pk: selectedSupplierPart, + pk: selectedSupplierPart?.pk, title: t`Delete Supplier Part`, table: table }); @@ -260,14 +272,21 @@ export function SupplierPartTable({ RowEditAction({ hidden: !user.hasChangeRole(UserRoles.purchase_order), onClick: () => { - setSelectedSupplierPart(record.pk); + setSelectedSupplierPart(record); editSupplierPart.open(); } }), + RowDuplicateAction({ + hidden: !user.hasAddRole(UserRoles.purchase_order), + onClick: () => { + setSelectedSupplierPart(record); + duplicateSupplierPart.open(); + } + }), RowDeleteAction({ hidden: !user.hasDeleteRole(UserRoles.purchase_order), onClick: () => { - setSelectedSupplierPart(record.pk); + setSelectedSupplierPart(record); deleteSupplierPart.open(); } }) @@ -280,6 +299,7 @@ export function SupplierPartTable({ <> {addSupplierPart.modal} {editSupplierPart.modal} + {duplicateSupplierPart.modal} {deleteSupplierPart.modal} {importPartWizard.wizard}