Use NumberInput elsewhere

This commit is contained in:
Oliver Walters 2026-06-27 09:14:17 +00:00
parent 91e6c69abb
commit 15c7df980c
4 changed files with 116 additions and 74 deletions

View File

@ -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 (
<StandaloneField
fieldName='quantity'
fieldDefinition={{
field_type: 'number',
required: true,
value: props.item.quantity,
onValueChange: (value: any) => {
props.changeFn(props.idx, 'quantity', value);
<NumberInput
radius='sm'
step={1}
decimalScale={10}
value={props.item.quantity ?? ''}
onChange={(value: number | string) => {
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 (
<Table.Tr key={`table-row-${record.pk}`}>
<Table.Td>
@ -636,9 +640,24 @@ function BuildAllocateLineRow({
/>
</Table.Td>
<Table.Td>
<StandaloneField
fieldName='quantity'
fieldDefinition={quantityField}
<NumberInput
radius='sm'
min={0}
step={1}
decimalScale={10}
value={props.item.quantity ?? ''}
onChange={(value: number | string) => {
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}
/>
</Table.Td>
@ -803,15 +822,22 @@ function BuildConsumeItemRow({
</Table.Td>
<Table.Td>{record.quantity}</Table.Td>
<Table.Td>
<StandaloneField
fieldName='quantity'
fieldDefinition={{
field_type: 'number',
required: true,
value: props.item.quantity,
onValueChange: (value: any) => {
props.changeFn(props.idx, 'quantity', value);
<NumberInput
radius='sm'
step={1}
decimalScale={10}
value={props.item.quantity ?? ''}
onChange={(value: number | string) => {
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}
/>

View File

@ -8,6 +8,7 @@ import {
Group,
HoverCard,
Modal,
NumberInput,
Table,
TextInput
} from '@mantine/core';
@ -574,15 +575,26 @@ function LineItemFormRow({
/>
</Table.Td>
<Table.Td style={{ whiteSpace: 'nowrap' }}>
<StandaloneField
fieldName='quantity'
fieldDefinition={{
field_type: 'number',
value: props.item.quantity,
onValueChange: (value) => {
props.changeFn(props.idx, 'quantity', value);
serialNumberGenerator.update({ quantity: value });
<NumberInput
radius='sm'
min={0}
step={1}
decimalScale={10}
value={props.item.quantity ?? ''}
onChange={(value: number | string) => {
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}
/>

View File

@ -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 (
<Table.Tr key={`table-row-${props.idx}-${record.pk}`}>
<Table.Td>
@ -381,9 +368,24 @@ function SalesOrderAllocateLineRow({
/>
</Table.Td>
<Table.Td>
<StandaloneField
fieldName='quantity'
fieldDefinition={quantityField}
<NumberInput
radius='sm'
min={0}
step={1}
decimalScale={10}
value={props.item.quantity ?? ''}
onChange={(value: number | string) => {
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}
/>
</Table.Td>

View File

@ -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 (
<Table.Tr key={`table-row-${props.idx}-${record.pk}`}>
<Table.Td>
@ -181,9 +168,24 @@ function TransferOrderAllocateLineRow({
/>
</Table.Td>
<Table.Td>
<StandaloneField
fieldName='quantity'
fieldDefinition={quantityField}
<NumberInput
radius='sm'
min={0}
step={1}
decimalScale={10}
value={props.item.quantity ?? ''}
onChange={(value: number | string) => {
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}
/>
</Table.Td>