From b0b2f15a517046af54169eba31066b7834e06139 Mon Sep 17 00:00:00 2001
From: Maksym Tishchenko <m.tishchenko@aimprosoft.com>
Date: Wed, 5 Feb 2025 13:05:18 +0200
Subject: [PATCH] Valid range integer

---
 workspaces/client/src/utilities/validators.ts             | 3 +++
 .../src/accession/ui/c/AccessionInvAttachForm.tsx         | 4 ++--
 .../src/appsetting/ui/\321\201/AppSettingForm.tsx"        | 4 ++--
 .../ui-express/src/crop/ui/admin/c/CropAttachForm.tsx     | 4 ++--
 .../ui-express/src/report/ui/c/DataviewFieldForm.tsx      | 8 ++++++--
 .../ui-express/src/report/ui/c/DataviewParamForm.tsx      | 8 ++++++--
 .../ui-express/src/request/ui/c/RequestAttachForm.tsx     | 4 ++--
 7 files changed, 23 insertions(+), 12 deletions(-)

diff --git a/workspaces/client/src/utilities/validators.ts b/workspaces/client/src/utilities/validators.ts
index 70bae7348..08603a489 100644
--- a/workspaces/client/src/utilities/validators.ts
+++ b/workspaces/client/src/utilities/validators.ts
@@ -1,6 +1,8 @@
 import { TFunction } from 'i18next';
 import _isArray from 'lodash/isArray';
 
+const INT_RANGE = 2147483647
+
 export const composeValidators = (...validators) => (value, allValues) =>
   validators.reduce((error, validator) => error || validator(value, allValues), undefined);
 
@@ -49,6 +51,7 @@ export const matchPasswords = (key) => (value, allValues) => value && allValues?
 
 export const validatePositiveNumber = (options: Options) => composeValidatorsWithOptions(options, decimalNumber, minValue(0));
 export const validatePositiveInteger = (options: Options) => composeValidatorsWithOptions(options, validInteger, minValue(0));
+export const validateRangeInteger = (options: Options) => composeValidatorsWithOptions(options, validInteger, minValue(-INT_RANGE), maxValue(INT_RANGE));
 export const validateRequiredPositiveInteger = (options: Options) => composeValidatorsWithOptions(options, required, validInteger, minValue(0));
 export const validateRequiredInteger = (options: Options) => composeValidatorsWithOptions(options, required, validInteger);
 export const validateLongitude = (options: Options) => composeValidatorsWithOptions(options, decimalNumber, minValue(-180), maxValue(180));
diff --git a/workspaces/ui-express/src/accession/ui/c/AccessionInvAttachForm.tsx b/workspaces/ui-express/src/accession/ui/c/AccessionInvAttachForm.tsx
index 7dfdbc8ec..5d164dac2 100644
--- a/workspaces/ui-express/src/accession/ui/c/AccessionInvAttachForm.tsx
+++ b/workspaces/ui-express/src/accession/ui/c/AccessionInvAttachForm.tsx
@@ -7,7 +7,7 @@ import { TextField } from '@gringlobal-ce/client/ui/common/form/TextField';
 import { Grid } from '@mui/material';
 import { CodeValueField } from 'common/CodeValue';
 // Utils
-import { decimalNumber, required } from '@gringlobal-ce/client/utilities/validators';
+import { required, validateRangeInteger } from '@gringlobal-ce/client/utilities/validators';
 import withDialog from 'ui/common/withDialog';
 import { YesNoSwitch } from '@gringlobal-ce/client/ui/common/form/Toggle';
 import { CooperatorAutocomplete } from 'common/Cooperator';
@@ -67,7 +67,7 @@ const AccessionInvAttachForm = ({ onSubmit, initialValues, error }: AccessionInv
             <Controller
               name="sortOrder"
               control={ control }
-              rules={{ validate: decimalNumber }}
+              rules={{ validate: validateRangeInteger({ t }) }}
               render={ ({ field: { ref, ...rest }, fieldState }) =>
                 <TextField
                   label={ t([ 'client:model.AccessionInvAttach.sortOrder', 'client:model._.sortOrder' ]) }
diff --git "a/workspaces/ui-express/src/appsetting/ui/\321\201/AppSettingForm.tsx" "b/workspaces/ui-express/src/appsetting/ui/\321\201/AppSettingForm.tsx"
index 72a5bcb56..7f283d6bb 100644
--- "a/workspaces/ui-express/src/appsetting/ui/\321\201/AppSettingForm.tsx"
+++ "b/workspaces/ui-express/src/appsetting/ui/\321\201/AppSettingForm.tsx"
@@ -2,7 +2,7 @@ import { useTranslation } from 'react-i18next';
 // UI
 import { TextField } from '@gringlobal-ce/client/ui/common/form/TextField';
 import { Grid } from '@mui/material';
-import { decimalNumber, required } from '@gringlobal-ce/client/utilities/validators';
+import { required, validateRangeInteger } from '@gringlobal-ce/client/utilities/validators';
 import withDialog from 'ui/common/withDialog';
 import AppSetting from '@gringlobal-ce/client/model/gringlobal/AppSetting';
 import { Controller, useForm, FormProvider } from 'react-hook-form';
@@ -43,7 +43,7 @@ const AppSettingForm = ({ onSubmit, initialValues, error }: IAppSettingForm) =>
             <Controller
               name="sortOrder"
               control={ control }
-              rules={{ validate: decimalNumber }}
+              rules={{ validate: validateRangeInteger({ t }) }}
               render={ ({ field: { ref, ...rest }, fieldState }) =>
                 <TextField
                   label={ t([ 'client:model.AppSetting.sortOrder', 'client:model._.sortOrder' ]) }
diff --git a/workspaces/ui-express/src/crop/ui/admin/c/CropAttachForm.tsx b/workspaces/ui-express/src/crop/ui/admin/c/CropAttachForm.tsx
index 0a1f7f005..046dc4172 100644
--- a/workspaces/ui-express/src/crop/ui/admin/c/CropAttachForm.tsx
+++ b/workspaces/ui-express/src/crop/ui/admin/c/CropAttachForm.tsx
@@ -5,7 +5,7 @@ import { TextField } from '@gringlobal-ce/client/ui/common/form/TextField';
 import { Grid } from '@mui/material';
 import { CodeValueField } from 'common/CodeValue';
 // Utils
-import { decimalNumber, required } from '@gringlobal-ce/client/utilities/validators';
+import { required, validateRangeInteger } from '@gringlobal-ce/client/utilities/validators';
 import withDialog from 'ui/common/withDialog';
 import { YesNoSwitch } from '@gringlobal-ce/client/ui/common/form/Toggle';
 import { CooperatorAutocomplete } from 'common/Cooperator';
@@ -68,7 +68,7 @@ const CropAttachForm = ({ onSubmit, initialValues, error }: CropAttachForm) => {
             <Controller
               name="sortOrder"
               control={ control }
-              rules={{ validate: decimalNumber }}
+              rules={{ validate: validateRangeInteger({ t }) }}
               render={ ({ field: { ref, ...rest }, fieldState }) =>
                 <TextField
                   label={ t([ 'client:model.CropAttach.sortOrder', 'client:model._.sortOrder' ]) }
diff --git a/workspaces/ui-express/src/report/ui/c/DataviewFieldForm.tsx b/workspaces/ui-express/src/report/ui/c/DataviewFieldForm.tsx
index 1cb90e31e..b9ef931ec 100644
--- a/workspaces/ui-express/src/report/ui/c/DataviewFieldForm.tsx
+++ b/workspaces/ui-express/src/report/ui/c/DataviewFieldForm.tsx
@@ -11,7 +11,11 @@ import { makeInitialValuesSafe } from '@gringlobal-ce/client/utilities';
 import { useCallback, useState } from 'react';
 import log from 'loglevel';
 import { createDataviewField, updateDataviewField } from '@gringlobal-ce/client/service/v2/DataviewEndpoints';
-import { composeValidatorsWithOptions, required, validatePositiveNumber } from '@gringlobal-ce/client/utilities/validators';
+import {
+  composeValidatorsWithOptions,
+  required,
+  validateRangeInteger
+} from '@gringlobal-ce/client/utilities/validators';
 import DropdownField from 'common/DropdownField';
 import { useDispatch, useSelector } from 'react-redux';
 import { IRootState } from 'reducers';
@@ -132,7 +136,7 @@ const DataviewFieldForm = ({ onConfirm, initialValues, onCancel }: DataviewField
               <Controller
                 name="sortOrder"
                 control={ control }
-                rules={{ validate: composeValidatorsWithOptions({ t }, validatePositiveNumber({ t }), required) }}
+                rules={{ validate: composeValidatorsWithOptions({ t }, validateRangeInteger({ t }), required) }}
                 render={ ({ field: { ref, ...rest }, fieldState }) =>
                   <TextField
                     required
diff --git a/workspaces/ui-express/src/report/ui/c/DataviewParamForm.tsx b/workspaces/ui-express/src/report/ui/c/DataviewParamForm.tsx
index 039e92807..d2741d51f 100644
--- a/workspaces/ui-express/src/report/ui/c/DataviewParamForm.tsx
+++ b/workspaces/ui-express/src/report/ui/c/DataviewParamForm.tsx
@@ -10,7 +10,11 @@ import { makeInitialValuesSafe } from '@gringlobal-ce/client/utilities';
 import { useCallback, useState } from 'react';
 import log from 'loglevel';
 import { createDataviewParam, updateDataviewParam } from '@gringlobal-ce/client/service/v2/DataviewEndpoints';
-import { composeValidatorsWithOptions, required, validatePositiveNumber } from '@gringlobal-ce/client/utilities/validators';
+import {
+  composeValidatorsWithOptions,
+  required,
+  validateRangeInteger
+} from '@gringlobal-ce/client/utilities/validators';
 import DropdownField from 'common/DropdownField';
 
 interface DataviewParamForm {
@@ -87,7 +91,7 @@ const DataviewParamForm = ({ onConfirm, initialValues, onCancel }: DataviewParam
               <Controller
                 name="sortOrder"
                 control={ control }
-                rules={{ validate: composeValidatorsWithOptions({ t }, validatePositiveNumber({ t }), required) }}
+                rules={{ validate: composeValidatorsWithOptions({ t }, validateRangeInteger({ t }), required) }}
                 render={ ({ field: { ref, ...rest }, fieldState }) =>
                   <TextField
                     required
diff --git a/workspaces/ui-express/src/request/ui/c/RequestAttachForm.tsx b/workspaces/ui-express/src/request/ui/c/RequestAttachForm.tsx
index 061c821ef..dd7e2666a 100644
--- a/workspaces/ui-express/src/request/ui/c/RequestAttachForm.tsx
+++ b/workspaces/ui-express/src/request/ui/c/RequestAttachForm.tsx
@@ -6,7 +6,7 @@ import { TextField } from '@gringlobal-ce/client/ui/common/form/TextField';
 import { Grid } from '@mui/material';
 import { CodeValueField } from 'common/CodeValue';
 // Utils
-import { decimalNumber, required } from '@gringlobal-ce/client/utilities/validators';
+import { required, validateRangeInteger } from '@gringlobal-ce/client/utilities/validators';
 import withDialog from 'ui/common/withDialog';
 import { YesNoSwitch } from '@gringlobal-ce/client/ui/common/form/Toggle';
 import { CooperatorAutocomplete } from 'common/Cooperator';
@@ -67,7 +67,7 @@ const RequestAttachForm = ({ onSubmit, initialValues, error }: RequestAttachForm
             <Controller
               name="sortOrder"
               control={ control }
-              rules={{ validate: decimalNumber }}
+              rules={{ validate: validateRangeInteger({ t }) }}
               render={ ({ field: { ref, ...rest }, fieldState }) =>
                 <TextField
                   label={ t([ 'client:model.OrderRequestAttach.sortOrder', 'client:model._.sortOrder' ]) }
-- 
GitLab