diff --git a/app/react-tools/yup-schemas.ts b/app/react-tools/yup-schemas.ts new file mode 100644 index 000000000..4f614e21d --- /dev/null +++ b/app/react-tools/yup-schemas.ts @@ -0,0 +1,19 @@ +import { NumberSchema, number } from 'yup'; + +/** + * Returns a Yup schema for a number that can also be NaN. + * + * This function is a workaround for a known issue in Yup where it throws type errors + * when the number input is empty, having a value NaN. Yup doesn't like NaN values. + * More details can be found in these GitHub issues: + * https://github.com/jquense/yup/issues/1330 + * https://github.com/jquense/yup/issues/211 + * + * @param errorMessage The custom error message to display when the value is required. + * @returns A Yup number schema with a custom type error message. + */ +export function nanNumberSchema( + errorMessage = 'Value is required' +): NumberSchema { + return number().typeError(errorMessage); +} diff --git a/app/react/components/form-components/Input/Input.tsx b/app/react/components/form-components/Input/Input.tsx index 2108b314a..1bd02e01f 100644 --- a/app/react/components/form-components/Input/Input.tsx +++ b/app/react/components/form-components/Input/Input.tsx @@ -12,6 +12,8 @@ export const InputWithRef = forwardRef< export function Input({ className, mRef: ref, + value, + type, ...props }: InputHTMLAttributes & { mRef?: Ref; @@ -20,6 +22,8 @@ export function Input({ diff --git a/app/react/components/form-components/Slider/SliderWithInput.tsx b/app/react/components/form-components/Slider/SliderWithInput.tsx index bfbff328f..c66d9725b 100644 --- a/app/react/components/form-components/Slider/SliderWithInput.tsx +++ b/app/react/components/form-components/Slider/SliderWithInput.tsx @@ -20,7 +20,7 @@ export function SliderWithInput({ visibleTooltip?: boolean; }) { return ( -
+
{max && (
- onChange(Number.isNaN(value) ? 0 : value) - } + onChange={(e) => onChange(e.target.valueAsNumber)} className="w-32" data-cy={`${dataCy}Input`} /> diff --git a/app/react/docker/containers/CreateView/ResourcesTab/ResourcesFieldset.tsx b/app/react/docker/containers/CreateView/ResourcesTab/ResourcesFieldset.tsx index aace001ef..e2bc40ddc 100644 --- a/app/react/docker/containers/CreateView/ResourcesTab/ResourcesFieldset.tsx +++ b/app/react/docker/containers/CreateView/ResourcesTab/ResourcesFieldset.tsx @@ -1,8 +1,9 @@ import { FormikErrors } from 'formik'; -import { number, object, SchemaOf } from 'yup'; +import { object, SchemaOf } from 'yup'; import { useSystemLimits } from '@/react/docker/proxy/queries/useInfo'; import { useEnvironmentId } from '@/react/hooks/useEnvironmentId'; +import { nanNumberSchema } from '@/react-tools/yup-schemas'; import { FormControl } from '@@/form-components/FormControl'; import { FormSection } from '@@/form-components/FormSection'; @@ -94,15 +95,15 @@ export function resourcesValidation({ maxCpu?: number; } = {}): SchemaOf { return object({ - reservation: number() + reservation: nanNumberSchema() .min(0) .max(maxMemory, `Value must be between 0 and ${maxMemory}`) .default(0), - limit: number() + limit: nanNumberSchema() .min(0) .max(maxMemory, `Value must be between 0 and ${maxMemory}`) .default(0), - cpu: number() + cpu: nanNumberSchema() .min(0) .max(maxCpu, `Value must be between 0 and ${maxCpu}`) .default(0), diff --git a/app/react/docker/services/ListView/ServicesDatatable/columns/schedulingMode/ScaleForm.tsx b/app/react/docker/services/ListView/ServicesDatatable/columns/schedulingMode/ScaleForm.tsx index 8cafed392..716903838 100644 --- a/app/react/docker/services/ListView/ServicesDatatable/columns/schedulingMode/ScaleForm.tsx +++ b/app/react/docker/services/ListView/ServicesDatatable/columns/schedulingMode/ScaleForm.tsx @@ -32,7 +32,7 @@ export function ScaleForm({ type="number" min={0} step={1} - value={values.replicas} + value={Number.isNaN(values.replicas) ? '' : values.replicas} onKeyUp={(event) => { if (event.key === 'Escape') { onClose(); @@ -48,6 +48,11 @@ export function ScaleForm({