Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/model/PartyUser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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));
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -422,7 +402,6 @@ export default function AddUserForm({
dynamicDocLink={dynamicDocLink}
formik={formik}
validTaxcode={validTaxcode}
addRole={addRole}
setIsAddInBulkEAFlow={setIsAddInBulkEAFlow}
setIsAsyncFlow={setIsAsyncFlow}
userProduct={userProduct}
Expand Down Expand Up @@ -462,6 +441,7 @@ export default function AddUserForm({
/>
}
aria-label={t(titleKey)}
onClick={() => formik.setFieldValue('toAddOnAggregates', value, true)}
/>
))}
</RadioGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -14,9 +16,8 @@ interface ProductRolesSectionProps {
party: Party;
productRoles: ProductRolesLists;
dynamicDocLink: string;
formik: any;
formik: FormikProps<PartyUserOnCreation>;
validTaxcode: string | undefined;
addRole: (role: ProductRole) => void;
setIsAddInBulkEAFlow: (value: SetStateAction<boolean>) => void;
setIsAsyncFlow: (value: SetStateAction<boolean>) => void;
userProduct: Product | undefined;
Expand All @@ -29,93 +30,114 @@ export const ProductRolesSection = ({
dynamicDocLink,
formik,
validTaxcode,
addRole,
setIsAddInBulkEAFlow,
setIsAsyncFlow,
userProduct,
party,
renderLabel,

t,
}: ProductRolesSectionProps) => (
<Grid item container xs={12} mb={3} sx={{ ...commonStyles, flexDirection: 'column' }}>
<TitleBox
variantTitle="h6"
variantSubTitle="body2"
title={t('userEdit.addForm.role.title')}
subTitle={t('userEdit.addForm.role.subTitle')}
mbTitle={2}
mbSubTitle={1}
/>
{dynamicDocLink.length > 0 && (
<Grid item xs={12} justifyContent={'left'}>
<ButtonNaked
component="button"
color="primary"
sx={{
fontWeight: 'fontWeightBold',
fontSize: '14px',
textDecoration: 'underline',
}}
onClick={() => {
window.open(dynamicDocLink);
}}
>
{t('userEdit.addForm.role.documentationLink')}
</ButtonNaked>
</Grid>
)}
{Object.values(productRoles.groupBySelcRole).map((roles) =>
roles
.filter((r) => isAddRoleFromDashboard(r.phasesAdditionAllowed))
.map((p, index: number, filteredRoles) => (
<React.Fragment key={p.productRole}>
<Box
aria-label={`${p.title}`}
sx={{
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
width: '100%',
my: 2,
}}
>
<CustomFormControlLabel
sx={{ marginTop: 0 }}
checked={formik.values.productRoles.indexOf(p.productRole) > -1}
disabled={!validTaxcode}
value={p.productRole}
control={roles.length > 1 && p.multiroleAllowed ? <Checkbox /> : <Radio />}
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 (
<Grid item container xs={12} mb={3} sx={{ ...commonStyles, flexDirection: 'column' }}>
<TitleBox
variantTitle="h6"
variantSubTitle="body2"
title={t('userEdit.addForm.role.title')}
subTitle={t('userEdit.addForm.role.subTitle')}
mbTitle={2}
mbSubTitle={1}
/>
{dynamicDocLink.length > 0 && (
<Grid item xs={12} justifyContent={'left'}>
<ButtonNaked
component="button"
color="primary"
sx={{
fontWeight: 'fontWeightBold',
fontSize: '14px',
textDecoration: 'underline',
}}
onClick={() => {
window.open(dynamicDocLink);
}}
>
{t('userEdit.addForm.role.documentationLink')}
</ButtonNaked>
</Grid>
)}
{Object.values(productRoles.groupBySelcRole).map((roles) =>
roles
.filter((r) => isAddRoleFromDashboard(r.phasesAdditionAllowed))
.map((p, index: number, filteredRoles) => (
<React.Fragment key={p.productRole}>
<Box
aria-label={`${p.title}`}
onClick={
validTaxcode
? () => {
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) && (
<Tooltip title={t('userEdit.addForm.role.adminTooltip')} placement="top" arrow>
<InfoOutlinedIcon sx={{ cursor: 'pointer' }} color="primary" />
</Tooltip>
sx={{
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
width: '100%',
my: 2,
}}
>
<CustomFormControlLabel
sx={{ marginTop: 0 }}
checked={formik.values.productRoles.indexOf(p.productRole) > -1}
disabled={!validTaxcode}
value={p.productRole}
control={roles.length > 1 && p.multiroleAllowed ? <Checkbox /> : <Radio />}
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) && (
<Tooltip title={t('userEdit.addForm.role.adminTooltip')} placement="top" arrow>
<InfoOutlinedIcon sx={{ cursor: 'pointer' }} color="primary" />
</Tooltip>
)}
</Box>
{filteredRoles.length !== index + 1 && (
<Grid item xs={12}>
<Divider sx={{ borderColor: 'background.default' }} />
</Grid>
)}
</Box>
{filteredRoles.length !== index + 1 && (
<Grid item xs={12}>
<Divider sx={{ borderColor: 'background.default' }} />
</Grid>
)}
</React.Fragment>
))
)}
</Grid>
);
</React.Fragment>
))
)}
</Grid>
);
};
Original file line number Diff line number Diff line change
@@ -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<PartyUserOnCreation>;
baseTextFieldProps: (
field: keyof PartyUserOnCreation,
label: string,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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)
);

Expand All @@ -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<PartyUserOnCreation>
) => {
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
Expand Down
Loading