Implement parameter duplication for more models:

- Company
- ManufacturerPart
- SupplierPart
This commit is contained in:
Oliver Walters 2026-07-02 12:38:07 +00:00
parent 2c94854253
commit 3303e4664f
6 changed files with 106 additions and 14 deletions

View File

@ -21,11 +21,13 @@ import { TagsField } from './CommonFields';
export function useSupplierPartFields({
manufacturerId,
manufacturerPartId,
partId
partId,
duplicateSupplierPartId
}: {
manufacturerId?: number;
manufacturerPartId?: number;
partId?: number;
duplicateSupplierPartId?: number | null;
}) {
const [part, setPart] = useState<any>({});
@ -95,14 +97,37 @@ export function useSupplierPartFields({
icon: <IconPackage />
},
primary: {},
active: {}
active: {},
duplicate: {
children: {
original: {
value: duplicateSupplierPartId,
hidden: true
},
copy_parameters: {}
}
}
};
if (!duplicateSupplierPartId) {
delete fields.duplicate;
}
return fields;
}, [manufacturerId, manufacturerPartId, partId, part]);
}, [
manufacturerId,
manufacturerPartId,
partId,
part,
duplicateSupplierPartId
]);
}
export function useManufacturerPartFields() {
export function useManufacturerPartFields({
duplicateManufacturerPartId
}: {
duplicateManufacturerPartId?: number | null;
} = {}) {
return useMemo(() => {
const fields: ApiFormFieldSet = {
part: {},
@ -120,18 +145,35 @@ export function useManufacturerPartFields() {
MPN: {},
description: {},
tags: TagsField({}),
link: {}
link: {},
duplicate: {
children: {
original: {
value: duplicateManufacturerPartId,
hidden: true
},
copy_parameters: {}
}
}
};
if (!duplicateManufacturerPartId) {
delete fields.duplicate;
}
return fields;
}, []);
}, [duplicateManufacturerPartId]);
}
/**
* Field set for editing a company instance
*/
export function companyFields(): ApiFormFieldSet {
return {
export function companyFields({
duplicateCompanyId
}: {
duplicateCompanyId?: number | null;
} = {}): ApiFormFieldSet {
const fields: ApiFormFieldSet = {
name: {},
description: {},
website: {
@ -151,6 +193,21 @@ export function companyFields(): ApiFormFieldSet {
is_supplier: {},
is_manufacturer: {},
is_customer: {},
active: {}
active: {},
duplicate: {
children: {
original: {
value: duplicateCompanyId,
hidden: true
},
copy_parameters: {}
}
}
};
if (!duplicateCompanyId) {
delete fields.duplicate;
}
return fields;
}

View File

@ -31,6 +31,7 @@ import { DetailsImage } from '../../components/details/DetailsImage';
import { ItemDetailsGrid } from '../../components/details/ItemDetails';
import {
DeleteItemAction,
DuplicateItemAction,
EditItemAction,
OptionsActionDropdown
} from '../../components/items/ActionDropdown';
@ -43,6 +44,7 @@ import { PanelGroup } from '../../components/panels/PanelGroup';
import ParametersPanel from '../../components/panels/ParametersPanel';
import { companyFields } from '../../forms/CompanyForms';
import {
useCreateApiFormModal,
useDeleteApiFormModal,
useEditApiFormModal
} from '../../hooks/UseForm';
@ -293,11 +295,23 @@ export default function CompanyDetail(props: Readonly<CompanyDetailProps>) {
url: ApiEndpoints.company_list,
pk: company?.pk,
title: t`Edit Company`,
fields: companyFields(),
fields: useMemo(() => companyFields({}), []),
queryParams: new URLSearchParams({ tags: 'true' }),
onFormSuccess: refreshInstance
});
const duplicateCompany = useCreateApiFormModal({
url: ApiEndpoints.company_list,
title: t`Duplicate Company`,
initialData: useMemo(() => ({ ...company }), [company]),
fields: useMemo(
() => companyFields({ duplicateCompanyId: company?.pk }),
[company]
),
follow: true,
modelType: ModelType.company
});
const deleteCompany = useDeleteApiFormModal({
url: ApiEndpoints.company_list,
pk: company?.pk,
@ -322,6 +336,10 @@ export default function CompanyDetail(props: Readonly<CompanyDetailProps>) {
hidden: !user.hasChangeRole(UserRoles.purchase_order),
onClick: () => editCompany.open()
}),
DuplicateItemAction({
hidden: !user.hasAddRole(UserRoles.purchase_order),
onClick: () => duplicateCompany.open()
}),
DeleteItemAction({
hidden: !user.hasDeleteRole(UserRoles.purchase_order),
onClick: () => deleteCompany.open()
@ -345,6 +363,7 @@ export default function CompanyDetail(props: Readonly<CompanyDetailProps>) {
<>
{editCompany.modal}
{deleteCompany.modal}
{duplicateCompany.modal}
<InstanceDetail
query={instanceQuery}
requiredPermission={ModelType.company}

View File

@ -220,10 +220,14 @@ export default function ManufacturerPartDetail() {
onFormSuccess: refreshInstance
});
const duplicateManufacturerPartFields = useManufacturerPartFields({
duplicateManufacturerPartId: manufacturerPart?.pk
});
const duplicateManufacturerPart = useCreateApiFormModal({
url: ApiEndpoints.manufacturer_part_list,
title: t`Add Manufacturer Part`,
fields: editManufacturerPartFields,
fields: duplicateManufacturerPartFields,
initialData: {
...manufacturerPart
},

View File

@ -357,10 +357,14 @@ export default function SupplierPartDetail() {
}
});
const duplicateSupplierPartFields = useSupplierPartFields({
duplicateSupplierPartId: supplierPart?.pk
});
const duplicateSupplierPart = useCreateApiFormModal({
url: ApiEndpoints.supplier_part_list,
title: t`Add Supplier Part`,
fields: supplierPartFields,
fields: duplicateSupplierPartFields,
initialData: {
...supplierPart
},

View File

@ -133,10 +133,14 @@ export function ManufacturerPartTable({
table: table
});
const duplicateManufacturerPartFields = useManufacturerPartFields({
duplicateManufacturerPartId: selectedPart?.pk
});
const duplicateManufacturerPart = useCreateApiFormModal({
url: ApiEndpoints.manufacturer_part_list,
title: t`Add Manufacturer Part`,
fields: useMemo(() => manufacturerPartFields, [manufacturerPartFields]),
fields: duplicateManufacturerPartFields,
table: table,
initialData: {
...selectedPart

View File

@ -292,10 +292,14 @@ export function SupplierPartTable({
}
});
const duplicateSupplierPartFields = useSupplierPartFields({
duplicateSupplierPartId: selectedSupplierPart?.pk
});
const duplicateSupplierPart = useCreateApiFormModal({
url: ApiEndpoints.supplier_part_list,
title: t`Add Supplier Part`,
fields: useMemo(() => editSupplierPartFields, [editSupplierPartFields]),
fields: duplicateSupplierPartFields,
initialData: {
...selectedSupplierPart,
primary: false,