diff --git a/packages/pn-personafisica-webapp/public/locales/it/recapiti.json b/packages/pn-personafisica-webapp/public/locales/it/recapiti.json index 7cfc2cafa..cba62e804 100644 --- a/packages/pn-personafisica-webapp/public/locales/it/recapiti.json +++ b/packages/pn-personafisica-webapp/public/locales/it/recapiti.json @@ -16,7 +16,8 @@ "pec-validation-banner": { "title": "La PEC è in validazione", "dod-enabled-message": "Fino al termine del processo, la Piattaforma SEND rimane attiva come domicilio digitale.", - "dod-disabled-message": "Fino al termine del processo non sarà possibile modificare i recapiti a valore legale." + "dod-disabled-message": "Fino al termine del processo non sarà possibile modificare i recapiti a valore legale.", + "parties-list": "La piattaforma SEND resterà il tuo domicilio digitale per {{list}} fino al completamento della validazione." }, "pec-description": "Quando un ente ti invia una notifica SEND, ricevi l’avviso a valore legale sulla PEC che hai scelto.", "link-pec-placeholder": "La tua PEC", diff --git a/packages/pn-personafisica-webapp/src/components/Contacts/EmailContactItem.tsx b/packages/pn-personafisica-webapp/src/components/Contacts/EmailContactItem.tsx index c0e59cd4b..69d8f63ed 100644 --- a/packages/pn-personafisica-webapp/src/components/Contacts/EmailContactItem.tsx +++ b/packages/pn-personafisica-webapp/src/components/Contacts/EmailContactItem.tsx @@ -223,6 +223,7 @@ const EmailContactItem: React.FC = () => { actions={getActions()} expanded={isEmailActive} data-testid="emailContact" + slotProps={{ Card: { id: 'emailContactSection' } }} > {!isEmailActive && ( diff --git a/packages/pn-personafisica-webapp/src/components/Contacts/IOContact.tsx b/packages/pn-personafisica-webapp/src/components/Contacts/IOContact.tsx index 5c8423f8a..9afa289dd 100644 --- a/packages/pn-personafisica-webapp/src/components/Contacts/IOContact.tsx +++ b/packages/pn-personafisica-webapp/src/components/Contacts/IOContact.tsx @@ -153,6 +153,7 @@ const IOContact: React.FC = () => { color="primary" fullWidth={isMobile} sx={{ mt: 3 }} + id="ioContactButton" > {t('io-contact.enable', { ns: 'recapiti' })} @@ -208,6 +209,7 @@ const IOContact: React.FC = () => { : undefined } expanded={isAppIOEnabled} + slotProps={{ Card: { id: 'ioContactSection' } }} > diff --git a/packages/pn-personafisica-webapp/src/components/Contacts/LegalContacts.tsx b/packages/pn-personafisica-webapp/src/components/Contacts/LegalContacts.tsx index a58a1f96e..5d51ef1ac 100644 --- a/packages/pn-personafisica-webapp/src/components/Contacts/LegalContacts.tsx +++ b/packages/pn-personafisica-webapp/src/components/Contacts/LegalContacts.tsx @@ -134,6 +134,9 @@ const LegalContacts = () => { ) .unwrap() .then(() => { + if (channelType === ChannelType.SERCQ_SEND) { + sessionStorage.removeItem('domicileBannerClosed'); + } PFEventStrategyFactory.triggerEvent( PFEventsType[`SEND_REMOVE_${channelType}_SUCCESS`], 'default' diff --git a/packages/pn-personafisica-webapp/src/components/Contacts/SercqSendContactWizard.tsx b/packages/pn-personafisica-webapp/src/components/Contacts/SercqSendContactWizard.tsx index 4be541d1c..6569144fa 100644 --- a/packages/pn-personafisica-webapp/src/components/Contacts/SercqSendContactWizard.tsx +++ b/packages/pn-personafisica-webapp/src/components/Contacts/SercqSendContactWizard.tsx @@ -142,6 +142,7 @@ const SercqSendContactWizard: React.FC = ({ goToNextStep, setShowPecWizar dispatch(createOrUpdateAddress(digitalAddressParams)) .unwrap() .then(() => { + sessionStorage.removeItem('domicileBannerClosed'); PFEventStrategyFactory.triggerEvent(PFEventsType.SEND_ADD_SERCQ_SEND_UX_SUCCESS, 'default'); // show success message dispatch( @@ -150,7 +151,6 @@ const SercqSendContactWizard: React.FC = ({ goToNextStep, setShowPecWizar message: t(`legal-contacts.sercq_send-added-successfully`, { ns: 'recapiti' }), }) ); - goToNextStep && goToNextStep(); }) .catch(() => {}); diff --git a/packages/pn-personafisica-webapp/src/components/DomicileBanner/DomicileBanner.tsx b/packages/pn-personafisica-webapp/src/components/DomicileBanner/DomicileBanner.tsx index 3dc4ef0dc..12424bb25 100644 --- a/packages/pn-personafisica-webapp/src/components/DomicileBanner/DomicileBanner.tsx +++ b/packages/pn-personafisica-webapp/src/components/DomicileBanner/DomicileBanner.tsx @@ -6,14 +6,13 @@ import { ButtonNaked } from '@pagopa/mui-italia'; import { PFEventsType } from '../../models/PFEventsType'; import { - AddressType, ChannelType, ContactOperation, ContactSource, IOAllowedValues, } from '../../models/contacts'; import * as routes from '../../navigation/routes.const'; -import { setExternalEvent } from '../../redux/contact/reducers'; +import { contactsSelectors, setExternalEvent } from '../../redux/contact/reducers'; import { useAppDispatch, useAppSelector } from '../../redux/hooks'; import { closeDomicileBanner } from '../../redux/sidemenu/reducers'; import { RootState } from '../../redux/store'; @@ -108,43 +107,47 @@ const DomicileBanner: React.FC = ({ source }) => { const dispatch = useAppDispatch(); const open = useAppSelector((state: RootState) => state.generalInfoState.domicileBannerOpened); const { IS_DOD_ENABLED } = getConfiguration(); + const { + defaultPECAddress, + defaultSERCQ_SENDAddress, + defaultAPPIOAddress, + defaultEMAILAddress, + defaultSMSAddress, + } = useAppSelector(contactsSelectors.selectAddresses); - const digitalAddresses = useAppSelector( - (state: RootState) => state.contactsState.digitalAddresses - ); - - const hasSercqSend = digitalAddresses.find((addr) => addr.channelType === ChannelType.SERCQ_SEND); - const hasAppIODisabled = digitalAddresses.find( - (addr) => addr.channelType === ChannelType.IOMSG && addr.value === IOAllowedValues.DISABLED - ); + const hasAppIODisabled = defaultAPPIOAddress?.value === IOAllowedValues.DISABLED; - const hasCourtesyAddresses = - digitalAddresses.filter( - (addr) => addr.addressType === AddressType.COURTESY && addr.value !== IOAllowedValues.DISABLED - ).length > 0; - const domicileBannerData: DomicileBannerData | null = getDomicileData( - source, - !!hasSercqSend, - hasCourtesyAddresses, - !!hasAppIODisabled, - IS_DOD_ENABLED - ); + const hasCourtesyAddresses = !!(defaultEMAILAddress || defaultSMSAddress); + const domicileBannerData: DomicileBannerData | null = defaultPECAddress + ? null + : getDomicileData( + source, + !!defaultSERCQ_SENDAddress, + hasCourtesyAddresses, + hasAppIODisabled, + IS_DOD_ENABLED + ); const handleClose = () => { dispatch(closeDomicileBanner()); - // sessionStorage.setItem('domicileBannerClosed', 'true'); + sessionStorage.setItem('domicileBannerClosed', 'true'); }; const handleClick = (destination?: ChannelType, operation?: ContactOperation) => { if (destination && operation) { - dispatch(setExternalEvent({ destination, source, operation })); + if (destination === ChannelType.SERCQ_SEND && operation === ContactOperation.ADD) { + navigate(routes.DIGITAL_DOMICILE_ACTIVATION); + return; + } else { + dispatch(setExternalEvent({ destination, source, operation })); + } } PFEventStrategyFactory.triggerEvent(PFEventsType.SEND_VIEW_CONTACT_DETAILS, { source }); navigate(routes.RECAPITI); }; return open && domicileBannerData ? ( - + { const button = getByText('domicile-banner.no-sercq-cta'); fireEvent.click(button); expect(mockNavigateFn).toHaveBeenCalledTimes(1); - expect(mockNavigateFn).toHaveBeenCalledWith(routes.RECAPITI); - expect(testStore.getState().contactsState.event).toStrictEqual({ - destination: ChannelType.SERCQ_SEND, - source: ContactSource.HOME_NOTIFICHE, - operation: ContactOperation.ADD, - }); + expect(mockNavigateFn).toHaveBeenCalledWith(routes.DIGITAL_DOMICILE_ACTIVATION); }); it('renders the component - no SERCQ SEND enabled - banner closed', () => { diff --git a/packages/pn-personafisica-webapp/src/pages/Contacts.page.tsx b/packages/pn-personafisica-webapp/src/pages/Contacts.page.tsx index 36a1eb330..04fe62aa4 100644 --- a/packages/pn-personafisica-webapp/src/pages/Contacts.page.tsx +++ b/packages/pn-personafisica-webapp/src/pages/Contacts.page.tsx @@ -1,4 +1,4 @@ -import { useCallback, useMemo } from 'react'; +import { useCallback, useEffect, useMemo } from 'react'; import { Trans, useTranslation } from 'react-i18next'; import { Alert, Box, Link, Stack, Typography } from '@mui/material'; @@ -9,27 +9,73 @@ import LegalContacts from '../components/Contacts/LegalContacts'; import DomicileBanner from '../components/DomicileBanner/DomicileBanner'; import LoadingPageWrapper from '../components/LoadingPageWrapper/LoadingPageWrapper'; import { PFEventsType } from '../models/PFEventsType'; -import { ContactSource } from '../models/contacts'; +import { ChannelType, ContactOperation, ContactSource } from '../models/contacts'; import { FAQ_WHAT_IS_AAR, FAQ_WHAT_IS_COURTESY_MESSAGE } from '../navigation/externalRoutes.const'; import { CONTACT_ACTIONS, getDigitalAddresses } from '../redux/contact/actions'; -import { contactsSelectors } from '../redux/contact/reducers'; +import { contactsSelectors, resetExternalEvent } from '../redux/contact/reducers'; import { useAppDispatch, useAppSelector } from '../redux/hooks'; +import { RootState } from '../redux/store'; import { getConfiguration } from '../services/configuration.service'; import PFEventStrategyFactory from '../utility/MixpanelUtils/PFEventStrategyFactory'; -const Contacts = () => { +const ValidatingPecBanner: React.FC = () => { const { t } = useTranslation(['recapiti']); - const dispatch = useAppDispatch(); const { defaultPECAddress, - defaultAPPIOAddress, defaultSERCQ_SENDAddress, specialPECAddresses, specialSERCQ_SENDAddresses, - addresses, } = useAppSelector(contactsSelectors.selectAddresses); + + const isValidatingDefaultPec = defaultPECAddress?.pecValid === false; + + const isDefaultSercqSendActive = !!defaultSERCQ_SENDAddress; + + const validatingSpecialPecList: Array = specialPECAddresses + .filter( + (pecAddr) => + pecAddr.pecValid === false && + (isDefaultSercqSendActive || + specialSERCQ_SENDAddresses.some((sercqAddr) => sercqAddr.senderId === pecAddr.senderId)) + ) + .map((addr) => addr.senderName ?? addr.senderId); + + // eslint-disable-next-line functional/no-let + let bannerMessage = ''; + if (!isValidatingDefaultPec && validatingSpecialPecList.length === 0) { + return; + } + if (isValidatingDefaultPec) { + if (isDefaultSercqSendActive) { + bannerMessage = 'dod-enabled-message'; + } else { + bannerMessage = 'dod-disabled-message'; + } + } else { + bannerMessage = 'parties-list'; + } + return ( + + + {t('legal-contacts.pec-validation-banner.title')} + + + {t(`legal-contacts.pec-validation-banner.${bannerMessage}`, { + list: validatingSpecialPecList.join(', '), + })} + + + ); +}; + +const Contacts = () => { + const { t } = useTranslation(['recapiti']); + const dispatch = useAppDispatch(); + const { defaultAPPIOAddress, addresses } = useAppSelector(contactsSelectors.selectAddresses); const { LANDING_SITE_URL } = getConfiguration(); + const externalEvent = useAppSelector((state: RootState) => state.contactsState.event); + const fetchAddresses = useCallback(() => { void dispatch(getDigitalAddresses()) .unwrap() @@ -41,19 +87,6 @@ const Contacts = () => { }); }, []); - const hasDodEnabledAndValidatingPec = - (!defaultPECAddress?.pecValid && defaultSERCQ_SENDAddress) || - specialSERCQ_SENDAddresses.some((sercqAddr) => - specialPECAddresses.some( - (pecAddr) => !pecAddr.pecValid && pecAddr.senderId === sercqAddr.senderId - ) - ); - - const hasValidatingPecSpecialContact = specialPECAddresses.some((address) => !address.pecValid); - - const verifyingPecAddress = - (defaultPECAddress && !defaultPECAddress.pecValid) || hasValidatingPecSpecialContact; - const faqWhatIsAarCompleteLink = useMemo( () => LANDING_SITE_URL && FAQ_WHAT_IS_AAR ? `${LANDING_SITE_URL}${FAQ_WHAT_IS_AAR}` : undefined, @@ -91,9 +124,20 @@ const Contacts = () => { /> ); - const bannerMessage = hasDodEnabledAndValidatingPec - ? 'legal-contacts.pec-validation-banner.dod-enabled-message' - : 'legal-contacts.pec-validation-banner.dod-disabled-message'; + const goToSection = (section: ChannelType) => { + const sectionId = section === ChannelType.EMAIL ? 'emailContactSection' : 'ioContactSection'; + const titleId = section === ChannelType.EMAIL ? 'default_email' : 'ioContactButton'; + + document.getElementById(sectionId)?.scrollIntoView({ behavior: 'smooth' }); + document.getElementById(titleId)?.focus({ preventScroll: true }); + }; + + useEffect(() => { + if (externalEvent && externalEvent.operation === ContactOperation.SCROLL) { + goToSection(externalEvent.destination); + dispatch(resetExternalEvent()); + } + }, [externalEvent]); return ( @@ -109,14 +153,7 @@ const Contacts = () => { reloadAction={fetchAddresses} > - {verifyingPecAddress && ( - - - {t('legal-contacts.pec-validation-banner.title', { ns: 'recapiti' })} - - {t(bannerMessage, { ns: 'recapiti' })} - - )} + diff --git a/packages/pn-personafisica-webapp/src/pages/NotificationDetail.page.tsx b/packages/pn-personafisica-webapp/src/pages/NotificationDetail.page.tsx index cf21b5f3d..11159050d 100644 --- a/packages/pn-personafisica-webapp/src/pages/NotificationDetail.page.tsx +++ b/packages/pn-personafisica-webapp/src/pages/NotificationDetail.page.tsx @@ -340,9 +340,9 @@ const NotificationDetail: React.FC = () => { const visibleDomicileBanner = () => !mandateId && - notification.notificationStatusHistory.findIndex( + notification.notificationStatusHistory.some( (history) => history.status === NotificationStatus.VIEWED - ) > -1; + ); useEffect(() => { if (checkIfUserHasPayments && !(isCancelled.cancelled || isCancelled.cancellationInProgress)) { diff --git a/packages/pn-personafisica-webapp/src/pages/__test__/Contacts.page.test.tsx b/packages/pn-personafisica-webapp/src/pages/__test__/Contacts.page.test.tsx index bd1fb219b..ddbec8a98 100644 --- a/packages/pn-personafisica-webapp/src/pages/__test__/Contacts.page.test.tsx +++ b/packages/pn-personafisica-webapp/src/pages/__test__/Contacts.page.test.tsx @@ -141,10 +141,10 @@ describe('Contacts page', async () => { const banner = result.getByTestId('PecVerificationAlert'); expect(banner).toBeInTheDocument(); - const alertIcon = within(banner).getByTestId('InfoOutlinedIcon'); + const alertIcon = within(banner).getByTestId('ReportProblemOutlinedIcon'); expect(alertIcon).toBeInTheDocument(); expect(banner).toHaveTextContent('legal-contacts.pec-validation-banner.title'); - expect(banner).toHaveTextContent('legal-contacts.pec-validation-banner.dod-enabled-message'); + expect(banner).toHaveTextContent('legal-contacts.pec-validation-banner.parties-list'); const specialContacts = result.getByTestId('specialContacts'); expect(specialContacts).toBeInTheDocument(); diff --git a/packages/pn-personagiuridica-webapp/public/locales/it/recapiti.json b/packages/pn-personagiuridica-webapp/public/locales/it/recapiti.json index 2403feaf2..ab1553ac1 100644 --- a/packages/pn-personagiuridica-webapp/public/locales/it/recapiti.json +++ b/packages/pn-personagiuridica-webapp/public/locales/it/recapiti.json @@ -16,7 +16,8 @@ "pec-validation-banner": { "title": "La PEC è in validazione", "dod-enabled-message": "Fino al termine del processo, la Piattaforma SEND rimane attiva come domicilio digitale.", - "dod-disabled-message": "Fino al termine del processo non sarà possibile modificare i recapiti a valore legale." + "dod-disabled-message": "Fino al termine del processo non sarà possibile modificare i recapiti a valore legale.", + "parties-list": "La piattaforma SEND resterà il tuo domicilio digitale per {{list}} fino al completamento della validazione." }, "pec-description": "Quando un ente invia alla tua impresa una notifica SEND, viene recapitata in modo sicuro e con valore legale sulla PEC che hai scelto.", "link-pec-placeholder": "Indirizzo PEC", diff --git a/packages/pn-personagiuridica-webapp/src/components/Contacts/EmailContactItem.tsx b/packages/pn-personagiuridica-webapp/src/components/Contacts/EmailContactItem.tsx index b088ca2dc..fd372d88d 100644 --- a/packages/pn-personagiuridica-webapp/src/components/Contacts/EmailContactItem.tsx +++ b/packages/pn-personagiuridica-webapp/src/components/Contacts/EmailContactItem.tsx @@ -201,6 +201,7 @@ const EmailContactItem: React.FC = () => { actions={getActions()} expanded={isEmailActive} data-testid="emailContact" + slotProps={{ Card: { id: 'emailContactSection' } }} > {!isEmailActive && ( diff --git a/packages/pn-personagiuridica-webapp/src/components/Contacts/LegalContacts.tsx b/packages/pn-personagiuridica-webapp/src/components/Contacts/LegalContacts.tsx index 4c1723a05..ea9b5df28 100644 --- a/packages/pn-personagiuridica-webapp/src/components/Contacts/LegalContacts.tsx +++ b/packages/pn-personagiuridica-webapp/src/components/Contacts/LegalContacts.tsx @@ -132,6 +132,9 @@ const LegalContacts = () => { ) .unwrap() .then(() => { + if (channelType === ChannelType.SERCQ_SEND) { + sessionStorage.removeItem('domicileBannerClosed'); + } dispatch( appStateActions.addSuccess({ title: '', diff --git a/packages/pn-personagiuridica-webapp/src/components/Contacts/SercqSendContactWizard.tsx b/packages/pn-personagiuridica-webapp/src/components/Contacts/SercqSendContactWizard.tsx index 9506e63b1..6eed5a649 100644 --- a/packages/pn-personagiuridica-webapp/src/components/Contacts/SercqSendContactWizard.tsx +++ b/packages/pn-personagiuridica-webapp/src/components/Contacts/SercqSendContactWizard.tsx @@ -124,6 +124,7 @@ const SercqSendContactWizard: React.FC = ({ goToNextStep, setShowPecWizar dispatch(createOrUpdateAddress(digitalAddressParams)) .unwrap() .then(() => { + sessionStorage.removeItem('domicileBannerClosed'); // show success message dispatch( appStateActions.addSuccess({ diff --git a/packages/pn-personagiuridica-webapp/src/components/DomicileBanner/DomicileBanner.tsx b/packages/pn-personagiuridica-webapp/src/components/DomicileBanner/DomicileBanner.tsx index 3e3403234..d70637d17 100644 --- a/packages/pn-personagiuridica-webapp/src/components/DomicileBanner/DomicileBanner.tsx +++ b/packages/pn-personagiuridica-webapp/src/components/DomicileBanner/DomicileBanner.tsx @@ -4,9 +4,9 @@ import { useNavigate } from 'react-router-dom'; import { Alert, AlertColor, Box, Typography } from '@mui/material'; import { ButtonNaked } from '@pagopa/mui-italia'; -import { AddressType, ChannelType, ContactOperation, ContactSource } from '../../models/contacts'; +import { ChannelType, ContactOperation, ContactSource } from '../../models/contacts'; import * as routes from '../../navigation/routes.const'; -import { setExternalEvent } from '../../redux/contact/reducers'; +import { contactsSelectors, setExternalEvent } from '../../redux/contact/reducers'; import { useAppDispatch, useAppSelector } from '../../redux/hooks'; import { closeDomicileBanner } from '../../redux/sidemenu/reducers'; import { RootState } from '../../redux/store'; @@ -85,35 +85,34 @@ const DomicileBanner: React.FC = ({ source }) => { const dispatch = useAppDispatch(); const open = useAppSelector((state: RootState) => state.generalInfoState.domicileBannerOpened); const { IS_DOD_ENABLED } = getConfiguration(); + const { defaultPECAddress, defaultSERCQ_SENDAddress, defaultEMAILAddress, defaultSMSAddress } = + useAppSelector(contactsSelectors.selectAddresses); - const digitalAddresses = useAppSelector( - (state: RootState) => state.contactsState.digitalAddresses - ); + const hasCourtesyAddresses = !!(defaultEMAILAddress || defaultSMSAddress); - const hasSercqSend = digitalAddresses.find((addr) => addr.channelType === ChannelType.SERCQ_SEND); - const hasCourtesyAddresses = - digitalAddresses.filter((addr) => addr.addressType === AddressType.COURTESY).length > 0; - const domicileBannerData: DomicileBannerData | null = getDomicileData( - source, - !!hasSercqSend, - hasCourtesyAddresses, - IS_DOD_ENABLED - ); + const domicileBannerData: DomicileBannerData | null = defaultPECAddress + ? null + : getDomicileData(source, !!defaultSERCQ_SENDAddress, hasCourtesyAddresses, IS_DOD_ENABLED); const handleClose = () => { dispatch(closeDomicileBanner()); - // sessionStorage.setItem('domicileBannerClosed', 'true'); + sessionStorage.setItem('domicileBannerClosed', 'true'); }; const handleClick = (destination?: ChannelType, operation?: ContactOperation) => { if (destination && operation) { - dispatch(setExternalEvent({ destination, source, operation })); + if (destination === ChannelType.SERCQ_SEND && operation === ContactOperation.ADD) { + navigate(routes.DIGITAL_DOMICILE_ACTIVATION); + return; + } else { + dispatch(setExternalEvent({ destination, source, operation })); + } } navigate(routes.RECAPITI); }; return open && domicileBannerData ? ( - + { const button = getByText('domicile-banner.no-sercq-cta'); fireEvent.click(button); expect(mockNavigateFn).toHaveBeenCalledTimes(1); - expect(mockNavigateFn).toHaveBeenCalledWith(routes.RECAPITI); - expect(testStore.getState().contactsState.event).toStrictEqual({ - destination: ChannelType.SERCQ_SEND, - source: ContactSource.HOME_NOTIFICHE, - operation: ContactOperation.ADD, - }); + expect(mockNavigateFn).toHaveBeenCalledWith(routes.DIGITAL_DOMICILE_ACTIVATION); }); it('renders the component - no SERCQ SEND enabled - banner closed', () => { diff --git a/packages/pn-personagiuridica-webapp/src/pages/Contacts.page.tsx b/packages/pn-personagiuridica-webapp/src/pages/Contacts.page.tsx index e0dd8e136..9577ab8e9 100644 --- a/packages/pn-personagiuridica-webapp/src/pages/Contacts.page.tsx +++ b/packages/pn-personagiuridica-webapp/src/pages/Contacts.page.tsx @@ -1,4 +1,4 @@ -import { useCallback } from 'react'; +import { useCallback, useEffect } from 'react'; import { Trans, useTranslation } from 'react-i18next'; import { Alert, Box, Link, Stack, Typography } from '@mui/material'; @@ -8,22 +8,69 @@ import CourtesyContacts from '../components/Contacts/CourtesyContacts'; import LegalContacts from '../components/Contacts/LegalContacts'; import DomicileBanner from '../components/DomicileBanner/DomicileBanner'; import LoadingPageWrapper from '../components/LoadingPageWrapper/LoadingPageWrapper'; -import { ContactSource } from '../models/contacts'; +import { ChannelType, ContactOperation, ContactSource } from '../models/contacts'; import { PROFILE } from '../navigation/routes.const'; import { CONTACT_ACTIONS, getDigitalAddresses } from '../redux/contact/actions'; -import { contactsSelectors } from '../redux/contact/reducers'; +import { contactsSelectors, resetExternalEvent } from '../redux/contact/reducers'; import { useAppDispatch, useAppSelector } from '../redux/hooks'; import { RootState } from '../redux/store'; -const Contacts = () => { - const { t, i18n } = useTranslation(['recapiti']); - const dispatch = useAppDispatch(); +const ValidatingPecBanner: React.FC = () => { + const { t } = useTranslation(['recapiti']); const { defaultPECAddress, defaultSERCQ_SENDAddress, specialPECAddresses, specialSERCQ_SENDAddresses, } = useAppSelector(contactsSelectors.selectAddresses); + + const isValidatingDefaultPec = defaultPECAddress?.pecValid === false; + + const isDefaultSercqSendActive = !!defaultSERCQ_SENDAddress; + + const validatingSpecialPecList: Array = specialPECAddresses + .filter( + (pecAddr) => + pecAddr.pecValid === false && + (isDefaultSercqSendActive || + specialSERCQ_SENDAddresses.some((sercqAddr) => sercqAddr.senderId === pecAddr.senderId)) + ) + .map((addr) => addr.senderName ?? addr.senderId); + + // eslint-disable-next-line functional/no-let + let bannerMessage = ''; + if (!isValidatingDefaultPec && validatingSpecialPecList.length === 0) { + return; + } + if (isValidatingDefaultPec) { + if (isDefaultSercqSendActive) { + bannerMessage = 'dod-enabled-message'; + } else { + bannerMessage = 'dod-disabled-message'; + } + } else { + bannerMessage = 'parties-list'; + } + return ( + + + {t('legal-contacts.pec-validation-banner.title')} + + + {t(`legal-contacts.pec-validation-banner.${bannerMessage}`, { + list: validatingSpecialPecList.join(', '), + })} + + + ); +}; + +const Contacts = () => { + const { t, i18n } = useTranslation(['recapiti']); + const dispatch = useAppDispatch(); + + const externalEvent = useAppSelector((state: RootState) => state.contactsState.event); + const organization = useAppSelector((state: RootState) => state.userState.user.organization); const profileUrl = PROFILE(organization?.id, i18n.language); @@ -55,22 +102,20 @@ const Contacts = () => { > ); - const hasDodEnabledAndValidatingPec = - (!defaultPECAddress?.pecValid && defaultSERCQ_SENDAddress) || - specialSERCQ_SENDAddresses.some((sercqAddr) => - specialPECAddresses.some( - (pecAddr) => !pecAddr.pecValid && pecAddr.senderId === sercqAddr.senderId - ) - ); - - const hasValidatingPecSpecialContact = specialPECAddresses.some((address) => !address.pecValid); + const goToSection = (section: ChannelType) => { + const sectionId = section === ChannelType.EMAIL ? 'emailContactSection' : 'ioContactSection'; + const titleId = section === ChannelType.EMAIL ? 'default_email' : 'ioContactButton'; - const verifyingPecAddress = - (defaultPECAddress && !defaultPECAddress.pecValid) || hasValidatingPecSpecialContact; + document.getElementById(sectionId)?.scrollIntoView({ behavior: 'smooth' }); + document.getElementById(titleId)?.focus({ preventScroll: true }); + }; - const bannerMessage = hasDodEnabledAndValidatingPec - ? 'legal-contacts.pec-validation-banner.dod-enabled-message' - : 'legal-contacts.pec-validation-banner.dod-disabled-message'; + useEffect(() => { + if (externalEvent && externalEvent.operation === ContactOperation.SCROLL) { + goToSection(externalEvent.destination); + dispatch(resetExternalEvent()); + } + }, [externalEvent]); return ( @@ -86,14 +131,7 @@ const Contacts = () => { reloadAction={fetchAddresses} > - {verifyingPecAddress && ( - - - {t('legal-contacts.pec-validation-banner.title', { ns: 'recapiti' })} - - {t(bannerMessage, { ns: 'recapiti' })} - - )} + diff --git a/packages/pn-personagiuridica-webapp/src/pages/NotificationDetail.page.tsx b/packages/pn-personagiuridica-webapp/src/pages/NotificationDetail.page.tsx index d1cf62ea9..ed8d25b40 100644 --- a/packages/pn-personagiuridica-webapp/src/pages/NotificationDetail.page.tsx +++ b/packages/pn-personagiuridica-webapp/src/pages/NotificationDetail.page.tsx @@ -387,9 +387,9 @@ const NotificationDetail = () => { userHasAdminPermissions && !currentUser.hasGroup && !mandateId && - notification.notificationStatusHistory.findIndex( + notification.notificationStatusHistory.some( (history) => history.status === NotificationStatus.VIEWED - ) > -1; + ); return ( diff --git a/packages/pn-personagiuridica-webapp/src/pages/__test__/Contacts.page.test.tsx b/packages/pn-personagiuridica-webapp/src/pages/__test__/Contacts.page.test.tsx index 0878006da..6cbbd788d 100644 --- a/packages/pn-personagiuridica-webapp/src/pages/__test__/Contacts.page.test.tsx +++ b/packages/pn-personagiuridica-webapp/src/pages/__test__/Contacts.page.test.tsx @@ -123,10 +123,10 @@ describe('Contacts page', async () => { const banner = result.getByTestId('PecVerificationAlert'); expect(banner).toBeInTheDocument(); - const alertIcon = within(banner).getByTestId('InfoOutlinedIcon'); + const alertIcon = within(banner).getByTestId('ReportProblemOutlinedIcon'); expect(alertIcon).toBeInTheDocument(); expect(banner).toHaveTextContent('legal-contacts.pec-validation-banner.title'); - expect(banner).toHaveTextContent('legal-contacts.pec-validation-banner.dod-enabled-message'); + expect(banner).toHaveTextContent('legal-contacts.pec-validation-banner.parties-list'); const specialContacts = result.getByTestId('specialContacts'); expect(specialContacts).toBeInTheDocument();