diff --git a/.talismanrc b/.talismanrc index 49040ca00..bd8b80cdc 100644 --- a/.talismanrc +++ b/.talismanrc @@ -49,7 +49,7 @@ fileignoreconfig: - filename: frontend/src/components/modals/HousingOwnersModal/HousingOwnersModal.tsx checksum: 0f56c244b78d19588ebfe7f31222d97a861b3eb775ea8c385c202d5b0d8af387 - filename: frontend/src/hooks/useForm.tsx - checksum: 6d16b338e7203dc37f64b3e00e4da0365dc35461e5c776853b55243509e3d9b9 + checksum: 3104539d0c97ef59db34c967b91e153fbb648e641a69084132951e8349f65636 - filename: frontend/src/hooks/useSort.tsx checksum: ab84c274637d24aa7f18456c2bb32f39802d5e3afe700a052ece484a1eec46a6 - filename: frontend/src/index.tsx diff --git a/frontend/src/components/modals/HousingOwnersModal/HousingAdditionalOwner.tsx b/frontend/src/components/modals/HousingOwnersModal/HousingAdditionalOwner.tsx index d30f4dbc5..9b5b5af35 100644 --- a/frontend/src/components/modals/HousingOwnersModal/HousingAdditionalOwner.tsx +++ b/frontend/src/components/modals/HousingOwnersModal/HousingAdditionalOwner.tsx @@ -13,30 +13,29 @@ interface Props { onAddOwner: (housingOwner: HousingOwner) => void; } -const HousingAdditionalOwner = ({ - housingId, - activeOwnersCount, - onAddOwner, -}: Props) => { - const [additionalOwnerRank, setAdditionalOwnerRank] = useState('invalid'); +function HousingAdditionalOwner({ activeOwnersCount, onAddOwner }: Props) { + const [additionalOwnerRank, setAdditionalOwnerRank] = + useState('invalid'); - const submitAddingHousingOwner = (owner: Owner) => { + function submitAddingHousingOwner(owner: Owner) { onAddOwner?.({ ...owner, rank: Number(additionalOwnerRank), - housingId, + idprocpte: null, + idprodroit: null, + locprop: null }); - }; + } const ownerRankOptions: SelectOption[] = [ { value: '1', label: `Propriétaire principal` }, ...Array.from(Array(activeOwnersCount).keys()).map((_) => ({ value: String(_ + 2), - label: _ + 2 + 'ème ayant droit', + label: _ + 2 + 'ème ayant droit' })), { value: '0', label: `Ancien propriétaire` }, - { value: '-1', label: 'Propriétaire incorrect'}, - { value: '-3', label: 'Propriétaire décédé.e'}, + { value: '-1', label: 'Propriétaire incorrect' }, + { value: '-3', label: 'Propriétaire décédé.e' } ]; return ( @@ -45,7 +44,7 @@ const HousingAdditionalOwner = ({ nativeSelectProps={{ onChange: (e: ChangeEvent) => setAdditionalOwnerRank(e.target.value), - value: additionalOwnerRank, + value: additionalOwnerRank }} label="Sélectionner les droits de propriétés" className="fr-pt-2w" @@ -60,13 +59,13 @@ const HousingAdditionalOwner = ({ > ))} - { additionalOwnerRank === 'invalid' && + {additionalOwnerRank === 'invalid' && ( - } + /> + )}
@@ -82,6 +81,6 @@ const HousingAdditionalOwner = ({
); -}; +} export default HousingAdditionalOwner; diff --git a/frontend/src/components/modals/HousingOwnersModal/HousingAdditionalOwnerCreation.tsx b/frontend/src/components/modals/HousingOwnersModal/HousingAdditionalOwnerCreation.tsx index 99470f9ff..abb1260ae 100644 --- a/frontend/src/components/modals/HousingOwnersModal/HousingAdditionalOwnerCreation.tsx +++ b/frontend/src/components/modals/HousingOwnersModal/HousingAdditionalOwnerCreation.tsx @@ -5,9 +5,8 @@ import * as yup from 'yup'; import { birthDateValidator, emailValidator, - useForm, + useForm } from '../../../hooks/useForm'; -import { parseDateInput } from '../../../utils/dateUtils'; import AppTextInput from '../../_app/AppTextInput/AppTextInput'; import { useCreateOwnerMutation } from '../../../services/owner.service'; import { Alert } from '@codegouvfr/react-dsfr/Alert'; @@ -32,7 +31,7 @@ const HousingAdditionalOwnerCreation = ({ onAdd, rank }: Props) => { rawAddress: yup.array().nullable(), email: emailValidator.nullable().notRequired(), phone: yup.string().nullable().notRequired(), - rank: yup.number(), + rank: yup.number() }; type FormShape = typeof shape; @@ -42,29 +41,28 @@ const HousingAdditionalOwnerCreation = ({ onAdd, rank }: Props) => { rawAddress, email, phone, - rank, + rank }); const [createOwner, { data: owner, isError: isCreateError }] = useCreateOwnerMutation(); - const submit = async () => { - await form.validate(() => { - createOwner({ + async function submit() { + await form.validate(async () => { + await createOwner({ fullName, - birthDate: parseDateInput(birthDate), + birthDate: birthDate, rawAddress: rawAddress ?? [], email, - phone, - rank - }); + phone + }).unwrap(); }); - }; + } useEffect(() => { if (owner) { onAdd(owner); } - }, [owner]); //eslint-disable-line react-hooks/exhaustive-deps + }, [onAdd, owner]); return ( diff --git a/frontend/src/hooks/useForm.tsx b/frontend/src/hooks/useForm.tsx index 3b0ed8579..8186acf61 100644 --- a/frontend/src/hooks/useForm.tsx +++ b/frontend/src/hooks/useForm.tsx @@ -15,15 +15,15 @@ export const passwordFormatValidator = yup .min(8, 'Au moins 8 caractères.') .matches(/[A-Z]/g, { name: 'uppercase', - message: 'Au moins une majuscule.', + message: 'Au moins une majuscule.' }) .matches(/[a-z]/g, { name: 'lowercase', - message: 'Au moins une minuscule.', + message: 'Au moins une minuscule.' }) .matches(/[0-9]/g, { name: 'number', - message: 'Au moins un chiffre.', + message: 'Au moins un chiffre.' }); export const passwordConfirmationValidator = yup @@ -53,12 +53,10 @@ export const fileValidator = (supportedFormats: string[]) => .test( 'fileType', 'Format de fichier invalide', - (value) => value && supportedFormats.includes(value.type), + (value) => value && supportedFormats.includes(value.type) ); -export const banAddressValidator = yup - .object() - .required('Veuillez sélectionner une adresse issue de la BAN.'); +export const banAddressValidator = yup.object(); export const birthDateValidator = dateValidator.nullable().notRequired(); @@ -77,7 +75,7 @@ interface Message { */ export function useForm< T extends ObjectShape, - U extends Record, + U extends Record >(schema: yup.ObjectSchema, input: U, fullValidationKeys?: (keyof U)[]) { const [errors, setErrors] = useState(); const [touchedKeys, setTouchedKeys] = useState>(new Set()); @@ -97,7 +95,7 @@ export function useForm< * @param key */ function errorList( - key?: K, + key?: K ): yup.ValidationError[] | undefined { return key && touchedKeys.has(key) ? errors?.filter((error) => error.path === key) @@ -115,7 +113,7 @@ export function useForm< function labels(key?: K): string[] { if (key) { return (schema.fields[key] as any).tests.map( - (test: any) => test.OPTIONS.message, + (test: any) => test.OPTIONS.message ); } return Object.values(schema.fields) @@ -125,7 +123,7 @@ export function useForm< function message( key: K, - whenValid?: string, + whenValid?: string ): string | undefined { return messageType(key) === 'success' && whenValid ? whenValid @@ -141,7 +139,7 @@ export function useForm< text: label, type: errorList(key)?.find((error) => error.message === label) ? 'error' - : 'valid', + : 'valid' })); } @@ -173,7 +171,7 @@ export function useForm< setTouchedKeys(touchedKeys.add(key)); try { await schema.validateAt(String(key), input, { - abortEarly: !fullValidationKeys?.includes(key), + abortEarly: !fullValidationKeys?.includes(key) }); setErrors([...errorsExcept(key)]); } catch (validationError) { @@ -181,7 +179,7 @@ export function useForm< ...errorsExcept(key), ...(!fullValidationKeys?.includes(key) ? [validationError as yup.ValidationError] - : (validationError as yup.ValidationError).inner), + : (validationError as yup.ValidationError).inner) ]); } } @@ -190,8 +188,8 @@ export function useForm< const validations = entriesDeep(input) .filter(([k1, v1]) => entriesDeep(previousInput.current || {}).find( - ([k2, v2]) => k1 === k2 && v1 !== v2, - ), + ([k2, v2]) => k1 === k2 && v1 !== v2 + ) ) .filter(([key]) => touchedKeys.has(key)) .map(([key]) => validateAt(key)); @@ -204,7 +202,7 @@ export function useForm< useEffect(() => { const validations = (fullValidationKeys ?? []).map((key) => - validateAt(key), + validateAt(key) ); (async () => await Promise.all(validations))(); // eslint-disable-next-line react-hooks/exhaustive-deps @@ -218,7 +216,7 @@ export function useForm< message, messageType, validate, - validateAt, + validateAt }; } @@ -228,8 +226,8 @@ function keysDeep(record: ObjectShape, prefix: string = ''): string[] { fp.flatMap<[string, unknown], string>(([key, value]) => fp.isObject(value) && 'fields' in value ? keysDeep(value.fields as ObjectShape, `${key}.`) - : `${prefix}${key}`, - ), + : `${prefix}${key}` + ) )(record); } @@ -239,7 +237,7 @@ function entriesDeep(record: object, prefix: string = ''): [string, unknown][] { fp.flatMap<[string, unknown], [string, unknown]>(([key, value]) => fp.isObject(value) ? entriesDeep(value, `${key}.`) - : [[`${prefix}${key}`, value]], - ), + : [[`${prefix}${key}`, value]] + ) )(record); } diff --git a/frontend/src/views/Housing/HousingView.tsx b/frontend/src/views/Housing/HousingView.tsx index 541d3cf1c..ae26b7282 100644 --- a/frontend/src/views/Housing/HousingView.tsx +++ b/frontend/src/views/Housing/HousingView.tsx @@ -64,7 +64,11 @@ const HousingView = () => { await updateOwner(housingOwner).unwrap(); } }); - if (hasRankChanges(housingOwners, housingOwnersUpdated)) { + + if ( + housingOwners.length !== housingOwnersUpdated.length || + hasRankChanges(housingOwners, housingOwnersUpdated) + ) { await updateHousingOwners({ housingId: housing.id, housingOwners: housingOwnersUpdated