From b6738c235ad810be2a17dcfc7c7184ba8eab0653 Mon Sep 17 00:00:00 2001 From: Tristan Chuine Date: Wed, 27 Nov 2024 16:37:10 +0100 Subject: [PATCH 1/2] Fix typescript nullable arguments in criteria form schema --- .../criteriaBased/CriteriaBasedFilterForm.tsx | 2 +- .../criteriaBased/criteriaBasedFilterUtils.ts | 108 ++++++++---------- .../reactHookForm/numbers/RangeInput.tsx | 47 ++++---- 3 files changed, 75 insertions(+), 82 deletions(-) diff --git a/src/components/filter/criteriaBased/CriteriaBasedFilterForm.tsx b/src/components/filter/criteriaBased/CriteriaBasedFilterForm.tsx index dcae3624..28a03203 100644 --- a/src/components/filter/criteriaBased/CriteriaBasedFilterForm.tsx +++ b/src/components/filter/criteriaBased/CriteriaBasedFilterForm.tsx @@ -17,7 +17,7 @@ export const criteriaBasedFilterSchema = getCriteriaBasedSchema({ ...filterPropertiesYupSchema, }); -export const criteriaBasedFilterEmptyFormData = getCriteriaBasedFormData(null, { +export const criteriaBasedFilterEmptyFormData = getCriteriaBasedFormData(undefined, { [FieldConstants.ENERGY_SOURCE]: null, [FreePropertiesTypes.SUBSTATION_FILTER_PROPERTIES]: [], [FreePropertiesTypes.FREE_FILTER_PROPERTIES]: [], diff --git a/src/components/filter/criteriaBased/criteriaBasedFilterUtils.ts b/src/components/filter/criteriaBased/criteriaBasedFilterUtils.ts index a74b6ccd..e963a1be 100644 --- a/src/components/filter/criteriaBased/criteriaBasedFilterUtils.ts +++ b/src/components/filter/criteriaBased/criteriaBasedFilterUtils.ts @@ -10,49 +10,44 @@ import { PROPERTY_NAME, PROPERTY_VALUES, PROPERTY_VALUES_1, PROPERTY_VALUES_2 } import { FilterType } from '../constants/FilterConstants'; import { PredefinedProperties } from '../../../utils/types/types'; import yup from '../../../utils/yupConfig'; -import { - DEFAULT_RANGE_VALUE, - getRangeInputDataForm, - getRangeInputSchema, -} from '../../inputs/reactHookForm/numbers/RangeInput'; +import { DEFAULT_RANGE_VALUE, getRangeInputSchema } from '../../inputs/reactHookForm/numbers/RangeInput'; import { FreePropertiesTypes } from './FilterFreeProperties'; -export const getCriteriaBasedSchema = (extraFields: Record) => ({ - [FieldConstants.CRITERIA_BASED]: yup.object().shape({ - [FieldConstants.COUNTRIES]: yup.array().of(yup.string()), - [FieldConstants.COUNTRIES_1]: yup.array().of(yup.string()), - [FieldConstants.COUNTRIES_2]: yup.array().of(yup.string()), - ...getRangeInputSchema(FieldConstants.NOMINAL_VOLTAGE), - ...getRangeInputSchema(FieldConstants.NOMINAL_VOLTAGE_1), - ...getRangeInputSchema(FieldConstants.NOMINAL_VOLTAGE_2), - ...getRangeInputSchema(FieldConstants.NOMINAL_VOLTAGE_3), - ...extraFields, - }), -}); -export const getCriteriaBasedFormData = (criteriaValues: any, extraFields: Record) => ({ - [FieldConstants.CRITERIA_BASED]: { - [FieldConstants.COUNTRIES]: criteriaValues?.[FieldConstants.COUNTRIES] ?? [], - [FieldConstants.COUNTRIES_1]: criteriaValues?.[FieldConstants.COUNTRIES_1] ?? [], - [FieldConstants.COUNTRIES_2]: criteriaValues?.[FieldConstants.COUNTRIES_2] ?? [], - ...getRangeInputDataForm( - FieldConstants.NOMINAL_VOLTAGE, - criteriaValues?.[FieldConstants.NOMINAL_VOLTAGE] ?? DEFAULT_RANGE_VALUE - ), - ...getRangeInputDataForm( - FieldConstants.NOMINAL_VOLTAGE_1, - criteriaValues?.[FieldConstants.NOMINAL_VOLTAGE_1] ?? DEFAULT_RANGE_VALUE - ), - ...getRangeInputDataForm( - FieldConstants.NOMINAL_VOLTAGE_2, - criteriaValues?.[FieldConstants.NOMINAL_VOLTAGE_2] ?? DEFAULT_RANGE_VALUE - ), - ...getRangeInputDataForm( - FieldConstants.NOMINAL_VOLTAGE_3, - criteriaValues?.[FieldConstants.NOMINAL_VOLTAGE_3] ?? DEFAULT_RANGE_VALUE - ), - ...extraFields, - }, -}); +export function getCriteriaBasedSchema(extraFields: Record = {}) { + return { + [FieldConstants.CRITERIA_BASED]: yup.object().shape({ + [FieldConstants.COUNTRIES]: yup.array().of(yup.string()), + [FieldConstants.COUNTRIES_1]: yup.array().of(yup.string()), + [FieldConstants.COUNTRIES_2]: yup.array().of(yup.string()), + ...getRangeInputSchema(FieldConstants.NOMINAL_VOLTAGE), + ...getRangeInputSchema(FieldConstants.NOMINAL_VOLTAGE_1), + ...getRangeInputSchema(FieldConstants.NOMINAL_VOLTAGE_2), + ...getRangeInputSchema(FieldConstants.NOMINAL_VOLTAGE_3), + ...extraFields, + }), + }; +} + +export function getCriteriaBasedFormData( + criteriaValues?: Record, + extraFields: Record = {} +) { + return { + [FieldConstants.CRITERIA_BASED]: { + [FieldConstants.COUNTRIES]: criteriaValues?.[FieldConstants.COUNTRIES] ?? [], + [FieldConstants.COUNTRIES_1]: criteriaValues?.[FieldConstants.COUNTRIES_1] ?? [], + [FieldConstants.COUNTRIES_2]: criteriaValues?.[FieldConstants.COUNTRIES_2] ?? [], + [FieldConstants.NOMINAL_VOLTAGE]: criteriaValues?.[FieldConstants.NOMINAL_VOLTAGE] ?? DEFAULT_RANGE_VALUE, + [FieldConstants.NOMINAL_VOLTAGE_1]: + criteriaValues?.[FieldConstants.NOMINAL_VOLTAGE_1] ?? DEFAULT_RANGE_VALUE, + [FieldConstants.NOMINAL_VOLTAGE_2]: + criteriaValues?.[FieldConstants.NOMINAL_VOLTAGE_2] ?? DEFAULT_RANGE_VALUE, + [FieldConstants.NOMINAL_VOLTAGE_3]: + criteriaValues?.[FieldConstants.NOMINAL_VOLTAGE_3] ?? DEFAULT_RANGE_VALUE, + ...extraFields, + }, + } as const; +} /** * Transform @@ -65,7 +60,7 @@ export const getCriteriaBasedFormData = (criteriaValues: any, extraFields: Recor * {name_property:namesB, prop_values:valuesB}] * @author Laurent LAUGARN modified by Florent MILLOT */ -export const backToFrontTweak = (response: any) => { +export function backToFrontTweak(response: any) { const subProps = response.equipmentFilterForm.substationFreeProperties; const freeProps = response.equipmentFilterForm.freeProperties; const props1 = response.equipmentFilterForm.freeProperties1; @@ -111,18 +106,17 @@ export const backToFrontTweak = (response: any) => { filterFreeProperties.push(prop); }); - const ret = { + return { [FieldConstants.EQUIPMENT_TYPE]: response[FieldConstants.EQUIPMENT_TYPE], ...getCriteriaBasedFormData(response.equipmentFilterForm, { [FieldConstants.ENERGY_SOURCE]: response.equipmentFilterForm[FieldConstants.ENERGY_SOURCE], [FreePropertiesTypes.SUBSTATION_FILTER_PROPERTIES]: filterSubstationProperties, [FreePropertiesTypes.FREE_FILTER_PROPERTIES]: filterFreeProperties, }), - }; - return ret; -}; + } as const; +} -function isNominalVoltageEmpty(nominalVoltage: Record): boolean { +function isNominalVoltageEmpty(nominalVoltage: Record) { return nominalVoltage[FieldConstants.VALUE_1] === null && nominalVoltage[FieldConstants.VALUE_2] === null; } @@ -155,20 +149,13 @@ function cleanNominalVoltages(formValues: any) { * freeProperties2.{nameA:valuesC}} * @author Laurent LAUGARN modified by Florent MILLOT */ -export const frontToBackTweak = (id?: string, filter?: any) => { +export function frontToBackTweak(id?: string, filter?: any) { const filterSubstationProperties = filter[FieldConstants.CRITERIA_BASED][FreePropertiesTypes.SUBSTATION_FILTER_PROPERTIES]; - const ret = { - id, - type: FilterType.CRITERIA_BASED.id, - equipmentFilterForm: undefined, - }; const eff = { [FieldConstants.EQUIPMENT_TYPE]: filter[FieldConstants.EQUIPMENT_TYPE], ...cleanNominalVoltages(filter[FieldConstants.CRITERIA_BASED]), }; - // in the back end we store everything in a field called equipmentFilterForm - ret.equipmentFilterForm = eff; delete eff[FreePropertiesTypes.SUBSTATION_FILTER_PROPERTIES]; const props: any = {}; const props1: any = {}; @@ -194,7 +181,7 @@ export const frontToBackTweak = (id?: string, filter?: any) => { const filterFreeProperties = filter[FieldConstants.CRITERIA_BASED][FreePropertiesTypes.FREE_FILTER_PROPERTIES]; // in the back end we store everything in a field called equipmentFilterForm delete eff[FreePropertiesTypes.FREE_FILTER_PROPERTIES]; - const freeProps: any = {}; + const freeProps: Record = {}; filterFreeProperties.forEach((prop: any) => { const values = prop[PROPERTY_VALUES]; if (values) { @@ -202,5 +189,10 @@ export const frontToBackTweak = (id?: string, filter?: any) => { } }); eff.freeProperties = freeProps; - return ret; -}; + return { + id, + type: FilterType.CRITERIA_BASED.id, + // in the back end we store everything in a field called equipmentFilterForm + equipmentFilterForm: eff, + }; +} diff --git a/src/components/inputs/reactHookForm/numbers/RangeInput.tsx b/src/components/inputs/reactHookForm/numbers/RangeInput.tsx index 3be68cdd..8b19c725 100644 --- a/src/components/inputs/reactHookForm/numbers/RangeInput.tsx +++ b/src/components/inputs/reactHookForm/numbers/RangeInput.tsx @@ -30,35 +30,36 @@ export const RangeType = { LESS_THAN: { id: 'LESS_THAN', label: 'lessThan' }, LESS_OR_EQUAL: { id: 'LESS_OR_EQUAL', label: 'lessOrEqual' }, RANGE: { id: 'RANGE', label: 'range' }, -}; +} as const; export const DEFAULT_RANGE_VALUE = { [FieldConstants.OPERATION_TYPE]: RangeType.EQUALITY.id, [FieldConstants.VALUE_1]: null, [FieldConstants.VALUE_2]: null, -}; -export const getRangeInputDataForm = (name: string, rangeValue: unknown) => ({ - [name]: rangeValue, -}); +} as const; -export const getRangeInputSchema = (name: string) => ({ - [name]: yup.object().shape( - { - [FieldConstants.OPERATION_TYPE]: yup.string(), - [FieldConstants.VALUE_1]: yup.number().when([FieldConstants.OPERATION_TYPE, FieldConstants.VALUE_2], { - is: (operationType: string, value2: unknown) => operationType === RangeType.RANGE.id && value2 !== null, - then: (schema) => schema.required(), - otherwise: (schema) => schema.nullable(), - }), - [FieldConstants.VALUE_2]: yup.number().when([FieldConstants.OPERATION_TYPE, FieldConstants.VALUE_1], { - is: (operationType: string, value1: unknown) => operationType === RangeType.RANGE.id && value1 !== null, - then: (schema) => schema.required(), - otherwise: (schema) => schema.nullable(), - }), - }, - [[FieldConstants.VALUE_1, FieldConstants.VALUE_2]] - ), -}); +export function getRangeInputSchema(name: TName) { + return { + [name]: yup.object().shape( + { + [FieldConstants.OPERATION_TYPE]: yup.string(), + [FieldConstants.VALUE_1]: yup.number().when([FieldConstants.OPERATION_TYPE, FieldConstants.VALUE_2], { + is: (operationType: string, value2: unknown) => + operationType === RangeType.RANGE.id && value2 !== null, + then: (schema) => schema.required(), + otherwise: (schema) => schema.nullable(), + }), + [FieldConstants.VALUE_2]: yup.number().when([FieldConstants.OPERATION_TYPE, FieldConstants.VALUE_1], { + is: (operationType: string, value1: unknown) => + operationType === RangeType.RANGE.id && value1 !== null, + then: (schema) => schema.required(), + otherwise: (schema) => schema.nullable(), + }), + }, + [[FieldConstants.VALUE_1, FieldConstants.VALUE_2]] + ), + } as const; +} interface RangeInputProps { name: string; From 38562f0f471c0e131fe2801625a39f664f572186 Mon Sep 17 00:00:00 2001 From: Tristan Chuine Date: Wed, 27 Nov 2024 18:10:07 +0100 Subject: [PATCH 2/2] Fixing types (bis) --- .../customMuiDialog/CustomMuiDialog.tsx | 29 ++-- .../criteriaBased/criteriaBasedFilterUtils.ts | 26 +++- .../reactHookForm/numbers/RangeInput.tsx | 131 ++++++++---------- .../provider/CustomFormProvider.tsx | 17 ++- .../provider/useCustomFormContext.ts | 1 + .../reactHookForm/utils/SubmitButton.tsx | 4 +- 6 files changed, 108 insertions(+), 100 deletions(-) diff --git a/src/components/dialogs/customMuiDialog/CustomMuiDialog.tsx b/src/components/dialogs/customMuiDialog/CustomMuiDialog.tsx index 7ede15d6..677d635b 100644 --- a/src/components/dialogs/customMuiDialog/CustomMuiDialog.tsx +++ b/src/components/dialogs/customMuiDialog/CustomMuiDialog.tsx @@ -5,28 +5,28 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import React, { useCallback, useState } from 'react'; +import { type MouseEvent, type ReactNode, useCallback, useState } from 'react'; import { FieldErrors, FieldValues, SubmitHandler, UseFormReturn } from 'react-hook-form'; import { FormattedMessage } from 'react-intl'; import { Dialog, DialogActions, DialogContent, DialogTitle, Grid, LinearProgress } from '@mui/material'; -import * as yup from 'yup'; +import { type ObjectSchema } from 'yup'; import { SubmitButton } from '../../inputs/reactHookForm/utils/SubmitButton'; import { CancelButton } from '../../inputs/reactHookForm/utils/CancelButton'; -import { CustomFormProvider, MergedFormContextProps } from '../../inputs/reactHookForm/provider/CustomFormProvider'; +import { CustomFormProvider } from '../../inputs/reactHookForm/provider/CustomFormProvider'; import { PopupConfirmationDialog } from '../popupConfirmationDialog/PopupConfirmationDialog'; export interface CustomMuiDialogProps { open: boolean; - formSchema: yup.AnySchema; - formMethods: UseFormReturn | MergedFormContextProps; - onClose: (event?: React.MouseEvent) => void; + formSchema: ObjectSchema; + formMethods: UseFormReturn; + onClose: (event?: MouseEvent) => void; onSave: SubmitHandler; onValidationError?: (errors: FieldErrors) => void; titleId: string; disabledSave?: boolean; removeOptional?: boolean; onCancel?: () => void; - children: React.ReactNode; + children: ReactNode; isDataFetching?: boolean; language?: string; confirmationMessageKey?: string; @@ -98,14 +98,14 @@ export function CustomMuiDialog({ const { handleSubmit } = formMethods; const handleCancel = useCallback( - (event: React.MouseEvent) => { + (event: MouseEvent) => { onCancel?.(); onClose(event); }, [onCancel, onClose] ); - const handleClose = (event: React.MouseEvent, reason?: string) => { + const handleClose = (event: MouseEvent, reason?: string) => { if (reason === 'backdropClick') { return; } @@ -139,12 +139,15 @@ export function CustomMuiDialog({ } }, [validate, validatedData]); - const handleValidationError = (errors: FieldErrors) => { - onValidationError?.(errors); - }; + const handleValidationError = useCallback( + (errors: FieldErrors) => { + onValidationError?.(errors); + }, + [onValidationError] + ); return ( - {...formMethods} validationSchema={formSchema} removeOptional={removeOptional} diff --git a/src/components/filter/criteriaBased/criteriaBasedFilterUtils.ts b/src/components/filter/criteriaBased/criteriaBasedFilterUtils.ts index e963a1be..bd52cd6a 100644 --- a/src/components/filter/criteriaBased/criteriaBasedFilterUtils.ts +++ b/src/components/filter/criteriaBased/criteriaBasedFilterUtils.ts @@ -5,27 +5,43 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +import { type ObjectSchema } from 'yup'; import { FieldConstants } from '../../../utils/constants/fieldConstants'; import { PROPERTY_NAME, PROPERTY_VALUES, PROPERTY_VALUES_1, PROPERTY_VALUES_2 } from './FilterProperty'; import { FilterType } from '../constants/FilterConstants'; import { PredefinedProperties } from '../../../utils/types/types'; import yup from '../../../utils/yupConfig'; -import { DEFAULT_RANGE_VALUE, getRangeInputSchema } from '../../inputs/reactHookForm/numbers/RangeInput'; +import { + DEFAULT_RANGE_VALUE, + getRangeInputSchema, + type RangeInputData, +} from '../../inputs/reactHookForm/numbers/RangeInput'; import { FreePropertiesTypes } from './FilterFreeProperties'; +export type CriteriaBasedData = { + [FieldConstants.COUNTRIES]?: string[]; + [FieldConstants.COUNTRIES_1]?: string[]; + [FieldConstants.COUNTRIES_2]?: string[]; + [FieldConstants.NOMINAL_VOLTAGE]?: RangeInputData | null; + [FieldConstants.NOMINAL_VOLTAGE_1]?: RangeInputData | null; + [FieldConstants.NOMINAL_VOLTAGE_2]?: RangeInputData | null; + [FieldConstants.NOMINAL_VOLTAGE_3]?: RangeInputData | null; + [key: string]: any; +}; + export function getCriteriaBasedSchema(extraFields: Record = {}) { return { [FieldConstants.CRITERIA_BASED]: yup.object().shape({ - [FieldConstants.COUNTRIES]: yup.array().of(yup.string()), - [FieldConstants.COUNTRIES_1]: yup.array().of(yup.string()), - [FieldConstants.COUNTRIES_2]: yup.array().of(yup.string()), + [FieldConstants.COUNTRIES]: yup.array().of(yup.string().required()), + [FieldConstants.COUNTRIES_1]: yup.array().of(yup.string().required()), + [FieldConstants.COUNTRIES_2]: yup.array().of(yup.string().required()), ...getRangeInputSchema(FieldConstants.NOMINAL_VOLTAGE), ...getRangeInputSchema(FieldConstants.NOMINAL_VOLTAGE_1), ...getRangeInputSchema(FieldConstants.NOMINAL_VOLTAGE_2), ...getRangeInputSchema(FieldConstants.NOMINAL_VOLTAGE_3), ...extraFields, }), - }; + } as const satisfies Record>; } export function getCriteriaBasedFormData( diff --git a/src/components/inputs/reactHookForm/numbers/RangeInput.tsx b/src/components/inputs/reactHookForm/numbers/RangeInput.tsx index 8b19c725..9c380f6d 100644 --- a/src/components/inputs/reactHookForm/numbers/RangeInput.tsx +++ b/src/components/inputs/reactHookForm/numbers/RangeInput.tsx @@ -7,9 +7,8 @@ import { useWatch } from 'react-hook-form'; import { FormattedMessage } from 'react-intl'; import { useMemo } from 'react'; -import InputLabel from '@mui/material/InputLabel'; -import { Grid } from '@mui/material'; -import FormControl from '@mui/material/FormControl'; +import { type ObjectSchema } from 'yup'; +import { FormControl, Grid, InputLabel } from '@mui/material'; import { FloatInput } from './FloatInput'; import yup from '../../../../utils/yupConfig'; import { MuiSelectInput } from '../selectInputs/MuiSelectInput'; @@ -32,33 +31,36 @@ export const RangeType = { RANGE: { id: 'RANGE', label: 'range' }, } as const; -export const DEFAULT_RANGE_VALUE = { +export type RangeInputData = { + [FieldConstants.OPERATION_TYPE]: string; + [FieldConstants.VALUE_1]: number | null; + [FieldConstants.VALUE_2]: number | null; +}; + +export const DEFAULT_RANGE_VALUE: RangeInputData = { [FieldConstants.OPERATION_TYPE]: RangeType.EQUALITY.id, [FieldConstants.VALUE_1]: null, [FieldConstants.VALUE_2]: null, -} as const; +}; export function getRangeInputSchema(name: TName) { - return { - [name]: yup.object().shape( - { - [FieldConstants.OPERATION_TYPE]: yup.string(), - [FieldConstants.VALUE_1]: yup.number().when([FieldConstants.OPERATION_TYPE, FieldConstants.VALUE_2], { - is: (operationType: string, value2: unknown) => - operationType === RangeType.RANGE.id && value2 !== null, - then: (schema) => schema.required(), - otherwise: (schema) => schema.nullable(), - }), - [FieldConstants.VALUE_2]: yup.number().when([FieldConstants.OPERATION_TYPE, FieldConstants.VALUE_1], { - is: (operationType: string, value1: unknown) => - operationType === RangeType.RANGE.id && value1 !== null, - then: (schema) => schema.required(), - otherwise: (schema) => schema.nullable(), - }), - }, - [[FieldConstants.VALUE_1, FieldConstants.VALUE_2]] - ), - } as const; + const result = yup.object().shape( + { + [FieldConstants.OPERATION_TYPE]: yup.string(), + [FieldConstants.VALUE_1]: yup.number().when([FieldConstants.OPERATION_TYPE, FieldConstants.VALUE_2], { + is: (operationType: string, value2: unknown) => operationType === RangeType.RANGE.id && value2 !== null, + then: (schema) => schema.required(), + otherwise: (schema) => schema.nullable(), + }), + [FieldConstants.VALUE_2]: yup.number().when([FieldConstants.OPERATION_TYPE, FieldConstants.VALUE_1], { + is: (operationType: string, value1: unknown) => operationType === RangeType.RANGE.id && value1 !== null, + then: (schema) => schema.required(), + otherwise: (schema) => schema.nullable(), + }), + }, + [[FieldConstants.VALUE_1, FieldConstants.VALUE_2]] + ); + return { [name]: result } as Record>; } interface RangeInputProps { @@ -67,64 +69,47 @@ interface RangeInputProps { } export function RangeInput({ name, label }: RangeInputProps) { - const watchOperationType = useWatch({ - name: `${name}.${FieldConstants.OPERATION_TYPE}`, - }); + const watchOperationType = useWatch({ name: `${name}.${FieldConstants.OPERATION_TYPE}` }); const isOperationTypeRange = useMemo(() => watchOperationType === RangeType.RANGE.id, [watchOperationType]); - const firstValueField = ( - - ); - - const secondValueField = ( - - ); - - const operationTypeField = ( - - ); - return ( - - {operationTypeField} + + + + + - {firstValueField} - {isOperationTypeRange && {secondValueField}} + {isOperationTypeRange && ( + + + + )} ); diff --git a/src/components/inputs/reactHookForm/provider/CustomFormProvider.tsx b/src/components/inputs/reactHookForm/provider/CustomFormProvider.tsx index e6630d21..e68b1e11 100644 --- a/src/components/inputs/reactHookForm/provider/CustomFormProvider.tsx +++ b/src/components/inputs/reactHookForm/provider/CustomFormProvider.tsx @@ -6,27 +6,30 @@ */ import React, { createContext, PropsWithChildren } from 'react'; -import { FormProvider, UseFormReturn } from 'react-hook-form'; +import { type FieldValues, FormProvider, type UseFormReturn } from 'react-hook-form'; import * as yup from 'yup'; +import { type ObjectSchema } from 'yup'; import { getSystemLanguage } from '../../../../hooks/useLocalizedCountries'; -type CustomFormContextProps = { +type CustomFormContextProps = { removeOptional?: boolean; - validationSchema: yup.AnySchema; + validationSchema: ObjectSchema; language?: string; }; -export type MergedFormContextProps = UseFormReturn & CustomFormContextProps; - -type CustomFormProviderProps = PropsWithChildren; +export type MergedFormContextProps = UseFormReturn & + CustomFormContextProps; +// TODO found how to manage generic type export const CustomFormContext = createContext({ removeOptional: false, validationSchema: yup.object(), language: getSystemLanguage(), }); -export function CustomFormProvider(props: CustomFormProviderProps) { +export function CustomFormProvider( + props: PropsWithChildren> +) { const { validationSchema, removeOptional, language, children, ...formMethods } = props; return ( diff --git a/src/components/inputs/reactHookForm/provider/useCustomFormContext.ts b/src/components/inputs/reactHookForm/provider/useCustomFormContext.ts index 08a9bf9d..98013c41 100644 --- a/src/components/inputs/reactHookForm/provider/useCustomFormContext.ts +++ b/src/components/inputs/reactHookForm/provider/useCustomFormContext.ts @@ -9,6 +9,7 @@ import { useFormContext } from 'react-hook-form'; import { useContext } from 'react'; import { CustomFormContext, MergedFormContextProps } from './CustomFormProvider'; +// TODO found how to manage generic type export const useCustomFormContext = (): MergedFormContextProps => { const formMethods = useFormContext(); const customFormMethods = useContext(CustomFormContext); diff --git a/src/components/inputs/reactHookForm/utils/SubmitButton.tsx b/src/components/inputs/reactHookForm/utils/SubmitButton.tsx index 217ce03b..f4c61890 100644 --- a/src/components/inputs/reactHookForm/utils/SubmitButton.tsx +++ b/src/components/inputs/reactHookForm/utils/SubmitButton.tsx @@ -5,11 +5,11 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import { Button } from '@mui/material'; +import { Button, ButtonProps } from '@mui/material'; import { useFormState } from 'react-hook-form'; import { FormattedMessage } from 'react-intl'; -export function SubmitButton({ ...buttonProps }) { +export function SubmitButton(buttonProps: Readonly) { const { isDirty } = useFormState(); return (