Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor/PN-13453 - Domicile Banner and Validating PEC #1475

Merged
merged 47 commits into from
Feb 24, 2025
Merged
Show file tree
Hide file tree
Changes from 44 commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
d42cce8
refactor: change DefaultDigitalContact component according to new des…
mflauti Dec 6, 2024
03a958d
refactor: change props name for DefaultDigitalContact
mflauti Dec 10, 2024
b2e90ce
refactor: set DefaultDigitalContact confirm button always to enabled
mflauti Dec 11, 2024
e2effc5
chore: small style changes on DefaultDigitalContact component
mflauti Dec 11, 2024
33bde3b
refactor: change DigitalContactsCard component layout making it more …
mflauti Dec 13, 2024
167ef30
Merge branch 'feature/rework_contacts' of github.com:pagopa/pn-fronte…
mflauti Dec 13, 2024
7ec032a
refactor: PnInfoCard now uses CardHeader to show title, subtitle and …
mflauti Dec 16, 2024
542532c
Merge branch 'feature/rework_contacts' of github.com:pagopa/pn-fronte…
mflauti Dec 16, 2024
88adf94
refactor: change LegalContacts component to follow new design specs (…
mflauti Dec 18, 2024
13bdb2e
Merge branch 'feature/rework_contacts' of github.com:pagopa/pn-fronte…
mflauti Dec 18, 2024
e2f7e20
test: fix tests not working after rework on LegalContacts component (…
mflauti Dec 18, 2024
9f3180b
test: fix test not working (draft)
mflauti Dec 19, 2024
047543c
Merge branch 'feature/rework_contacts' into refactor/PN-13436
mflauti Jan 7, 2025
097a8c5
refactor: pass senderId to DefaultDigitalContact to differentiate its…
mflauti Jan 8, 2025
6c68adb
Merge branch 'feature/rework_contacts' into refactor/PN-13436
mflauti Jan 8, 2025
c7e7c62
added data-testid attr to PnInfoCard
AndreaCimini90 Jan 15, 2025
b85e7d9
refactor: apply cr
mflauti Jan 15, 2025
5e03d73
Merge branch 'refactor/PN-13436' of github.com:pagopa/pn-frontend int…
mflauti Jan 15, 2025
6b97166
fix: make data-testid optional for PnInfoCard
mflauti Jan 15, 2025
0025555
Merge branch 'feature/rework_contacts' into refactor/PN-13436
mflauti Jan 15, 2025
766f25d
Merge remote-tracking branch 'origin/feature/rework_contacts' into re…
AndreaCimini90 Jan 15, 2025
aac62b6
reduce complexity
AndreaCimini90 Jan 15, 2025
cce4ca9
refactor: change LegalContacts to reduce cognitive complexity (PF and…
mflauti Jan 16, 2025
fb21315
chore: change localization key
mflauti Jan 16, 2025
3b575b7
fix: fix bug showing a wrong copy while pec is validating
mflauti Jan 16, 2025
500bae4
test: add test to verify digital domicile disabling
mflauti Jan 16, 2025
7f41c8b
fix: fix bug showing wrong text on DeleteDialog while disabling digit…
mflauti Jan 16, 2025
2da2186
removed useless variable
AndreaCimini90 Jan 17, 2025
83f05cf
fixed pec validation show condition
AndreaCimini90 Jan 17, 2025
eb988cf
fix: fix LegalContacts title italian translation for PG
mflauti Jan 17, 2025
f779f58
feat: add components to implement digital domicile management feature
mflauti Jan 20, 2025
e7e1709
test: implement tests for digital domicile management
mflauti Jan 21, 2025
a0a565e
Merge branch 'feature/rework_contacts' of github.com:pagopa/pn-fronte…
mflauti Jan 21, 2025
d162657
Merge branch 'feature/rework_contacts' of github.com:pagopa/pn-fronte…
mflauti Jan 23, 2025
7352d2a
Merge remote-tracking branch 'origin/feature/rework_contacts' into re…
AndreaCimini90 Jan 27, 2025
0ed0155
refactor: apply cr
mflauti Jan 29, 2025
01e371d
refactor: apply cr
mflauti Feb 7, 2025
68690cd
refactor: add draft EmailSmsContactWizard
mflauti Feb 11, 2025
9b83979
feat: add EmailSmsContactWizard (draft)
mflauti Feb 11, 2025
4eb0251
Merge branch 'feature/rework_contacts' into feat/PN-13447
mflauti Feb 11, 2025
799a475
feat: add EmailSmsContactWizard (pf and pg)
mflauti Feb 13, 2025
2fc0d69
refactor: add slotsProps to DigitalContact and SmsContactItem to furt…
mflauti Feb 13, 2025
89d87ff
refactor: rework on 'Digital Domicile' and 'Validating Pec' Banners (…
mflauti Feb 18, 2025
3266fb5
Merge remote-tracking branch 'origin/feature/rework_contacts' into re…
AndreaCimini90 Feb 19, 2025
35182d8
removed useless code
AndreaCimini90 Feb 19, 2025
deb2476
refactor: apply cr
mflauti Feb 20, 2025
e520c30
return empty element when no banner must be shown
AndreaCimini90 Feb 24, 2025
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
8 changes: 4 additions & 4 deletions packages/pn-commons/src/components/PnWizard/PnWizard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ import PnWizardStep, { PnWizardStepProps } from './PnWizardStep';
import PnWizardStepper from './PnWizardStepper';

type Props = {
activeStep: number;
setActiveStep: (step: number) => void;
activeStep?: number;
setActiveStep?: (step: number) => void;
title: ReactNode;
children: ReactNode;
onExit: () => void;
Expand All @@ -47,8 +47,8 @@ type Props = {
};

const PnWizard: React.FC<Props> = ({
activeStep,
setActiveStep,
activeStep = 0,
setActiveStep = () => {},
title,
children,
onExit,
Expand Down
101 changes: 101 additions & 0 deletions packages/pn-commons/src/hooks/__test__/usePreviousLocation.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import { act } from 'react-dom/test-utils';
import * as reactRouterDom from 'react-router-dom';
import { vi } from 'vitest';

import { renderHook } from '../../test-utils';
import { usePreviousLocation } from '../usePreviousLocation';

const mockNavigateFn = vi.fn();

const MemoryRouter = reactRouterDom.MemoryRouter;

const mockLocation = {
pathname: '/page-b',
state: { from: '/page-a' },
key: '',
search: '',
hash: '',
};

vi.mock('react-router-dom', async () => ({
...(await vi.importActual<any>('react-router-dom')),
useNavigate: () => mockNavigateFn,
}));

describe('usePreviousLocation', () => {
beforeEach(() => {
vi.clearAllMocks();
});

afterEach(() => {
vi.clearAllMocks();
vi.resetAllMocks();
});

afterAll(() => {
vi.restoreAllMocks();
});

it('should return undefined for previousLocation if no state is provided', () => {
const { result } = renderHook(() => usePreviousLocation(), {
wrapper: ({ children }) => <MemoryRouter>{children}</MemoryRouter>,
});

expect(result.current.previousLocation).toBeUndefined();
});

it('should call navigate with the correct state', () => {
const { result } = renderHook(() => usePreviousLocation(), {
wrapper: ({ children }) => <MemoryRouter>{children}</MemoryRouter>,
});

act(() => {
result.current.navigateWithState('/page-b');
});

expect(mockNavigateFn).toHaveBeenCalledWith('/page-b', {
state: { from: '/' },
});
});

it('should return previousLocation from state', () => {
vi.spyOn(reactRouterDom, 'useLocation').mockReturnValue(mockLocation);

const { result } = renderHook(() => usePreviousLocation(), {
wrapper: ({ children }) => <MemoryRouter>{children}</MemoryRouter>,
});

expect(result.current.previousLocation).toBe('/page-a');
});

it('should call navigate(previousLocation) when previousLocation exists', () => {
vi.spyOn(reactRouterDom, 'useLocation').mockReturnValue(mockLocation);

const { result } = renderHook(() => usePreviousLocation(), {
wrapper: ({ children }) => <MemoryRouter>{children}</MemoryRouter>,
});

act(() => {
result.current.navigateToPreviousLocation();
});

expect(mockNavigateFn).toHaveBeenCalledWith('/page-a', { replace: true });
});

it('should call navigate(-1) when previousLocation is undefined', () => {
vi.spyOn(reactRouterDom, 'useLocation').mockReturnValue({
...mockLocation,
state: { from: undefined },
});

const { result } = renderHook(() => usePreviousLocation(), {
wrapper: ({ children }) => <MemoryRouter>{children}</MemoryRouter>,
});

act(() => {
result.current.navigateToPreviousLocation();
});

expect(mockNavigateFn).toHaveBeenCalledWith(-1);
});
});
26 changes: 26 additions & 0 deletions packages/pn-commons/src/hooks/usePreviousLocation.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { useLocation, useNavigate } from 'react-router-dom';

interface LocationState {
from?: string;
}

export const usePreviousLocation = () => {
const navigate = useNavigate();
const location = useLocation();

const previousLocation = (location.state as LocationState)?.from ?? undefined;

const navigateWithState = (path: string) => {
navigate(path, { state: { from: location.pathname } });
};

const navigateToPreviousLocation = () => {
if (previousLocation) {
navigate(previousLocation, { replace: true });
} else {
navigate(-1);
}
};

return { navigateWithState, navigateToPreviousLocation, previousLocation };
};
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ const EmailContactItem: React.FC = () => {
actions={getActions()}
expanded={isEmailActive}
data-testid="emailContact"
slotProps={{ Card: { id: 'emailContactSection' } }}
>
{!isEmailActive && (
<Typography variant="body1" fontSize={{ xs: '14px', lg: '16px' }} mb={3}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ const IOContact: React.FC = () => {
color="primary"
fullWidth={isMobile}
sx={{ mt: 3 }}
id="ioContactButton"
>
{t('io-contact.enable', { ns: 'recapiti' })}
</Button>
Expand Down Expand Up @@ -208,6 +209,7 @@ const IOContact: React.FC = () => {
: undefined
}
expanded={isAppIOEnabled}
slotProps={{ Card: { id: 'ioContactSection' } }}
>
<Stack direction="row" alignItems="center" data-testid="ioContact">
<Avatar variant="rounded" sx={{ bgcolor: '#0B3EE3', width: '36px', height: '36px' }}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,9 @@ const LegalContacts = () => {
)
.unwrap()
.then(() => {
if (channelType === ChannelType.SERCQ_SEND) {
sessionStorage.removeItem('domicileBannerClosed');
}
PFEventStrategyFactory.triggerEvent(
PFEventsType[`SEND_REMOVE_${channelType}_SUCCESS`],
'default'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ const SercqSendContactWizard: React.FC<Props> = ({ goToNextStep, setShowPecWizar
dispatch(createOrUpdateAddress(digitalAddressParams))
.unwrap()
.then(() => {
sessionStorage.removeItem('domicileBannerClosed');
PFEventStrategyFactory.triggerEvent(PFEventsType.SEND_ADD_SERCQ_SEND_UX_SUCCESS, 'default');
// show success message
dispatch(
Expand All @@ -150,7 +151,6 @@ const SercqSendContactWizard: React.FC<Props> = ({ goToNextStep, setShowPecWizar
message: t(`legal-contacts.sercq_send-added-successfully`, { ns: 'recapiti' }),
})
);

goToNextStep && goToNextStep();
})
.catch(() => {});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -108,43 +107,47 @@ const DomicileBanner: React.FC<Props> = ({ 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 ? (
<Box mb={5}>
<Box my={4}>
<Alert
severity={domicileBannerData.severity}
variant="outlined"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,7 @@ describe('DomicileBanner component', () => {
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', () => {
Expand Down
Loading