diff --git a/CHANGELOG.md b/CHANGELOG.md index 248c2eb13f..3f89ebeaab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [2.11.1](https://github.com/pagopa/pn-frontend/compare/v2.11.0...v2.11.1) (2025-01-31) + +**Note:** Version bump only for package pn-frontend + + + + + # [2.11.0](https://github.com/pagopa/pn-frontend/compare/v2.11.0-RC.2...v2.11.0) (2025-01-20) **Note:** Version bump only for package pn-frontend diff --git a/lerna.json b/lerna.json index f85c280421..af92cdeea7 100644 --- a/lerna.json +++ b/lerna.json @@ -2,7 +2,7 @@ "packages": [ "packages/*" ], - "version": "2.11.0", + "version": "2.11.1", "npmClient": "yarn", "useWorkspaces": true, "command": { diff --git a/packages/pn-commons/CHANGELOG.md b/packages/pn-commons/CHANGELOG.md index a63aed7bb4..cc79cfc7b8 100644 --- a/packages/pn-commons/CHANGELOG.md +++ b/packages/pn-commons/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [2.11.1](https://github.com/pagopa/pn-frontend/compare/v2.11.0...v2.11.1) (2025-01-31) + +**Note:** Version bump only for package @pagopa-pn/pn-commons + + + + + # [2.11.0](https://github.com/pagopa/pn-frontend/compare/v2.11.0-RC.2...v2.11.0) (2025-01-20) **Note:** Version bump only for package @pagopa-pn/pn-commons diff --git a/packages/pn-commons/package.json b/packages/pn-commons/package.json index 4ea0ebf6d6..7a8ccf4a63 100644 --- a/packages/pn-commons/package.json +++ b/packages/pn-commons/package.json @@ -1,6 +1,6 @@ { "name": "@pagopa-pn/pn-commons", - "version": "2.11.0", + "version": "2.11.1", "private": true, "main": "./src/index.ts", "dependencies": { @@ -65,7 +65,7 @@ "@typescript-eslint/eslint-plugin": "^6.7.3", "@typescript-eslint/parser": "^6.7.3", "@vitejs/plugin-react": "^4.2.1", - "@vitest/coverage-v8": "^1.3.1", + "@vitest/coverage-v8": "^1.6.1", "css-mediaquery": "^0.1.2", "eslint": "7.11.0", "eslint-config-prettier": "^8.10.0", @@ -78,7 +78,7 @@ "prettier": "^2.8.8", "sonarqube-scanner": "^3.3.0", "vite": "^5.1.4", - "vitest": "1.3.1", + "vitest": "^1.6.1", "vitest-sonar-reporter": "^2.0.0" } } diff --git a/packages/pn-commons/src/components/CustomMobileDialog/CustomMobileDialogContent.tsx b/packages/pn-commons/src/components/CustomMobileDialog/CustomMobileDialogContent.tsx index 64f5092992..81880b03d1 100644 --- a/packages/pn-commons/src/components/CustomMobileDialog/CustomMobileDialogContent.tsx +++ b/packages/pn-commons/src/components/CustomMobileDialog/CustomMobileDialogContent.tsx @@ -1,10 +1,11 @@ import { ReactElement, ReactNode, Ref, forwardRef, useImperativeHandle } from 'react'; import CloseIcon from '@mui/icons-material/Close'; -import { Dialog, DialogTitle, Grid, Slide, Typography } from '@mui/material'; +import { Dialog, DialogTitle, Grid, IconButton, Slide, Typography } from '@mui/material'; import { styled } from '@mui/material/styles'; import { TransitionProps } from '@mui/material/transitions'; +import { getLocalizedOrDefaultLabel } from '../../utility/localization.utility'; import { useCustomMobileDialogContext } from './CustomMobileDialog.context'; type Props = { @@ -82,17 +83,19 @@ const CustomMobileDialogContent = forwardRef<{ toggleOpen: () => void }, Props>( - + aria-label={getLocalizedOrDefaultLabel('common', 'button.close')} + > + + diff --git a/packages/pn-commons/src/components/CustomTagGroup/CustomTagGroup.tsx b/packages/pn-commons/src/components/CustomTagGroup/CustomTagGroup.tsx index 188ab61c29..dfce81ee87 100644 --- a/packages/pn-commons/src/components/CustomTagGroup/CustomTagGroup.tsx +++ b/packages/pn-commons/src/components/CustomTagGroup/CustomTagGroup.tsx @@ -21,9 +21,15 @@ const TagIndicator: React.FC<{ arrayChildren: Array; visibleItems: number; dataTestId: string; -}> = ({ boxProps, arrayChildren, visibleItems, dataTestId }) => ( - - + ariaLabel?: string; +}> = ({ boxProps, arrayChildren, visibleItems, dataTestId, ariaLabel }) => ( + + ); @@ -48,14 +54,18 @@ const CustomTagGroup: React.FC = ({ onOpen={onOpen} tooltipContent={<>{arrayChildren.slice(visibleItems).map((c) => c)}>} > - + c.props?.children?.props?.value) // + .filter(Boolean) + .join(',')} /> - + )} {disableTooltip && ( diff --git a/packages/pn-commons/src/components/CustomTagGroup/__test__/CustomTagGroup.test.tsx b/packages/pn-commons/src/components/CustomTagGroup/__test__/CustomTagGroup.test.tsx index 182a14ef9e..e878eecc58 100644 --- a/packages/pn-commons/src/components/CustomTagGroup/__test__/CustomTagGroup.test.tsx +++ b/packages/pn-commons/src/components/CustomTagGroup/__test__/CustomTagGroup.test.tsx @@ -1,13 +1,18 @@ import { vi } from 'vitest'; import { Box } from '@mui/material'; +import { Tag } from '@pagopa/mui-italia'; import { fireEvent, render, screen, waitFor } from '../../../test-utils'; import CustomTagGroup from '../CustomTagGroup'; describe('CustomTagGroup component', () => { const tagsArray = ['mock-tag-1', 'mock-tag-2', 'mock-tag-3', 'mock-tag-4']; - const tags = tagsArray.map((v, i) => {v}); + const tags = tagsArray.map((v, i) => ( + + + + )); const mockCallbackFn = vi.fn(); beforeEach(() => { @@ -57,4 +62,15 @@ describe('CustomTagGroup component', () => { expect(tooltip).not.toBeInTheDocument(); expect(mockCallbackFn).toBeCalledTimes(0); }); + + it('renders component with limited 1 tags with aria-label', () => { + const { getByTestId } = render( + + {tags} + + ); + const tooltipIndicator = getByTestId('custom-tooltip-indicator'); + expect(tooltipIndicator).toBeInTheDocument(); + expect(tooltipIndicator).toHaveAttribute('aria-label', 'mock-tag-3,mock-tag-4'); + }); }); diff --git a/packages/pn-commons/src/components/Data/PnTable/PnTableHeaderCell.tsx b/packages/pn-commons/src/components/Data/PnTable/PnTableHeaderCell.tsx index c9d54df47e..6405ae6215 100644 --- a/packages/pn-commons/src/components/Data/PnTable/PnTableHeaderCell.tsx +++ b/packages/pn-commons/src/components/Data/PnTable/PnTableHeaderCell.tsx @@ -49,6 +49,13 @@ const PnTableHeaderCell = ({ direction={sort.orderBy === columnId ? sort.order : 'asc'} onClick={sortHandler(columnId)} data-testid={testId ? `${testId}.sort.${columnId.toString()}` : null} + sx={{ + '&:focus-visible': { + borderRadius: '2px', + outlineOffset: '4px', + outline: '2px solid currentColor' + } + }} > {children} {sort.orderBy === columnId && ( diff --git a/packages/pn-commons/src/components/InactivityHandler.tsx b/packages/pn-commons/src/components/InactivityHandler.tsx index 61c63dc4f6..f6b8c023a8 100644 --- a/packages/pn-commons/src/components/InactivityHandler.tsx +++ b/packages/pn-commons/src/components/InactivityHandler.tsx @@ -1,4 +1,11 @@ -import { Fragment, useEffect, useState } from 'react'; +import { useEffect, useState } from 'react'; + +import { Button, DialogContentText, DialogTitle } from '@mui/material'; + +import { getLocalizedOrDefaultLabel } from '../utility/localization.utility'; +import PnDialog from './PnDialog/PnDialog'; +import PnDialogActions from './PnDialog/PnDialogActions'; +import PnDialogContent from './PnDialog/PnDialogContent'; type Props = { /** Inactivity timer (in milliseconds), if 0 the inactivity timer is disabled */ @@ -8,43 +15,66 @@ type Props = { children?: React.ReactNode; }; -const InactivityHandler: React.FC = ({ inactivityTimer, children, onTimerExpired }) => { +const InactivityHandler: React.FC = ({ inactivityTimer, onTimerExpired, children }) => { const [initTimeout, setInitTimeout] = useState(true); - + const [openModal, setOpenModal] = useState(false); const resetTimer = () => setInitTimeout(!initTimeout); - const initListeners = () => { - window.addEventListener('mousemove', resetTimer); - window.addEventListener('scroll', resetTimer); - window.addEventListener('keydown', resetTimer); - }; - - const cleanUpListeners = () => { - window.removeEventListener('mousemove', resetTimer); - window.removeEventListener('scroll', resetTimer); - window.removeEventListener('keydown', resetTimer); - }; - // init timer useEffect(() => { if (inactivityTimer) { - // init listeners - initListeners(); + // this is the timer after wich the inactivity modal is shown + const inactivityWarningTimer = inactivityTimer - 30 * 1000; // init timer const timer = setTimeout(() => { - cleanUpListeners(); onTimerExpired(); }, inactivityTimer); + + const warningTimer = setTimeout(() => { + setOpenModal(true); + }, inactivityWarningTimer); + // cleanup function return () => { + setOpenModal(false); clearTimeout(timer); - cleanUpListeners(); + clearTimeout(warningTimer); }; } return () => {}; }, [initTimeout]); - return {children}; + return ( + <> + + + {getLocalizedOrDefaultLabel('common', 'inactivity.title')} + + + + {getLocalizedOrDefaultLabel('common', 'inactivity.body')} + + + + + {getLocalizedOrDefaultLabel('common', 'inactivity.action')} + + + + {children} + > + ); }; export default InactivityHandler; diff --git a/packages/pn-commons/src/components/SessionModal.tsx b/packages/pn-commons/src/components/SessionModal.tsx index 2e44d3ffbf..7d7a1b8717 100644 --- a/packages/pn-commons/src/components/SessionModal.tsx +++ b/packages/pn-commons/src/components/SessionModal.tsx @@ -75,7 +75,7 @@ const SessionModal: React.FC = ({ {onConfirm && ( - + {onConfirmLabel} diff --git a/packages/pn-commons/src/components/__test__/InactivityHandler.test.tsx b/packages/pn-commons/src/components/__test__/InactivityHandler.test.tsx index 5db76205b4..bdec93615d 100644 --- a/packages/pn-commons/src/components/__test__/InactivityHandler.test.tsx +++ b/packages/pn-commons/src/components/__test__/InactivityHandler.test.tsx @@ -1,10 +1,10 @@ import { vi } from 'vitest'; -import { fireEvent, render, waitFor } from '../../test-utils'; +import { act, fireEvent, render, within } from '../../test-utils'; import InactivityHandler from '../InactivityHandler'; const timerExpiredHandler = vi.fn(); -const inactivityTimer = 2000; +const inactivityTimer = 60 * 1000; const Component = () => ( @@ -13,31 +13,35 @@ const Component = () => ( ); describe('InactivityHandler Component', () => { + beforeAll(() => { + vi.useFakeTimers(); + }); + beforeEach(() => { vi.resetAllMocks(); vi.clearAllMocks(); }); + afterAll(() => { + vi.useRealTimers(); + }); + it('test inactivity', async () => { // render component - render(); - await waitFor( - () => { - expect(timerExpiredHandler).toBeCalledTimes(1); - }, - { timeout: inactivityTimer + 1000 } - ); + const { container } = render(); + expect(container).toHaveTextContent('Mocked children'); + await act(() => vi.advanceTimersByTime(inactivityTimer)); + expect(timerExpiredHandler).toHaveBeenCalledTimes(1); }); it('test user interaction', async () => { // render component - const result = render(); - fireEvent.mouseMove(result.container); - await waitFor( - () => { - expect(timerExpiredHandler).toBeCalledTimes(0); - }, - { timeout: inactivityTimer + 1000 } - ); + const { getByTestId } = render(); + await act(() => vi.advanceTimersByTime(inactivityTimer - 30 * 1000)); + const inactivityDialog = getByTestId('inactivity-modal'); + expect(inactivityDialog).toBeInTheDocument(); + const inactivityButton = within(inactivityDialog).getByTestId('inactivity-button'); + fireEvent.click(inactivityButton); + expect(timerExpiredHandler).toHaveBeenCalledTimes(0); }); }); diff --git a/packages/pn-commons/src/utility/costants.tsx b/packages/pn-commons/src/utility/costants.tsx index c38886d7d7..765ed24128 100644 --- a/packages/pn-commons/src/utility/costants.tsx +++ b/packages/pn-commons/src/utility/costants.tsx @@ -15,7 +15,7 @@ export const LANGUAGES: Languages = { export const PRIVACY_LINK_RELATIVE_PATH = '/informativa-privacy'; export const TOS_LINK_RELATIVE_PATH = '/termini-di-servizio'; -const ACCESSIBILITY_LINK = 'https://form.agid.gov.it/view/5bd4c880-772d-11ef-b5af-e9d3099e743c'; +const ACCESSIBILITY_LINK = 'https://form.agid.gov.it/view/978876c0-df2d-11ef-8637-9f856ac3da10'; const getFooterLinkLabels = ( link: string, diff --git a/packages/pn-data-viz/CHANGELOG.md b/packages/pn-data-viz/CHANGELOG.md index 31a97b3454..8a38b5a085 100644 --- a/packages/pn-data-viz/CHANGELOG.md +++ b/packages/pn-data-viz/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [2.11.1](https://github.com/pagopa/pn-frontend/compare/v2.11.0...v2.11.1) (2025-01-31) + +**Note:** Version bump only for package @pagopa-pn/pn-data-viz + + + + + # [2.11.0](https://github.com/pagopa/pn-frontend/compare/v2.11.0-RC.2...v2.11.0) (2025-01-20) **Note:** Version bump only for package @pagopa-pn/pn-data-viz diff --git a/packages/pn-data-viz/package.json b/packages/pn-data-viz/package.json index b500f66066..208f38bf96 100644 --- a/packages/pn-data-viz/package.json +++ b/packages/pn-data-viz/package.json @@ -1,6 +1,6 @@ { "name": "@pagopa-pn/pn-data-viz", - "version": "2.11.0", + "version": "2.11.1", "private": true, "description": "SEND component library for data visualization", "keywords": [ @@ -33,7 +33,7 @@ "eslint-plugin-react-hooks": "^4.3.0", "eslint-plugin-sonarjs": "^0.10.0", "vite": "^5.1.4", - "vitest": "1.3.1", + "vitest": "^1.6.1", "vitest-canvas-mock": "^0.3.3", "vitest-sonar-reporter": "^2.0.0" } diff --git a/packages/pn-pa-webapp/CHANGELOG.md b/packages/pn-pa-webapp/CHANGELOG.md index 5050e28846..91466f126a 100644 --- a/packages/pn-pa-webapp/CHANGELOG.md +++ b/packages/pn-pa-webapp/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [2.11.1](https://github.com/pagopa/pn-frontend/compare/v2.11.0...v2.11.1) (2025-01-31) + +**Note:** Version bump only for package @pagopa-pn/pn-pa-webapp + + + + + # [2.11.0](https://github.com/pagopa/pn-frontend/compare/v2.11.0-RC.2...v2.11.0) (2025-01-20) **Note:** Version bump only for package @pagopa-pn/pn-pa-webapp diff --git a/packages/pn-pa-webapp/package.json b/packages/pn-pa-webapp/package.json index 5714ca126f..f392c6ab8d 100644 --- a/packages/pn-pa-webapp/package.json +++ b/packages/pn-pa-webapp/package.json @@ -1,7 +1,7 @@ { "name": "@pagopa-pn/pn-pa-webapp", "description": "Backoffice di SEND per la Pubblica Amministrazione", - "version": "2.11.0", + "version": "2.11.1", "private": true, "dependencies": { "@emotion/react": "^11.11.1", @@ -77,7 +77,7 @@ "@typescript-eslint/parser": "^6.7.3", "@vitejs/plugin-basic-ssl": "^1.1.0", "@vitejs/plugin-react": "^4.2.1", - "@vitest/coverage-v8": "^1.3.1", + "@vitest/coverage-v8": "^1.6.1", "axios-mock-adapter": "^1.22.0", "eslint": "7.11.0", "eslint-config-prettier": "^8.10.0", @@ -90,7 +90,7 @@ "prettier": "^2.8.8", "sonarqube-scanner": "^3.3.0", "vite": "^5.1.4", - "vitest": "^1.3.1", + "vitest": "^1.6.1", "vitest-canvas-mock": "^0.3.3", "vitest-sonar-reporter": "^2.0.0" } diff --git a/packages/pn-pa-webapp/public/locales/it/apikeys.json b/packages/pn-pa-webapp/public/locales/it/apikeys.json index 5713ef3604..575f73a0e5 100644 --- a/packages/pn-pa-webapp/public/locales/it/apikeys.json +++ b/packages/pn-pa-webapp/public/locales/it/apikeys.json @@ -41,7 +41,7 @@ "status": "Stato" }, "context-menu": { - "title": "Opzioni su API Key", + "title": "Menu azioni su API Key", "enable": "Attiva", "block": "Blocca", "rotate": "Ruota", @@ -86,5 +86,6 @@ "continue-button": "Continua", "required-fields": "Campi obbligatori", "no-groups": "Nessun gruppo disponibile" - } + }, + "api-key-succesfully-deleted": "Chiave pubblica eliminata con successo." } diff --git a/packages/pn-pa-webapp/public/locales/it/common.json b/packages/pn-pa-webapp/public/locales/it/common.json index bbb3fd06bb..8e4271c9f3 100644 --- a/packages/pn-pa-webapp/public/locales/it/common.json +++ b/packages/pn-pa-webapp/public/locales/it/common.json @@ -24,7 +24,8 @@ "logout": "Esci", "pago-pa-link": "Sito di PagoPA S.p.A.", "reserved-area": "Area Riservata", - "notification-platform": "SEND - Servizio Notifiche Digitali" + "notification-platform": "SEND - Servizio Notifiche Digitali", + "logout-message": "Confermi di voler uscire da SEND?" }, "tos": { "title": "SEND - Servizio Notifiche Digitali", @@ -167,5 +168,10 @@ "downtime_language_banner": { "message": "Il testo originario di questi documenti è in lingua italiana. In caso di contrasto tra la versione italiana e le traduzioni in altre lingue, prevarranno il significato e le condizioni della lingua italiana.", "link": "Consulta le traduzioni" + }, + "inactivity": { + "title": "Vuoi davvero uscire da SEND?", + "body": "La disconnessione è in corso. Se hai cambiato idea premi “Mantieni l’accesso” entro pochi secondi.", + "action": "Mantieni l’accesso" } } diff --git a/packages/pn-pa-webapp/src/App.tsx b/packages/pn-pa-webapp/src/App.tsx index 52650e5706..e59f96a376 100644 --- a/packages/pn-pa-webapp/src/App.tsx +++ b/packages/pn-pa-webapp/src/App.tsx @@ -8,13 +8,15 @@ import ErrorIcon from '@mui/icons-material/Error'; import HelpIcon from '@mui/icons-material/Help'; import StatisticsIcon from '@mui/icons-material/ShowChart'; import VpnKey from '@mui/icons-material/VpnKey'; -import { Box } from '@mui/material'; +import { Box, Button, DialogTitle } from '@mui/material'; import { APP_VERSION, AppMessage, AppResponseMessage, Layout, LoadingOverlay, + PnDialog, + PnDialogActions, ResponseEventDispatcher, SideMenu, SideMenuItem, @@ -33,7 +35,6 @@ import { getAdditionalLanguages, getInstitutions, getProductsOfInstitution, - logout, } from './redux/auth/actions'; import { useAppDispatch, useAppSelector } from './redux/hooks'; import { RootState } from './redux/store'; @@ -41,6 +42,7 @@ import { getConfiguration } from './services/configuration.service'; import { PAAppErrorFactory } from './utility/AppError/PAAppErrorFactory'; import './utility/onetrust'; import { getMenuItems } from './utility/role.utility'; +import { goToSelfcareLogin } from './navigation/navigation.utility'; // Cfr. PN-6096 // -------------------- @@ -70,6 +72,7 @@ const ActualApp = () => { // TODO check if it can exist more than one role on user const role = loggedUserOrganizationParty?.roles[0]; const idOrganization = loggedUserOrganizationParty?.id; + const [openModal, setOpenModal] = useState(false); const { tosConsent, privacyConsent } = useAppSelector((state: RootState) => state.userState); const currentStatus = useAppSelector((state: RootState) => state.appStatus.currentStatus); const { SELFCARE_BASE_URL, SELFCARE_SEND_PROD_ID, IS_STATISTICS_ENABLED } = getConfiguration(); @@ -88,21 +91,21 @@ const ActualApp = () => { const productsList = products.length > 0 ? [ - reservedArea, - ...products.map((product) => ({ - ...product, - productUrl: `${product.productUrl}&lang=${i18n.language}`, - })), - ] + reservedArea, + ...products.map((product) => ({ + ...product, + productUrl: `${product.productUrl}&lang=${i18n.language}`, + })), + ] : [ - reservedArea, - { - id: '0', - title: t('header.notification-platform'), - productUrl: '', - linkType: 'internal' as LinkType, - }, - ]; + reservedArea, + { + id: '0', + title: t('header.notification-platform'), + productUrl: '', + linkType: 'internal' as LinkType, + }, + ]; const productId = products.length > 0 ? SELFCARE_SEND_PROD_ID : '0'; const institutionsList = institutions.map((institution) => ({ @@ -200,7 +203,7 @@ const ActualApp = () => { const isPrivacyPage = path[1] === 'privacy-tos'; const handleLogout = () => { - void dispatch(logout()); + setOpenModal(true); }; const handleAssistanceClick = () => { @@ -255,6 +258,31 @@ const ActualApp = () => { onAssistanceClick={handleAssistanceClick} isLogged={!!sessionToken} > + + {t("header.logout-message")} + + setOpenModal(false)} + > + {t("button.annulla")} + + { + sessionStorage.clear(); + goToSelfcareLogin(); + setOpenModal(false); + }} + > + {t("header.logout")} + + + + diff --git a/packages/pn-pa-webapp/src/components/ApiKeys/ApiKeyDataSwitch.tsx b/packages/pn-pa-webapp/src/components/ApiKeys/ApiKeyDataSwitch.tsx index 9d0599606e..a9201f7ebf 100644 --- a/packages/pn-pa-webapp/src/components/ApiKeys/ApiKeyDataSwitch.tsx +++ b/packages/pn-pa-webapp/src/components/ApiKeys/ApiKeyDataSwitch.tsx @@ -45,6 +45,11 @@ const ApiKeyContextMenu = ({ setAnchorEl(null); }; + const handleModalClickAndClose = (view: ModalApiKeyView) => { + handleClose(); // a11y: force close menu for keyboard navigation + handleModalClick(view, apiKeyId); + }; + return ( @@ -66,12 +71,14 @@ const ApiKeyContextMenu = ({ open={open} onClose={handleClose} onClick={handleClose} - PaperProps={{ - elevation: 0, - sx: { - overflow: 'visible', - filter: 'drop-shadow(0px 2px 8px rgba(0,0,0,0.32))', - mt: 1.5, + slotProps={{ + paper: { + elevation: 0, + sx: { + overflow: 'visible', + filter: 'drop-shadow(0px 2px 8px rgba(0,0,0,0.32))', + mt: 1.5, + }, }, }} transformOrigin={{ horizontal: 'right', vertical: 'top' }} @@ -81,7 +88,7 @@ const ApiKeyContextMenu = ({ handleModalClick(ModalApiKeyView.VIEW, apiKeyId)} + onClick={() => handleModalClickAndClose(ModalApiKeyView.VIEW)} > {t('context-menu.view')} @@ -90,7 +97,7 @@ const ApiKeyContextMenu = ({ handleModalClick(ModalApiKeyView.ROTATE, apiKeyId)} + onClick={() => handleModalClickAndClose(ModalApiKeyView.ROTATE)} > {t('context-menu.rotate')} @@ -99,7 +106,7 @@ const ApiKeyContextMenu = ({ handleModalClick(ModalApiKeyView.BLOCK, apiKeyId)} + onClick={() => handleModalClickAndClose(ModalApiKeyView.BLOCK)} > {t('context-menu.block')} @@ -108,7 +115,7 @@ const ApiKeyContextMenu = ({ handleModalClick(ModalApiKeyView.DELETE, apiKeyId)} + onClick={() => handleModalClickAndClose(ModalApiKeyView.DELETE)} > {t('context-menu.delete')} @@ -117,7 +124,7 @@ const ApiKeyContextMenu = ({ handleModalClick(ModalApiKeyView.ENABLE, apiKeyId)} + onClick={() => handleModalClickAndClose(ModalApiKeyView.ENABLE)} > {t('context-menu.enable')} @@ -126,7 +133,7 @@ const ApiKeyContextMenu = ({ handleModalClick(ModalApiKeyView.VIEW_GROUPS_ID, apiKeyId)} + onClick={() => handleModalClickAndClose(ModalApiKeyView.VIEW_GROUPS_ID)} > {t('context-menu.view-groups-id')} diff --git a/packages/pn-pa-webapp/src/navigation/SessionGuard.tsx b/packages/pn-pa-webapp/src/navigation/SessionGuard.tsx index 7a814fe9c7..0d3835afe8 100644 --- a/packages/pn-pa-webapp/src/navigation/SessionGuard.tsx +++ b/packages/pn-pa-webapp/src/navigation/SessionGuard.tsx @@ -54,7 +54,6 @@ const SessionGuardRender = () => { const { isUnauthorizedUser, messageUnauthorizedUser, isClosedSession } = useAppSelector( (state: RootState) => state.userState ); - const dispatch = useAppDispatch(); const { t } = useTranslation(['common']); const { hasApiErrors } = useErrors(); @@ -89,7 +88,10 @@ const SessionGuardRender = () => { ) : ( dispatch(logout())} + onTimerExpired={() => { + sessionStorage.clear(); + goToSelfcareLogin(); + }} > diff --git a/packages/pn-pa-webapp/src/pages/ApiKeys.page.tsx b/packages/pn-pa-webapp/src/pages/ApiKeys.page.tsx index 7175aee367..a263efb7b5 100644 --- a/packages/pn-pa-webapp/src/pages/ApiKeys.page.tsx +++ b/packages/pn-pa-webapp/src/pages/ApiKeys.page.tsx @@ -9,6 +9,7 @@ import { CustomPagination, PaginationData, TitleBox, + appStateActions, calculatePages, useIsMobile, } from '@pagopa-pn/pn-commons'; @@ -146,7 +147,16 @@ const ApiKeys = () => { const apiKeyDeleted = (apiKeyId: string) => { handleCloseModal(); - void dispatch(deleteApiKey(apiKeyId)).then(fetchApiKeys); + void dispatch(deleteApiKey(apiKeyId)) + .then(() => + dispatch( + appStateActions.addSuccess({ + title: '', + message: t('api-key-succesfully-deleted'), + }) + ) + ) + .then(fetchApiKeys); }; // Pagination handlers diff --git a/packages/pn-personafisica-login/CHANGELOG.md b/packages/pn-personafisica-login/CHANGELOG.md index de4f53a5d3..e3191288fc 100644 --- a/packages/pn-personafisica-login/CHANGELOG.md +++ b/packages/pn-personafisica-login/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [2.11.1](https://github.com/pagopa/pn-frontend/compare/v2.11.0...v2.11.1) (2025-01-31) + +**Note:** Version bump only for package @pagopa-pn/pn-personafisica-login + + + + + # [2.11.0](https://github.com/pagopa/pn-frontend/compare/v2.11.0-RC.2...v2.11.0) (2025-01-20) **Note:** Version bump only for package @pagopa-pn/pn-personafisica-login diff --git a/packages/pn-personafisica-login/package.json b/packages/pn-personafisica-login/package.json index 32ade8a655..61e0a85d9f 100644 --- a/packages/pn-personafisica-login/package.json +++ b/packages/pn-personafisica-login/package.json @@ -1,7 +1,7 @@ { "name": "@pagopa-pn/pn-personafisica-login", "description": "Pagina di login di SEND per il cittadino", - "version": "2.11.0", + "version": "2.11.1", "private": true, "homepage": "auth", "dependencies": { @@ -67,7 +67,7 @@ "@typescript-eslint/parser": "^6.7.3", "@vitejs/plugin-basic-ssl": "^1.1.0", "@vitejs/plugin-react": "^4.2.1", - "@vitest/coverage-v8": "^1.3.1", + "@vitest/coverage-v8": "^1.6.1", "eslint": "7.11.0", "eslint-config-prettier": "^8.10.0", "eslint-plugin-functional": "^3.7.2", @@ -79,7 +79,7 @@ "prettier": "^2.8.8", "sonarqube-scanner": "^3.3.0", "vite": "^5.1.4", - "vitest": "^1.3.1", + "vitest": "^1.6.1", "vitest-sonar-reporter": "^2.0.0" } } diff --git a/packages/pn-personafisica-login/src/pages/login/Login.tsx b/packages/pn-personafisica-login/src/pages/login/Login.tsx index acbb2bd839..cf44eed5e0 100644 --- a/packages/pn-personafisica-login/src/pages/login/Login.tsx +++ b/packages/pn-personafisica-login/src/pages/login/Login.tsx @@ -59,10 +59,6 @@ const Login = () => { }); }; - if (showIDPS) { - return setShowIDPS(false)} />; - } - const changeLanguageHandler = async (langCode: string) => { await i18n.changeLanguage(langCode); }; @@ -72,6 +68,10 @@ const Login = () => { window.location.href = `mailto:${PAGOPA_HELP_EMAIL}`; }; + const closeIDPS = () => { + setShowIDPS(false); + }; + return ( { + ); }; diff --git a/packages/pn-personafisica-login/src/pages/login/SpidSelect.tsx b/packages/pn-personafisica-login/src/pages/login/SpidSelect.tsx index 3e71bc7195..44e63dc30f 100644 --- a/packages/pn-personafisica-login/src/pages/login/SpidSelect.tsx +++ b/packages/pn-personafisica-login/src/pages/login/SpidSelect.tsx @@ -1,7 +1,7 @@ import { Trans, useTranslation } from 'react-i18next'; import ClearOutlinedIcon from '@mui/icons-material/ClearOutlined'; -import { IconButton } from '@mui/material'; +import { Dialog, DialogContent, IconButton } from '@mui/material'; import Button from '@mui/material/Button'; import Grid from '@mui/material/Grid'; import Icon from '@mui/material/Icon'; @@ -15,7 +15,7 @@ import { IdentityProvider, getIDPS } from '../../utility/IDPS'; import PFLoginEventStrategyFactory from '../../utility/MixpanelUtils/PFLoginEventStrategyFactory'; import { shuffleList } from '../../utility/utils'; -const SpidSelect = ({ onBack }: { onBack: () => void }) => { +const SpidSelect = ({ show, onClose }: { show: boolean; onClose: () => void }) => { const { URL_API_LOGIN, SPID_TEST_ENV_ENABLED, SPID_VALIDATOR_ENV_ENABLED } = getConfiguration(); const { t } = useTranslation(['login']); const IDPS = getIDPS(SPID_TEST_ENV_ENABLED, SPID_VALIDATOR_ENV_ENABLED); @@ -35,102 +35,108 @@ const SpidSelect = ({ onBack }: { onBack: () => void }) => { }; return ( - - - - - - - - - - - - - - - {t('spidSelect.title')} - - - - - {shuffledIDPS.map((IDP, i) => ( - + + + + + + + - getSPID(IDP)} - sx={{ width: '100px', padding: '0' }} - aria-label={IDP.name} + + + + + + + {t('spidSelect.title')} + + + + + {shuffledIDPS.map((IDP, i) => ( + - - - - - - ))} + getSPID(IDP)} + sx={{ width: '100px', padding: '0' }} + aria-label={IDP.name} + > + + + + + + ))} + + + + + + + {'spidSelect.hintText'} + + + + + {t('spidSelect.cancelButton')} + - - - - - {'spidSelect.hintText'} - - - - - {t('spidSelect.cancelButton')} - - - - + + ); }; diff --git a/packages/pn-personafisica-login/src/pages/login/__test__/Login.test.tsx b/packages/pn-personafisica-login/src/pages/login/__test__/Login.test.tsx index e1d5f820ad..8e44c0c0c9 100644 --- a/packages/pn-personafisica-login/src/pages/login/__test__/Login.test.tsx +++ b/packages/pn-personafisica-login/src/pages/login/__test__/Login.test.tsx @@ -2,7 +2,7 @@ import { BrowserRouter } from 'react-router-dom'; import { vi } from 'vitest'; import { AppRouteParams } from '@pagopa-pn/pn-commons'; -import { getById, queryById } from '@pagopa-pn/pn-commons/src/test-utils'; +import { getById, queryById, waitFor } from '@pagopa-pn/pn-commons/src/test-utils'; import { fireEvent, render } from '../../../__test__/test-utils'; import { getConfiguration } from '../../../services/configuration.service'; @@ -72,7 +72,7 @@ describe('test login page', () => { expect(storageAarOps.read()).toBe('fake-aar-token'); }); - it('select spid login', () => { + it('select spid login', async () => { const { container } = render( @@ -80,7 +80,7 @@ describe('test login page', () => { ); const spidButton = getById(container, 'spidButton'); fireEvent.click(spidButton!); - const spidSelect = getById(container, 'spidSelect'); + const spidSelect = await waitFor(() => document.querySelector('#spidSelect')); expect(spidSelect).toBeInTheDocument(); }); diff --git a/packages/pn-personafisica-login/src/pages/login/__test__/SpidSelect.test.tsx b/packages/pn-personafisica-login/src/pages/login/__test__/SpidSelect.test.tsx index b52dbaf784..7e2ad0ce50 100644 --- a/packages/pn-personafisica-login/src/pages/login/__test__/SpidSelect.test.tsx +++ b/packages/pn-personafisica-login/src/pages/login/__test__/SpidSelect.test.tsx @@ -39,7 +39,8 @@ describe('test spid select page', () => { it('renders page', () => { const { URL_API_LOGIN } = getConfiguration(); - const { container } = render(); + render(); + const container = document.body; expect(container).toHaveTextContent('spidSelect.title'); const backIcon = getById(container, 'backIcon'); expect(backIcon).toBeInTheDocument(); @@ -58,8 +59,9 @@ describe('test spid select page', () => { }); it('clicks on back buttons', () => { - const { container } = render(); - const backIcon = getById(container, 'backIcon'); + render(); + const container = document.body; + const backIcon = getById(document.body, 'backIcon'); fireEvent.click(backIcon); expect(backHandler).toBeCalledTimes(1); const backButton = getById(container, 'backButton'); @@ -68,7 +70,8 @@ describe('test spid select page', () => { }); it('request spid', () => { - const { container } = render(); + render(); + const container = document.body; const requestForSpid = getById(container, 'requestForSpid'); expect(requestForSpid).toHaveAttribute('href', idps.richiediSpid); }); diff --git a/packages/pn-personafisica-webapp/CHANGELOG.md b/packages/pn-personafisica-webapp/CHANGELOG.md index 3374f6deea..696ffb393a 100644 --- a/packages/pn-personafisica-webapp/CHANGELOG.md +++ b/packages/pn-personafisica-webapp/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [2.11.1](https://github.com/pagopa/pn-frontend/compare/v2.11.0...v2.11.1) (2025-01-31) + +**Note:** Version bump only for package @pagopa-pn/pn-personafisica-webapp + + + + + # [2.11.0](https://github.com/pagopa/pn-frontend/compare/v2.11.0-RC.2...v2.11.0) (2025-01-20) **Note:** Version bump only for package @pagopa-pn/pn-personafisica-webapp diff --git a/packages/pn-personafisica-webapp/package.json b/packages/pn-personafisica-webapp/package.json index 368d2fcc11..11d4672aa4 100644 --- a/packages/pn-personafisica-webapp/package.json +++ b/packages/pn-personafisica-webapp/package.json @@ -1,7 +1,7 @@ { "name": "@pagopa-pn/pn-personafisica-webapp", "description": "SEND - Servizio Notifiche Digitali per il cittadino", - "version": "2.11.0", + "version": "2.11.1", "private": true, "dependencies": { "@emotion/react": "^11.11.1", @@ -82,7 +82,7 @@ "@typescript-eslint/parser": "^6.7.3", "@vitejs/plugin-basic-ssl": "^1.1.0", "@vitejs/plugin-react": "^4.2.1", - "@vitest/coverage-v8": "^1.3.1", + "@vitest/coverage-v8": "^1.6.1", "axios-mock-adapter": "^1.22.0", "eslint": "7.11.0", "eslint-config-prettier": "^8.10.0", @@ -95,7 +95,7 @@ "prettier": "^2.8.8", "sonarqube-scanner": "^3.3.0", "vite": "^5.1.4", - "vitest": "^1.3.1", + "vitest": "^1.6.1", "vitest-sonar-reporter": "^2.0.0" } } diff --git a/packages/pn-personafisica-webapp/public/locales/de/deleghe.json b/packages/pn-personafisica-webapp/public/locales/de/deleghe.json index 18b30d8067..a114e129ee 100644 --- a/packages/pn-personafisica-webapp/public/locales/de/deleghe.json +++ b/packages/pn-personafisica-webapp/public/locales/de/deleghe.json @@ -42,7 +42,8 @@ "notificationsFrom": "Zustellungen von:", "allNotifications": "Alle Zustellungen", "active": "Aktivieren", - "pending": "Wartet auf Bestätigung" + "pending": "Wartet auf Bestätigung", + "menu-aria-label": "Aktionsmenü" } }, "nuovaDelega": { diff --git a/packages/pn-personafisica-webapp/public/locales/en/deleghe.json b/packages/pn-personafisica-webapp/public/locales/en/deleghe.json index 2291612e6c..dbe3a27063 100644 --- a/packages/pn-personafisica-webapp/public/locales/en/deleghe.json +++ b/packages/pn-personafisica-webapp/public/locales/en/deleghe.json @@ -42,7 +42,8 @@ "notificationsFrom": "Notifications from:", "allNotifications": "All notifications", "active": "Active", - "pending": "Awaiting confirmation" + "pending": "Awaiting confirmation", + "menu-aria-label": "Actions menu" } }, "nuovaDelega": { diff --git a/packages/pn-personafisica-webapp/public/locales/fr/deleghe.json b/packages/pn-personafisica-webapp/public/locales/fr/deleghe.json index 6853ce8ece..f782ee7735 100644 --- a/packages/pn-personafisica-webapp/public/locales/fr/deleghe.json +++ b/packages/pn-personafisica-webapp/public/locales/fr/deleghe.json @@ -42,7 +42,8 @@ "notificationsFrom": "Notifications de :", "allNotifications": "Toutes les notifications", "active": "Activer", - "pending": "En attente de confirmation" + "pending": "En attente de confirmation", + "menu-aria-label": "Menu actions" } }, "nuovaDelega": { diff --git a/packages/pn-personafisica-webapp/public/locales/it/common.json b/packages/pn-personafisica-webapp/public/locales/it/common.json index 017e3520af..7f38bd5bd3 100644 --- a/packages/pn-personafisica-webapp/public/locales/it/common.json +++ b/packages/pn-personafisica-webapp/public/locales/it/common.json @@ -31,7 +31,8 @@ }, "header": { "logout": "Esci", - "pago-pa-link": "Sito di PagoPA S.p.A." + "pago-pa-link": "Sito di PagoPA S.p.A.", + "logout-message": "Confermi di voler uscire da SEND?" }, "tos": { "title": "SEND - Servizio Notifiche Digitali", @@ -192,5 +193,10 @@ "message": "Il testo originario di questi documenti è in lingua italiana. In caso di contrasto tra la versione italiana e le traduzioni in altre lingue, prevarranno il significato e le condizioni della lingua italiana.", "link": "Consulta le traduzioni" }, - "no-spaces-at-edges": "Elimina gli spazi all'inizio o alla fine" + "no-spaces-at-edges": "Elimina gli spazi all'inizio o alla fine", + "inactivity": { + "title": "Vuoi davvero uscire da SEND?", + "body": "La disconnessione è in corso. Se hai cambiato idea premi “Mantieni l’accesso” entro pochi secondi.", + "action": "Mantieni l’accesso" + } } diff --git a/packages/pn-personafisica-webapp/public/locales/it/deleghe.json b/packages/pn-personafisica-webapp/public/locales/it/deleghe.json index 1258d3dbc3..fe71397ff4 100644 --- a/packages/pn-personafisica-webapp/public/locales/it/deleghe.json +++ b/packages/pn-personafisica-webapp/public/locales/it/deleghe.json @@ -42,7 +42,8 @@ "notificationsFrom": "Notifiche da:", "allNotifications": "Tutte le notifiche", "active": "Attiva", - "pending": "In attesa di conferma" + "pending": "In attesa di conferma", + "menu-aria-label": "Menù azioni" } }, "nuovaDelega": { diff --git a/packages/pn-personafisica-webapp/public/locales/sl/deleghe.json b/packages/pn-personafisica-webapp/public/locales/sl/deleghe.json index 72c766c143..b1eced0a81 100644 --- a/packages/pn-personafisica-webapp/public/locales/sl/deleghe.json +++ b/packages/pn-personafisica-webapp/public/locales/sl/deleghe.json @@ -42,7 +42,8 @@ "notificationsFrom": "Obvestila od:", "allNotifications": "Vsa obvestila", "active": "Aktiviraj", - "pending": "Čakanje na potrditev" + "pending": "Čakanje na potrditev", + "menu-aria-label": "Meni dejanj" } }, "nuovaDelega": { diff --git a/packages/pn-personafisica-webapp/src/App.tsx b/packages/pn-personafisica-webapp/src/App.tsx index e35ceee655..8f00069cdb 100644 --- a/packages/pn-personafisica-webapp/src/App.tsx +++ b/packages/pn-personafisica-webapp/src/App.tsx @@ -10,7 +10,7 @@ import LogoutRoundedIcon from '@mui/icons-material/LogoutRounded'; import MailOutlineIcon from '@mui/icons-material/MailOutline'; import MarkunreadMailboxIcon from '@mui/icons-material/MarkunreadMailbox'; import SettingsIcon from '@mui/icons-material/Settings'; -import { Box } from '@mui/material'; +import { Box, Button, DialogTitle } from '@mui/material'; import { APP_VERSION, AppMessage, @@ -18,6 +18,8 @@ import { AppResponseError, AppResponseMessage, Layout, + PnDialog, + PnDialogActions, ResponseEventDispatcher, SideMenu, SideMenuItem, @@ -30,11 +32,10 @@ import { import { ProductEntity } from '@pagopa/mui-italia'; import { PFEventsType } from './models/PFEventsType'; -import { getCurrentEventTypePage } from './navigation/navigation.utility'; +import { getCurrentEventTypePage, goToLoginPortal } from './navigation/navigation.utility'; import Router from './navigation/routes'; import * as routes from './navigation/routes.const'; import { getCurrentAppStatus } from './redux/appStatus/actions'; -import { logout } from './redux/auth/actions'; import { useAppDispatch, useAppSelector } from './redux/hooks'; import { getDomicileInfo, getSidemenuInformation } from './redux/sidemenu/actions'; import { RootState } from './redux/store'; @@ -69,6 +70,7 @@ const App = () => { const dispatch = useAppDispatch(); const { t, i18n } = useTranslation(['common', 'notifiche']); const [isInitialized, setIsInitialized] = useState(false); + const [openModal, setOpenModal] = useState(false); const loggedUser = useAppSelector((state: RootState) => state.userState.user); const { tosConsent, fetchedTos, privacyConsent, fetchedPrivacy } = useAppSelector( (state: RootState) => state.userState @@ -226,7 +228,7 @@ const App = () => { }); const handleUserLogout = () => { - void dispatch(logout()); + setOpenModal(true); }; const handleEventTrackingCallbackAppCrash = (e: Error, eInfo: ErrorInfo) => { @@ -302,6 +304,25 @@ const App = () => { eventTrackingCallbackRefreshPage={handleEventTrackingCallbackRefreshPage} enableAssistanceButton={showAssistanceButton} > + + {t('header.logout-message')} + + setOpenModal(false)}> + {t('button.annulla')} + + { + sessionStorage.clear(); + goToLoginPortal(); + setOpenModal(false); + }} + > + {t('header.logout')} + + + {/* await dispatch(logout())} /> */} ({ @@ -71,7 +62,6 @@ const reduxInitialState = { describe('App', async () => { let mock: MockAdapter; let result: RenderResult; - const original = window.location; const mockOpenFn = vi.fn(); const originalOpen = window.open; @@ -152,18 +142,19 @@ describe('App', async () => { await waitFor(() => { expect(result.container).toHaveTextContent('Profile Page'); }); - Object.defineProperty(window, 'location', { - writable: true, - value: { href: '', replace: vi.fn() }, - }); + fireEvent.click(userButton!); menu = await waitFor(() => screen.getByRole('presentation')); menuItems = within(menu).getAllByRole('menuitem'); fireEvent.click(menuItems[1]); - await waitFor(() => { - expect(testStore.getState().userState.user.sessionToken).toBe(''); - }); - Object.defineProperty(window, 'location', { writable: true, value: original }); + + const logoutDialog = await waitFor(() => screen.getByTestId('dialog')); + expect(logoutDialog).toBeInTheDocument(); + const confirmLogoutButton = within(logoutDialog).getByTestId('confirm-button'); + fireEvent.click(confirmLogoutButton); + expect(sessionStorage.getItem('user')).toBeNull(); + expect(mockOpenFn).toHaveBeenCalledTimes(1); + expect(mockOpenFn).toHaveBeenCalledWith(`${LOGOUT}`, '_self'); }); it('sidemenu not included if error in API call to fetch TOS and Privacy', async () => { diff --git a/packages/pn-personafisica-webapp/src/components/Contacts/DefaultDigitalContact.tsx b/packages/pn-personafisica-webapp/src/components/Contacts/DefaultDigitalContact.tsx index f1e5c0949f..8e5ecb4a82 100644 --- a/packages/pn-personafisica-webapp/src/components/Contacts/DefaultDigitalContact.tsx +++ b/packages/pn-personafisica-webapp/src/components/Contacts/DefaultDigitalContact.tsx @@ -134,7 +134,6 @@ const DefaultDigitalContact = forwardRef<{ toggleEdit: () => void }, Props>( void }, Props>( { name: 'courtesy-contacts.sms-add', }) ); - expect(phoneButton).toBeDisabled(); + expect(phoneButton).toBeEnabled(); expect(emailInput).toHaveValue(''); const emaileButton = await waitFor(() => within(emailContact).getByRole('button', { name: 'courtesy-contacts.email-add', }) ); - expect(emaileButton).toBeDisabled(); + expect(emaileButton).toBeEnabled(); }); it('renders components - contacts', () => { diff --git a/packages/pn-personafisica-webapp/src/components/Contacts/__test__/DefaultDigitalContact.test.tsx b/packages/pn-personafisica-webapp/src/components/Contacts/__test__/DefaultDigitalContact.test.tsx index 8482787eb4..ef19bc84f0 100644 --- a/packages/pn-personafisica-webapp/src/components/Contacts/__test__/DefaultDigitalContact.test.tsx +++ b/packages/pn-personafisica-webapp/src/components/Contacts/__test__/DefaultDigitalContact.test.tsx @@ -49,7 +49,7 @@ describe('DefaultDigitalContact Component', () => { expect(input).toHaveValue(''); const button = await waitFor(() => getById(container, 'default_pec-button')); expect(button).toHaveTextContent('Button'); - expect(button).toBeDisabled(); + expect(button).toBeEnabled(); }); it('insert value', async () => { @@ -102,7 +102,7 @@ describe('DefaultDigitalContact Component', () => { expect(input).toHaveValue('not valid'); }); const button = await waitFor(() => getById(container, 'default_pec-button')); - expect(button).toBeDisabled(); + expect(button).toBeEnabled(); const errorMessage = container.querySelector(`#default_pec-helper-text`); expect(errorMessage).toBeInTheDocument(); }); @@ -221,7 +221,7 @@ describe('DefaultDigitalContact Component', () => { expect(input).toHaveValue('invalid value'); }); const newButtons = container.querySelectorAll('button'); - expect(newButtons[0]).toBeDisabled(); + expect(newButtons[0]).toBeEnabled(); }); it('remove contact', () => { diff --git a/packages/pn-personafisica-webapp/src/components/Contacts/__test__/EmailContactItem.test.tsx b/packages/pn-personafisica-webapp/src/components/Contacts/__test__/EmailContactItem.test.tsx index 21eb25902e..ee58404184 100644 --- a/packages/pn-personafisica-webapp/src/components/Contacts/__test__/EmailContactItem.test.tsx +++ b/packages/pn-personafisica-webapp/src/components/Contacts/__test__/EmailContactItem.test.tsx @@ -52,7 +52,7 @@ describe('testing EmailContactItem', () => { expect(errorMessage).toBeInTheDocument(); expect(errorMessage).toHaveTextContent('courtesy-contacts.valid-email'); const buttons = form!.querySelectorAll('button'); - expect(buttons[0]).toBeDisabled(); + expect(buttons[0]).toBeEnabled(); fireEvent.change(input!, { target: { value: '' } }); await waitFor(() => expect(input!).toHaveValue('')); expect(errorMessage).toBeInTheDocument(); @@ -76,7 +76,7 @@ describe('testing EmailContactItem', () => { await waitFor(() => { expect(input).toHaveValue(INVALID_EMAIL); }); - expect(saveButton).toBeDisabled(); + expect(saveButton).toBeEnabled(); const inputError = container.querySelector(`#default_email-helper-text`); expect(inputError).toHaveTextContent('courtesy-contacts.valid-email'); }); diff --git a/packages/pn-personafisica-webapp/src/components/Contacts/__test__/LegalContacts.test.tsx b/packages/pn-personafisica-webapp/src/components/Contacts/__test__/LegalContacts.test.tsx index 69fb92480f..4f4aecd74c 100644 --- a/packages/pn-personafisica-webapp/src/components/Contacts/__test__/LegalContacts.test.tsx +++ b/packages/pn-personafisica-webapp/src/components/Contacts/__test__/LegalContacts.test.tsx @@ -78,7 +78,7 @@ describe('LegalContacts Component', async () => { expect(pecInput).toHaveValue(''); const button = within(pecContact).getByRole('button', { name: 'button.attiva' }); await waitFor(() => { - expect(button).toBeDisabled(); + expect(button).toBeEnabled(); }); const sercqSendContact = getByTestId(`default_sercqSendContact`); expect(sercqSendContact).toBeInTheDocument(); diff --git a/packages/pn-personafisica-webapp/src/components/Contacts/__test__/PecContactItem.test.tsx b/packages/pn-personafisica-webapp/src/components/Contacts/__test__/PecContactItem.test.tsx index fdf05c09c3..d4fa771149 100644 --- a/packages/pn-personafisica-webapp/src/components/Contacts/__test__/PecContactItem.test.tsx +++ b/packages/pn-personafisica-webapp/src/components/Contacts/__test__/PecContactItem.test.tsx @@ -64,7 +64,7 @@ describe('PecContactItem component', () => { expect(errorMessage).toBeInTheDocument(); expect(errorMessage).toHaveTextContent('legal-contacts.valid-pec'); const buttons = form!.querySelectorAll('button'); - expect(buttons[0]).toBeDisabled(); + expect(buttons[0]).toBeEnabled(); fireEvent.change(input!, { target: { value: '' } }); await waitFor(() => expect(input!).toHaveValue('')); expect(errorMessage).toBeInTheDocument(); @@ -238,7 +238,7 @@ describe('PecContactItem component', () => { await waitFor(() => { expect(input).toHaveValue('invalid-pec'); }); - expect(saveButton).toBeDisabled(); + expect(saveButton).toBeEnabled(); const inputError = container.querySelector('#default_pec-helper-text'); expect(inputError).toHaveTextContent('legal-contacts.valid-pec'); }); diff --git a/packages/pn-personafisica-webapp/src/components/Contacts/__test__/SmsContactItem.test.tsx b/packages/pn-personafisica-webapp/src/components/Contacts/__test__/SmsContactItem.test.tsx index 824b34da98..dd0c9b9e1b 100644 --- a/packages/pn-personafisica-webapp/src/components/Contacts/__test__/SmsContactItem.test.tsx +++ b/packages/pn-personafisica-webapp/src/components/Contacts/__test__/SmsContactItem.test.tsx @@ -55,7 +55,7 @@ describe('test SmsContactItem', () => { expect(errorMessage).toBeInTheDocument(); expect(errorMessage).toHaveTextContent('courtesy-contacts.valid-sms'); const buttons = form!.querySelectorAll('button'); - expect(buttons[0]).toBeDisabled(); + expect(buttons[0]).toBeEnabled(); fireEvent.change(input!, { target: { value: '' } }); await waitFor(() => { expect(input!).toHaveValue(''); @@ -81,7 +81,7 @@ describe('test SmsContactItem', () => { await waitFor(() => { expect(input).toHaveValue(INPUT_INVALID_PHONE); }); - expect(saveButton).toBeDisabled(); + expect(saveButton).toBeEnabled(); const inputError = container.querySelector(`#default_sms-helper-text`); expect(inputError).toHaveTextContent('courtesy-contacts.valid-sms'); }); diff --git a/packages/pn-personafisica-webapp/src/components/Deleghe/Delegates.tsx b/packages/pn-personafisica-webapp/src/components/Deleghe/Delegates.tsx index d836b1a5b0..94b6f4aa74 100644 --- a/packages/pn-personafisica-webapp/src/components/Deleghe/Delegates.tsx +++ b/packages/pn-personafisica-webapp/src/components/Deleghe/Delegates.tsx @@ -81,12 +81,12 @@ const Delegates = () => { { id: 'visibilityIds', label: t('deleghe.table.permissions'), - cellProps: { width: '14%' }, + cellProps: { width: '20%' }, }, { id: 'status', label: t('deleghe.table.status'), - cellProps: { width: '18%' }, + cellProps: { width: '15%' }, }, { id: 'menu', @@ -140,7 +140,10 @@ const Delegates = () => { reloadAction={() => dispatch(getMandatesByDelegator())} > {rows.length > 0 ? ( - + {delegatesColumns.map((column) => ( { sortable={column.sortable} handleClick={handleChangeSorting} testId="delegatesTable.header.cell" + cellProps={column.cellProps} > {column.label} diff --git a/packages/pn-personafisica-webapp/src/components/Deleghe/DelegationsElements.tsx b/packages/pn-personafisica-webapp/src/components/Deleghe/DelegationsElements.tsx index 083d91ac13..6659494431 100644 --- a/packages/pn-personafisica-webapp/src/components/Deleghe/DelegationsElements.tsx +++ b/packages/pn-personafisica-webapp/src/components/Deleghe/DelegationsElements.tsx @@ -4,7 +4,7 @@ import { useTranslation } from 'react-i18next'; import MoreVertIcon from '@mui/icons-material/MoreVert'; import { Box, Button, IconButton, Menu as MUIMenu, MenuItem, Typography } from '@mui/material'; import { Variant } from '@mui/material/styles/createTypography'; -import { CustomTagGroup, useIsMobile } from '@pagopa-pn/pn-commons'; +import { CustomTagGroup } from '@pagopa-pn/pn-commons'; import { Tag } from '@pagopa/mui-italia'; import { PFEventsType } from '../../models/PFEventsType'; @@ -76,7 +76,7 @@ export const Menu = (props: any) => { id={`delegation-menu-icon-${props.id}`} onClick={handleClick} data-testid="delegationMenuIcon" - aria-label="Delegation Menu Icon" + aria-label={t('deleghe.table.menu-aria-label')} > @@ -99,7 +99,6 @@ export const OrganizationsList = (props: { visibleItems?: number; }) => { const { t } = useTranslation(['deleghe']); - const isMobile = useIsMobile(); return ( <> {props.organizations.length === 0 ? ( @@ -107,7 +106,7 @@ export const OrganizationsList = (props: { {t('deleghe.table.allNotifications')} ) : ( - + {t('deleghe.table.notificationsFrom')} diff --git a/packages/pn-personafisica-webapp/src/navigation/SessionGuard.tsx b/packages/pn-personafisica-webapp/src/navigation/SessionGuard.tsx index 733f70d2ef..51e31903be 100644 --- a/packages/pn-personafisica-webapp/src/navigation/SessionGuard.tsx +++ b/packages/pn-personafisica-webapp/src/navigation/SessionGuard.tsx @@ -62,7 +62,6 @@ const SessionGuardRender = () => { const { isUnauthorizedUser, messageUnauthorizedUser, isClosedSession } = useAppSelector( (state: RootState) => state.userState ); - const dispatch = useAppDispatch(); const { t } = useTranslation(['common']); const { hasApiErrors } = useErrors(); @@ -102,7 +101,10 @@ const SessionGuardRender = () => { return ( dispatch(logout())} + onTimerExpired={() => { + sessionStorage.clear(); + goToLoginPortal(); + }} > diff --git a/packages/pn-personagiuridica-webapp/CHANGELOG.md b/packages/pn-personagiuridica-webapp/CHANGELOG.md index 00c22cf413..e51c63efda 100644 --- a/packages/pn-personagiuridica-webapp/CHANGELOG.md +++ b/packages/pn-personagiuridica-webapp/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [2.11.1](https://github.com/pagopa/pn-frontend/compare/v2.11.0...v2.11.1) (2025-01-31) + +**Note:** Version bump only for package @pagopa-pn/pn-personagiuridica-webapp + + + + + # [2.11.0](https://github.com/pagopa/pn-frontend/compare/v2.11.0-RC.2...v2.11.0) (2025-01-20) **Note:** Version bump only for package @pagopa-pn/pn-personagiuridica-webapp diff --git a/packages/pn-personagiuridica-webapp/package.json b/packages/pn-personagiuridica-webapp/package.json index 75412f2ab1..596aefa2e3 100644 --- a/packages/pn-personagiuridica-webapp/package.json +++ b/packages/pn-personagiuridica-webapp/package.json @@ -1,7 +1,7 @@ { "name": "@pagopa-pn/pn-personagiuridica-webapp", "description": "SEND per la persona giuridica", - "version": "2.11.0", + "version": "2.11.1", "private": true, "dependencies": { "@emotion/react": "^11.11.1", @@ -82,7 +82,7 @@ "@typescript-eslint/parser": "^6.7.3", "@vitejs/plugin-basic-ssl": "^1.1.0", "@vitejs/plugin-react": "^4.2.1", - "@vitest/coverage-v8": "^1.3.1", + "@vitest/coverage-v8": "^1.6.1", "axios-mock-adapter": "^1.22.0", "eslint": "7.11.0", "eslint-config-prettier": "^8.10.0", @@ -95,7 +95,7 @@ "prettier": "^2.8.8", "sonarqube-scanner": "^3.3.0", "vite": "^5.1.4", - "vitest": "^1.3.1", + "vitest": "^1.6.1", "vitest-sonar-reporter": "^2.0.0" } } diff --git a/packages/pn-personagiuridica-webapp/public/locales/it/common.json b/packages/pn-personagiuridica-webapp/public/locales/it/common.json index 0396cf5849..7ae65a4bdc 100644 --- a/packages/pn-personagiuridica-webapp/public/locales/it/common.json +++ b/packages/pn-personagiuridica-webapp/public/locales/it/common.json @@ -39,6 +39,7 @@ "organization-dashboard": "La tua impresa", "notification-platform": "SEND - Servizio Notifiche Digitali" }, + "logout-message": "Confermi di voler uscire da SEND?", "logout": "Esci", "pago-pa-link": "Sito di PagoPA S.p.A." }, @@ -205,5 +206,10 @@ "message": "Il testo originario di questi documenti è in lingua italiana. In caso di contrasto tra la versione italiana e le traduzioni in altre lingue, prevarranno il significato e le condizioni della lingua italiana.", "link": "Consulta le traduzioni" }, - "no-spaces-at-edges": "Elimina gli spazi all'inizio o alla fine" + "no-spaces-at-edges": "Elimina gli spazi all'inizio o alla fine", + "inactivity": { + "title": "Vuoi davvero uscire da SEND?", + "body": "La disconnessione è in corso. Se hai cambiato idea premi “Mantieni l’accesso” entro pochi secondi.", + "action": "Mantieni l’accesso" + } } diff --git a/packages/pn-personagiuridica-webapp/src/App.tsx b/packages/pn-personagiuridica-webapp/src/App.tsx index b456e312b1..12560ed691 100644 --- a/packages/pn-personagiuridica-webapp/src/App.tsx +++ b/packages/pn-personagiuridica-webapp/src/App.tsx @@ -10,12 +10,14 @@ import HelpIcon from '@mui/icons-material/Help'; import MailOutlineIcon from '@mui/icons-material/MailOutline'; import MarkunreadMailboxIcon from '@mui/icons-material/MarkunreadMailbox'; import SettingsEthernet from '@mui/icons-material/SettingsEthernet'; -import { Box } from '@mui/material'; +import { Box, Button, DialogTitle } from '@mui/material'; import { APP_VERSION, AppMessage, AppResponseMessage, Layout, + PnDialog, + PnDialogActions, ResponseEventDispatcher, SideMenu, SideMenuItem, @@ -31,7 +33,6 @@ import { PartyEntity, ProductEntity } from '@pagopa/mui-italia'; import Router from './navigation/routes'; import * as routes from './navigation/routes.const'; import { getCurrentAppStatus } from './redux/appStatus/actions'; -import { logout } from './redux/auth/actions'; import { PNRole } from './redux/auth/types'; import { getDigitalAddresses } from './redux/contact/actions'; import { useAppDispatch, useAppSelector } from './redux/hooks'; @@ -40,6 +41,7 @@ import { RootState } from './redux/store'; import { getConfiguration } from './services/configuration.service'; import { PGAppErrorFactory } from './utility/AppError/PGAppErrorFactory'; import './utility/onetrust'; +import { goToLoginPortal } from './navigation/navigation.utility'; // Cfr. PN-6096 // -------------------- @@ -69,6 +71,7 @@ const ActualApp = () => { getConfiguration(); const dispatch = useAppDispatch(); const { t, i18n } = useTranslation(['common', 'notifiche']); + const [openModal, setOpenModal] = useState(false); const loggedUser = useAppSelector((state: RootState) => state.userState.user); const { tosConsent, fetchedTos, privacyConsent, fetchedPrivacy } = useAppSelector( (state: RootState) => state.userState @@ -258,7 +261,7 @@ const ActualApp = () => { }); const handleUserLogout = () => { - void dispatch(logout()); + setOpenModal(true); }; return ( @@ -292,6 +295,29 @@ const ActualApp = () => { isLogged={!!sessionToken} hasTermsOfService={true} > + + {t("header.logout-message")} + + setOpenModal(false)} + > + {t("button.annulla")} + + { + sessionStorage.clear(); + goToLoginPortal(); + setOpenModal(false); + }} + > + {t("header.logout")} + + + {/* await dispatch(logout())} /> */} diff --git a/packages/pn-personagiuridica-webapp/src/components/Contacts/DefaultDigitalContact.tsx b/packages/pn-personagiuridica-webapp/src/components/Contacts/DefaultDigitalContact.tsx index 90c6fcb579..3b9637e23a 100644 --- a/packages/pn-personagiuridica-webapp/src/components/Contacts/DefaultDigitalContact.tsx +++ b/packages/pn-personagiuridica-webapp/src/components/Contacts/DefaultDigitalContact.tsx @@ -134,7 +134,6 @@ const DefaultDigitalContact = forwardRef<{ toggleEdit: () => void }, Props>( void }, Props>( { name: 'courtesy-contacts.sms-add', }) ); - expect(phoneButton).toBeDisabled(); + expect(phoneButton).toBeEnabled(); expect(emailInput).toHaveValue(''); const emaileButton = await waitFor(() => within(emailContact).getByRole('button', { name: 'courtesy-contacts.email-add', }) ); - expect(emaileButton).toBeDisabled(); + expect(emaileButton).toBeEnabled(); }); it('renders components - contacts', async () => { diff --git a/packages/pn-personagiuridica-webapp/src/components/Contacts/__test__/DefaultDigitalContact.test.tsx b/packages/pn-personagiuridica-webapp/src/components/Contacts/__test__/DefaultDigitalContact.test.tsx index 8482787eb4..ef19bc84f0 100644 --- a/packages/pn-personagiuridica-webapp/src/components/Contacts/__test__/DefaultDigitalContact.test.tsx +++ b/packages/pn-personagiuridica-webapp/src/components/Contacts/__test__/DefaultDigitalContact.test.tsx @@ -49,7 +49,7 @@ describe('DefaultDigitalContact Component', () => { expect(input).toHaveValue(''); const button = await waitFor(() => getById(container, 'default_pec-button')); expect(button).toHaveTextContent('Button'); - expect(button).toBeDisabled(); + expect(button).toBeEnabled(); }); it('insert value', async () => { @@ -102,7 +102,7 @@ describe('DefaultDigitalContact Component', () => { expect(input).toHaveValue('not valid'); }); const button = await waitFor(() => getById(container, 'default_pec-button')); - expect(button).toBeDisabled(); + expect(button).toBeEnabled(); const errorMessage = container.querySelector(`#default_pec-helper-text`); expect(errorMessage).toBeInTheDocument(); }); @@ -221,7 +221,7 @@ describe('DefaultDigitalContact Component', () => { expect(input).toHaveValue('invalid value'); }); const newButtons = container.querySelectorAll('button'); - expect(newButtons[0]).toBeDisabled(); + expect(newButtons[0]).toBeEnabled(); }); it('remove contact', () => { diff --git a/packages/pn-personagiuridica-webapp/src/components/Contacts/__test__/EmailContactItem.test.tsx b/packages/pn-personagiuridica-webapp/src/components/Contacts/__test__/EmailContactItem.test.tsx index baeca3a138..081ef2c34e 100644 --- a/packages/pn-personagiuridica-webapp/src/components/Contacts/__test__/EmailContactItem.test.tsx +++ b/packages/pn-personagiuridica-webapp/src/components/Contacts/__test__/EmailContactItem.test.tsx @@ -52,7 +52,7 @@ describe('testing EmailContactItem', () => { expect(errorMessage).toBeInTheDocument(); expect(errorMessage).toHaveTextContent('courtesy-contacts.valid-email'); const buttons = form!.querySelectorAll('button'); - expect(buttons[0]).toBeDisabled(); + expect(buttons[0]).toBeEnabled(); fireEvent.change(input!, { target: { value: '' } }); await waitFor(() => expect(input!).toHaveValue('')); expect(errorMessage).toBeInTheDocument(); @@ -80,7 +80,7 @@ describe('testing EmailContactItem', () => { await waitFor(() => { expect(input).toHaveValue(INVALID_EMAIL); }); - expect(saveButton).toBeDisabled(); + expect(saveButton).toBeEnabled(); const inputError = container.querySelector(`#default_email-helper-text`); expect(inputError).toHaveTextContent('courtesy-contacts.valid-email'); }); diff --git a/packages/pn-personagiuridica-webapp/src/components/Contacts/__test__/LegalContacts.test.tsx b/packages/pn-personagiuridica-webapp/src/components/Contacts/__test__/LegalContacts.test.tsx index 3abdcc6be5..e3a2e46b57 100644 --- a/packages/pn-personagiuridica-webapp/src/components/Contacts/__test__/LegalContacts.test.tsx +++ b/packages/pn-personagiuridica-webapp/src/components/Contacts/__test__/LegalContacts.test.tsx @@ -77,7 +77,7 @@ describe('LegalContacts Component', async () => { expect(pecInput).toHaveValue(''); const button = within(pecContact).getByRole('button', { name: 'button.attiva' }); await waitFor(() => { - expect(button).toBeDisabled(); + expect(button).toBeEnabled(); }); const sercqSendContact = getByTestId(`default_sercqSendContact`); expect(sercqSendContact).toBeInTheDocument(); diff --git a/packages/pn-personagiuridica-webapp/src/components/Contacts/__test__/PecContactItem.test.tsx b/packages/pn-personagiuridica-webapp/src/components/Contacts/__test__/PecContactItem.test.tsx index 20addd5986..8197b53463 100644 --- a/packages/pn-personagiuridica-webapp/src/components/Contacts/__test__/PecContactItem.test.tsx +++ b/packages/pn-personagiuridica-webapp/src/components/Contacts/__test__/PecContactItem.test.tsx @@ -64,7 +64,7 @@ describe('PecContactItem component', () => { expect(errorMessage).toBeInTheDocument(); expect(errorMessage).toHaveTextContent('legal-contacts.valid-pec'); const buttons = form!.querySelectorAll('button'); - expect(buttons[0]).toBeDisabled(); + expect(buttons[0]).toBeEnabled(); fireEvent.change(input!, { target: { value: '' } }); await waitFor(() => expect(input!).toHaveValue('')); expect(errorMessage).toBeInTheDocument(); @@ -238,7 +238,7 @@ describe('PecContactItem component', () => { await waitFor(() => { expect(input).toHaveValue('invalid-pec'); }); - expect(saveButton).toBeDisabled(); + expect(saveButton).toBeEnabled(); const inputError = container.querySelector('#default_pec-helper-text'); expect(inputError).toHaveTextContent('legal-contacts.valid-pec'); }); diff --git a/packages/pn-personagiuridica-webapp/src/components/Contacts/__test__/SmsContactItem.test.tsx b/packages/pn-personagiuridica-webapp/src/components/Contacts/__test__/SmsContactItem.test.tsx index cead8ed58e..ec8992600e 100644 --- a/packages/pn-personagiuridica-webapp/src/components/Contacts/__test__/SmsContactItem.test.tsx +++ b/packages/pn-personagiuridica-webapp/src/components/Contacts/__test__/SmsContactItem.test.tsx @@ -55,7 +55,7 @@ describe('test SmsContactItem', () => { expect(errorMessage).toBeInTheDocument(); expect(errorMessage).toHaveTextContent('courtesy-contacts.valid-sms'); const buttons = form!.querySelectorAll('button'); - expect(buttons[0]).toBeDisabled(); + expect(buttons[0]).toBeEnabled(); fireEvent.change(input!, { target: { value: '' } }); await waitFor(() => { expect(input!).toHaveValue(''); @@ -85,7 +85,7 @@ describe('test SmsContactItem', () => { await waitFor(() => { expect(input).toHaveValue(INPUT_INVALID_PHONE); }); - expect(saveButton).toBeDisabled(); + expect(saveButton).toBeEnabled(); const inputError = container.querySelector(`#default_sms-helper-text`); expect(inputError).toHaveTextContent('courtesy-contacts.valid-sms'); }); diff --git a/packages/pn-personagiuridica-webapp/src/components/Deleghe/DelegatesByCompany.tsx b/packages/pn-personagiuridica-webapp/src/components/Deleghe/DelegatesByCompany.tsx index 3c1b48e366..dce49f1402 100644 --- a/packages/pn-personagiuridica-webapp/src/components/Deleghe/DelegatesByCompany.tsx +++ b/packages/pn-personagiuridica-webapp/src/components/Deleghe/DelegatesByCompany.tsx @@ -98,7 +98,7 @@ const DelegatesByCompany = () => { id: 'visibilityIds', label: t('deleghe.table.permissions'), tableConfiguration: { - cellProps: { width: '11%' }, + cellProps: { width: '20%' }, }, cardConfiguration: { wrapValueInTypography: false, @@ -108,7 +108,7 @@ const DelegatesByCompany = () => { id: 'status', label: t('deleghe.table.status'), tableConfiguration: { - cellProps: { width: '18%' }, + cellProps: { width: '15%' }, }, cardConfiguration: { position: 'left', @@ -178,6 +178,7 @@ const DelegatesByCompany = () => { currentSort={sort} onChangeSorting={setSort} testId="delegatesTable" + slotProps={{ table: { sx: { tableLayout: 'fixed' } } }} > {delegatesColumn.map((column) => ( @@ -185,6 +186,7 @@ const DelegatesByCompany = () => { key={column.id.toString()} columnId={column.id} sortable={column.tableConfiguration.sortable} + cellProps={column.tableConfiguration.cellProps} > {column.label} diff --git a/packages/pn-personagiuridica-webapp/src/components/Deleghe/DelegationsElements.tsx b/packages/pn-personagiuridica-webapp/src/components/Deleghe/DelegationsElements.tsx index 5ffb78d3ef..37f165d122 100644 --- a/packages/pn-personagiuridica-webapp/src/components/Deleghe/DelegationsElements.tsx +++ b/packages/pn-personagiuridica-webapp/src/components/Deleghe/DelegationsElements.tsx @@ -11,7 +11,6 @@ import { CustomTagGroup, Row, appStateActions, - useIsMobile, } from '@pagopa-pn/pn-commons'; import { Tag } from '@pagopa/mui-italia'; import { AnyAction } from '@reduxjs/toolkit'; @@ -294,7 +293,6 @@ export const OrganizationsList: React.FC = ({ visibleItems, }) => { const { t } = useTranslation(['deleghe']); - const isMobile = useIsMobile(); return ( <> @@ -303,7 +301,7 @@ export const OrganizationsList: React.FC = ({ {t('deleghe.table.allNotifications')} ) : ( - + {t('deleghe.table.notificationsFrom')} diff --git a/packages/pn-personagiuridica-webapp/src/navigation/SessionGuard.tsx b/packages/pn-personagiuridica-webapp/src/navigation/SessionGuard.tsx index 23ce442658..e1b210b9ce 100644 --- a/packages/pn-personagiuridica-webapp/src/navigation/SessionGuard.tsx +++ b/packages/pn-personagiuridica-webapp/src/navigation/SessionGuard.tsx @@ -44,6 +44,7 @@ const manageUnforbiddenError = (e: any) => { return true; }; + // Perché ci sono due componenti. // Il codice in SessionGuard implementa i steps necessari per determinare se c'è sessione, se è utente abilitato, se è sessione anonima, ecc.. // D'altra parte, SessionGuardRender implementa la logica di cosa si deve renderizzare, @@ -56,14 +57,14 @@ const manageUnforbiddenError = (e: any) => { */ const SessionGuardRender = () => { const [params] = useSearchParams(); - const { IS_INACTIVITY_HANDLER_ENABLED } = getConfiguration(); + const isInitialized = useAppSelector((state: RootState) => state.appState.isInitialized); const { sessionToken } = useAppSelector((state: RootState) => state.userState.user); const { isUnauthorizedUser, messageUnauthorizedUser, isClosedSession } = useAppSelector( (state: RootState) => state.userState ); - const dispatch = useAppDispatch(); + const { t } = useTranslation(['common']); const { hasApiErrors } = useErrors(); @@ -110,7 +111,10 @@ const SessionGuardRender = () => { return ( dispatch(logout())} + onTimerExpired={() => { + sessionStorage.clear(); + goToLoginPortal(); + }} > diff --git a/packages/pn-validator/CHANGELOG.md b/packages/pn-validator/CHANGELOG.md index b34cb08fd8..c79d77de62 100644 --- a/packages/pn-validator/CHANGELOG.md +++ b/packages/pn-validator/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [2.11.1](https://github.com/pagopa/pn-frontend/compare/v2.11.0...v2.11.1) (2025-01-31) + +**Note:** Version bump only for package @pagopa-pn/pn-validator + + + + + # [2.11.0](https://github.com/pagopa/pn-frontend/compare/v2.11.0-RC.2...v2.11.0) (2025-01-20) **Note:** Version bump only for package @pagopa-pn/pn-validator diff --git a/packages/pn-validator/package.json b/packages/pn-validator/package.json index 93a8056d33..db534f7ae0 100644 --- a/packages/pn-validator/package.json +++ b/packages/pn-validator/package.json @@ -1,6 +1,6 @@ { "name": "@pagopa-pn/pn-validator", - "version": "2.11.0", + "version": "2.11.1", "private": true, "main": "./src/index.ts", "dependencies": { @@ -21,14 +21,14 @@ "@trivago/prettier-plugin-sort-imports": "^4.3.0", "@typescript-eslint/eslint-plugin": "^6.7.3", "@typescript-eslint/parser": "^6.7.3", - "@vitest/coverage-v8": "^1.3.1", + "@vitest/coverage-v8": "^1.6.1", "eslint": "7.11.0", "eslint-config-prettier": "^8.10.0", "eslint-plugin-functional": "^3.7.2", "eslint-plugin-import": "^2.25.3", "eslint-plugin-sonarjs": "^0.10.0", "sonarqube-scanner": "^3.3.0", - "vitest": "^1.3.1", + "vitest": "^1.6.1", "vitest-sonar-reporter": "^2.0.0" } } diff --git a/yarn.lock b/yarn.lock index 650bd2aa42..d24408909b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7,7 +7,7 @@ resolved "https://registry.yarnpkg.com/@adobe/css-tools/-/css-tools-4.3.3.tgz#90749bde8b89cd41764224f5aac29cd4138f75ff" integrity sha512-rE0Pygv0sEZ4vBWHlAgJLGDU7Pm8xoO6p3wsEceb7GYAjScrOHpEo8KK/eVkAcnSM+slAEtXjA2JpdjLp4fJQQ== -"@ampproject/remapping@^2.2.0", "@ampproject/remapping@^2.2.1": +"@ampproject/remapping@^2.2.0": version "2.2.1" resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.1.tgz#99e8e11851128b8702cd57c33684f1d0f260b630" integrity sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg== @@ -15,6 +15,14 @@ "@jridgewell/gen-mapping" "^0.3.0" "@jridgewell/trace-mapping" "^0.3.9" +"@ampproject/remapping@^2.2.1": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.3.0.tgz#ed441b6fa600072520ce18b43d2c8cc8caecc7f4" + integrity sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw== + dependencies: + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.24" + "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4": version "7.16.7" resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz" @@ -437,6 +445,11 @@ resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz#9478c707febcbbe1ddb38a3d91a2e054ae622d83" integrity sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ== +"@babel/helper-string-parser@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz#1aabb72ee72ed35789b4bbcad3ca2862ce614e8c" + integrity sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA== + "@babel/helper-validator-identifier@^7.16.7": version "7.16.7" resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz" @@ -457,6 +470,11 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz#9544ef6a33999343c8740fa51350f30eeaaaf193" integrity sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ== +"@babel/helper-validator-identifier@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz#24b64e2c3ec7cd3b3c547729b8d16871f22cbdc7" + integrity sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ== + "@babel/helper-validator-option@^7.22.15": version "7.22.15" resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz#694c30dfa1d09a6534cdfcafbe56789d36aba040" @@ -579,11 +597,18 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.22.7.tgz#df8cf085ce92ddbdbf668a7f186ce848c9036cae" integrity sha512-7NF8pOkHP5o2vpmGgNGcfAeCvOYhGLyA3Z4eBQkT1RJlWu47n63bCs93QfJ2hIAFCil7L5P2IWhs1oToVgrL0Q== -"@babel/parser@^7.23.6", "@babel/parser@^7.24.0": +"@babel/parser@^7.24.0": version "7.24.0" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.24.0.tgz#26a3d1ff49031c53a97d03b604375f028746a9ac" integrity sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg== +"@babel/parser@^7.25.4": + version "7.26.7" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.26.7.tgz#e114cd099e5f7d17b05368678da0fb9f69b3385c" + integrity sha512-kEvgGGgEjRUutvdVvZhbn/BxVt+5VSpwXz1j3WYXQbXDo8KzFOPNG2GQbdAiNq8g6wn1yKk7C/qrke03a84V+w== + dependencies: + "@babel/types" "^7.26.7" + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.22.15": version "7.22.15" resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.22.15.tgz#02dc8a03f613ed5fdc29fb2f728397c78146c962" @@ -1484,9 +1509,17 @@ "@babel/helper-validator-identifier" "^7.22.20" to-fast-properties "^2.0.0" +"@babel/types@^7.25.4", "@babel/types@^7.26.7": + version "7.26.7" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.26.7.tgz#5e2b89c0768e874d4d061961f3a5a153d71dc17a" + integrity sha512-t8kDRGrKXyp6+tjUh7hw2RLyclsW4TRoRvRHtSyAX9Bb5ldlFh+90YAYY6awRXrlB4G5G2izNeGySpATlFzmOg== + dependencies: + "@babel/helper-string-parser" "^7.25.9" + "@babel/helper-validator-identifier" "^7.25.9" + "@bcoe/v8-coverage@^0.2.3": version "0.2.3" - resolved "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz" + resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== "@date-io/core@^2.15.0": @@ -1844,7 +1877,7 @@ "@istanbuljs/schema@^0.1.2": version "0.1.3" - resolved "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz" + resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== "@jest/expect-utils@^29.7.0": @@ -1882,6 +1915,15 @@ "@jridgewell/sourcemap-codec" "^1.4.10" "@jridgewell/trace-mapping" "^0.3.9" +"@jridgewell/gen-mapping@^0.3.5": + version "0.3.8" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz#4f0e06362e01362f823d348f1872b08f666d8142" + integrity sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA== + dependencies: + "@jridgewell/set-array" "^1.2.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.24" + "@jridgewell/resolve-uri@3.1.0": version "3.1.0" resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" @@ -1897,6 +1939,11 @@ resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== +"@jridgewell/set-array@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.2.1.tgz#558fb6472ed16a4c850b889530e6b36438c49280" + integrity sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A== + "@jridgewell/sourcemap-codec@1.4.14": version "1.4.14" resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" @@ -1912,14 +1959,6 @@ resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== -"@jridgewell/trace-mapping@^0.3.12": - version "0.3.20" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz#72e45707cf240fa6b081d0366f8265b0cd10197f" - integrity sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q== - dependencies: - "@jridgewell/resolve-uri" "^3.1.0" - "@jridgewell/sourcemap-codec" "^1.4.14" - "@jridgewell/trace-mapping@^0.3.17": version "0.3.19" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz#f8a3249862f91be48d3127c3cfe992f79b4b8811" @@ -1928,6 +1967,14 @@ "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" +"@jridgewell/trace-mapping@^0.3.23", "@jridgewell/trace-mapping@^0.3.24": + version "0.3.25" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0" + integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ== + dependencies: + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" + "@jridgewell/trace-mapping@^0.3.9": version "0.3.17" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz#793041277af9073b0951a7fe0f0d8c4c98c36985" @@ -2955,11 +3002,6 @@ resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz#7739c232a1fee9b4d3ce8985f314c0c6d33549d7" integrity sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w== -"@types/istanbul-lib-coverage@^2.0.1": - version "2.0.4" - resolved "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz" - integrity sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g== - "@types/istanbul-lib-report@*": version "3.0.3" resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz#53047614ae72e19fc0401d872de3ae2b4ce350bf" @@ -3279,63 +3321,63 @@ "@types/babel__core" "^7.20.5" react-refresh "^0.14.0" -"@vitest/coverage-v8@^1.3.1": - version "1.3.1" - resolved "https://registry.yarnpkg.com/@vitest/coverage-v8/-/coverage-v8-1.3.1.tgz#cf5ed8eb5bff6658cea126d0f8fcd2872de0b59f" - integrity sha512-UuBnkSJUNE9rdHjDCPyJ4fYuMkoMtnghes1XohYa4At0MS3OQSAo97FrbwSLRshYsXThMZy1+ybD/byK5llyIg== +"@vitest/coverage-v8@^1.6.1": + version "1.6.1" + resolved "https://registry.yarnpkg.com/@vitest/coverage-v8/-/coverage-v8-1.6.1.tgz#47230491ec73aa288a92e36b75c1671b3f741d4e" + integrity sha512-6YeRZwuO4oTGKxD3bijok756oktHSIm3eczVVzNe3scqzuhLwltIF3S9ZL/vwOVIpURmU6SnZhziXXAfw8/Qlw== dependencies: "@ampproject/remapping" "^2.2.1" "@bcoe/v8-coverage" "^0.2.3" debug "^4.3.4" istanbul-lib-coverage "^3.2.2" istanbul-lib-report "^3.0.1" - istanbul-lib-source-maps "^4.0.1" + istanbul-lib-source-maps "^5.0.4" istanbul-reports "^3.1.6" magic-string "^0.30.5" magicast "^0.3.3" picocolors "^1.0.0" std-env "^3.5.0" + strip-literal "^2.0.0" test-exclude "^6.0.0" - v8-to-istanbul "^9.2.0" -"@vitest/expect@1.3.1": - version "1.3.1" - resolved "https://registry.yarnpkg.com/@vitest/expect/-/expect-1.3.1.tgz#d4c14b89c43a25fd400a6b941f51ba27fe0cb918" - integrity sha512-xofQFwIzfdmLLlHa6ag0dPV8YsnKOCP1KdAeVVh34vSjN2dcUiXYCD9htu/9eM7t8Xln4v03U9HLxLpPlsXdZw== +"@vitest/expect@1.6.1": + version "1.6.1" + resolved "https://registry.yarnpkg.com/@vitest/expect/-/expect-1.6.1.tgz#b90c213f587514a99ac0bf84f88cff9042b0f14d" + integrity sha512-jXL+9+ZNIJKruofqXuuTClf44eSpcHlgj3CiuNihUF3Ioujtmc0zIa3UJOW5RjDK1YLBJZnWBlPuqhYycLioog== dependencies: - "@vitest/spy" "1.3.1" - "@vitest/utils" "1.3.1" + "@vitest/spy" "1.6.1" + "@vitest/utils" "1.6.1" chai "^4.3.10" -"@vitest/runner@1.3.1": - version "1.3.1" - resolved "https://registry.yarnpkg.com/@vitest/runner/-/runner-1.3.1.tgz#e7f96cdf74842934782bfd310eef4b8695bbfa30" - integrity sha512-5FzF9c3jG/z5bgCnjr8j9LNq/9OxV2uEBAITOXfoe3rdZJTdO7jzThth7FXv/6b+kdY65tpRQB7WaKhNZwX+Kg== +"@vitest/runner@1.6.1": + version "1.6.1" + resolved "https://registry.yarnpkg.com/@vitest/runner/-/runner-1.6.1.tgz#10f5857c3e376218d58c2bfacfea1161e27e117f" + integrity sha512-3nSnYXkVkf3mXFfE7vVyPmi3Sazhb/2cfZGGs0JRzFsPFvAMBEcrweV1V1GsrstdXeKCTXlJbvnQwGWgEIHmOA== dependencies: - "@vitest/utils" "1.3.1" + "@vitest/utils" "1.6.1" p-limit "^5.0.0" pathe "^1.1.1" -"@vitest/snapshot@1.3.1": - version "1.3.1" - resolved "https://registry.yarnpkg.com/@vitest/snapshot/-/snapshot-1.3.1.tgz#193a5d7febf6ec5d22b3f8c5a093f9e4322e7a88" - integrity sha512-EF++BZbt6RZmOlE3SuTPu/NfwBF6q4ABS37HHXzs2LUVPBLx2QoY/K0fKpRChSo8eLiuxcbCVfqKgx/dplCDuQ== +"@vitest/snapshot@1.6.1": + version "1.6.1" + resolved "https://registry.yarnpkg.com/@vitest/snapshot/-/snapshot-1.6.1.tgz#90414451a634bb36cd539ccb29ae0d048a8c0479" + integrity sha512-WvidQuWAzU2p95u8GAKlRMqMyN1yOJkGHnx3M1PL9Raf7AQ1kwLKg04ADlCa3+OXUZE7BceOhVZiuWAbzCKcUQ== dependencies: magic-string "^0.30.5" pathe "^1.1.1" pretty-format "^29.7.0" -"@vitest/spy@1.3.1": - version "1.3.1" - resolved "https://registry.yarnpkg.com/@vitest/spy/-/spy-1.3.1.tgz#814245d46d011b99edd1c7528f5725c64e85a88b" - integrity sha512-xAcW+S099ylC9VLU7eZfdT9myV67Nor9w9zhf0mGCYJSO+zM2839tOeROTdikOi/8Qeusffvxb/MyBSOja1Uig== +"@vitest/spy@1.6.1": + version "1.6.1" + resolved "https://registry.yarnpkg.com/@vitest/spy/-/spy-1.6.1.tgz#33376be38a5ed1ecd829eb986edaecc3e798c95d" + integrity sha512-MGcMmpGkZebsMZhbQKkAf9CX5zGvjkBTqf8Zx3ApYWXr3wG+QvEu2eXWfnIIWYSJExIp4V9FCKDEeygzkYrXMw== dependencies: tinyspy "^2.2.0" -"@vitest/utils@1.3.1": - version "1.3.1" - resolved "https://registry.yarnpkg.com/@vitest/utils/-/utils-1.3.1.tgz#7b05838654557544f694a372de767fcc9594d61a" - integrity sha512-d3Waie/299qqRyHTm2DjADeTaNdNSVsnwHPWrs20JMpjh6eiVq7ggggweO8rc4arhf6rRkWuHKwvxGvejUXZZQ== +"@vitest/utils@1.6.1": + version "1.6.1" + resolved "https://registry.yarnpkg.com/@vitest/utils/-/utils-1.6.1.tgz#6d2f36cb6d866f2bbf59da854a324d6bf8040f17" + integrity sha512-jOrrUvXM4Av9ZWiG1EajNto0u96kWAhJ1LmPmJhXXQx/32MecEKd10pOLYgS2BQx1TgkGhloPU1ArDW2vvaY6g== dependencies: diff-sequences "^29.6.3" estree-walker "^3.0.3" @@ -5834,7 +5876,7 @@ html-encoding-sniffer@^4.0.0: html-escaper@^2.0.0: version "2.0.2" - resolved "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz" + resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== html-parse-stringify@^3.0.1: @@ -6409,26 +6451,12 @@ isobject@^3.0.1: resolved "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz" integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= -istanbul-lib-coverage@^3.0.0: - version "3.2.0" - resolved "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz" - integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== - -istanbul-lib-coverage@^3.2.2: +istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.2: version "3.2.2" resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz#2d166c4b0644d43a39f04bf6c2edd1e585f31756" integrity sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg== -istanbul-lib-report@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz" - integrity sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw== - dependencies: - istanbul-lib-coverage "^3.0.0" - make-dir "^3.0.0" - supports-color "^7.1.0" - -istanbul-lib-report@^3.0.1: +istanbul-lib-report@^3.0.0, istanbul-lib-report@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz#908305bac9a5bd175ac6a74489eafd0fc2445a7d" integrity sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw== @@ -6437,14 +6465,14 @@ istanbul-lib-report@^3.0.1: make-dir "^4.0.0" supports-color "^7.1.0" -istanbul-lib-source-maps@^4.0.1: - version "4.0.1" - resolved "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz" - integrity sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw== +istanbul-lib-source-maps@^5.0.4: + version "5.0.6" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz#acaef948df7747c8eb5fbf1265cb980f6353a441" + integrity sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A== dependencies: + "@jridgewell/trace-mapping" "^0.3.23" debug "^4.1.1" istanbul-lib-coverage "^3.0.0" - source-map "^0.6.1" istanbul-reports@^3.1.6: version "3.1.7" @@ -6947,15 +6975,15 @@ magic-string@^0.30.5: "@jridgewell/sourcemap-codec" "^1.4.15" magicast@^0.3.3: - version "0.3.3" - resolved "https://registry.yarnpkg.com/magicast/-/magicast-0.3.3.tgz#a15760f982deec9dabc5f314e318d7c6bddcb27b" - integrity sha512-ZbrP1Qxnpoes8sz47AM0z08U+jW6TyRgZzcWy3Ma3vDhJttwMwAFDMMQFobwdBxByBD46JYmxRzeF7w2+wJEuw== + version "0.3.5" + resolved "https://registry.yarnpkg.com/magicast/-/magicast-0.3.5.tgz#8301c3c7d66704a0771eb1bad74274f0ec036739" + integrity sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ== dependencies: - "@babel/parser" "^7.23.6" - "@babel/types" "^7.23.6" - source-map-js "^1.0.2" + "@babel/parser" "^7.25.4" + "@babel/types" "^7.25.4" + source-map-js "^1.2.0" -make-dir@3.1.0, make-dir@^3.0.0: +make-dir@3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== @@ -8872,7 +8900,7 @@ semver@7.3.8: dependencies: lru-cache "^6.0.0" -semver@7.5.4, semver@^7.0.0, semver@^7.1.1, semver@^7.2.1, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7, semver@^7.3.8, semver@^7.5.3, semver@^7.5.4: +semver@7.5.4, semver@^7.0.0, semver@^7.1.1, semver@^7.2.1, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7, semver@^7.3.8, semver@^7.5.4: version "7.5.4" resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== @@ -8884,6 +8912,11 @@ semver@^6.0.0, semver@^6.3.0, semver@^6.3.1: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== +semver@^7.5.3: + version "7.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.1.tgz#abd5098d82b18c6c81f6074ff2647fd3e7220c9f" + integrity sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA== + set-blocking@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" @@ -9020,12 +9053,7 @@ sort-keys@^2.0.0: dependencies: is-plain-obj "^1.0.0" -source-map-js@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz" - integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== - -source-map-js@^1.2.1: +source-map-js@^1.2.0, source-map-js@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46" integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA== @@ -9376,7 +9404,7 @@ tempy@1.0.0: test-exclude@^6.0.0: version "6.0.0" - resolved "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== dependencies: "@istanbuljs/schema" "^0.1.2" @@ -9423,10 +9451,10 @@ tinybench@^2.5.1: resolved "https://registry.yarnpkg.com/tinybench/-/tinybench-2.6.0.tgz#1423284ee22de07c91b3752c048d2764714b341b" integrity sha512-N8hW3PG/3aOoZAN5V/NSAEDz0ZixDSSt5b/a05iqtpgfLWMSVuCo7w0k2vVvEjdrIoeGqZzweX2WlyioNIHchA== -tinypool@^0.8.2: - version "0.8.2" - resolved "https://registry.yarnpkg.com/tinypool/-/tinypool-0.8.2.tgz#84013b03dc69dacb322563a475d4c0a9be00f82a" - integrity sha512-SUszKYe5wgsxnNOVlBYO6IC+8VGWdVGZWAqUxp3UErNBtptZvWbwyUOyzNL59zigz2rCA92QiL3wvG+JDSdJdQ== +tinypool@^0.8.3: + version "0.8.4" + resolved "https://registry.yarnpkg.com/tinypool/-/tinypool-0.8.4.tgz#e217fe1270d941b39e98c625dcecebb1408c9aa8" + integrity sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ== tinyspy@^2.2.0: version "2.2.1" @@ -9784,15 +9812,6 @@ v8-compile-cache@2.3.0, v8-compile-cache@^2.0.3: resolved "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz" integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== -v8-to-istanbul@^9.2.0: - version "9.2.0" - resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz#2ed7644a245cddd83d4e087b9b33b3e62dfd10ad" - integrity sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA== - dependencies: - "@jridgewell/trace-mapping" "^0.3.12" - "@types/istanbul-lib-coverage" "^2.0.1" - convert-source-map "^2.0.0" - validate-npm-package-license@3.0.4, validate-npm-package-license@^3.0.1, validate-npm-package-license@^3.0.4: version "3.0.4" resolved "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz" @@ -9822,10 +9841,10 @@ validate-npm-package-name@^5.0.0: dependencies: builtins "^5.0.0" -vite-node@1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/vite-node/-/vite-node-1.3.1.tgz#a93f7372212f5d5df38e945046b945ac3f4855d2" - integrity sha512-azbRrqRxlWTJEVbzInZCTchx0X69M/XPTCz4H+TLvlTcR/xH/3hkRqhOakT41fMJCMzXTu4UvegkZiEoJAWvng== +vite-node@1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/vite-node/-/vite-node-1.6.1.tgz#fff3ef309296ea03ceaa6ca4bb660922f5416c57" + integrity sha512-YAXkfvGtuTzwWbDSACdJSg4A4DZiAqckWe90Zapc/sEX3XvHcw1NdurM/6od8J207tSDqNbSsgdCacBgvJKFuA== dependencies: cac "^6.7.14" debug "^4.3.4" @@ -9856,16 +9875,16 @@ vitest-sonar-reporter@^2.0.0: resolved "https://registry.yarnpkg.com/vitest-sonar-reporter/-/vitest-sonar-reporter-2.0.0.tgz#6372e5faba2b2834eac0b2cd1283263d38d0e718" integrity sha512-LorC3NnmrBrryx4+l3BEsNQjD0Y7wfmrD1y/+tHDuZUuVj7w8nOxRXCBSppDfmgfpToOhwchh0JcL4IGMKUKDA== -vitest@1.3.1, vitest@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/vitest/-/vitest-1.3.1.tgz#2d7e9861f030d88a4669392a4aecb40569d90937" - integrity sha512-/1QJqXs8YbCrfv/GPQ05wAZf2eakUPLPa18vkJAKE7RXOKfVHqMZZ1WlTjiwl6Gcn65M5vpNUB6EFLnEdRdEXQ== - dependencies: - "@vitest/expect" "1.3.1" - "@vitest/runner" "1.3.1" - "@vitest/snapshot" "1.3.1" - "@vitest/spy" "1.3.1" - "@vitest/utils" "1.3.1" +vitest@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/vitest/-/vitest-1.6.1.tgz#b4a3097adf8f79ac18bc2e2e0024c534a7a78d2f" + integrity sha512-Ljb1cnSJSivGN0LqXd/zmDbWEM0RNNg2t1QW/XUhYl/qPqyu7CsqeWtqQXHVaJsecLPuDoak2oJcZN2QoRIOag== + dependencies: + "@vitest/expect" "1.6.1" + "@vitest/runner" "1.6.1" + "@vitest/snapshot" "1.6.1" + "@vitest/spy" "1.6.1" + "@vitest/utils" "1.6.1" acorn-walk "^8.3.2" chai "^4.3.10" debug "^4.3.4" @@ -9877,9 +9896,9 @@ vitest@1.3.1, vitest@^1.3.1: std-env "^3.5.0" strip-literal "^2.0.0" tinybench "^2.5.1" - tinypool "^0.8.2" + tinypool "^0.8.3" vite "^5.0.0" - vite-node "1.3.1" + vite-node "1.6.1" why-is-node-running "^2.2.2" void-elements@3.1.0: