Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
…into fix/PN-13257
  • Loading branch information
leleOFA committed Feb 6, 2025
2 parents 753d82e + 03fb1b7 commit 76e0d0e
Show file tree
Hide file tree
Showing 65 changed files with 684 additions and 407 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion lerna.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"packages": [
"packages/*"
],
"version": "2.11.0",
"version": "2.11.1",
"npmClient": "yarn",
"useWorkspaces": true,
"command": {
Expand Down
8 changes: 8 additions & 0 deletions packages/pn-commons/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions packages/pn-commons/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@pagopa-pn/pn-commons",
"version": "2.11.0",
"version": "2.11.1",
"private": true,
"main": "./src/index.ts",
"dependencies": {
Expand Down Expand Up @@ -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",
Expand All @@ -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"
}
}
Original file line number Diff line number Diff line change
@@ -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 = {
Expand Down Expand Up @@ -82,17 +83,19 @@ const CustomMobileDialogContent = forwardRef<{ toggleOpen: () => void }, Props>(
</Typography>
</Grid>
<Grid item xs={6} textAlign="right">
<CloseIcon
<IconButton
edge="end"
onClick={handleClose}
sx={{
position: 'relative',
right: 0,
top: 4,
color: 'action.active',
width: '32px',
height: '32px',
}}
/>
aria-label={getLocalizedOrDefaultLabel('common', 'button.close')}
>
<CloseIcon
sx={{
color: 'action.active',
width: '32px',
height: '32px',
}}
/>
</IconButton>
</Grid>
</Grid>
</DialogTitle>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,15 @@ const TagIndicator: React.FC<{
arrayChildren: Array<JSX.Element>;
visibleItems: number;
dataTestId: string;
}> = ({ boxProps, arrayChildren, visibleItems, dataTestId }) => (
<Box {...boxProps} sx={{ cursor: 'pointer', display: 'inline-block' }} data-testid={dataTestId}>
<Tag value={`+${arrayChildren.length - visibleItems}`} />
ariaLabel?: string;
}> = ({ boxProps, arrayChildren, visibleItems, dataTestId, ariaLabel }) => (
<Box
{...boxProps}
sx={{ cursor: 'pointer', display: 'inline-block' }}
data-testid={dataTestId}
aria-label={ariaLabel || undefined}
>
<Tag value={`+${arrayChildren.length - visibleItems}`} aria-hidden={!!ariaLabel} />
</Box>
);

Expand All @@ -48,14 +54,18 @@ const CustomTagGroup: React.FC<CustomTagGroupProps> = ({
onOpen={onOpen}
tooltipContent={<>{arrayChildren.slice(visibleItems).map((c) => c)}</>}
>
<div>
<Box sx={{ width: 'fit-content' }}>
<TagIndicator
boxProps={{ role: 'button' }}
arrayChildren={arrayChildren}
visibleItems={visibleItems as number}
dataTestId="custom-tooltip-indicator"
ariaLabel={arrayChildren
.slice(visibleItems)
.map((c) => c.props?.children?.props?.value) // <Box><Tag value={v}></Tag></Box>
.filter(Boolean)
.join(',')}
/>
</div>
</Box>
</CustomTooltip>
)}
{disableTooltip && (
Expand Down
Original file line number Diff line number Diff line change
@@ -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) => <Box key={i}>{v}</Box>);
const tags = tagsArray.map((v, i) => (
<Box key={i}>
<Tag value={v}></Tag>
</Box>
));
const mockCallbackFn = vi.fn();

beforeEach(() => {
Expand Down Expand Up @@ -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(
<CustomTagGroup visibleItems={2} disableTooltip={false}>
{tags}
</CustomTagGroup>
);
const tooltipIndicator = getByTestId('custom-tooltip-indicator');
expect(tooltipIndicator).toBeInTheDocument();
expect(tooltipIndicator).toHaveAttribute('aria-label', 'mock-tag-3,mock-tag-4');
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,13 @@ const PnTableHeaderCell = <T,>({
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 && (
Expand Down
70 changes: 50 additions & 20 deletions packages/pn-commons/src/components/InactivityHandler.tsx
Original file line number Diff line number Diff line change
@@ -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 */
Expand All @@ -8,43 +15,66 @@ type Props = {
children?: React.ReactNode;
};

const InactivityHandler: React.FC<Props> = ({ inactivityTimer, children, onTimerExpired }) => {
const InactivityHandler: React.FC<Props> = ({ 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 <Fragment>{children}</Fragment>;
return (
<>
<PnDialog
open={openModal}
aria-labelledby="inactivity-dialog-title"
aria-describedby="inactivity-dialog-description"
data-testid="inactivity-modal"
>
<DialogTitle id="inactivity-dialog-title">
{getLocalizedOrDefaultLabel('common', 'inactivity.title')}
</DialogTitle>
<PnDialogContent>
<DialogContentText id="inactivity-dialog-description">
{getLocalizedOrDefaultLabel('common', 'inactivity.body')}
</DialogContentText>
</PnDialogContent>
<PnDialogActions>
<Button
fullWidth
color="primary"
variant="outlined"
data-testid="inactivity-button"
onClick={resetTimer}
>
{getLocalizedOrDefaultLabel('common', 'inactivity.action')}
</Button>
</PnDialogActions>
</PnDialog>
{children}
</>
);
};

export default InactivityHandler;
2 changes: 1 addition & 1 deletion packages/pn-commons/src/components/SessionModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ const SessionModal: React.FC<Props> = ({
</PnDialogContent>
{onConfirm && (
<PnDialogActions>
<Button sx={{ width: '100%' }} color="primary" variant="contained" onClick={onConfirm}>
<Button sx={{ width: '100%' }} color="primary" variant="contained" data-testid='buttonOfSessionModal' onClick={onConfirm}>
{onConfirmLabel}
</Button>
</PnDialogActions>
Expand Down
Original file line number Diff line number Diff line change
@@ -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 = () => (
<InactivityHandler inactivityTimer={inactivityTimer} onTimerExpired={timerExpiredHandler}>
Expand All @@ -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(<Component />);
await waitFor(
() => {
expect(timerExpiredHandler).toBeCalledTimes(1);
},
{ timeout: inactivityTimer + 1000 }
);
const { container } = render(<Component />);
expect(container).toHaveTextContent('Mocked children');
await act(() => vi.advanceTimersByTime(inactivityTimer));
expect(timerExpiredHandler).toHaveBeenCalledTimes(1);
});

it('test user interaction', async () => {
// render component
const result = render(<Component />);
fireEvent.mouseMove(result.container);
await waitFor(
() => {
expect(timerExpiredHandler).toBeCalledTimes(0);
},
{ timeout: inactivityTimer + 1000 }
);
const { getByTestId } = render(<Component />);
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);
});
});
2 changes: 1 addition & 1 deletion packages/pn-commons/src/utility/costants.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
8 changes: 8 additions & 0 deletions packages/pn-data-viz/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading

0 comments on commit 76e0d0e

Please sign in to comment.