mirror of
https://github.com/inventree/InvenTree.git
synced 2025-10-30 20:55:42 +00:00
[UI] Duplicate part fixes (#10709)
* Refactor part duplication - Move duplication items into the form definition * Expand to part variants table
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
import { t } from '@lingui/core/macro';
|
import { t } from '@lingui/core/macro';
|
||||||
import { IconPackages } from '@tabler/icons-react';
|
import { IconBuildingStore, IconCopy, IconPackages } from '@tabler/icons-react';
|
||||||
import { useMemo, useState } from 'react';
|
import { useMemo, useState } from 'react';
|
||||||
|
|
||||||
import { ApiEndpoints } from '@lib/enums/ApiEndpoints';
|
import { ApiEndpoints } from '@lib/enums/ApiEndpoints';
|
||||||
@@ -12,8 +12,10 @@ import { useGlobalSettingsState } from '../states/SettingsStates';
|
|||||||
* Construct a set of fields for creating / editing a Part instance
|
* Construct a set of fields for creating / editing a Part instance
|
||||||
*/
|
*/
|
||||||
export function usePartFields({
|
export function usePartFields({
|
||||||
create = false
|
create = false,
|
||||||
|
duplicatePartInstance
|
||||||
}: {
|
}: {
|
||||||
|
duplicatePartInstance?: any;
|
||||||
create?: boolean;
|
create?: boolean;
|
||||||
}): ApiFormFieldSet {
|
}): ApiFormFieldSet {
|
||||||
const settings = useGlobalSettingsState();
|
const settings = useGlobalSettingsState();
|
||||||
@@ -89,6 +91,7 @@ export function usePartFields({
|
|||||||
};
|
};
|
||||||
|
|
||||||
fields.initial_supplier = {
|
fields.initial_supplier = {
|
||||||
|
icon: <IconBuildingStore />,
|
||||||
children: {
|
children: {
|
||||||
supplier: {
|
supplier: {
|
||||||
filters: {
|
filters: {
|
||||||
@@ -106,6 +109,36 @@ export function usePartFields({
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Additional fields for part duplication
|
||||||
|
if (create && duplicatePartInstance?.pk) {
|
||||||
|
fields.duplicate = {
|
||||||
|
icon: <IconCopy />,
|
||||||
|
children: {
|
||||||
|
part: {
|
||||||
|
value: duplicatePartInstance?.pk,
|
||||||
|
hidden: true
|
||||||
|
},
|
||||||
|
copy_image: {
|
||||||
|
value: true
|
||||||
|
},
|
||||||
|
copy_bom: {
|
||||||
|
value: settings.isSet('PART_COPY_BOM'),
|
||||||
|
hidden: !duplicatePartInstance?.assembly
|
||||||
|
},
|
||||||
|
copy_notes: {
|
||||||
|
value: true
|
||||||
|
},
|
||||||
|
copy_parameters: {
|
||||||
|
value: settings.isSet('PART_COPY_PARAMETERS')
|
||||||
|
},
|
||||||
|
copy_tests: {
|
||||||
|
value: true,
|
||||||
|
hidden: !duplicatePartInstance?.testable
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
if (settings.isSet('PART_REVISION_ASSEMBLY_ONLY')) {
|
if (settings.isSet('PART_REVISION_ASSEMBLY_ONLY')) {
|
||||||
fields.revision_of.filters['assembly'] = true;
|
fields.revision_of.filters['assembly'] = true;
|
||||||
}
|
}
|
||||||
@@ -126,7 +159,7 @@ export function usePartFields({
|
|||||||
}
|
}
|
||||||
|
|
||||||
return fields;
|
return fields;
|
||||||
}, [create, settings]);
|
}, [create, duplicatePartInstance, settings]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ import { UserRoles } from '@lib/enums/Roles';
|
|||||||
import { apiUrl } from '@lib/functions/Api';
|
import { apiUrl } from '@lib/functions/Api';
|
||||||
import { getDetailUrl } from '@lib/functions/Navigation';
|
import { getDetailUrl } from '@lib/functions/Navigation';
|
||||||
import { ActionButton } from '@lib/index';
|
import { ActionButton } from '@lib/index';
|
||||||
import type { ApiFormFieldSet, StockOperationProps } from '@lib/types/Forms';
|
import type { StockOperationProps } from '@lib/types/Forms';
|
||||||
import AdminButton from '../../components/buttons/AdminButton';
|
import AdminButton from '../../components/buttons/AdminButton';
|
||||||
import { PrintingActions } from '../../components/buttons/PrintingActions';
|
import { PrintingActions } from '../../components/buttons/PrintingActions';
|
||||||
import StarredToggleButton from '../../components/buttons/StarredToggleButton';
|
import StarredToggleButton from '../../components/buttons/StarredToggleButton';
|
||||||
@@ -1048,38 +1048,10 @@ export default function PartDetail() {
|
|||||||
onFormSuccess: refreshInstance
|
onFormSuccess: refreshInstance
|
||||||
});
|
});
|
||||||
|
|
||||||
const createPartFields = usePartFields({ create: true });
|
const duplicatePartFields = usePartFields({
|
||||||
|
create: true,
|
||||||
const duplicatePartFields: ApiFormFieldSet = useMemo(() => {
|
duplicatePartInstance: part
|
||||||
return {
|
});
|
||||||
...createPartFields,
|
|
||||||
duplicate: {
|
|
||||||
children: {
|
|
||||||
part: {
|
|
||||||
value: part.pk,
|
|
||||||
hidden: true
|
|
||||||
},
|
|
||||||
copy_image: {
|
|
||||||
value: true
|
|
||||||
},
|
|
||||||
copy_bom: {
|
|
||||||
value: part.assembly && globalSettings.isSet('PART_COPY_BOM'),
|
|
||||||
hidden: !part.assembly
|
|
||||||
},
|
|
||||||
copy_notes: {
|
|
||||||
value: true
|
|
||||||
},
|
|
||||||
copy_parameters: {
|
|
||||||
value: globalSettings.isSet('PART_COPY_PARAMETERS')
|
|
||||||
},
|
|
||||||
copy_tests: {
|
|
||||||
value: part.testable,
|
|
||||||
hidden: !part.testable
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}, [createPartFields, globalSettings, part]);
|
|
||||||
|
|
||||||
const duplicatePart = useCreateApiFormModal({
|
const duplicatePart = useCreateApiFormModal({
|
||||||
url: ApiEndpoints.part_list,
|
url: ApiEndpoints.part_list,
|
||||||
|
|||||||
@@ -336,11 +336,13 @@ function partTableFilters(): TableFilter[] {
|
|||||||
*/
|
*/
|
||||||
export function PartListTable({
|
export function PartListTable({
|
||||||
enableImport = true,
|
enableImport = true,
|
||||||
|
basePartInstance,
|
||||||
props,
|
props,
|
||||||
defaultPartData
|
defaultPartData
|
||||||
}: Readonly<{
|
}: Readonly<{
|
||||||
enableImport?: boolean;
|
enableImport?: boolean;
|
||||||
props?: InvenTreeTableProps;
|
props?: InvenTreeTableProps;
|
||||||
|
basePartInstance?: any;
|
||||||
defaultPartData?: any;
|
defaultPartData?: any;
|
||||||
}>) {
|
}>) {
|
||||||
const tableColumns = useMemo(() => partTableColumns(), []);
|
const tableColumns = useMemo(() => partTableColumns(), []);
|
||||||
@@ -384,10 +386,15 @@ export function PartListTable({
|
|||||||
return defaultPartData ?? props?.params ?? {};
|
return defaultPartData ?? props?.params ?? {};
|
||||||
}, [defaultPartData, props?.params]);
|
}, [defaultPartData, props?.params]);
|
||||||
|
|
||||||
|
const newPartFields = usePartFields({
|
||||||
|
create: true,
|
||||||
|
duplicatePartInstance: basePartInstance
|
||||||
|
});
|
||||||
|
|
||||||
const newPart = useCreateApiFormModal({
|
const newPart = useCreateApiFormModal({
|
||||||
url: ApiEndpoints.part_list,
|
url: ApiEndpoints.part_list,
|
||||||
title: t`Add Part`,
|
title: t`Add Part`,
|
||||||
fields: usePartFields({ create: true }),
|
fields: newPartFields,
|
||||||
initialData: initialPartData,
|
initialData: initialPartData,
|
||||||
follow: true,
|
follow: true,
|
||||||
modelType: ModelType.part
|
modelType: ModelType.part
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ export function PartVariantTable({ part }: Readonly<{ part: any }>) {
|
|||||||
ancestor: part.pk
|
ancestor: part.pk
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
basePartInstance={part}
|
||||||
defaultPartData={{
|
defaultPartData={{
|
||||||
...part,
|
...part,
|
||||||
variant_of: part.pk,
|
variant_of: part.pk,
|
||||||
|
|||||||
Reference in New Issue
Block a user