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

Feat/PN-13447 Add EmailSmsContactWizard component #1469

Merged
merged 48 commits into from
Feb 19, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 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
22ab9a6
removed useless hook
AndreaCimini90 Feb 17, 2025
323d266
Merge remote-tracking branch 'origin/feature/rework_contacts' into fe…
AndreaCimini90 Feb 18, 2025
c2f9c14
refactor: apply cr
mflauti Feb 18, 2025
4cc8b85
fix: fix test not working after ConfirmationModal refactor
mflauti Feb 19, 2025
0aabb06
added slotsProps to confirmation modal
AndreaCimini90 Feb 19, 2025
e2047f1
added extra line
AndreaCimini90 Feb 19, 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
60 changes: 60 additions & 0 deletions packages/pn-commons/src/components/ConfirmationModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import * as React from 'react';

import { Button, ButtonProps, DialogTitle } from '@mui/material';
import { PnDialog, PnDialogActions, PnDialogContent } from '@pagopa-pn/pn-commons';

type Props = {
open: boolean;
title: string;
slotsProps?: {
confirmButton?: ButtonProps;
closeButton?: ButtonProps;
};
onConfirmLabel?: string;
onCloseLabel?: string;
children?: React.ReactNode;
};

const ConfirmationModal: React.FC<Props> = ({
open,
title,
slotsProps,
onConfirmLabel = 'Riprova',
onCloseLabel = 'Annulla',
children,
}: Props) => (
<PnDialog
id="confirmation-dialog"
open={open}
onClose={slotsProps?.closeButton?.onClick}
aria-labelledby="confirmation-dialog-title"
aria-describedby="confirmation-dialog-description"
maxWidth="sm"
data-testid="confirmationDialog"
>
<DialogTitle id="confirmation-dialog-title">{title}</DialogTitle>
{children && <PnDialogContent>{children}</PnDialogContent>}
<PnDialogActions>
<Button
id="dialog-close-button"
color="primary"
variant="outlined"
data-testid="closeButton"
{...slotsProps?.closeButton}
>
{onCloseLabel}
</Button>
<Button
id="dialog-confirm-button"
color="primary"
variant="contained"
data-testid="confirmButton"
{...slotsProps?.confirmButton}
>
{onConfirmLabel}
</Button>
</PnDialogActions>
</PnDialog>
);

export default ConfirmationModal;
11 changes: 5 additions & 6 deletions packages/pn-commons/src/components/PnWizard/PnWizard.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React, { JSXElementConstructor, ReactElement, ReactNode } from 'react';
import { useNavigate } from 'react-router-dom';

import ArrowBackIcon from '@mui/icons-material/ArrowBack';
import {
Expand All @@ -24,6 +23,7 @@ type Props = {
setActiveStep: (step: number) => void;
title: ReactNode;
children: ReactNode;
onExit: () => void;
slots?: {
nextButton?: JSXElementConstructor<ButtonProps>;
prevButton?: JSXElementConstructor<ButtonProps>;
Expand All @@ -36,6 +36,7 @@ type Props = {
prevButton?: Omit<ButtonProps, 'onClick'> & {
onClick?: (previous: () => void, step: number) => void;
};
actions?: StackProps;
container?: Omit<StackProps, 'children'> & { 'data-testid'?: string };
feedback?: {
title: string;
Expand All @@ -50,13 +51,11 @@ const PnWizard: React.FC<Props> = ({
setActiveStep,
title,
children,
onExit,
slots,
slotsProps,
}) => {
checkChildren(children, [{ cmp: PnWizardStep }], 'PnWizard');

const navigate = useNavigate();

const PrevButton = slots?.prevButton || Button;
const NextButton = slots?.nextButton || Button;

Expand Down Expand Up @@ -127,7 +126,7 @@ const PnWizard: React.FC<Props> = ({
size="medium"
color="primary"
startIcon={<ArrowBackIcon />}
onClick={() => navigate(-1)}
onClick={onExit}
>
{getLocalizedOrDefaultLabel('common', 'button.exit', 'Esci')}
</ButtonNaked>
Expand All @@ -142,7 +141,7 @@ const PnWizard: React.FC<Props> = ({
{childrens[activeStep]}
</Paper>

<Stack direction={{ xs: 'column-reverse', md: 'row' }}>
<Stack direction={{ xs: 'column-reverse', md: 'row' }} {...slotsProps?.actions}>
<PrevButton
data-testid="prev-button"
sx={{ mt: { xs: 2, md: 0 } }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,16 @@ import PnWizardStep from '../PnWizardStep';
describe('PnWizard Component', () => {
disableConsoleLogging('error');
const setActiveStep = vi.fn();
const onExitMock = vi.fn();

it('renders PnWizard', () => {
const { getByTestId, getByText, queryByText } = render(
<PnWizard activeStep={0} setActiveStep={setActiveStep} title="Wizard Title">
<PnWizard
activeStep={0}
setActiveStep={setActiveStep}
onExit={onExitMock}
title="Wizard Title"
>
<PnWizardStep label="Label Step 1">Step 1</PnWizardStep>
<PnWizardStep label="Label Step 2">Step 2</PnWizardStep>
</PnWizard>
Expand All @@ -21,9 +27,32 @@ describe('PnWizard Component', () => {
expect(queryByText('Step 2')).not.toBeInTheDocument();
});

it('should call the exit callback', () => {
const { getByRole } = render(
<PnWizard
activeStep={0}
setActiveStep={setActiveStep}
onExit={onExitMock}
title="Wizard Title"
>
<PnWizardStep label="Label Step 1">Step 1</PnWizardStep>
<PnWizardStep label="Label Step 2">Step 2</PnWizardStep>
</PnWizard>
);

const exitButton = getByRole('button', { name: 'Esci' });
fireEvent.click(exitButton);
expect(onExitMock).toHaveBeenCalledOnce();
});

it('should call setActiveStep on step navigation', () => {
const { getByTestId } = render(
<PnWizard activeStep={0} setActiveStep={setActiveStep} title="Wizard Title">
<PnWizard
activeStep={0}
setActiveStep={setActiveStep}
onExit={onExitMock}
title="Wizard Title"
>
<PnWizardStep label="Label Step 1">Step 1</PnWizardStep>
<PnWizardStep label="Label Step 2">Step 2</PnWizardStep>
</PnWizard>
Expand All @@ -43,6 +72,7 @@ describe('PnWizard Component', () => {
<PnWizard
activeStep={0}
setActiveStep={setActiveStep}
onExit={onExitMock}
title="Wizard Title"
slots={{ nextButton: CustomNextButton }}
>
Expand All @@ -62,6 +92,7 @@ describe('PnWizard Component', () => {
<PnWizard
activeStep={1}
setActiveStep={setActiveStep}
onExit={onExitMock}
title="Wizard Title"
slotsProps={{
nextButton: { onClick: customNextClick },
Expand All @@ -88,6 +119,7 @@ describe('PnWizard Component', () => {
<PnWizard
activeStep={2}
setActiveStep={setActiveStep}
onExit={onExitMock}
title="Wizard Title"
slotsProps={{
feedback: {
Expand All @@ -108,7 +140,12 @@ describe('PnWizard Component', () => {

it('should not render feedback step', () => {
const { queryByTestId } = render(
<PnWizard activeStep={2} setActiveStep={setActiveStep} title="Wizard Title">
<PnWizard
activeStep={2}
setActiveStep={setActiveStep}
onExit={onExitMock}
title="Wizard Title"
>
<PnWizardStep label="Label Step 1">Step 1</PnWizardStep>
<PnWizardStep label="Label Step 2">Step 2</PnWizardStep>
</PnWizard>
Expand All @@ -125,6 +162,7 @@ describe('PnWizard Component', () => {
<PnWizard
activeStep={2}
setActiveStep={setActiveStep}
onExit={onExitMock}
title="Wizard Title"
slotsProps={{
feedback: {
Expand Down Expand Up @@ -153,7 +191,12 @@ describe('PnWizard Component', () => {
it('should throw an error if children are not PnWizardStep', () => {
expect(() =>
render(
<PnWizard activeStep={0} setActiveStep={setActiveStep} title="Wizard Title">
<PnWizard
activeStep={0}
setActiveStep={setActiveStep}
onExit={onExitMock}
title="Wizard Title"
>
<div>Step 1</div>
</PnWizard>
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import { vi } from 'vitest';

import { fireEvent, render } from '../../test-utils';
import ConfirmationModal from '../ConfirmationModal';

const mockCancelFunction = vi.fn();
const mockConfirmFunction = vi.fn();

describe('ConfirmationModal Component', () => {
it('renders the component', () => {
const { getByRole, getByTestId } = render(
<ConfirmationModal
title={'Test title'}
slotsProps={{
closeButton: { onClick: mockCancelFunction },
confirmButton: { onClick: mockConfirmFunction },
}}
onCloseLabel={'Cancel'}
open
onConfirmLabel={'Confirm'}
/>
);

const dialog = getByRole('dialog');
expect(dialog).toBeInTheDocument();
expect(dialog).toHaveTextContent(/Test Title/i);
const confirmButton = getByTestId('confirmButton');
const closeButton = getByTestId('closeButton');
expect(confirmButton).toHaveTextContent(/Confirm/i);
expect(closeButton).toHaveTextContent(/Cancel/i);
});

it('checks that the confirm and cancel functions are executed', () => {
const { getByTestId } = render(
<ConfirmationModal
title={'Test title'}
slotsProps={{
closeButton: { onClick: mockCancelFunction },
confirmButton: { onClick: mockConfirmFunction },
}}
onCloseLabel={'Cancel'}
open
onConfirmLabel={'Confirm'}
/>
);

const confirmButton = getByTestId('confirmButton');
const cancelButton = getByTestId('closeButton');
fireEvent.click(confirmButton);
expect(mockConfirmFunction).toHaveBeenCalledTimes(1);
fireEvent.click(cancelButton);
expect(mockCancelFunction).toHaveBeenCalledTimes(1);
});

it('renders the dialog with default labels', () => {
const { getByTestId } = render(
<ConfirmationModal
title={'Test title'}
slotsProps={{
closeButton: { onClick: mockCancelFunction },
confirmButton: { onClick: mockConfirmFunction },
}}
open
/>
);

const confirmButton = getByTestId('confirmButton');
const cancelButton = getByTestId('closeButton');
expect(confirmButton).toHaveTextContent(/Riprova/i);
expect(cancelButton).toHaveTextContent(/Annulla/i);
});

it('renders the dialog with children', () => {
const { getByRole } = render(
<ConfirmationModal
title={'Test title'}
slotsProps={{
closeButton: { onClick: mockCancelFunction },
confirmButton: { onClick: mockConfirmFunction },
}}
onCloseLabel={'Cancel'}
open
onConfirmLabel={'Confirm'}
>
<p>Test Content</p>
</ConfirmationModal>
);
const dialog = getByRole('dialog');
expect(dialog).toBeInTheDocument();
expect(dialog).toHaveTextContent(/Test Title/i);
expect(dialog).toHaveTextContent(/Test Content/i);
});
});
2 changes: 2 additions & 0 deletions packages/pn-commons/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import AppResponseMessage from './AppResponseMessage';
import { AppStatusRender } from './AppStatus/AppStatusRender';
import CodeModal from './CodeModal/CodeModal';
import CollapsedList from './CollapsedList';
import ConfirmationModal from './ConfirmationModal';
import CopyToClipboard from './CopyToClipboard';
import CustomDatePicker from './CustomDatePicker';
import CustomDropdown from './CustomDropdown';
Expand Down Expand Up @@ -86,6 +87,7 @@ export {
AppResponseMessage,
AppStatusRender,
CodeModal,
ConfirmationModal,
CopyToClipboard,
CustomDatePicker,
CustomDropdown,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"go-to-home": "Vai alla homepage",
"go-to-login": "Accedi",
"not-now": "Non ora",
"do-later": "Lo farò più tardi",
"add": "Aggiungi",
"understand": "Ok, ho capito"
},
Expand Down
18 changes: 17 additions & 1 deletion packages/pn-personafisica-webapp/public/locales/it/recapiti.json
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,17 @@
],
"confirm": "Collega SEND su IO"
},
"step_3": {
"title": "La tua mail per ricevere aggiornamenti",
"step-title": "Inserisci una email",
"content": "L’email dove possiamo informarti quando c’è una comunicazione a valore legale per te su SEND.",
"io-list": [
"Ricevi le notifiche in tempo reale, appena l’ente le carica su SEND",
"Puoi aprire e leggere i documenti allegati alla notifica",
"Puoi pagare gli importi dovuti se la notifica prevede un pagamento"
],
"confirm": "Collega SEND su IO"
},
"feedback": {
"title-activation": "Hai attivato il tuo domicilio digitale",
"title-transfer": "Hai aggiornato il tuo domicilio digitale",
Expand Down Expand Up @@ -196,7 +207,12 @@
"info-modal-email-content": "Se non hai il domicilio digitale attivo e non apri la notifica entro 5 giorni dall’invio della email, riceverai i documenti in formato cartaceo a casa.",
"info-modal-sms-title": "Avvisi via SMS: come funzionano",
"info-modal-sms-subtitle": "Quando ci sono nuove notifiche per te, riceverai un SMS al numero inserito.",
"info-modal-sms-content": "Se non hai il domicilio digitale attivo e non apri la notifica entro 5 giorni dall’invio dell’SMS, riceverai i documenti in formato cartaceo a casa."
"info-modal-sms-content": "Se non hai il domicilio digitale attivo e non apri la notifica entro 5 giorni dall’invio dell’SMS, riceverai i documenti in formato cartaceo a casa.",
"confirmation-modal-title": "Non rischiare di leggere in ritardo le tue notifiche",
"confirmation-modal-io-content": "<0>Se non colleghi SEND a IO non riceverai aggiornamenti in app quando ricevi una comunicazione a valore legale.</0><1>Ricorda che se non leggi in tempo una notifica SEND, potresti non essere al corrente di eventuali scadenze e incorrere in sanzioni.</1>",
"confirmation-modal-io-accept": "Collega SEND a IO",
"confirmation-modal-email-content": "<0>Senza un indirizzo email o un altro recapito non possiamo informarti quando ricevi una comunicazione a valore legale su SEND.</0><1>Ricorda che se non leggi in tempo una notifica SEND, potresti non essere al corrente di eventuali scadenze e incorrere in sanzioni.</1>",
"confirmation-modal-email-accept": "Inserisci email"
},
"special-contacts": {
"select-address": "Tipologia",
Expand Down
Loading