From 15c7df980cb814530197d987734e0410d2479452 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Sat, 27 Jun 2026 09:14:17 +0000 Subject: [PATCH] Use NumberInput elsewhere --- src/frontend/src/forms/BuildForms.tsx | 90 ++++++++++++------- src/frontend/src/forms/PurchaseOrderForms.tsx | 28 ++++-- src/frontend/src/forms/SalesOrderForms.tsx | 36 ++++---- src/frontend/src/forms/TransferOrderForms.tsx | 36 ++++---- 4 files changed, 116 insertions(+), 74 deletions(-) diff --git a/src/frontend/src/forms/BuildForms.tsx b/src/frontend/src/forms/BuildForms.tsx index 2ff3c0bd53..1b2680c3dc 100644 --- a/src/frontend/src/forms/BuildForms.tsx +++ b/src/frontend/src/forms/BuildForms.tsx @@ -1,5 +1,14 @@ import { t } from '@lingui/core/macro'; -import { Alert, Divider, Group, List, Stack, Table, Text } from '@mantine/core'; +import { + Alert, + Divider, + Group, + List, + NumberInput, + Stack, + Table, + Text +} from '@mantine/core'; import { IconCalendar, IconCircleCheck, @@ -272,15 +281,22 @@ function BuildOutputFormRow({ // Non-serialized output - quantity can be changed return ( - { - props.changeFn(props.idx, 'quantity', value); + { + let nextValue: number | '' = ''; + + if (typeof value === 'number') { + nextValue = Number.isFinite(value) ? value : ''; + } else if (value.trim() !== '') { + const parsed = Number.parseFloat(value); + nextValue = Number.isFinite(parsed) ? parsed : ''; } + + props.changeFn(props.idx, 'quantity', nextValue); }} error={props.rowErrors?.quantity?.message} /> @@ -600,18 +616,6 @@ function BuildAllocateLineRow({ }; }, [record, props]); - const quantityField: ApiFormFieldType = useMemo(() => { - return { - field_type: 'number', - name: 'quantity', - required: true, - value: props.item.quantity, - onValueChange: (value: any) => { - props.changeFn(props.idx, 'quantity', value); - } - }; - }, [props]); - return ( @@ -636,9 +640,24 @@ function BuildAllocateLineRow({ /> - { + let nextValue: number | '' = ''; + + if (typeof value === 'number') { + nextValue = Number.isFinite(value) ? value : ''; + } else if (value.trim() !== '') { + const parsed = Number.parseFloat(value); + nextValue = Number.isFinite(parsed) ? parsed : ''; + } + + props.changeFn(props.idx, 'quantity', nextValue); + }} error={props.rowErrors?.quantity?.message} /> @@ -803,15 +822,22 @@ function BuildConsumeItemRow({ {record.quantity} - { - props.changeFn(props.idx, 'quantity', value); + { + let nextValue: number | '' = ''; + + if (typeof value === 'number') { + nextValue = Number.isFinite(value) ? value : ''; + } else if (value.trim() !== '') { + const parsed = Number.parseFloat(value); + nextValue = Number.isFinite(parsed) ? parsed : ''; } + + props.changeFn(props.idx, 'quantity', nextValue); }} error={props.rowErrors?.quantity?.message} /> diff --git a/src/frontend/src/forms/PurchaseOrderForms.tsx b/src/frontend/src/forms/PurchaseOrderForms.tsx index 3dce873eb6..50824f9a13 100644 --- a/src/frontend/src/forms/PurchaseOrderForms.tsx +++ b/src/frontend/src/forms/PurchaseOrderForms.tsx @@ -8,6 +8,7 @@ import { Group, HoverCard, Modal, + NumberInput, Table, TextInput } from '@mantine/core'; @@ -574,15 +575,26 @@ function LineItemFormRow({ /> - { - props.changeFn(props.idx, 'quantity', value); - serialNumberGenerator.update({ quantity: value }); + { + let nextValue: number | '' = ''; + + if (typeof value === 'number') { + nextValue = Number.isFinite(value) ? value : ''; + } else if (value.trim() !== '') { + const parsed = Number.parseFloat(value); + nextValue = Number.isFinite(parsed) ? parsed : ''; } + + props.changeFn(props.idx, 'quantity', nextValue); + serialNumberGenerator.update({ + quantity: nextValue === '' ? undefined : nextValue + }); }} error={props.rowErrors?.quantity?.message} /> diff --git a/src/frontend/src/forms/SalesOrderForms.tsx b/src/frontend/src/forms/SalesOrderForms.tsx index a863a51852..c6f81f2ffb 100644 --- a/src/frontend/src/forms/SalesOrderForms.tsx +++ b/src/frontend/src/forms/SalesOrderForms.tsx @@ -1,5 +1,5 @@ import { t } from '@lingui/core/macro'; -import { Alert, Table, Text } from '@mantine/core'; +import { Alert, NumberInput, Table, Text } from '@mantine/core'; import { IconAddressBook, IconCalendar, @@ -348,19 +348,6 @@ function SalesOrderAllocateLineRow({ }; }, [sourceLocation, record, props]); - // Statically defined field for selecting the allocation quantity - const quantityField: ApiFormFieldType = useMemo(() => { - return { - field_type: 'number', - name: 'quantity', - required: true, - value: props.item.quantity, - onValueChange: (value: any) => { - props.changeFn(props.idx, 'quantity', value); - } - }; - }, [props]); - return ( @@ -381,9 +368,24 @@ function SalesOrderAllocateLineRow({ /> - { + let nextValue: number | '' = ''; + + if (typeof value === 'number') { + nextValue = Number.isFinite(value) ? value : ''; + } else if (value.trim() !== '') { + const parsed = Number.parseFloat(value); + nextValue = Number.isFinite(parsed) ? parsed : ''; + } + + props.changeFn(props.idx, 'quantity', nextValue); + }} error={props.rowErrors?.quantity?.message} /> diff --git a/src/frontend/src/forms/TransferOrderForms.tsx b/src/frontend/src/forms/TransferOrderForms.tsx index 638028603d..80007d5c37 100644 --- a/src/frontend/src/forms/TransferOrderForms.tsx +++ b/src/frontend/src/forms/TransferOrderForms.tsx @@ -1,7 +1,7 @@ import { ApiEndpoints, ModelType, ProgressBar, apiUrl } from '@lib/index'; import type { ApiFormFieldSet, ApiFormFieldType } from '@lib/types/Forms'; import { t } from '@lingui/core/macro'; -import { Table } from '@mantine/core'; +import { NumberInput, Table } from '@mantine/core'; import { IconCalendar, IconUsers } from '@tabler/icons-react'; import { useMemo, useState } from 'react'; import RemoveRowButton from '../components/buttons/RemoveRowButton'; @@ -148,19 +148,6 @@ function TransferOrderAllocateLineRow({ }; }, [sourceLocation, record, props]); - // Statically defined field for selecting the allocation quantity - const quantityField: ApiFormFieldType = useMemo(() => { - return { - field_type: 'number', - name: 'quantity', - required: true, - value: props.item.quantity, - onValueChange: (value: any) => { - props.changeFn(props.idx, 'quantity', value); - } - }; - }, [props]); - return ( @@ -181,9 +168,24 @@ function TransferOrderAllocateLineRow({ /> - { + let nextValue: number | '' = ''; + + if (typeof value === 'number') { + nextValue = Number.isFinite(value) ? value : ''; + } else if (value.trim() !== '') { + const parsed = Number.parseFloat(value); + nextValue = Number.isFinite(parsed) ? parsed : ''; + } + + props.changeFn(props.idx, 'quantity', nextValue); + }} error={props.rowErrors?.quantity?.message} />