2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-07-18 10:46:31 +00:00

[UI] Build page tweak (#10027)

* Hide "consumed stock" panel if not required

* Docs updates

* Hide allocation fields if the build has no required parts

* Additional serializer options
This commit is contained in:
Oliver
2025-07-15 18:27:09 +10:00
committed by GitHub
parent 42abc61494
commit 75ab57bc0b
4 changed files with 62 additions and 22 deletions

View File

@@ -532,8 +532,10 @@ class BuildLineEndpoint:
try:
params = self.request.query_params
kwargs['bom_item_detail'] = str2bool(params.get('bom_item_detail', True))
kwargs['part_detail'] = str2bool(params.get('part_detail', True))
kwargs['build_detail'] = str2bool(params.get('build_detail', False))
kwargs['allocations'] = str2bool(params.get('allocations', True))
except AttributeError:
pass

View File

@@ -1328,19 +1328,27 @@ class BuildLineSerializer(DataImportExportSerializerMixin, InvenTreeModelSeriali
def __init__(self, *args, **kwargs):
"""Determine which extra details fields should be included."""
part_detail = kwargs.pop('part_detail', True)
bom_item_detail = kwargs.pop('bom_item_detail', True)
build_detail = kwargs.pop('build_detail', True)
allocations = kwargs.pop('allocations', True)
super().__init__(*args, **kwargs)
if isGeneratingSchema():
return
if not bom_item_detail:
self.fields.pop('bom_item_detail', None)
if not part_detail:
self.fields.pop('part_detail', None)
if not build_detail:
self.fields.pop('build_detail', None)
if not allocations:
self.fields.pop('allocations', None)
# Build info fields
build_reference = serializers.CharField(
source='build.reference', label=_('Build Reference'), read_only=True

View File

@@ -2,6 +2,7 @@ import { t } from '@lingui/core/macro';
import { Alert, Grid, Skeleton, Stack, Text } from '@mantine/core';
import {
IconChecklist,
IconCircleCheck,
IconClipboardCheck,
IconClipboardList,
IconInfoCircle,
@@ -19,6 +20,7 @@ import { ModelType } from '@lib/enums/ModelType';
import { UserRoles } from '@lib/enums/Roles';
import { apiUrl } from '@lib/functions/Api';
import { getDetailUrl } from '@lib/functions/Navigation';
import type { ApiFormFieldSet } from '@lib/types/Forms';
import AdminButton from '../../components/buttons/AdminButton';
import PrimaryActionButton from '../../components/buttons/PrimaryActionButton';
import { PrintingActions } from '../../components/buttons/PrintingActions';
@@ -130,6 +132,10 @@ export default function BuildDetail() {
endpoint: ApiEndpoints.build_line_list,
params: {
build: id,
allocations: false,
part_detail: false,
build_detail: false,
bom_item_detail: false,
limit: 1
},
disabled: !id,
@@ -417,7 +423,8 @@ export default function BuildDetail() {
icon: <IconList />,
hidden:
build.status == buildStatus.COMPLETE ||
build.status == buildStatus.CANCELLED,
build.status == buildStatus.CANCELLED ||
(buildLineData?.count ?? 0) <= 0, // Hide if no required parts
content: (
<BuildAllocationsPanel
build={build}
@@ -430,6 +437,7 @@ export default function BuildDetail() {
name: 'consumed-stock',
label: t`Consumed Stock`,
icon: <IconListCheck />,
hidden: (buildLineData?.count ?? 0) <= 0, // Hide if no required parts
content: (
<StockItemTable
allowAdd={false}
@@ -590,17 +598,33 @@ export default function BuildDetail() {
successMessage: t`Order issued`
});
const completeOrderFields: ApiFormFieldSet = useMemo(() => {
const hasBom = (buildLineData?.count ?? 0) > 0;
return {
accept_overallocated: {
hidden: !hasBom
},
accept_unallocated: {
hidden: !hasBom
},
accept_incomplete: {}
};
}, [buildLineData.count]);
const completeOrder = useCreateApiFormModal({
url: apiUrl(ApiEndpoints.build_order_complete, build.pk),
title: t`Complete Build Order`,
onFormSuccess: refreshInstance,
preFormWarning: t`Mark this order as complete`,
preFormContent: (
<Alert
color='green'
icon={<IconCircleCheck />}
title={t`Mark this order as complete`}
/>
),
successMessage: t`Order completed`,
fields: {
accept_overallocated: {},
accept_unallocated: {},
accept_incomplete: {}
}
fields: completeOrderFields
});
const buildActions = useMemo(() => {