Skip to content

Commit

Permalink
Merge pull request #168 from InseeFr/feat/typescript
Browse files Browse the repository at this point in the history
feat: continue the migration to TypeScript
  • Loading branch information
prwozny authored Dec 3, 2024
2 parents 30c5110 + d40e20b commit e8a0819
Show file tree
Hide file tree
Showing 67 changed files with 224 additions and 231 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"react-router-dom": "^6.21.0",
"react-swipeable-views": "^0.14.0",
"typescript": "^5.6.2",
"zod": "^3.22.4"
"zod": "^3.23.8"
},
"scripts": {
"dev": "vite",
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { createDictionary, getLang } from './build-dictionary';
import { expect, test } from 'vitest';
import { createDictionary, getLang, SupportedLocales } from './build-dictionary';

['browserLanguage', 'language'].forEach(property => {
test(`should return the french version when the navigator.${property} is FR`, () => {
Expand All @@ -10,7 +11,7 @@ import { createDictionary, getLang } from './build-dictionary';
});

test(`should return the english version the navigator.${property} is not supported`, () => {
expect(createDictionary('de').welcome).toBeUndefined();
expect(createDictionary('de' as SupportedLocales).welcome).toBeUndefined();
});
});

Expand Down
3 changes: 1 addition & 2 deletions src/i18n/build-dictionary.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ type Dictionary = Record<DictionaryKey, DictionaryValue>;
*
* @param {string} lang the lang of the user
*/
export const createDictionary = (lang: SupportedLocales) => {
export const createDictionary = (lang: SupportedLocales): Record<string, string> => {
// Set date-fns lang for French and Albanian
if (lang === 'fr') {
setDefaultOptions({ locale: fr });
Expand All @@ -34,7 +34,6 @@ export const createDictionary = (lang: SupportedLocales) => {
* For example, with fr-FR, will return fr
* If the lang is not recognized, will return en
* Now also checks for Albanian (sq)
* @param {string} lang the lang of the user
*/
export const getLang = (defaultLang?: string) => {
const lang = (defaultLang ?? navigator.language).split('-')[0];
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
14 changes: 14 additions & 0 deletions src/i18n/mailMessage.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { expect, it } from 'vitest';
import mailMessage from './mailMessage';

it('should define bodyTempZonePearl', () => {
expect(mailMessage.bodyTempZonePearl.fr('1')()).toContain(
'Les données sont de nature organisationnelle.'
);
});

it('should define bodyTempZonePearl', () => {
expect(mailMessage.bodyTempZoneQueen.fr('1')()).toContain(
'Les données sont de nature questionnaire.'
);
});
139 changes: 57 additions & 82 deletions src/i18n/mailMessage.js → src/i18n/mailMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,47 @@ const commonMailMessage = {
},
};

const bodyTempZoneFactory = ({ fr, en, sq }: { fr: string; en: string; sq: string }) => {
return {
fr:
(userId: string) =>
(tempZoneUnits = []) => {
return (
`Bonjour Madame, Monsieur. \n\n` +
`Pour information, l'utilisateur d'identifant "${userId}" n'a pas pu sauvegardé correctement certaines unités enquêtées pour un problème de droit.\n` +
`${fr}\n` +
`Les unités concernées sont : ${tempZoneUnits.join(', ')}.\n` +
`Ces unités ont donc été sauvegardées dans une zone tampon en attendant un éventuel traitement.\n\n` +
`Merci de bien en prendre notes, afin de vérifier qu'il ne s'agît pas d'une erreur.\n\n ${commonMailMessage.autoMail.fr}`
);
},
en:
(userId: string) =>
(tempZoneUnits = []) => {
return (
`Hello. \n\n` +
`For information, the user of identifier "${userId}" was not able to correctly save some of the survey-units due to a rights issue.\n` +
`${en}\n` +
`The survey-units are : ${tempZoneUnits.join(', ')}.\n` +
`These units were therefore saved in a buffer zone pending possible treatment.\n\n` +
`Please take note of it, to make sure it is not a mistake.\n\n ${commonMailMessage.autoMail.en}`
);
},
sq:
(userId: string) =>
(tempZoneUnits = []) => {
return (
`Përshëndetje. \n\n` +
`Për informacion, përdoruesi me identifikatorin "${userId}" nuk ka mundur të ruajë saktësisht disa nga njësitë hetimore për shkak të një çështje të drejtave.\n` +
`${sq}\n` +
`Njësitë hetimore janë : ${tempZoneUnits.join(', ')}.\n` +
`Këto njësi janë kështu që ruajtur në një zonë buffer deri në trajtim të mundshëm.\n\n` +
`Ju lutemi bëni shënime për këtë, për të siguruar që nuk është një gabim.\n\n ${commonMailMessage.autoMail.sq}`
);
},
};
};

const mailMessage = {
subjectPearlMissingUnits: {
fr: `${commonMailMessage.subjectTitle.fr} : Trop d'unités enquêtées`,
Expand All @@ -29,7 +70,7 @@ const mailMessage = {
},
bodyPearlMissingUnits: {
fr:
userId =>
(userId: string) =>
(pearlMissing = []) => {
return (
`Bonjour Madame, Monsieur. \n\n ` +
Expand All @@ -39,7 +80,7 @@ const mailMessage = {
);
},
en:
userId =>
(userId: string) =>
(pearlMissing = []) => {
return (
`Hello. \n\n ` +
Expand All @@ -49,7 +90,7 @@ const mailMessage = {
);
},
sq:
userId =>
(userId: string) =>
(pearlMissing = []) => {
return (
`Përshëndetje. \n\n ` +
Expand All @@ -61,7 +102,7 @@ const mailMessage = {
},
bodyQueenMissingUnits: {
fr:
userId =>
(userId: string) =>
(queenMissing = []) => {
return (
`Bonjour Madame, Monsieur. \n\n ` +
Expand All @@ -72,7 +113,7 @@ const mailMessage = {
);
},
en:
userId =>
(userId: string) =>
(queenMissing = []) => {
return (
`Hello. \n\n ` +
Expand All @@ -83,7 +124,7 @@ const mailMessage = {
);
},
sq:
userId =>
(userId: string) =>
(queenMissing = []) => {
return (
`Përshëndetje. \n\n ` +
Expand All @@ -94,82 +135,16 @@ const mailMessage = {
);
},
},
bodyTempZonePearl: {
fr:
userId =>
(tempZoneUnits = []) => {
return (
`Bonjour Madame, Monsieur. \n\n` +
`Pour information, l'utilisateur d'identifant "${userId}" n'a pas pu sauvegardé correctement certaines unités enquêtées pour un problème de droit.\n` +
`Les données sont de nature organisationnelle.\n` +
`Les unités concernées sont : ${tempZoneUnits.join(', ')}.\n` +
`Ces unités ont donc été sauvegardées dans une zone tampon en attendant un éventuel traitement.\n\n` +
`Merci de bien en prendre notes, afin de vérifier qu'il ne s'agît pas d'une erreur.\n\n ${commonMailMessage.autoMail.fr}`
);
},
en:
userId =>
(tempZoneUnits = []) => {
return (
`Hello. \n\n` +
`For information, the user of identifier "${userId}" was not able to correctly save some of the survey-units due to a rights issue.\n` +
`The data is organizational.\n` +
`The survey-units are : ${tempZoneUnits.join(', ')}.\n` +
`These units were therefore saved in a buffer zone pending possible treatment.\n\n` +
`Please take note of it, to make sure it is not a mistake.\n\n ${commonMailMessage.autoMail.en}`
);
},
sq:
userId =>
(tempZoneUnits = []) => {
return (
`Përshëndetje. \n\n` +
`Për informacion, përdoruesi me identifikatorin "${userId}" nuk ka mundur të ruajë saktësisht disa nga njësitë hetimore për shkak të një çështje të drejtave.\n` +
`Të dhënat janë organizative.\n` +
`Njësitë hetimore janë : ${tempZoneUnits.join(', ')}.\n` +
`Këto njësi janë kështu që ruajtur në një zonë buffer deri në trajtim të mundshëm.\n\n` +
`Ju lutemi bëni shënime për këtë, për të siguruar që nuk është një gabim.\n\n ${commonMailMessage.autoMail.sq}`
);
},
},
bodyTempZoneQueen: {
fr:
userId =>
(tempZoneUnits = []) => {
return (
`Bonjour Madame, Monsieur. \n\n` +
`Pour information, l'utilisateur d'identifant "${userId}" n'a pas pu sauvegardé correctement certaines unités enquêtées pour un problème de droit.\n` +
`Les données sont de nature questionnaire.\n` +
`Les unités concernées sont : ${tempZoneUnits.join(', ')}.\n` +
`Ces unités ont donc été sauvegardées dans une zone tampon en attendant un éventuel traitement.\n\n` +
`Merci de bien en prendre notes, afin de vérifier qu'il ne s'agît pas d'une erreur.\n\n ${commonMailMessage.autoMail.fr}`
);
},
en:
userId =>
(tempZoneUnits = []) => {
return (
`Hello. \n\n` +
`For information, the user of identifier "${userId}" was not able to correctly save some of the survey-units due to a rights issue.\n` +
`These are questionnaire data.\n` +
`The survey-units are : ${tempZoneUnits.join(', ')}.\n` +
`These units were therefore saved in a buffer zone pending possible treatment.\n\n` +
`Please take note of it, to make sure it is not a mistake.\n\n ${commonMailMessage.autoMail.en}`
);
},
sq:
userId =>
(tempZoneUnits = []) => {
return (
`Përshëndetje. \n\n` +
`Për informacion, përdoruesi me identifikatorin "${userId}" nuk ka mundur të ruajë saktësisht disa nga njësitë hetimore për shkak të një çështje të drejtave.\n` +
`Këto janë të dhënat e pyetësorit.\n` +
`Njësitë hetimore janë : ${tempZoneUnits.join(', ')}.\n` +
`Këto njësi janë kështu që ruajtur në një zonë buffer deri në trajtim të mundshëm.\n\n` +
`Ju lutemi bëni shënime për këtë, për të siguruar që nuk është një gabim.\n\n ${commonMailMessage.autoMail.sq}`
);
},
},
bodyTempZonePearl: bodyTempZoneFactory({
fr: 'Les données sont de nature organisationnelle.',
en: 'The data is organizational.',
sq: 'Të dhënat janë organizative.',
}),
bodyTempZoneQueen: bodyTempZoneFactory({
fr: 'Les données sont de nature questionnaire.',
en: 'These are questionnaire data.',
sq: 'Këto janë të dhënat e pyetësorit.',
}),
};

export default mailMessage;
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
7 changes: 7 additions & 0 deletions src/types/mui.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Button } from '@mui/material/Button';
import { Card } from '@mui/material/Card';
import { ScrollableBox } from '@mui/material/ScrollableBox';
import { Dialog } from '@mui/material/Dialog';
import { CircularProgressProps } from '@mui/material/CircularProgress';

// Update the Card's variant prop options
declare module '@mui/material/Card' {
Expand Down Expand Up @@ -37,3 +38,9 @@ declare module '@mui/material/Dialog' {
maxWidht: 's';
}
}

declare module '@mui/material/CircularProgress' {
interface CircularProgressPropsColorOverrides {
white: true;
}
}
3 changes: 2 additions & 1 deletion src/ui/CenteredBox.jsx → src/ui/CenteredBox.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import Box from '@mui/material/Box';
import { ComponentPropsWithoutRef } from 'react';

export function CenteredBox(props) {
export function CenteredBox(props: Readonly<ComponentPropsWithoutRef<typeof Box>>) {
return (
<Box
{...props}
Expand Down
19 changes: 19 additions & 0 deletions src/ui/Preloader.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { render, screen } from '@testing-library/react';
import { describe, it } from 'vitest';
import { PearlTheme } from './PearlTheme';
import { Preloader } from './Preloader';
import D from 'i18n';

const renderWithTheme = (ui: React.ReactElement) => render(<PearlTheme>{ui}</PearlTheme>);

describe('Preloader Component', () => {
it('renders the Preloader component correctly', () => {
const message = 'Loading data...';

renderWithTheme(<Preloader message={message} />);

screen.getByRole('heading', { name: D.pleaseWait, level: 2, hidden: true });
screen.getByRole('heading', { name: D.message, level: 3, hidden: true });
screen.getByRole('progressbar', { hidden: true });
});
});
12 changes: 6 additions & 6 deletions src/ui/Preloader.jsx → src/ui/Preloader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,19 @@ import CircularProgress from '@mui/material/CircularProgress';
import Stack from '@mui/material/Stack';
import Box from '@mui/material/Box';

/**
* @param {string} message
* @constructor
*/
export function Preloader({ message }) {
type PreloaderTypes = {
message: string;
};

export function Preloader({ message }: Readonly<PreloaderTypes>) {
return (
<Backdrop open sx={{ color: '#FFF' }}>
<Stack gap={2} alignItems="center">
<CircularProgress color="white" size="6em" />
<Box component="h2" m={0} mt={2}>
{D.pleaseWait}
</Box>
<Box component="h3" m={0} sx={{ opacity: 0.75 }} variant="m" color="textTertiary">
<Box component="h3" m={0} sx={{ opacity: 0.75 }} color="textTertiary">
{message}
</Box>
</Stack>
Expand Down
10 changes: 0 additions & 10 deletions src/ui/Row.jsx

This file was deleted.

11 changes: 11 additions & 0 deletions src/ui/Row.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import Stack from '@mui/material/Stack';
import { ComponentProps } from 'react';

/**
* A horizontal stack
*/

type RowTypes = Omit<ComponentProps<typeof Stack>, 'direction' | 'alignItems'>
export function Row(props: Readonly<RowTypes>) {
return <Stack direction="row" alignItems="center" {...props} />;
}
2 changes: 1 addition & 1 deletion src/ui/ScrollableBox.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import Box, { BoxProps } from '@mui/material/Box';
import { ComponentProps } from 'react';

type ScrollableBoxProps = {
height: string;
Expand All @@ -14,6 +13,7 @@ export function ScrollableBox({ height, ...props }: Readonly<ScrollableBoxProps>
overflow: 'auto',
marginRight: '-.5rem',
paddingRight: '.5rem',
...props.sx,
}}
/>
);
Expand Down
2 changes: 1 addition & 1 deletion src/utils/enum/ContactAttemptConfigurationEnum.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export const contactAttemptConfigurationEnum = {
F2F: 'F2F',
TEL: 'TEL',
};
} as const;
Loading

0 comments on commit e8a0819

Please sign in to comment.