From 9fbc7ac40c8c56cfaaaa974bf224dfae783b34aa Mon Sep 17 00:00:00 2001 From: Matthias Mair Date: Thu, 12 Feb 2026 03:05:12 +0100 Subject: [PATCH] feat(frontend): add warning to SO line calcs (#11296) --- src/frontend/lib/types/Forms.tsx | 2 + .../components/forms/fields/ApiFormField.tsx | 4 ++ .../forms/fields/AutoFillRightSection.tsx | 20 ++++++- .../components/forms/fields/NumberField.tsx | 56 ++++++++++++++----- src/frontend/src/forms/SalesOrderForms.tsx | 4 +- 5 files changed, 71 insertions(+), 15 deletions(-) diff --git a/src/frontend/lib/types/Forms.tsx b/src/frontend/lib/types/Forms.tsx index f37a291921..1bc3dc62f3 100644 --- a/src/frontend/lib/types/Forms.tsx +++ b/src/frontend/lib/types/Forms.tsx @@ -111,6 +111,8 @@ export type ApiFormFieldType = { read_only?: boolean; placeholder?: string; placeholderAutofill?: boolean; + placeholderWarningCompare?: string | number; + placeholderWarning?: string; description?: string; preFieldContent?: JSX.Element; postFieldContent?: JSX.Element; diff --git a/src/frontend/src/components/forms/fields/ApiFormField.tsx b/src/frontend/src/components/forms/fields/ApiFormField.tsx index 1bbc8f932c..fe5964eec5 100644 --- a/src/frontend/src/components/forms/fields/ApiFormField.tsx +++ b/src/frontend/src/components/forms/fields/ApiFormField.tsx @@ -179,6 +179,10 @@ export function ApiFormField({ fieldName={fieldName} definition={reducedDefinition} placeholderAutofill={fieldDefinition.placeholderAutofill ?? false} + placeholderWarningCompare={ + fieldDefinition.placeholderWarningCompare ?? undefined + } + placeholderWarning={fieldDefinition.placeholderWarning ?? undefined} onChange={(value: any) => { onChange(value); }} diff --git a/src/frontend/src/components/forms/fields/AutoFillRightSection.tsx b/src/frontend/src/components/forms/fields/AutoFillRightSection.tsx index c3c5a5661e..4365d97392 100644 --- a/src/frontend/src/components/forms/fields/AutoFillRightSection.tsx +++ b/src/frontend/src/components/forms/fields/AutoFillRightSection.tsx @@ -1,6 +1,6 @@ import { t } from '@lingui/core/macro'; import { Tooltip } from '@mantine/core'; -import { IconCopyCheck, IconX } from '@tabler/icons-react'; +import { IconCopyCheck, IconExclamationMark, IconX } from '@tabler/icons-react'; /** * Custom "RightSection" component for form fields, @@ -55,3 +55,21 @@ export default function AutoFillRightSection({ ); } } + +export function AutoFillWarning({ + fieldName, + message +}: { + fieldName: string; + message: string; +}) { + return ( + + + + ); +} diff --git a/src/frontend/src/components/forms/fields/NumberField.tsx b/src/frontend/src/components/forms/fields/NumberField.tsx index 63bfbb2868..0369d0935a 100644 --- a/src/frontend/src/components/forms/fields/NumberField.tsx +++ b/src/frontend/src/components/forms/fields/NumberField.tsx @@ -1,7 +1,7 @@ import { NumberInput } from '@mantine/core'; import { useId, useMemo } from 'react'; import type { FieldValues, UseControllerReturn } from 'react-hook-form'; -import AutoFillRightSection from './AutoFillRightSection'; +import AutoFillRightSection, { AutoFillWarning } from './AutoFillRightSection'; /** * Custom implementation of the mantine component, @@ -12,12 +12,16 @@ export default function NumberField({ fieldName, definition, placeholderAutofill, + placeholderWarningCompare, + placeholderWarning, onChange }: Readonly<{ controller: UseControllerReturn; definition: any; fieldName: string; placeholderAutofill?: boolean; + placeholderWarningCompare?: number | string; + placeholderWarning?: string; onChange: (value: any) => void; }>) { const fieldId = useId(); @@ -56,6 +60,43 @@ export default function NumberField({ return val; }, [definition.field_type, value]); + const rightSection = useMemo(() => { + if ( + definition.placeholder && + placeholderAutofill && + numericalValue == null + ) { + return ( + + ); + } else if (placeholderWarning && numericalValue != null) { + if ( + placeholderWarningCompare != null && + numericalValue === placeholderWarningCompare + ) { + return undefined; + } + return ( + + ); + } + return undefined; + }, [ + definition, + placeholderAutofill, + placeholderWarning, + placeholderWarningCompare, + numericalValue, + field.name, + field.value, + onChange + ]); + return ( - ) - } + rightSection={rightSection} /> ); } diff --git a/src/frontend/src/forms/SalesOrderForms.tsx b/src/frontend/src/forms/SalesOrderForms.tsx index 7550534dc0..5adab0a6f6 100644 --- a/src/frontend/src/forms/SalesOrderForms.tsx +++ b/src/frontend/src/forms/SalesOrderForms.tsx @@ -174,7 +174,9 @@ export function useSalesOrderLineItemFields({ }, sale_price: { placeholder: salePrice, - placeholderAutofill: true + placeholderAutofill: true, + placeholderWarningCompare: salePrice, + placeholderWarning: t`Price based on part and quantity differs${salePrice ? `; suggested: (${salePrice})` : '.'}` }, sale_price_currency: { icon: ,