diff --git a/src/model/PartyUser.ts b/src/model/PartyUser.ts index df19de5..7842613 100644 --- a/src/model/PartyUser.ts +++ b/src/model/PartyUser.ts @@ -54,13 +54,14 @@ export type PartyUserOnCreation = { certifiedName: boolean; certifiedSurname: boolean; certifiedMail: boolean; + toAddOnAggregates?: boolean; }; export type AddedUsersList = { name: string; surname: string; taxCode: string; - from?: string; + from?: string; email: string; role: RoleEnum; }; diff --git a/src/pages/addUserFlow/addUser/__tests__/AddUserForm.test.tsx b/src/pages/addUserFlow/addUser/__tests__/AddUserForm.test.tsx index 93c2e1b..8f9ede6 100644 --- a/src/pages/addUserFlow/addUser/__tests__/AddUserForm.test.tsx +++ b/src/pages/addUserFlow/addUser/__tests__/AddUserForm.test.tsx @@ -106,6 +106,7 @@ describe('AddUserForm Component', () => { const radio = screen.getByDisplayValue('referente-legale'); fireEvent.click(radio); + }); test('should validate tax code format when changed', async () => { diff --git a/src/pages/addUserFlow/addUser/components/AddUserForm/AddUserForm.tsx b/src/pages/addUserFlow/addUser/components/AddUserForm/AddUserForm.tsx index c5f70ee..eb6e1b7 100644 --- a/src/pages/addUserFlow/addUser/components/AddUserForm/AddUserForm.tsx +++ b/src/pages/addUserFlow/addUser/components/AddUserForm/AddUserForm.tsx @@ -17,7 +17,7 @@ import { useIsMobile } from '../../../../../hooks/useIsMobile'; import { Party } from '../../../../../model/Party'; import { AddedUsersList, PartyUserOnCreation, TextTransform } from '../../../../../model/PartyUser'; import { Product } from '../../../../../model/Product'; -import { ProductRole, ProductRolesLists, ProductsRolesMap } from '../../../../../model/ProductRole'; +import { ProductRolesLists, ProductsRolesMap } from '../../../../../model/ProductRole'; import { DASHBOARD_USERS_ROUTES } from '../../../../../routes'; import { fetchUserRegistryByFiscalCode } from '../../../../../services/usersService'; import { @@ -221,8 +221,8 @@ export default function AddUserForm({ const fetchTaxCode = (taxCode: string, partyId: string) => { setLoadingFetchTaxCode(true); fetchUserRegistryByFiscalCode(taxCode.toUpperCase(), partyId) - .then((userRegistry) => { - buildFormValues(userRegistry, formik.values, initialFormData); + .then(async (userRegistry) => { + await buildFormValues(userRegistry, formik.values, initialFormData, formik); }) .catch((errors) => errorNotify(errors, taxCode)) .finally(() => setLoadingFetchTaxCode(false)); @@ -331,26 +331,6 @@ export default function AddUserForm({ }); }; - const addRole = async (r: ProductRole) => { - // eslint-disable-next-line functional/no-let - let nextProductRoles; - if (r.multiroleAllowed && formik.values.productRoles.length > 0) { - if (productRoles?.groupByProductRole[formik.values.productRoles[0]].selcRole !== r.selcRole) { - nextProductRoles = [r.productRole]; - } else { - const productRoleIndex = formik.values.productRoles.findIndex((p) => p === r.productRole); - if (productRoleIndex === -1) { - nextProductRoles = formik.values.productRoles.concat([r.productRole]); - } else { - nextProductRoles = formik.values.productRoles.filter((_p, i) => i !== productRoleIndex); - } - } - } else { - nextProductRoles = [r.productRole]; - } - await formik.setFieldValue('productRoles', nextProductRoles, true); - }; - const baseTextFieldProps = ( field: keyof PartyUserOnCreation, label: string, @@ -422,7 +402,6 @@ export default function AddUserForm({ dynamicDocLink={dynamicDocLink} formik={formik} validTaxcode={validTaxcode} - addRole={addRole} setIsAddInBulkEAFlow={setIsAddInBulkEAFlow} setIsAsyncFlow={setIsAsyncFlow} userProduct={userProduct} @@ -462,6 +441,7 @@ export default function AddUserForm({ /> } aria-label={t(titleKey)} + onClick={() => formik.setFieldValue('toAddOnAggregates', value, true)} /> ))} diff --git a/src/pages/addUserFlow/addUser/components/AddUserForm/components/ProductRolesSection.tsx b/src/pages/addUserFlow/addUser/components/AddUserForm/components/ProductRolesSection.tsx index 9e4d848..fc82524 100644 --- a/src/pages/addUserFlow/addUser/components/AddUserForm/components/ProductRolesSection.tsx +++ b/src/pages/addUserFlow/addUser/components/AddUserForm/components/ProductRolesSection.tsx @@ -2,8 +2,10 @@ import InfoOutlinedIcon from '@mui/icons-material/InfoOutlined'; import { Box, Checkbox, Divider, Grid, Radio, Tooltip } from '@mui/material'; import { ButtonNaked } from '@pagopa/mui-italia'; import { TitleBox } from '@pagopa/selfcare-common-frontend/lib'; +import { FormikProps } from 'formik'; import React, { SetStateAction } from 'react'; import { Party } from '../../../../../../model/Party'; +import { PartyUserOnCreation } from '../../../../../../model/PartyUser'; import { Product } from '../../../../../../model/Product'; import { ProductRole, ProductRolesLists } from '../../../../../../model/ProductRole'; import { commonStyles, CustomFormControlLabel } from '../../../../utils/helpers'; @@ -14,9 +16,8 @@ interface ProductRolesSectionProps { party: Party; productRoles: ProductRolesLists; dynamicDocLink: string; - formik: any; + formik: FormikProps; validTaxcode: string | undefined; - addRole: (role: ProductRole) => void; setIsAddInBulkEAFlow: (value: SetStateAction) => void; setIsAsyncFlow: (value: SetStateAction) => void; userProduct: Product | undefined; @@ -29,7 +30,6 @@ export const ProductRolesSection = ({ dynamicDocLink, formik, validTaxcode, - addRole, setIsAddInBulkEAFlow, setIsAsyncFlow, userProduct, @@ -37,85 +37,107 @@ export const ProductRolesSection = ({ renderLabel, t, -}: ProductRolesSectionProps) => ( - - - {dynamicDocLink.length > 0 && ( - - { - window.open(dynamicDocLink); - }} - > - {t('userEdit.addForm.role.documentationLink')} - - - )} - {Object.values(productRoles.groupBySelcRole).map((roles) => - roles - .filter((r) => isAddRoleFromDashboard(r.phasesAdditionAllowed)) - .map((p, index: number, filteredRoles) => ( - - - -1} - disabled={!validTaxcode} - value={p.productRole} - control={roles.length > 1 && p.multiroleAllowed ? : } - label={renderLabel(p, !!validTaxcode)} +}: ProductRolesSectionProps) => { + const addRole = async (r: ProductRole) => { + // eslint-disable-next-line functional/no-let + let nextProductRoles; + if (r.multiroleAllowed && formik.values.productRoles.length > 0) { + if (productRoles?.groupByProductRole[formik.values.productRoles[0]].selcRole !== r.selcRole) { + nextProductRoles = [r.productRole]; + } else { + const productRoleIndex = formik.values.productRoles.findIndex((p) => p === r.productRole); + if (productRoleIndex === -1) { + nextProductRoles = formik.values.productRoles.concat([r.productRole]); + } else { + nextProductRoles = formik.values.productRoles.filter((_p, i) => i !== productRoleIndex); + } + } + } else { + nextProductRoles = [r.productRole]; + } + await formik.setFieldValue('productRoles', nextProductRoles, true); + }; + + return ( + + + {dynamicDocLink.length > 0 && ( + + { + window.open(dynamicDocLink); + }} + > + {t('userEdit.addForm.role.documentationLink')} + + + )} + {Object.values(productRoles.groupBySelcRole).map((roles) => + roles + .filter((r) => isAddRoleFromDashboard(r.phasesAdditionAllowed)) + .map((p, index: number, filteredRoles) => ( + + { - addRole(p); - setIsAddInBulkEAFlow( - p?.phasesAdditionAllowed.includes('dashboard-aggregator') && - party.products.some( - (p) => p.productId === userProduct?.id && p.isAggregator - ) - ); - setIsAsyncFlow(p?.phasesAdditionAllowed.includes('dashboard-async')); - } - : undefined - } - /> - {isAddRoleFromDashboardAsync(p?.phasesAdditionAllowed) && ( - - - + sx={{ + display: 'flex', + justifyContent: 'space-between', + alignItems: 'center', + width: '100%', + my: 2, + }} + > + -1} + disabled={!validTaxcode} + value={p.productRole} + control={roles.length > 1 && p.multiroleAllowed ? : } + label={renderLabel(p, !!validTaxcode)} + aria-label={`${p.title}`} + onClick={ + validTaxcode + ? async () => { + await addRole(p); + setIsAddInBulkEAFlow( + p?.phasesAdditionAllowed.includes('dashboard-aggregator') && + party.products.some( + (p) => p.productId === userProduct?.id && p.isAggregator + ) + ); + setIsAsyncFlow(p?.phasesAdditionAllowed.includes('dashboard-async')); + } + : undefined + } + /> + {isAddRoleFromDashboardAsync(p?.phasesAdditionAllowed) && ( + + + + )} + + {filteredRoles.length !== index + 1 && ( + + + )} - - {filteredRoles.length !== index + 1 && ( - - - - )} - - )) - )} - -); + + )) + )} + + ); +}; diff --git a/src/pages/addUserFlow/addUser/components/AddUserForm/components/UserDataSection.tsx b/src/pages/addUserFlow/addUser/components/AddUserForm/components/UserDataSection.tsx index bbf9f7d..6a91d70 100644 --- a/src/pages/addUserFlow/addUser/components/AddUserForm/components/UserDataSection.tsx +++ b/src/pages/addUserFlow/addUser/components/AddUserForm/components/UserDataSection.tsx @@ -1,11 +1,12 @@ import { Grid } from '@mui/material'; import { theme } from '@pagopa/mui-italia'; import { TitleBox } from '@pagopa/selfcare-common-frontend/lib'; +import { FormikProps } from 'formik'; import { PartyUserOnCreation, TextTransform } from '../../../../../../model/PartyUser'; import { commonStyles, CustomTextField } from '../../../../utils/helpers'; type UserDataSectionProps = { - formik: any; + formik: FormikProps; baseTextFieldProps: ( field: keyof PartyUserOnCreation, label: string, diff --git a/src/pages/addUserFlow/addUser/components/AddUserForm/utils/addUserFormUtils.ts b/src/pages/addUserFlow/addUser/components/AddUserForm/utils/addUserFormUtils.ts index ce9b087..d4ecec7 100644 --- a/src/pages/addUserFlow/addUser/components/AddUserForm/utils/addUserFormUtils.ts +++ b/src/pages/addUserFlow/addUser/components/AddUserForm/utils/addUserFormUtils.ts @@ -2,6 +2,7 @@ import { emailRegexp } from '@pagopa/selfcare-common-frontend/lib/utils/constant import { verifyChecksumMatchWithTaxCode } from '@pagopa/selfcare-common-frontend/lib/utils/verifyChecksumMatchWithTaxCode'; import { verifyNameMatchWithTaxCode } from '@pagopa/selfcare-common-frontend/lib/utils/verifyNameMatchWithTaxCode'; import { verifySurnameMatchWithTaxCode } from '@pagopa/selfcare-common-frontend/lib/utils/verifySurnameMatchWithTaxCode'; +import { FormikProps } from 'formik'; import { PartyUserOnCreation } from '../../../../../../model/PartyUser'; import { UserRegistry } from '../../../../../../model/UserRegistry'; import { requiredError, taxCodeRegexp } from '../../../../utils/validation'; @@ -41,6 +42,7 @@ export const validateUserForm = ( ? t('userEdit.addForm.errors.mismatchEmail') : undefined, productRoles: values.productRoles?.length === 0 ? requiredError : undefined, + toAddOnAggregates: values.toAddOnAggregates === undefined ? requiredError : undefined, }).filter(([_key, value]) => value) ); @@ -64,32 +66,36 @@ export const EA_RADIO_OPTIONS = [ }, ]; -export const buildFormValues = ( +export const buildFormValues = async ( userRegistry: UserRegistry | null, - currentValues: any, - initialFormData: any -) => ({ - ...currentValues, - name: - userRegistry?.name ?? (currentValues.certifiedName ? initialFormData.name : currentValues.name), - surname: - userRegistry?.surname ?? - (currentValues.certifiedSurname ? initialFormData.surname : currentValues.surname), - email: - userRegistry?.email ?? - (currentValues.certifiedName || currentValues.certifiedSurname - ? initialFormData.email - : currentValues.email), - confirmEmail: '', - certifiedName: - userRegistry?.certifiedName ?? - (currentValues.certifiedName ? initialFormData.certifiedName : currentValues.certifiedName), - certifiedSurname: - userRegistry?.certifiedSurname ?? - (currentValues.certifiedSurname - ? initialFormData.certifiedSurname - : currentValues.certifiedSurname), -}); + currentValues: PartyUserOnCreation, + initialFormData: PartyUserOnCreation, + formik: FormikProps +) => { + await formik.setValues({ + ...currentValues, + name: + userRegistry?.name ?? + (currentValues.certifiedName ? initialFormData.name : currentValues.name), + surname: + userRegistry?.surname ?? + (currentValues.certifiedSurname ? initialFormData.surname : currentValues.surname), + email: + userRegistry?.email ?? + (currentValues.certifiedName || currentValues.certifiedSurname + ? initialFormData.email + : currentValues.email), + confirmEmail: '', + certifiedName: + userRegistry?.certifiedName ?? + (currentValues.certifiedName ? initialFormData.certifiedName : currentValues.certifiedName), + certifiedSurname: + userRegistry?.certifiedSurname ?? + (currentValues.certifiedSurname + ? initialFormData.certifiedSurname + : currentValues.certifiedSurname), + }); +}; /* // Role management utilities