From b40bbfdb5be3c26ea4a6e8a68917cbaf2f125633 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Demazi=C3=A8re?= Date: Thu, 10 Jun 2021 11:21:10 +0200 Subject: [PATCH 01/62] add 500ms between successive state additions --- package.json | 2 +- src/common-tools/functions/surveyUnitFunctions.js | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index b16ad0e1c..40c775796 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pearl", - "version": "0.3.2", + "version": "0.3.3", "private": true, "dependencies": { "@testing-library/jest-dom": "^5.11.9", diff --git a/src/common-tools/functions/surveyUnitFunctions.js b/src/common-tools/functions/surveyUnitFunctions.js index 01d9c4691..d0432ec63 100644 --- a/src/common-tools/functions/surveyUnitFunctions.js +++ b/src/common-tools/functions/surveyUnitFunctions.js @@ -74,15 +74,16 @@ const lastContactAttemptIsSuccessfull = surveyUnit => { return CONTACT_SUCCESS_LIST.includes(lastContactAttempt.status); }; -const isContactAttemptOk = async surveyUnit => lastContactAttemptIsSuccessfull(surveyUnit); +const isContactAttemptOk = surveyUnit => lastContactAttemptIsSuccessfull(surveyUnit); const addContactState = async (surveyUnit, newState) => { switch (newState.type) { case surveyUnitStateEnum.AT_LEAST_ONE_CONTACT.type: surveyUnit.states.push(newState); - if (await isContactAttemptOk(surveyUnit)) { + if (isContactAttemptOk(surveyUnit)) { surveyUnit.states.push({ - date: new Date().getTime(), + // prevent two succesive state additions to have same timestamp + date: new Date().getTime() + 500, type: surveyUnitStateEnum.APPOINTMENT_MADE.type, }); } @@ -91,7 +92,8 @@ const addContactState = async (surveyUnit, newState) => { case surveyUnitStateEnum.APPOINTMENT_MADE.type: if (getContactAttemptNumber(surveyUnit) === 0) { surveyUnit.states.push({ - date: newState.date - 1, + // make sure the AOC state is inserted 'earlier' than APS in states + date: newState.date - 500, type: surveyUnitStateEnum.AT_LEAST_ONE_CONTACT.type, }); } From a72591b6590f82eb345ef44d6186a55e84a27446 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Demazi=C3=A8re?= Date: Thu, 1 Jul 2021 14:55:55 +0200 Subject: [PATCH 02/62] update contact enums --- src/common-tools/enum/ContactAttemptEnum.js | 10 ++++---- src/common-tools/enum/ContactOutcomEnum.js | 14 ++++++++--- src/i18n/contactAttemptMessage.js | 23 ++++++++++-------- src/i18n/contactOutcomeMessage.js | 27 ++++++++++++++++----- 4 files changed, 49 insertions(+), 25 deletions(-) diff --git a/src/common-tools/enum/ContactAttemptEnum.js b/src/common-tools/enum/ContactAttemptEnum.js index fbbb46498..1b44bb7ed 100644 --- a/src/common-tools/enum/ContactAttemptEnum.js +++ b/src/common-tools/enum/ContactAttemptEnum.js @@ -1,14 +1,14 @@ import D from 'i18n'; const contactAttempt = { - NO_CONTACT: { type: 'NOC', value: `${D.noContact}` }, INTERVIEW_ACCEPTED: { type: 'INA', value: `${D.interviewAccepted}` }, APPOINTMENT_MADE: { type: 'APT', value: `${D.appointmentMade}` }, REFUSAL: { type: 'REF', value: `${D.refusal}` }, - OCCASIONAL_ABSENCE_OF_INTERVIEWEE: { type: 'ABS', value: `${D.occasionalAbsence}` }, - INTERVIEW_IMPOSSIBLE: { type: 'INI', value: `${D.interviewImpossible}` }, - ALREADY_ANSWERED_IN_ANOTHER_MODE: { type: 'ALA', value: `${D.alreadyAnsweredAnotherMode}` }, - WISH_TO_ANSWER_IN_ANOTHER_MODE: { type: 'WAM', value: `${D.wishAnswerAnotherMode}` }, + TEMPORARY_UNAVAILABLE: { type: 'TUN', value: `${D.temporaryUnavailable}` }, + NO_CONTACT: { type: 'NOC', value: `${D.noContact}` }, + MESSAGE_SENT: { type: 'MES', value: `${D.messageSent}` }, + UNUSABLE_CONTACT_DATA: { type: 'UCD', value: `${D.unusableContactData}` }, + PERMANENTLY_UNAVAILABLE: { type: 'PUN', value: `${D.permanentlyUnavailable}` }, }; export default contactAttempt; diff --git a/src/common-tools/enum/ContactOutcomEnum.js b/src/common-tools/enum/ContactOutcomEnum.js index ff3c26634..3b8a95eb4 100644 --- a/src/common-tools/enum/ContactOutcomEnum.js +++ b/src/common-tools/enum/ContactOutcomEnum.js @@ -2,12 +2,18 @@ import D from 'i18n'; const contactOutcome = { INTERVIEW_ACCEPTED: { type: 'INA', value: `${D.interviewAccepted}` }, - IMPOSSIBLE_TO_REACH: { type: 'IMP', value: `${D.impossibleReach}` }, REFUSAL: { type: 'REF', value: `${D.refusal}` }, - INTERVIEW_IMPOSSIBLE: { type: 'INI', value: `${D.interviewImpossible}` }, + IMPOSSIBLE_TO_REACH: { type: 'IMP', value: `${D.impossibleReach}` }, + UNUSABLE_CONTACT_DATA: { type: 'UCD', value: `${D.unusableContactData}` }, + UNABLE_TO_RESPOND: { type: 'UTR', value: `${D.unableToRespond}` }, ALREADY_ANSWERED: { type: 'ALA', value: `${D.alreadyAnsweredAnotherMode}` }, - WISH_ANOTHER_MODE: { type: 'WAM', value: `${D.wishAnswerAnotherMode}` }, - OUT_OF_SCOPE: { type: 'OOS', value: `${D.outOfScope}` }, + ABSENCE_DURING_COLLECTION: { type: 'ACP', value: `${D.absenceDuringCollection}` }, + DECEASED: { type: 'DCD', value: `${D.deceased}` }, + NO_LONGER_USED_FOR_HABITATION: { type: 'NUH', value: `${D.noLongerUsedForHabitation}` }, + NO_INTERVIEW_FOR_EXCEPTIONNAL_REASONS: { + type: 'NER', + value: `${D.noInterviewForExceptionalReasons}`, + }, }; export default contactOutcome; diff --git a/src/i18n/contactAttemptMessage.js b/src/i18n/contactAttemptMessage.js index abe39429d..d3b45298c 100644 --- a/src/i18n/contactAttemptMessage.js +++ b/src/i18n/contactAttemptMessage.js @@ -1,18 +1,21 @@ const contactAttemptMessage = { - noContact: { fr: 'Pas de contact', en: 'No contact' }, interviewAccepted: { fr: 'Enquête acceptée', en: 'Interview accepted' }, - appointmentMade: { fr: 'Rendez-vous pris', en: 'Appointment made' }, refusal: { fr: `Refus`, en: 'Refusal' }, - occasionalAbsence: { - fr: `Absence occasionnelle de l'enquêté`, - en: 'Occasional absence of the interviewee', + noContact: { fr: 'Pas de contact', en: 'No contact' }, + appointmentMade: { fr: 'Rendez-vous pris', en: 'Appointment made' }, + temporaryUnavailable: { + fr: `Indisponibilité provisoire`, + en: 'Temporary unavailable', + }, + messageSent: { + fr: "Dépôt d'un message (tél,sms,mail)", + en: 'Message sent (answering machine, sms, email)', }, - interviewImpossible: { fr: 'Enquête impossible', en: 'Interview impossible' }, - alreadyAnsweredAnotherMode: { - fr: 'Déjà répondu par un autre mode', - en: 'Already answered by another mode', + unusableContactData: { + fr: 'Données de contact inutilisables (tél, mail)', + en: 'Unusable contact data (phone, email)', }, - wishAnswerAnotherMode: { fr: 'Souhaite répondre par un autre mode', en: 'Wish to answer' }, + permanentlyUnavailable: { fr: 'Indisponibilité définitive', en: 'Permanently unavailable' }, contactAttempts: { fr: 'Mes essais de contact', en: 'Contact attempts' }, contactAttempt: { diff --git a/src/i18n/contactOutcomeMessage.js b/src/i18n/contactOutcomeMessage.js index 70e78fe2e..ed97ccc16 100644 --- a/src/i18n/contactOutcomeMessage.js +++ b/src/i18n/contactOutcomeMessage.js @@ -1,5 +1,4 @@ const contactOutcomeMessage = { - outOfScope: { fr: 'Hors champ', en: 'Out of scope' }, impossibleReach: { fr: 'Impossible à joindre', en: 'Impossible to reach' }, contactOutcome: { fr: 'Issue des contacts', en: 'Contact outcome' }, contactOutcomeValidation: { @@ -7,13 +6,29 @@ const contactOutcomeMessage = { en: 'Please confirm the contacts outcome', }, contactOutcomeAttempts: { fr: 'essais', en: 'attempts' }, - wishAnswerAnotherMode: { - fr: 'Souhaite répondre dans un autre mode', - en: 'Wish to answer in another mode', + unableToRespond: { + fr: 'Incapacité à répondre', + en: 'Unable to respond', }, alreadyAnsweredAnotherMode: { - fr: 'Déjà répondu par un autre mode', - en: 'Already answered by another mode', + fr: "A déjà répondu à une autre enquête de l'Insee depuis moins d'un an", + en: 'Already answered another Insee survey since last year', + }, + absenceDuringCollection: { + fr: 'Absence pendant toute la durée de la collecte', + en: 'Absence during collection', + }, + deceased: { + fr: 'Enquêté décédé', + en: 'Deceased respondent', + }, + noLongerUsedForHabitation: { + fr: "Logement ayant perdu son usage d'habitation", + en: 'No longer used for habitation', + }, + noInterviewForExceptionalReasons: { + fr: 'Non enquêté pour cause exceptionnelle', + en: 'No interview for exceptional reasons', }, totalNumberOfContactAttempts: { fr: "Nombre total d'essais de contact", From cd712f65151aad6ee6feeacf81ba393b679438fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Demazi=C3=A8re?= Date: Thu, 1 Jul 2021 15:04:37 +0200 Subject: [PATCH 03/62] upgrade version : no backward compatilibity with API (contact enums) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 40c775796..65c1e5cd1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pearl", - "version": "0.3.3", + "version": "0.4.0", "private": true, "dependencies": { "@testing-library/jest-dom": "^5.11.9", From f6c5fd96847fb3072e57a126ef2e2bc84a69d7fe Mon Sep 17 00:00:00 2001 From: Laurent Caouissin Date: Mon, 2 Aug 2021 14:57:05 +0200 Subject: [PATCH 04/62] Move common-tools to utils package --- src/App.js | 4 ++-- src/Root.js | 2 +- src/components/common/Notification/index.js | 2 +- src/components/common/navigation/component.js | 2 +- src/components/common/online-status/index.js | 2 +- src/components/common/synchronize/component.js | 6 +++--- src/components/panel-body/UESpage/component.js | 6 +----- .../panel-body/UESpage/filterPanel/component.js | 2 +- .../panel-body/UESpage/material/surveyUnitCard.js | 6 +++--- src/components/panel-body/UEpage/atomicInfoTile.js | 2 +- .../UEpage/comments/comment/component.js | 2 +- src/components/panel-body/UEpage/component.js | 4 ++-- .../UEpage/contacts/contactAttempts/component.js | 4 ++-- .../contacts/contactAttempts/contactAttemptLine.js | 2 +- .../contacts/contactAttempts/upDownCounter.js | 2 +- .../UEpage/contacts/contactOutcome/component.js | 4 ++-- .../panel-body/UEpage/details/component.js | 4 ++-- .../panel-body/UEpage/details/contact.js | 4 ++-- .../panel-body/UEpage/details/phoneList.js | 4 ++-- .../panel-body/UEpage/details/phoneTile.js | 4 ++-- .../panel-body/UEpage/forms/contactAttemptsForm.js | 6 +++--- .../panel-body/UEpage/forms/contactOutcomeForm.js | 8 +++----- src/components/panel-body/UEpage/forms/index.js | 4 ++-- src/components/panel-body/UEpage/forms/mailForm.js | 2 +- .../panel-body/UEpage/forms/phoneForm.js | 2 +- src/components/panel-body/UEpage/forms/userForm.js | 2 +- src/components/panel-body/UEpage/infoTile.js | 2 +- .../panel-body/UEpage/navigation/component.js | 8 ++------ src/components/panel-body/UEpage/stateLine.js | 4 ++-- .../panel-body/queen-container/component.js | 2 +- .../functions/surveyUnitFunctions.test.js | 4 ++-- src/{common-tools => utils}/api/index.js | 0 src/{common-tools => utils}/api/surveyUnitAPI.js | 14 ++++++++------ src/{common-tools => utils}/api/utils.js | 4 ++-- src/{common-tools => utils}/auth/initAuth.js | 4 ++-- src/{common-tools => utils}/constants/index.js | 4 ++-- .../enum/ContactAttemptEnum.js | 0 .../enum/ContactOutcomEnum.js | 0 .../enum/QuestionnaireStateEnum.js | 0 src/{common-tools => utils}/enum/SUStateEnum.js | 0 src/{common-tools => utils}/enum/SUToDoEnum.js | 0 src/{common-tools => utils}/enum/formEnum.js | 0 .../functions/convertSUStateInToDo.js | 4 ++-- src/{common-tools => utils}/functions/index.js | 0 .../functions/sortOnColumn.js | 2 +- .../functions/surveyUnitFunctions.js | 6 +++--- src/{common-tools => utils}/hooks/listenQueen.js | 6 +++--- src/{common-tools => utils}/hooks/useAsyncState.js | 0 src/{common-tools => utils}/hooks/useCounter.js | 0 .../hooks/useQueenFromConfig.js | 0 .../hooks/useServiceWorker.js | 0 src/{common-tools => utils}/hooks/useTimer.js | 0 src/{common-tools => utils}/icons/SyncIcon.js | 0 src/{common-tools => utils}/icons/materialIcons.js | 0 src/{common-tools => utils}/index.js | 0 src/{common-tools => utils}/keycloak/index.js | 0 src/{common-tools => utils}/keycloak/keycloak.js | 2 +- .../online-status-observer.js | 0 src/{common-tools => utils}/synchronize/index.js | 8 ++++---- src/{common-tools => utils}/token.js | 0 60 files changed, 79 insertions(+), 87 deletions(-) rename src/tests/{common-tools => utils}/functions/surveyUnitFunctions.test.js (96%) rename src/{common-tools => utils}/api/index.js (100%) rename src/{common-tools => utils}/api/surveyUnitAPI.js (81%) rename src/{common-tools => utils}/api/utils.js (89%) rename src/{common-tools => utils}/auth/initAuth.js (93%) rename src/{common-tools => utils}/constants/index.js (91%) rename src/{common-tools => utils}/enum/ContactAttemptEnum.js (100%) rename src/{common-tools => utils}/enum/ContactOutcomEnum.js (100%) rename src/{common-tools => utils}/enum/QuestionnaireStateEnum.js (100%) rename src/{common-tools => utils}/enum/SUStateEnum.js (100%) rename src/{common-tools => utils}/enum/SUToDoEnum.js (100%) rename src/{common-tools => utils}/enum/formEnum.js (100%) rename src/{common-tools => utils}/functions/convertSUStateInToDo.js (89%) rename src/{common-tools => utils}/functions/index.js (100%) rename src/{common-tools => utils}/functions/sortOnColumn.js (92%) rename src/{common-tools => utils}/functions/surveyUnitFunctions.js (98%) rename src/{common-tools => utils}/hooks/listenQueen.js (91%) rename src/{common-tools => utils}/hooks/useAsyncState.js (100%) rename src/{common-tools => utils}/hooks/useCounter.js (100%) rename src/{common-tools => utils}/hooks/useQueenFromConfig.js (100%) rename src/{common-tools => utils}/hooks/useServiceWorker.js (100%) rename src/{common-tools => utils}/hooks/useTimer.js (100%) rename src/{common-tools => utils}/icons/SyncIcon.js (100%) rename src/{common-tools => utils}/icons/materialIcons.js (100%) rename src/{common-tools => utils}/index.js (100%) rename src/{common-tools => utils}/keycloak/index.js (100%) rename src/{common-tools => utils}/keycloak/keycloak.js (95%) rename src/{common-tools => utils}/online-status-observer.js (100%) rename src/{common-tools => utils}/synchronize/index.js (94%) rename src/{common-tools => utils}/token.js (100%) diff --git a/src/App.js b/src/App.js index 939a80d64..788f0e0b2 100644 --- a/src/App.js +++ b/src/App.js @@ -1,5 +1,5 @@ -import { useAuth } from 'common-tools/auth/initAuth'; -import useServiceWorker from 'common-tools/hooks/useServiceWorker'; +import { useAuth } from 'utils/auth/initAuth'; +import useServiceWorker from 'utils/hooks/useServiceWorker'; import Preloader from 'components/common/loader'; import Notification from 'components/common/Notification'; import Palette from 'components/common/palette'; diff --git a/src/Root.js b/src/Root.js index 3f9fa01f5..4cbba0b74 100644 --- a/src/Root.js +++ b/src/Root.js @@ -1,6 +1,6 @@ import { CssBaseline, ThemeProvider } from '@material-ui/core'; import App from 'App'; -import { useQueenFromConfig } from 'common-tools/hooks/useQueenFromConfig'; +import { useQueenFromConfig } from 'utils/hooks/useQueenFromConfig'; import QueenContainer from 'components/panel-body/queen-container'; import React from 'react'; import { BrowserRouter as Router, Route, Switch } from 'react-router-dom'; diff --git a/src/components/common/Notification/index.js b/src/components/common/Notification/index.js index 8440fb003..bbfac4021 100644 --- a/src/components/common/Notification/index.js +++ b/src/components/common/Notification/index.js @@ -1,5 +1,5 @@ import { Button, CircularProgress, makeStyles, Slide, Snackbar } from '@material-ui/core'; -import useTimer from 'common-tools/hooks/useTimer'; +import useTimer from 'utils/hooks/useTimer'; import D from 'i18n'; import PropTypes from 'prop-types'; import React, { useEffect, useState } from 'react'; diff --git a/src/components/common/navigation/component.js b/src/components/common/navigation/component.js index d6934a2c5..a863cd825 100644 --- a/src/components/common/navigation/component.js +++ b/src/components/common/navigation/component.js @@ -4,7 +4,7 @@ import { makeStyles } from '@material-ui/core/styles'; import Toolbar from '@material-ui/core/Toolbar'; import Typography from '@material-ui/core/Typography'; import MenuIcon from '@material-ui/icons/Menu'; -import { PEARL_USER_KEY } from 'common-tools/constants'; +import { PEARL_USER_KEY } from 'utils/constants'; import Synchronize from 'components/common/synchronize'; import InfoTile from 'components/panel-body/UEpage/infoTile'; import D from 'i18n'; diff --git a/src/components/common/online-status/index.js b/src/components/common/online-status/index.js index e76cbf8e4..5509d4742 100644 --- a/src/components/common/online-status/index.js +++ b/src/components/common/online-status/index.js @@ -1,7 +1,7 @@ import { makeStyles } from '@material-ui/core/styles'; import WifiIcon from '@material-ui/icons/Wifi'; import clsx from 'clsx'; -import { addOnlineStatusObserver } from 'common-tools'; +import { addOnlineStatusObserver } from 'utils'; import React, { useEffect, useState } from 'react'; const useStyles = makeStyles(theme => ({ diff --git a/src/components/common/synchronize/component.js b/src/components/common/synchronize/component.js index 231a73331..e1c4ac173 100644 --- a/src/components/common/synchronize/component.js +++ b/src/components/common/synchronize/component.js @@ -1,8 +1,8 @@ import { Dialog, makeStyles, Typography } from '@material-ui/core'; import IconButton from '@material-ui/core/IconButton'; -import { addOnlineStatusObserver } from 'common-tools'; -import SyncIcon from 'common-tools/icons/SyncIcon'; -import { synchronizePearl, synchronizeQueen } from 'common-tools/synchronize'; +import { addOnlineStatusObserver } from 'utils'; +import SyncIcon from 'utils/icons/SyncIcon'; +import { synchronizePearl, synchronizeQueen } from 'utils/synchronize'; import D from 'i18n'; import PropTypes from 'prop-types'; import React, { useEffect, useState } from 'react'; diff --git a/src/components/panel-body/UESpage/component.js b/src/components/panel-body/UESpage/component.js index 4781e4ac1..ea998b4fa 100644 --- a/src/components/panel-body/UESpage/component.js +++ b/src/components/panel-body/UESpage/component.js @@ -1,10 +1,6 @@ import { Grid } from '@material-ui/core'; import { makeStyles } from '@material-ui/core/styles'; -import { - applyFilters, - sortOnColumnCompareFunction, - updateStateWithDates, -} from 'common-tools/functions'; +import { applyFilters, sortOnColumnCompareFunction, updateStateWithDates } from 'utils/functions'; import surveyUnitDBService from 'indexedbb/services/surveyUnit-idb-service'; import PropTypes from 'prop-types'; import React, { useEffect, useState } from 'react'; diff --git a/src/components/panel-body/UESpage/filterPanel/component.js b/src/components/panel-body/UESpage/filterPanel/component.js index e5d5e4c4c..bd7780be1 100644 --- a/src/components/panel-body/UESpage/filterPanel/component.js +++ b/src/components/panel-body/UESpage/filterPanel/component.js @@ -10,7 +10,7 @@ import RadioGroup from '@material-ui/core/RadioGroup'; import { makeStyles } from '@material-ui/core/styles'; import Typography from '@material-ui/core/Typography'; import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; -import toDoEnum from 'common-tools/enum/SUToDoEnum'; +import toDoEnum from 'utils/enum/SUToDoEnum'; import D from 'i18n'; import PropTypes from 'prop-types'; import React, { useState } from 'react'; diff --git a/src/components/panel-body/UESpage/material/surveyUnitCard.js b/src/components/panel-body/UESpage/material/surveyUnitCard.js index 5a96c68c6..2814fb413 100644 --- a/src/components/panel-body/UESpage/material/surveyUnitCard.js +++ b/src/components/panel-body/UESpage/material/surveyUnitCard.js @@ -7,13 +7,13 @@ import LocationOnIcon from '@material-ui/icons/LocationOn'; import PersonIcon from '@material-ui/icons/Person'; import RadioButtonUncheckedSharpIcon from '@material-ui/icons/RadioButtonUncheckedSharp'; import ScheduleIcon from '@material-ui/icons/Schedule'; -import { intervalInDays } from 'common-tools/functions'; -import { convertSUStateInToDo } from 'common-tools/functions/convertSUStateInToDo'; +import { intervalInDays } from 'utils/functions'; +import { convertSUStateInToDo } from 'utils/functions/convertSUStateInToDo'; import { getLastState, getprivilegedPerson, isSelectable, -} from 'common-tools/functions/surveyUnitFunctions'; +} from 'utils/functions/surveyUnitFunctions'; import PropTypes from 'prop-types'; import React from 'react'; import { useHistory } from 'react-router-dom'; diff --git a/src/components/panel-body/UEpage/atomicInfoTile.js b/src/components/panel-body/UEpage/atomicInfoTile.js index 840f91847..95d1c14a4 100644 --- a/src/components/panel-body/UEpage/atomicInfoTile.js +++ b/src/components/panel-body/UEpage/atomicInfoTile.js @@ -1,6 +1,6 @@ import { Paper, Typography } from '@material-ui/core'; import { makeStyles } from '@material-ui/core/styles'; -import MaterialIcons from 'common-tools/icons/materialIcons'; +import MaterialIcons from 'utils/icons/materialIcons'; import PropTypes from 'prop-types'; import React from 'react'; diff --git a/src/components/panel-body/UEpage/comments/comment/component.js b/src/components/panel-body/UEpage/comments/comment/component.js index cea8ba29b..8fb2454e0 100644 --- a/src/components/panel-body/UEpage/comments/comment/component.js +++ b/src/components/panel-body/UEpage/comments/comment/component.js @@ -1,5 +1,5 @@ import { makeStyles, Paper, TextareaAutosize } from '@material-ui/core'; -import { getCommentByType } from 'common-tools/functions/surveyUnitFunctions'; +import { getCommentByType } from 'utils/functions/surveyUnitFunctions'; import D from 'i18n'; import PropTypes from 'prop-types'; import React, { useContext, useState } from 'react'; diff --git a/src/components/panel-body/UEpage/component.js b/src/components/panel-body/UEpage/component.js index ffc0cb293..ffa2e6428 100644 --- a/src/components/panel-body/UEpage/component.js +++ b/src/components/panel-body/UEpage/component.js @@ -1,5 +1,5 @@ -import suStateEnum from 'common-tools/enum/SUStateEnum'; -import { addNewState, getLastState } from 'common-tools/functions'; +import suStateEnum from 'utils/enum/SUStateEnum'; +import { addNewState, getLastState } from 'utils/functions'; import D from 'i18n'; import surveyUnitDBService from 'indexedbb/services/surveyUnit-idb-service'; import PropTypes from 'prop-types'; diff --git a/src/components/panel-body/UEpage/contacts/contactAttempts/component.js b/src/components/panel-body/UEpage/contacts/contactAttempts/component.js index 7bbd24e6e..722a7c5d8 100644 --- a/src/components/panel-body/UEpage/contacts/contactAttempts/component.js +++ b/src/components/panel-body/UEpage/contacts/contactAttempts/component.js @@ -1,6 +1,6 @@ import { makeStyles, Paper, Typography } from '@material-ui/core'; -import formEnum from 'common-tools/enum/formEnum'; -import { getSortedContactAttempts } from 'common-tools/functions'; +import formEnum from 'utils/enum/formEnum'; +import { getSortedContactAttempts } from 'utils/functions'; import D from 'i18n'; import PropTypes from 'prop-types'; import React, { useContext, useEffect, useState } from 'react'; diff --git a/src/components/panel-body/UEpage/contacts/contactAttempts/contactAttemptLine.js b/src/components/panel-body/UEpage/contacts/contactAttempts/contactAttemptLine.js index 3f131454d..7d70a222e 100644 --- a/src/components/panel-body/UEpage/contacts/contactAttempts/contactAttemptLine.js +++ b/src/components/panel-body/UEpage/contacts/contactAttempts/contactAttemptLine.js @@ -1,6 +1,6 @@ import { makeStyles, Typography } from '@material-ui/core'; import DeleteIcon from '@material-ui/icons/Delete'; -import { findContactAttemptValueByType } from 'common-tools/enum/ContactAttemptEnum'; +import { findContactAttemptValueByType } from 'utils/enum/ContactAttemptEnum'; import format from 'date-fns/format'; import { fr } from 'date-fns/locale'; import PropTypes from 'prop-types'; diff --git a/src/components/panel-body/UEpage/contacts/contactAttempts/upDownCounter.js b/src/components/panel-body/UEpage/contacts/contactAttempts/upDownCounter.js index bb7fe5c47..6fa4772e2 100644 --- a/src/components/panel-body/UEpage/contacts/contactAttempts/upDownCounter.js +++ b/src/components/panel-body/UEpage/contacts/contactAttempts/upDownCounter.js @@ -1,7 +1,7 @@ import { IconButton, makeStyles } from '@material-ui/core'; import ExpandLessIcon from '@material-ui/icons/ExpandLess'; import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; -import useCounter from 'common-tools/hooks/useCounter'; +import useCounter from 'utils/hooks/useCounter'; import { getHours, getMinutes, setHours, setMinutes } from 'date-fns'; import PropTypes from 'prop-types'; import React, { useEffect } from 'react'; diff --git a/src/components/panel-body/UEpage/contacts/contactOutcome/component.js b/src/components/panel-body/UEpage/contacts/contactOutcome/component.js index 871561874..18985f02b 100644 --- a/src/components/panel-body/UEpage/contacts/contactOutcome/component.js +++ b/src/components/panel-body/UEpage/contacts/contactOutcome/component.js @@ -1,6 +1,6 @@ import { makeStyles, Paper, Typography } from '@material-ui/core'; -import { findContactOutcomeValueByType } from 'common-tools/enum/ContactOutcomEnum'; -import formEnum from 'common-tools/enum/formEnum'; +import { findContactOutcomeValueByType } from 'utils/enum/ContactOutcomEnum'; +import formEnum from 'utils/enum/formEnum'; import D from 'i18n'; import PropTypes from 'prop-types'; import React, { useContext, useEffect, useState } from 'react'; diff --git a/src/components/panel-body/UEpage/details/component.js b/src/components/panel-body/UEpage/details/component.js index 9e205c1ea..11e1c3b2d 100644 --- a/src/components/panel-body/UEpage/details/component.js +++ b/src/components/panel-body/UEpage/details/component.js @@ -1,5 +1,5 @@ -import formEnum from 'common-tools/enum/formEnum'; -import { getAddressData, personPlaceholder } from 'common-tools/functions'; +import formEnum from 'utils/enum/formEnum'; +import { getAddressData, personPlaceholder } from 'utils/functions'; import D from 'i18n'; import PropTypes from 'prop-types'; import React, { useContext } from 'react'; diff --git a/src/components/panel-body/UEpage/details/contact.js b/src/components/panel-body/UEpage/details/contact.js index 0066055f4..f26b93c57 100644 --- a/src/components/panel-body/UEpage/details/contact.js +++ b/src/components/panel-body/UEpage/details/contact.js @@ -1,6 +1,6 @@ import { Grid } from '@material-ui/core'; -import formEnum from 'common-tools/enum/formEnum'; -import { getMailData, getPhoneData, getUserData } from 'common-tools/functions'; +import formEnum from 'utils/enum/formEnum'; +import { getMailData, getPhoneData, getUserData } from 'utils/functions'; import D from 'i18n'; import PropTypes from 'prop-types'; import React from 'react'; diff --git a/src/components/panel-body/UEpage/details/phoneList.js b/src/components/panel-body/UEpage/details/phoneList.js index c2065474a..65603c7e7 100644 --- a/src/components/panel-body/UEpage/details/phoneList.js +++ b/src/components/panel-body/UEpage/details/phoneList.js @@ -1,7 +1,7 @@ import { TextField, Typography } from '@material-ui/core'; import { makeStyles } from '@material-ui/core/styles'; -import { getPhoneSource } from 'common-tools/functions'; -import MaterialIcons from 'common-tools/icons/materialIcons'; +import { getPhoneSource } from 'utils/functions'; +import MaterialIcons from 'utils/icons/materialIcons'; import PropTypes from 'prop-types'; import React from 'react'; diff --git a/src/components/panel-body/UEpage/details/phoneTile.js b/src/components/panel-body/UEpage/details/phoneTile.js index 8c49f0557..971ea8af5 100644 --- a/src/components/panel-body/UEpage/details/phoneTile.js +++ b/src/components/panel-body/UEpage/details/phoneTile.js @@ -1,7 +1,7 @@ import { Paper } from '@material-ui/core'; import { makeStyles } from '@material-ui/core/styles'; -import { sortPhoneNumbers } from 'common-tools/functions'; -import MaterialIcons from 'common-tools/icons/materialIcons'; +import { sortPhoneNumbers } from 'utils/functions'; +import MaterialIcons from 'utils/icons/materialIcons'; import PropTypes from 'prop-types'; import React from 'react'; import PhoneList from './phoneList'; diff --git a/src/components/panel-body/UEpage/forms/contactAttemptsForm.js b/src/components/panel-body/UEpage/forms/contactAttemptsForm.js index f844a007f..2edcd0b19 100644 --- a/src/components/panel-body/UEpage/forms/contactAttemptsForm.js +++ b/src/components/panel-body/UEpage/forms/contactAttemptsForm.js @@ -3,9 +3,9 @@ import { Fab, makeStyles, Paper, Typography } from '@material-ui/core'; import AddIcon from '@material-ui/icons/Add'; import ScheduleIcon from '@material-ui/icons/Schedule'; import { DatePicker, KeyboardTimePicker, MuiPickersUtilsProvider } from '@material-ui/pickers'; -import contactAttemptEnum from 'common-tools/enum/ContactAttemptEnum'; -import surveyUnitStateEnum from 'common-tools/enum/SUStateEnum'; -import { addNewState, areCaEqual, getSortedContactAttempts } from 'common-tools/functions'; +import contactAttemptEnum from 'utils/enum/ContactAttemptEnum'; +import surveyUnitStateEnum from 'utils/enum/SUStateEnum'; +import { addNewState, areCaEqual, getSortedContactAttempts } from 'utils/functions'; import frLocale from 'date-fns/locale/fr'; import D from 'i18n'; import PropTypes from 'prop-types'; diff --git a/src/components/panel-body/UEpage/forms/contactOutcomeForm.js b/src/components/panel-body/UEpage/forms/contactOutcomeForm.js index 9e63e1837..03cef8150 100644 --- a/src/components/panel-body/UEpage/forms/contactOutcomeForm.js +++ b/src/components/panel-body/UEpage/forms/contactOutcomeForm.js @@ -1,11 +1,9 @@ import { Fab, Grid, makeStyles, Paper, Typography } from '@material-ui/core'; import AddIcon from '@material-ui/icons/Add'; import RemoveIcon from '@material-ui/icons/Remove'; -import contactOutcomeEnum, { - findContactOutcomeValueByType, -} from 'common-tools/enum/ContactOutcomEnum'; -import surveyUnitStateEnum from 'common-tools/enum/SUStateEnum'; -import { addNewState } from 'common-tools/functions'; +import contactOutcomeEnum, { findContactOutcomeValueByType } from 'utils/enum/ContactOutcomEnum'; +import surveyUnitStateEnum from 'utils/enum/SUStateEnum'; +import { addNewState } from 'utils/functions'; import D from 'i18n'; import PropTypes from 'prop-types'; import React, { useContext, useEffect, useState } from 'react'; diff --git a/src/components/panel-body/UEpage/forms/index.js b/src/components/panel-body/UEpage/forms/index.js index 3e6ac6dbb..71fbd2e1d 100644 --- a/src/components/panel-body/UEpage/forms/index.js +++ b/src/components/panel-body/UEpage/forms/index.js @@ -1,5 +1,5 @@ -import formEnum from 'common-tools/enum/formEnum'; -import { deleteContactAttempt, getAddressData, getCommentByType } from 'common-tools/functions'; +import formEnum from 'utils/enum/formEnum'; +import { deleteContactAttempt, getAddressData, getCommentByType } from 'utils/functions'; import React from 'react'; import AddressForm from './addressForm'; import ContactAttemptsForm from './contactAttemptsForm'; diff --git a/src/components/panel-body/UEpage/forms/mailForm.js b/src/components/panel-body/UEpage/forms/mailForm.js index d5e5bd404..eec993e7e 100644 --- a/src/components/panel-body/UEpage/forms/mailForm.js +++ b/src/components/panel-body/UEpage/forms/mailForm.js @@ -1,5 +1,5 @@ import { Button, DialogActions, DialogTitle, makeStyles, TextField } from '@material-ui/core'; -import MaterialIcons from 'common-tools/icons/materialIcons'; +import MaterialIcons from 'utils/icons/materialIcons'; import D from 'i18n'; import PropTypes from 'prop-types'; import React, { useContext, useState } from 'react'; diff --git a/src/components/panel-body/UEpage/forms/phoneForm.js b/src/components/panel-body/UEpage/forms/phoneForm.js index baf49d074..7fda75227 100644 --- a/src/components/panel-body/UEpage/forms/phoneForm.js +++ b/src/components/panel-body/UEpage/forms/phoneForm.js @@ -1,5 +1,5 @@ import { Button, DialogActions, DialogTitle, makeStyles } from '@material-ui/core'; -import { sortPhoneNumbers } from 'common-tools/functions'; +import { sortPhoneNumbers } from 'utils/functions'; import D from 'i18n'; import PropTypes from 'prop-types'; import React, { useContext, useState } from 'react'; diff --git a/src/components/panel-body/UEpage/forms/userForm.js b/src/components/panel-body/UEpage/forms/userForm.js index d0f444f32..28268f762 100644 --- a/src/components/panel-body/UEpage/forms/userForm.js +++ b/src/components/panel-body/UEpage/forms/userForm.js @@ -1,7 +1,7 @@ import DateFnsUtils from '@date-io/date-fns'; import { Button, DialogActions, DialogTitle, makeStyles, TextField } from '@material-ui/core'; import { DatePicker, MuiPickersUtilsProvider } from '@material-ui/pickers'; -import { getTitle } from 'common-tools/functions'; +import { getTitle } from 'utils/functions'; import frLocale from 'date-fns/locale/fr'; import D from 'i18n'; import PropTypes from 'prop-types'; diff --git a/src/components/panel-body/UEpage/infoTile.js b/src/components/panel-body/UEpage/infoTile.js index d2ea3150a..1e8f90a26 100644 --- a/src/components/panel-body/UEpage/infoTile.js +++ b/src/components/panel-body/UEpage/infoTile.js @@ -4,7 +4,7 @@ import { makeStyles } from '@material-ui/core/styles'; import Typography from '@material-ui/core/Typography'; import PersonIcon from '@material-ui/icons/Person'; import { Skeleton } from '@material-ui/lab'; -import { getprivilegedPerson } from 'common-tools/functions'; +import { getprivilegedPerson } from 'utils/functions'; import surveyUnitDBService from 'indexedbb/services/surveyUnit-idb-service'; import React, { useEffect, useState } from 'react'; import { useParams } from 'react-router-dom'; diff --git a/src/components/panel-body/UEpage/navigation/component.js b/src/components/panel-body/UEpage/navigation/component.js index f79f5d865..827009aca 100644 --- a/src/components/panel-body/UEpage/navigation/component.js +++ b/src/components/panel-body/UEpage/navigation/component.js @@ -1,10 +1,6 @@ import { Button, makeStyles, Tab, Tabs } from '@material-ui/core'; -import suStateEnum from 'common-tools/enum/SUStateEnum'; -import { - addNewState, - isQuestionnaireAvailable, - isValidForTransmission, -} from 'common-tools/functions'; +import suStateEnum from 'utils/enum/SUStateEnum'; +import { addNewState, isQuestionnaireAvailable, isValidForTransmission } from 'utils/functions'; import D from 'i18n'; import PropTypes from 'prop-types'; import React, { useContext, useState } from 'react'; diff --git a/src/components/panel-body/UEpage/stateLine.js b/src/components/panel-body/UEpage/stateLine.js index 241281013..381b897e2 100644 --- a/src/components/panel-body/UEpage/stateLine.js +++ b/src/components/panel-body/UEpage/stateLine.js @@ -4,8 +4,8 @@ import Stepper from '@material-ui/core/Stepper'; import { makeStyles } from '@material-ui/core/styles'; import CheckCircleOutlineIcon from '@material-ui/icons/CheckCircleOutline'; import RadioButtonUncheckedIcon from '@material-ui/icons/RadioButtonUnchecked'; -import toDoEnum from 'common-tools/enum/SUToDoEnum'; -import { convertSUStateInToDo, getLastState } from 'common-tools/functions'; +import toDoEnum from 'utils/enum/SUToDoEnum'; +import { convertSUStateInToDo, getLastState } from 'utils/functions'; import PropTypes from 'prop-types'; import React, { useContext } from 'react'; import SurveyUnitContext from './UEContext'; diff --git a/src/components/panel-body/queen-container/component.js b/src/components/panel-body/queen-container/component.js index fc65ddcbf..67203a70b 100644 --- a/src/components/panel-body/queen-container/component.js +++ b/src/components/panel-body/queen-container/component.js @@ -1,5 +1,5 @@ import { makeStyles } from '@material-ui/core'; -import listenQueen from 'common-tools/hooks/listenQueen'; +import listenQueen from 'utils/hooks/listenQueen'; import React from 'react'; import { useHistory } from 'react-router-dom'; diff --git a/src/tests/common-tools/functions/surveyUnitFunctions.test.js b/src/tests/utils/functions/surveyUnitFunctions.test.js similarity index 96% rename from src/tests/common-tools/functions/surveyUnitFunctions.test.js rename to src/tests/utils/functions/surveyUnitFunctions.test.js index 93dadee8a..b724640fa 100644 --- a/src/tests/common-tools/functions/surveyUnitFunctions.test.js +++ b/src/tests/utils/functions/surveyUnitFunctions.test.js @@ -1,11 +1,11 @@ -const surveyUnitStateEnum = require('common-tools/enum/SUStateEnum'); +const surveyUnitStateEnum = require('utils/enum/SUStateEnum'); const { getContactAttemptNumber, getLastState, isSelectable, updateStateWithDates, -} = require('common-tools/functions'); +} = require('utils/functions'); describe('getLastState', () => { it('should return the only state', () => { diff --git a/src/common-tools/api/index.js b/src/utils/api/index.js similarity index 100% rename from src/common-tools/api/index.js rename to src/utils/api/index.js diff --git a/src/common-tools/api/surveyUnitAPI.js b/src/utils/api/surveyUnitAPI.js similarity index 81% rename from src/common-tools/api/surveyUnitAPI.js rename to src/utils/api/surveyUnitAPI.js index 5fc1497d1..7c28d6b03 100644 --- a/src/common-tools/api/surveyUnitAPI.js +++ b/src/utils/api/surveyUnitAPI.js @@ -10,11 +10,13 @@ export const getSurveyUnits = (urlPearApi, authenticationMode) => }) .then(res => resolve(res)) .catch(e => { - reject(new Error(`Failed to fetch survey-units : ${e.response.data.error.message}`)); + reject( + new Error(`Failed to fetch survey-units : ${e?.response?.data?.error?.message}`) + ); }); }) .catch(e => { - reject(new Error(`Error during refreshToken : ${e.response.data.error.message}`)); + reject(new Error(`Error during refreshToken : ${e?.response?.data?.error?.message}`)); }); }); @@ -26,9 +28,9 @@ export const getSurveyUnitById = (urlPearApi, authenticationMode) => id => headers: getHeader(authenticationMode), }) .then(res => resolve(res)) - .catch(e => reject(new Error(`Failed to fetch survey-unit (id:${id}) : ${e.message}`))); + .catch(e => reject(new Error(`Failed to fetch survey-unit (id:${id}) : ${e?.message}`))); }) - .catch(e => reject(new Error(`Error during refreshToken : ${e.message}`))); + .catch(e => reject(new Error(`Error during refreshToken : ${e?.message}`))); }); export const putDataSurveyUnitById = (urlPearApi, authenticationMode) => (id, su) => @@ -39,7 +41,7 @@ export const putDataSurveyUnitById = (urlPearApi, authenticationMode) => (id, su headers: getHeader(authenticationMode), }) .then(res => resolve(res)) - .catch(e => reject(new Error(`Failed to put survey-unit (id:${id}) : ${e.message}`))); + .catch(e => reject(new Error(`Failed to put survey-unit (id:${id}) : ${e?.message}`))); }) - .catch(e => reject(new Error(`Error during refreshToken : ${e.message}`))); + .catch(e => reject(new Error(`Error during refreshToken : ${e?.message}`))); }); diff --git a/src/common-tools/api/utils.js b/src/utils/api/utils.js similarity index 89% rename from src/common-tools/api/utils.js rename to src/utils/api/utils.js index 1ae01a730..1150a60a7 100644 --- a/src/common-tools/api/utils.js +++ b/src/utils/api/utils.js @@ -1,5 +1,5 @@ -import { ANONYMOUS, JSON_UTF8_HEADER, KEYCLOAK, PEARL_USER_KEY } from 'common-tools/constants'; -import { kc, keycloakAuthentication, refreshToken } from 'common-tools/keycloak'; +import { ANONYMOUS, JSON_UTF8_HEADER, KEYCLOAK, PEARL_USER_KEY } from 'utils/constants'; +import { kc, keycloakAuthentication, refreshToken } from 'utils/keycloak'; export const getSecureHeader = token => token diff --git a/src/common-tools/auth/initAuth.js b/src/utils/auth/initAuth.js similarity index 93% rename from src/common-tools/auth/initAuth.js rename to src/utils/auth/initAuth.js index 0d50ca51d..5dc20f2d9 100644 --- a/src/common-tools/auth/initAuth.js +++ b/src/utils/auth/initAuth.js @@ -1,5 +1,5 @@ -import { GUEST_PEARL_USER, PEARL_USER_KEY } from 'common-tools/constants'; -import { getTokenInfo, keycloakAuthentication } from 'common-tools/keycloak'; +import { GUEST_PEARL_USER, PEARL_USER_KEY } from 'utils/constants'; +import { getTokenInfo, keycloakAuthentication } from 'utils/keycloak'; import { useEffect, useState } from 'react'; export const useAuth = () => { diff --git a/src/common-tools/constants/index.js b/src/utils/constants/index.js similarity index 91% rename from src/common-tools/constants/index.js rename to src/utils/constants/index.js index 7e7ddf61b..0667154b5 100644 --- a/src/common-tools/constants/index.js +++ b/src/utils/constants/index.js @@ -1,5 +1,5 @@ -import contactAttemptEnum from 'common-tools/enum/ContactAttemptEnum'; -import surveyUnitStateEnum from 'common-tools/enum/SUStateEnum'; +import contactAttemptEnum from 'utils/enum/ContactAttemptEnum'; +import surveyUnitStateEnum from 'utils/enum/SUStateEnum'; export const KEYCLOAK = 'keycloak'; export const ANONYMOUS = 'anonymous'; diff --git a/src/common-tools/enum/ContactAttemptEnum.js b/src/utils/enum/ContactAttemptEnum.js similarity index 100% rename from src/common-tools/enum/ContactAttemptEnum.js rename to src/utils/enum/ContactAttemptEnum.js diff --git a/src/common-tools/enum/ContactOutcomEnum.js b/src/utils/enum/ContactOutcomEnum.js similarity index 100% rename from src/common-tools/enum/ContactOutcomEnum.js rename to src/utils/enum/ContactOutcomEnum.js diff --git a/src/common-tools/enum/QuestionnaireStateEnum.js b/src/utils/enum/QuestionnaireStateEnum.js similarity index 100% rename from src/common-tools/enum/QuestionnaireStateEnum.js rename to src/utils/enum/QuestionnaireStateEnum.js diff --git a/src/common-tools/enum/SUStateEnum.js b/src/utils/enum/SUStateEnum.js similarity index 100% rename from src/common-tools/enum/SUStateEnum.js rename to src/utils/enum/SUStateEnum.js diff --git a/src/common-tools/enum/SUToDoEnum.js b/src/utils/enum/SUToDoEnum.js similarity index 100% rename from src/common-tools/enum/SUToDoEnum.js rename to src/utils/enum/SUToDoEnum.js diff --git a/src/common-tools/enum/formEnum.js b/src/utils/enum/formEnum.js similarity index 100% rename from src/common-tools/enum/formEnum.js rename to src/utils/enum/formEnum.js diff --git a/src/common-tools/functions/convertSUStateInToDo.js b/src/utils/functions/convertSUStateInToDo.js similarity index 89% rename from src/common-tools/functions/convertSUStateInToDo.js rename to src/utils/functions/convertSUStateInToDo.js index f7b52bca1..7913ebf52 100644 --- a/src/common-tools/functions/convertSUStateInToDo.js +++ b/src/utils/functions/convertSUStateInToDo.js @@ -1,5 +1,5 @@ -import suStateEnum from 'common-tools/enum/SUStateEnum'; -import toDoEnum from 'common-tools/enum/SUToDoEnum'; +import suStateEnum from 'utils/enum/SUStateEnum'; +import toDoEnum from 'utils/enum/SUToDoEnum'; export const convertSUStateInToDo = suState => { if ( diff --git a/src/common-tools/functions/index.js b/src/utils/functions/index.js similarity index 100% rename from src/common-tools/functions/index.js rename to src/utils/functions/index.js diff --git a/src/common-tools/functions/sortOnColumn.js b/src/utils/functions/sortOnColumn.js similarity index 92% rename from src/common-tools/functions/sortOnColumn.js rename to src/utils/functions/sortOnColumn.js index 65366cb05..ccbdaa6b4 100644 --- a/src/common-tools/functions/sortOnColumn.js +++ b/src/utils/functions/sortOnColumn.js @@ -1,4 +1,4 @@ -import { intervalInDays } from 'common-tools/functions/surveyUnitFunctions'; +import { intervalInDays } from 'utils/functions/surveyUnitFunctions'; export const sortOnColumnCompareFunction = criteria => { let compareFunction; diff --git a/src/common-tools/functions/surveyUnitFunctions.js b/src/utils/functions/surveyUnitFunctions.js similarity index 98% rename from src/common-tools/functions/surveyUnitFunctions.js rename to src/utils/functions/surveyUnitFunctions.js index d0432ec63..64629f9b2 100644 --- a/src/common-tools/functions/surveyUnitFunctions.js +++ b/src/utils/functions/surveyUnitFunctions.js @@ -1,6 +1,6 @@ -import { CONTACT_RELATED_STATES, CONTACT_SUCCESS_LIST } from 'common-tools/constants'; -import surveyUnitStateEnum from 'common-tools/enum/SUStateEnum'; -import { convertSUStateInToDo } from 'common-tools/functions/convertSUStateInToDo'; +import { CONTACT_RELATED_STATES, CONTACT_SUCCESS_LIST } from 'utils/constants'; +import surveyUnitStateEnum from 'utils/enum/SUStateEnum'; +import { convertSUStateInToDo } from 'utils/functions/convertSUStateInToDo'; import { differenceInYears, formatDistanceStrict } from 'date-fns'; import D from 'i18n'; import surveyUnitDBService from 'indexedbb/services/surveyUnit-idb-service'; diff --git a/src/common-tools/hooks/listenQueen.js b/src/utils/hooks/listenQueen.js similarity index 91% rename from src/common-tools/hooks/listenQueen.js rename to src/utils/hooks/listenQueen.js index 4c71af0c1..3f3394159 100644 --- a/src/common-tools/hooks/listenQueen.js +++ b/src/utils/hooks/listenQueen.js @@ -1,6 +1,6 @@ -import questionnaireEnum from 'common-tools/enum/QuestionnaireStateEnum'; -import suStateEnum from 'common-tools/enum/SUStateEnum'; -import { addNewState } from 'common-tools/functions/surveyUnitFunctions'; +import questionnaireEnum from 'utils/enum/QuestionnaireStateEnum'; +import suStateEnum from 'utils/enum/SUStateEnum'; +import { addNewState } from 'utils/functions/surveyUnitFunctions'; import surveyUnitDBService from 'indexedbb/services/surveyUnit-idb-service'; import { useEffect } from 'react'; diff --git a/src/common-tools/hooks/useAsyncState.js b/src/utils/hooks/useAsyncState.js similarity index 100% rename from src/common-tools/hooks/useAsyncState.js rename to src/utils/hooks/useAsyncState.js diff --git a/src/common-tools/hooks/useCounter.js b/src/utils/hooks/useCounter.js similarity index 100% rename from src/common-tools/hooks/useCounter.js rename to src/utils/hooks/useCounter.js diff --git a/src/common-tools/hooks/useQueenFromConfig.js b/src/utils/hooks/useQueenFromConfig.js similarity index 100% rename from src/common-tools/hooks/useQueenFromConfig.js rename to src/utils/hooks/useQueenFromConfig.js diff --git a/src/common-tools/hooks/useServiceWorker.js b/src/utils/hooks/useServiceWorker.js similarity index 100% rename from src/common-tools/hooks/useServiceWorker.js rename to src/utils/hooks/useServiceWorker.js diff --git a/src/common-tools/hooks/useTimer.js b/src/utils/hooks/useTimer.js similarity index 100% rename from src/common-tools/hooks/useTimer.js rename to src/utils/hooks/useTimer.js diff --git a/src/common-tools/icons/SyncIcon.js b/src/utils/icons/SyncIcon.js similarity index 100% rename from src/common-tools/icons/SyncIcon.js rename to src/utils/icons/SyncIcon.js diff --git a/src/common-tools/icons/materialIcons.js b/src/utils/icons/materialIcons.js similarity index 100% rename from src/common-tools/icons/materialIcons.js rename to src/utils/icons/materialIcons.js diff --git a/src/common-tools/index.js b/src/utils/index.js similarity index 100% rename from src/common-tools/index.js rename to src/utils/index.js diff --git a/src/common-tools/keycloak/index.js b/src/utils/keycloak/index.js similarity index 100% rename from src/common-tools/keycloak/index.js rename to src/utils/keycloak/index.js diff --git a/src/common-tools/keycloak/keycloak.js b/src/utils/keycloak/keycloak.js similarity index 95% rename from src/common-tools/keycloak/keycloak.js rename to src/utils/keycloak/keycloak.js index e31afe00d..5dafd3968 100644 --- a/src/common-tools/keycloak/keycloak.js +++ b/src/utils/keycloak/keycloak.js @@ -1,5 +1,5 @@ import Keycloak from 'keycloak-js'; -import { PEARL_URL } from 'common-tools/constants'; +import { PEARL_URL } from 'utils/constants'; export const kc = Keycloak(`${PEARL_URL}/keycloak.json`); export const keycloakAuthentication = params => diff --git a/src/common-tools/online-status-observer.js b/src/utils/online-status-observer.js similarity index 100% rename from src/common-tools/online-status-observer.js rename to src/utils/online-status-observer.js diff --git a/src/common-tools/synchronize/index.js b/src/utils/synchronize/index.js similarity index 94% rename from src/common-tools/synchronize/index.js rename to src/utils/synchronize/index.js index 88586d57a..7363c75b2 100644 --- a/src/common-tools/synchronize/index.js +++ b/src/utils/synchronize/index.js @@ -1,5 +1,5 @@ -import * as api from 'common-tools/api'; -import { getLastState } from 'common-tools/functions'; +import * as api from 'utils/api'; +import { getLastState } from 'utils/functions'; import surveyUnitDBService from 'indexedbb/services/surveyUnit-idb-service'; export const synchronizeQueen = async history => { @@ -61,7 +61,7 @@ const clean = async () => { await surveyUnitDBService.deleteAll(); }; -const validateSU = async su => { +const validateSU = su => { const { states, comments } = su; if (Array.isArray(states) && states.length === 0) { su.states.push(su.lastState); @@ -88,7 +88,7 @@ const getData = async (pearlApiUrl, pearlAuthenticationMode) => { )(su.id); const surveyUnit = await surveyUnitResponse.data; const mergedSurveyUnit = { ...surveyUnit, ...su }; - const validSurveyUnit = await validateSU(mergedSurveyUnit); + const validSurveyUnit = validateSU(mergedSurveyUnit); await putSurveyUnitInDataBase(validSurveyUnit); }) ); diff --git a/src/common-tools/token.js b/src/utils/token.js similarity index 100% rename from src/common-tools/token.js rename to src/utils/token.js From e802ed302195b78998d057d93312c900ee82b658 Mon Sep 17 00:00:00 2001 From: Laurent Caouissin Date: Tue, 3 Aug 2021 11:29:33 +0200 Subject: [PATCH 05/62] Create context for configuration (to prevent too many load of configuration file) --- src/Root.js | 30 ++++++++++++++++++--------- src/utils/hooks/configuration.js | 18 ++++++++++++++++ src/utils/hooks/useQueenFromConfig.js | 11 +++++----- src/utils/hooks/useServiceWorker.js | 9 ++++---- 4 files changed, 48 insertions(+), 20 deletions(-) create mode 100644 src/utils/hooks/configuration.js diff --git a/src/Root.js b/src/Root.js index 4cbba0b74..feaa6a6d5 100644 --- a/src/Root.js +++ b/src/Root.js @@ -5,19 +5,29 @@ import QueenContainer from 'components/panel-body/queen-container'; import React from 'react'; import { BrowserRouter as Router, Route, Switch } from 'react-router-dom'; import theme from './theme'; +import { useConfiguration } from 'utils/hooks/configuration'; + +export const AppContext = React.createContext(); function Root() { - useQueenFromConfig(`${window.location.origin}/configuration.json`); + const { configuration } = useConfiguration(); + useQueenFromConfig(configuration); return ( - - - } /> - - - - - - + <> + {configuration && ( + + + } /> + + + + + + + + + )} + ); } diff --git a/src/utils/hooks/configuration.js b/src/utils/hooks/configuration.js new file mode 100644 index 000000000..5c175a407 --- /dev/null +++ b/src/utils/hooks/configuration.js @@ -0,0 +1,18 @@ +import { useState, useEffect } from 'react'; + +export const useConfiguration = () => { + const [configuration, setConfiguration] = useState(null); + + useEffect(() => { + if (!configuration) { + const loadConfiguration = async () => { + const response = await fetch(`${window.location.origin}/configuration.json`); + const configurationResponse = await response.json(); + setConfiguration(configurationResponse); + }; + loadConfiguration(); + } + }, [configuration]); + + return { configuration }; +}; diff --git a/src/utils/hooks/useQueenFromConfig.js b/src/utils/hooks/useQueenFromConfig.js index 017fab9bf..99ef023b4 100644 --- a/src/utils/hooks/useQueenFromConfig.js +++ b/src/utils/hooks/useQueenFromConfig.js @@ -1,15 +1,14 @@ import { useEffect } from 'react'; -export const useQueenFromConfig = url => { - const importQueenScript = async configurationUrl => { - const response = await fetch(configurationUrl); - const { QUEEN_URL } = await response.json(); +export const useQueenFromConfig = configuration => { + const importQueenScript = configuration => { + const { QUEEN_URL } = configuration; const script = document.createElement('script'); script.src = `${QUEEN_URL}/entry.js`; document.body.appendChild(script); }; useEffect(() => { - importQueenScript(url); - }, [url]); + if (configuration) importQueenScript(configuration); + }, [configuration]); }; diff --git a/src/utils/hooks/useServiceWorker.js b/src/utils/hooks/useServiceWorker.js index 9705f2c18..60a4fd757 100644 --- a/src/utils/hooks/useServiceWorker.js +++ b/src/utils/hooks/useServiceWorker.js @@ -1,7 +1,9 @@ -import { useEffect, useState } from 'react'; +import { useContext, useEffect, useState } from 'react'; +import { AppContext } from 'Root'; import * as serviceWorker from 'serviceWorkerRegistration'; const useServiceWorker = authenticated => { + const configuration = useContext(AppContext); const [installingServiceWorker, setInstallingServiceWorker] = useState(false); const [waitingServiceWorker, setWaitingServiceWorker] = useState(null); const [isUpdateAvailable, setUpdateAvailable] = useState(false); @@ -9,8 +11,7 @@ const useServiceWorker = authenticated => { useEffect(() => { const install = async () => { - const configuration = await fetch(`${window.location.origin}/configuration.json`); - const { QUEEN_URL } = await configuration.json(); + const { QUEEN_URL } = configuration; serviceWorker.register({ QUEEN_URL, onInstalling: installing => { @@ -31,7 +32,7 @@ const useServiceWorker = authenticated => { }); }; if (authenticated) install(); - }, [authenticated]); + }, [authenticated, configuration]); return { installingServiceWorker, From dab18c08da694cffbc7d24a9acf13ce7303f7b15 Mon Sep 17 00:00:00 2001 From: Laurent Caouissin Date: Tue, 3 Aug 2021 11:31:18 +0200 Subject: [PATCH 06/62] Refactor api (remove axios to manage error) --- src/utils/api/fetcher.js | 33 ++++++++++++++ src/utils/api/index.js | 1 + src/utils/api/mailAPI.js | 12 +++++ src/utils/api/requests.js | 30 ++++++++++++ src/utils/api/surveyUnitAPI.js | 83 ++++++++++++++++------------------ src/utils/api/utils.js | 4 +- yarn.lock | 21 --------- 7 files changed, 118 insertions(+), 66 deletions(-) create mode 100644 src/utils/api/fetcher.js create mode 100644 src/utils/api/mailAPI.js create mode 100644 src/utils/api/requests.js diff --git a/src/utils/api/fetcher.js b/src/utils/api/fetcher.js new file mode 100644 index 000000000..7f801459d --- /dev/null +++ b/src/utils/api/fetcher.js @@ -0,0 +1,33 @@ +// manage empty response during PUT or POST request +const readJsonResponse = async response => { + try { + return await response.json(); + } catch (e) { + return {}; + } +}; + +export const fetcher = async (url, token, method, body) => { + const headers = { Accept: 'application/json', 'Content-Type': 'application/json' }; + try { + const response = await fetch(url, { + headers: token ? { ...headers, Authorization: `Bearer ${token}` } : headers, + method, + body: body ? JSON.stringify(body) : null, + }); + const { ok, status, statusText } = response; + if (ok) { + try { + const data = await readJsonResponse(response); + return { data, status, statusText }; + } catch (error) { + return { error: true, status, statusText: error?.message }; + } + } else { + return { error: true, status, statusText }; + } + } catch (error) { + // network error + return { error: true, statusText: error.message }; + } +}; diff --git a/src/utils/api/index.js b/src/utils/api/index.js index 11a3e5c38..492677416 100644 --- a/src/utils/api/index.js +++ b/src/utils/api/index.js @@ -1 +1,2 @@ export * from './surveyUnitAPI'; +export * from './mailAPI'; diff --git a/src/utils/api/mailAPI.js b/src/utils/api/mailAPI.js new file mode 100644 index 000000000..684a4ce25 --- /dev/null +++ b/src/utils/api/mailAPI.js @@ -0,0 +1,12 @@ +import { authentication, getToken } from './utils'; +import { API } from './requests'; + +export const sendMail = (urlPearApi, authenticationMode) => async (subject, content) => { + try { + await authentication(authenticationMode); + const token = getToken(); + return API.sendMail(urlPearApi)(subject)(content)(token); + } catch (e) { + throw new Error(`Error during refreshToken : ${e}`); + } +}; diff --git a/src/utils/api/requests.js b/src/utils/api/requests.js new file mode 100644 index 000000000..d6a23a178 --- /dev/null +++ b/src/utils/api/requests.js @@ -0,0 +1,30 @@ +import { fetcher } from './fetcher'; + +const getRequest = url => token => fetcher(url, token, 'GET', null); +const putRequest = url => token => body => fetcher(url, token, 'PUT', body); +const postRequest = url => token => body => fetcher(url, token, 'POST', body); + +/* All surveyUnits */ +const getSurveyUnits = apiUrl => token => getRequest(`${apiUrl}/api/survey-units`)(token); + +/* SurveyUnit's data */ +const getSurveyUnitById = apiUrl => id => token => + getRequest(`${apiUrl}/api/survey-unit/${id}`)(token); +const putDataSurveyUnitById = apiUrl => id => token => body => + putRequest(`${apiUrl}/api/survey-unit/${id}`)(token)(body); +const putToTempZone = apiUrl => id => token => body => + putRequest(`${apiUrl}/api/survey-unit/${id}/temp-zone`)(token)(body); + +const sendMail = apiUrl => subject => content => token => { + const mailBody = { subject, content }; + return postRequest(`${apiUrl}/api/mail`)(token)(mailBody); +}; + +export const API = { + getRequest, + getSurveyUnits, + getSurveyUnitById, + putDataSurveyUnitById, + putToTempZone, + sendMail, +}; diff --git a/src/utils/api/surveyUnitAPI.js b/src/utils/api/surveyUnitAPI.js index 7c28d6b03..85bd19ce2 100644 --- a/src/utils/api/surveyUnitAPI.js +++ b/src/utils/api/surveyUnitAPI.js @@ -1,47 +1,42 @@ -import Axios from 'axios'; -import { authentication, getHeader } from './utils'; +import { authentication, getToken } from './utils'; +import { API } from './requests'; -export const getSurveyUnits = (urlPearApi, authenticationMode) => - new Promise((resolve, reject) => { - authentication(authenticationMode) - .then(() => { - Axios.get(`${urlPearApi}/api/survey-units`, { - headers: getHeader(authenticationMode), - }) - .then(res => resolve(res)) - .catch(e => { - reject( - new Error(`Failed to fetch survey-units : ${e?.response?.data?.error?.message}`) - ); - }); - }) - .catch(e => { - reject(new Error(`Error during refreshToken : ${e?.response?.data?.error?.message}`)); - }); - }); +export const getSurveyUnits = async (urlPearApi, authenticationMode) => { + try { + await authentication(authenticationMode); + const token = getToken(); + return API.getSurveyUnits(urlPearApi)(token); + } catch (e) { + throw new Error(`Error during refreshToken : ${e}`); + } +}; -export const getSurveyUnitById = (urlPearApi, authenticationMode) => id => - new Promise((resolve, reject) => { - authentication(authenticationMode) - .then(() => { - Axios.get(`${urlPearApi}/api/survey-unit/${id}`, { - headers: getHeader(authenticationMode), - }) - .then(res => resolve(res)) - .catch(e => reject(new Error(`Failed to fetch survey-unit (id:${id}) : ${e?.message}`))); - }) - .catch(e => reject(new Error(`Error during refreshToken : ${e?.message}`))); - }); +export const getSurveyUnitById = (urlPearApi, authenticationMode) => async id => { + try { + await authentication(authenticationMode); + const token = getToken(); + return API.getSurveyUnitById(urlPearApi)(id)(token); + } catch (e) { + throw new Error(`Error during refreshToken : ${e}`); + } +}; -export const putDataSurveyUnitById = (urlPearApi, authenticationMode) => (id, su) => - new Promise((resolve, reject) => { - authentication(authenticationMode) - .then(() => { - Axios.put(`${urlPearApi}/api/survey-unit/${id}`, su, { - headers: getHeader(authenticationMode), - }) - .then(res => resolve(res)) - .catch(e => reject(new Error(`Failed to put survey-unit (id:${id}) : ${e?.message}`))); - }) - .catch(e => reject(new Error(`Error during refreshToken : ${e?.message}`))); - }); +export const putDataSurveyUnitById = (urlPearApi, authenticationMode) => async (id, su) => { + try { + await authentication(authenticationMode); + const token = getToken(); + return API.putDataSurveyUnitById(urlPearApi)(id)(token)(su); + } catch (e) { + throw new Error(`Error during refreshToken : ${e}`); + } +}; + +export const putSurveyUnitToTempZone = (urlPearApi, authenticationMode) => async (id, su) => { + try { + await authentication(authenticationMode); + const token = getToken(); + return API.putToTempZone(urlPearApi)(id)(token)(su); + } catch (e) { + throw new Error(`Error during refreshToken : ${e}`); + } +}; diff --git a/src/utils/api/utils.js b/src/utils/api/utils.js index 1150a60a7..833cb1ca3 100644 --- a/src/utils/api/utils.js +++ b/src/utils/api/utils.js @@ -1,6 +1,8 @@ import { ANONYMOUS, JSON_UTF8_HEADER, KEYCLOAK, PEARL_USER_KEY } from 'utils/constants'; import { kc, keycloakAuthentication, refreshToken } from 'utils/keycloak'; +export const getToken = () => kc.token; + export const getSecureHeader = token => token ? { @@ -33,7 +35,7 @@ export const getHeader = mode => { }; } return { - ...getSecureHeader(kc.token), + ...getSecureHeader(getToken()), Accept: JSON_UTF8_HEADER, }; default: diff --git a/yarn.lock b/yarn.lock index afbc6ff8c..9d05e0597 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2919,13 +2919,6 @@ axe-core@^4.0.2: resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.1.3.tgz#64a4c85509e0991f5168340edc4bedd1ceea6966" integrity sha512-vwPpH4Aj4122EW38mxO/fxhGKtwWTMLDIJfZ1He0Edbtjcfna/R3YB67yVhezUMzqc3Jr3+Ii50KRntlENL4xQ== -axios@^0.19.2: - version "0.19.2" - resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.2.tgz#3ea36c5d8818d0d5f8a8a97a6d36b86cdc00cb27" - integrity sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA== - dependencies: - follow-redirects "1.5.10" - axobject-query@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.2.0.tgz#943d47e10c0b704aa42275e20edf3722648989be" @@ -4401,13 +4394,6 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.9: dependencies: ms "2.0.0" -debug@=3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" - integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== - dependencies: - ms "2.0.0" - debug@^3.1.1: version "3.2.6" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" @@ -5732,13 +5718,6 @@ flush-write-stream@^1.0.0: inherits "^2.0.3" readable-stream "^2.3.6" -follow-redirects@1.5.10: - version "1.5.10" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a" - integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ== - dependencies: - debug "=3.1.0" - follow-redirects@^1.0.0: version "1.13.0" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.0.tgz#b42e8d93a2a7eea5ed88633676d6597bc8e384db" From f7c3494c5cf638f3158ed67023ecfb56855e9c95 Mon Sep 17 00:00:00 2001 From: Laurent Caouissin Date: Tue, 3 Aug 2021 11:34:43 +0200 Subject: [PATCH 07/62] remove axios --- package.json | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 65c1e5cd1..1e6580beb 100644 --- a/package.json +++ b/package.json @@ -3,15 +3,14 @@ "version": "0.4.0", "private": true, "dependencies": { - "@testing-library/jest-dom": "^5.11.9", - "@testing-library/react": "^11.2.5", - "@testing-library/user-event": "^11.2.5", "@date-io/date-fns": "1.x", "@material-ui/core": "^4.11.2", "@material-ui/icons": "^4.11.2", "@material-ui/lab": "^4.0.0-alpha.57", "@material-ui/pickers": "^3.2.10", - "axios": "^0.19.2", + "@testing-library/jest-dom": "^5.11.9", + "@testing-library/react": "^11.2.5", + "@testing-library/user-event": "^11.2.5", "clsx": "^1.1.1", "date-fns": "^2.18.0", "dexie": "^2.0.4", @@ -95,7 +94,6 @@ ] }, "devDependencies": { - "@types/react": "^16.9.23", "@types/react-router-dom": "^5.1.3", "copy-and-watch": "^0.1.4", @@ -107,8 +105,8 @@ "eslint-plugin-jsx-a11y": "^6.4.1", "eslint-plugin-prettier": "^3.3.1", "eslint-plugin-react": "^7.16.0", - "jest-sonar-reporter": "^2.0.0", "eslint-plugin-react-hooks": "^4.2.0", + "jest-sonar-reporter": "^2.0.0", "prettier": "^1.19.1" } } From 96eff4a956fab1e9363a5fad8174bbe66777ddd7 Mon Sep 17 00:00:00 2001 From: Laurent Caouissin Date: Tue, 3 Aug 2021 11:39:22 +0200 Subject: [PATCH 08/62] Create new table in dataBase to save units in error during synchro --- src/indexedbb/schema.json | 1 + src/indexedbb/services/surveyUnitMissing-idb-service.js | 9 +++++++++ 2 files changed, 10 insertions(+) create mode 100644 src/indexedbb/services/surveyUnitMissing-idb-service.js diff --git a/src/indexedbb/schema.json b/src/indexedbb/schema.json index 3cc87981d..ae2a34267 100644 --- a/src/indexedbb/schema.json +++ b/src/indexedbb/schema.json @@ -1,4 +1,5 @@ { "surveyUnit": "id,sampleIdentifiers,persons,lastName,firstName,address,phoneNumbers,state,comments,questionnaireState,campaign,campaignLabel,collectionStartDate,collectionEndDate,identificationPhaseStartDate,interviewerStartDate,managementStartDate,endDate,geographicalLocation,lastState,states,contactAttempts,contactOutcome", + "surveyUnitMissing": "id", "notification": "++id,date,time,title,message" } diff --git a/src/indexedbb/services/surveyUnitMissing-idb-service.js b/src/indexedbb/services/surveyUnitMissing-idb-service.js new file mode 100644 index 000000000..a2f20beaf --- /dev/null +++ b/src/indexedbb/services/surveyUnitMissing-idb-service.js @@ -0,0 +1,9 @@ +import AbstractIdbService from './abstract-idb-service'; + +class SurveyUnitMissingIdbService extends AbstractIdbService { + constructor() { + super('surveyUnitMissing'); + } +} + +export default new SurveyUnitMissingIdbService(); From 16613cb67a5c0072ed0f49168ec00433c00aa376 Mon Sep 17 00:00:00 2001 From: Laurent Caouissin Date: Tue, 3 Aug 2021 11:39:45 +0200 Subject: [PATCH 09/62] Use context to load confifg --- src/utils/auth/initAuth.js | 74 +++++++++++++++++++------------------- 1 file changed, 36 insertions(+), 38 deletions(-) diff --git a/src/utils/auth/initAuth.js b/src/utils/auth/initAuth.js index 5dc20f2d9..b704152ce 100644 --- a/src/utils/auth/initAuth.js +++ b/src/utils/auth/initAuth.js @@ -1,9 +1,11 @@ import { GUEST_PEARL_USER, PEARL_USER_KEY } from 'utils/constants'; import { getTokenInfo, keycloakAuthentication } from 'utils/keycloak'; -import { useEffect, useState } from 'react'; +import { useContext, useEffect, useState } from 'react'; +import { AppContext } from 'Root'; export const useAuth = () => { const [authenticated, setAuthenticated] = useState(false); + const configuration = useContext(AppContext); const interviewerRoles = ['pearl-interviewer', 'uma_authorization', 'Guest']; @@ -29,45 +31,41 @@ export const useAuth = () => { }; useEffect(() => { - const configURL = `${window.location.origin}/configuration.json`; - fetch(configURL) - .then(response => response.json()) - .then(data => { - switch (data.PEARL_AUTHENTICATION_MODE) { - case 'anonymous': - window.localStorage.setItem(PEARL_USER_KEY, JSON.stringify(GUEST_PEARL_USER)); - accessAuthorized(); - break; + const { PEARL_AUTHENTICATION_MODE } = configuration; + switch (PEARL_AUTHENTICATION_MODE) { + case 'anonymous': + window.localStorage.setItem(PEARL_USER_KEY, JSON.stringify(GUEST_PEARL_USER)); + accessAuthorized(); + break; - case 'keycloak': - if (!authenticated) { - keycloakAuthentication({ - onLoad: 'login-required', - checkLoginIframe: false, - }) - .then(auth => { - if (auth) { - const interviewerInfos = getTokenInfo(); - const { roles } = interviewerInfos; - if (isAuthorized(roles)) { - window.localStorage.setItem(PEARL_USER_KEY, JSON.stringify(interviewerInfos)); - accessAuthorized(); - } else { - accessDenied(); - } - // offline mode - } else if (isLocalStorageTokenValid()) { - accessAuthorized(); - } else { - accessDenied(); - } - }) - .catch(() => (isLocalStorageTokenValid() ? accessAuthorized() : accessDenied())); - } - break; - default: + case 'keycloak': + if (!authenticated) { + keycloakAuthentication({ + onLoad: 'login-required', + checkLoginIframe: false, + }) + .then(auth => { + if (auth) { + const interviewerInfos = getTokenInfo(); + const { roles } = interviewerInfos; + if (isAuthorized(roles)) { + window.localStorage.setItem(PEARL_USER_KEY, JSON.stringify(interviewerInfos)); + accessAuthorized(); + } else { + accessDenied(); + } + // offline mode + } else if (isLocalStorageTokenValid()) { + accessAuthorized(); + } else { + accessDenied(); + } + }) + .catch(() => (isLocalStorageTokenValid() ? accessAuthorized() : accessDenied())); } - }); + break; + default: + } }); return { authenticated }; From 96a0046830a39f066b93b09b859bcec1924bcbea Mon Sep 17 00:00:00 2001 From: Laurent Caouissin Date: Tue, 3 Aug 2021 11:41:57 +0200 Subject: [PATCH 10/62] Manage inacessible unit (when there is no data in queen dataBase) --- .../panel-body/UESpage/component.js | 9 ++++- .../UESpage/material/surveyUnitCard.js | 39 ++++++++++++------- .../UEpage/comments/comment/component.js | 2 +- src/components/panel-body/UEpage/component.js | 18 ++++++--- .../contacts/contactAttempts/component.js | 2 +- .../panel-body/UEpage/details/component.js | 2 +- .../panel-body/UEpage/forms/addressForm.js | 2 +- .../UEpage/forms/contactAttemptsForm.js | 2 +- .../UEpage/forms/contactOutcomeForm.js | 2 +- .../panel-body/UEpage/forms/mailForm.js | 2 +- .../panel-body/UEpage/forms/phoneForm.js | 2 +- .../panel-body/UEpage/forms/userForm.js | 2 +- .../panel-body/UEpage/navigation/component.js | 6 ++- src/components/panel-body/UEpage/router.js | 2 +- src/components/panel-body/UEpage/stateLine.js | 2 +- src/utils/functions/surveyUnitFunctions.js | 4 +- 16 files changed, 61 insertions(+), 37 deletions(-) diff --git a/src/components/panel-body/UESpage/component.js b/src/components/panel-body/UESpage/component.js index ea998b4fa..eb2efbaed 100644 --- a/src/components/panel-body/UESpage/component.js +++ b/src/components/panel-body/UESpage/component.js @@ -6,6 +6,7 @@ import PropTypes from 'prop-types'; import React, { useEffect, useState } from 'react'; import FilterPanel from './filterPanel'; import SurveyUnitCard from './material/surveyUnitCard'; +import surveyUnitMissingIdbService from 'indexedbb/services/surveyUnitMissing-idb-service'; const UESPage = ({ textSearch }) => { const [surveyUnits, setSurveyUnits] = useState([]); @@ -22,9 +23,15 @@ const UESPage = ({ textSearch }) => { terminated: false, }); + const [inaccessibles, setInaccessibles] = useState([]); + useEffect(() => { if (!init) { setInit(true); + surveyUnitMissingIdbService + .getAll() + .then(units => setInaccessibles(units.map(({ id }) => id))); + surveyUnitDBService.getAll().then(units => { const initializedSU = units.map(su => ({ ...su, selected: false })); setCampaigns([...new Set(units.map(unit => unit.campaign))]); @@ -89,7 +96,7 @@ const UESPage = ({ textSearch }) => { {filteredSurveyUnits.map(su => ( - + ))} diff --git a/src/components/panel-body/UESpage/material/surveyUnitCard.js b/src/components/panel-body/UESpage/material/surveyUnitCard.js index 2814fb413..c868ef78e 100644 --- a/src/components/panel-body/UESpage/material/surveyUnitCard.js +++ b/src/components/panel-body/UESpage/material/surveyUnitCard.js @@ -3,6 +3,7 @@ import CardContent from '@material-ui/core/CardContent'; import { makeStyles } from '@material-ui/core/styles'; import Typography from '@material-ui/core/Typography'; import CheckCircleOutlineIcon from '@material-ui/icons/CheckCircleOutline'; +import WarningIcon from '@material-ui/icons/Warning'; import LocationOnIcon from '@material-ui/icons/LocationOn'; import PersonIcon from '@material-ui/icons/Person'; import RadioButtonUncheckedSharpIcon from '@material-ui/icons/RadioButtonUncheckedSharp'; @@ -17,6 +18,7 @@ import { import PropTypes from 'prop-types'; import React from 'react'; import { useHistory } from 'react-router-dom'; +import { Tooltip } from '@material-ui/core'; const useStyles = makeStyles(() => ({ root: { @@ -33,12 +35,12 @@ const useStyles = makeStyles(() => ({ justifyContent: 'space-between', }, justifyStart: { + display: 'flex', justifyContent: 'flex-start', }, flexColumn: { display: 'flex', flexDirection: 'column', - justifyContent: 'flex-end', }, content: { flex: '1 0 auto', @@ -57,7 +59,6 @@ const useStyles = makeStyles(() => ({ '&:hover': { cursor: 'not-allowed' }, }, paddingTop: { - height: 'max-content', paddingTop: '10px', fontSize: 'xxx-large', }, @@ -79,9 +80,10 @@ const useStyles = makeStyles(() => ({ leftMargin: { marginLeft: '2px', }, + warning: { color: 'orange' }, })); -const SurveyUnitCard = ({ surveyUnit }) => { +const SurveyUnitCard = ({ surveyUnit, inaccessible = false }) => { const classes = useStyles(); const history = useHistory(); @@ -127,16 +129,23 @@ const SurveyUnitCard = ({ surveyUnit }) => { {ssech} - - -
- - {firstName} - - - {lastName} - + +
+ +
+ + {firstName} + + + {lastName} + +
+ {inaccessible && ( + + + + )}
@@ -170,9 +179,9 @@ const SurveyUnitCard = ({ surveyUnit }) => { export default SurveyUnitCard; SurveyUnitCard.propTypes = { surveyUnit: PropTypes.shape({ - id: PropTypes.string.isRequired, - firstName: PropTypes.string.isRequired, - lastName: PropTypes.string.isRequired, + id: PropTypes.string, + firstName: PropTypes.string, + lastName: PropTypes.string, address: PropTypes.shape({ l6: PropTypes.string.isRequired }).isRequired, campaign: PropTypes.string.isRequired, states: PropTypes.arrayOf(PropTypes.shape({ type: PropTypes.string.isRequired })).isRequired, diff --git a/src/components/panel-body/UEpage/comments/comment/component.js b/src/components/panel-body/UEpage/comments/comment/component.js index 8fb2454e0..c9b8477e9 100644 --- a/src/components/panel-body/UEpage/comments/comment/component.js +++ b/src/components/panel-body/UEpage/comments/comment/component.js @@ -21,7 +21,7 @@ const useStyles = makeStyles(() => ({ })); const Comment = ({ editable, save }) => { - const surveyUnit = useContext(SurveyUnitContext); + const { surveyUnit } = useContext(SurveyUnitContext); const value = editable ? getCommentByType('INTERVIEWER', surveyUnit) : getCommentByType('MANAGEMENT', surveyUnit); diff --git a/src/components/panel-body/UEpage/component.js b/src/components/panel-body/UEpage/component.js index ffa2e6428..1e1193a23 100644 --- a/src/components/panel-body/UEpage/component.js +++ b/src/components/panel-body/UEpage/component.js @@ -7,19 +7,25 @@ import React, { useEffect, useState } from 'react'; import { useHistory, useParams } from 'react-router-dom'; import Router from './router'; import { SurveyUnitProvider } from './UEContext'; +import surveyUnitMissingIdbService from 'indexedbb/services/surveyUnitMissing-idb-service'; const UEPage = ({ match, refresh: homeRefresh }) => { const [surveyUnit, setSurveyUnit] = useState(undefined); const [shouldRefresh, setShouldRefresh] = useState(true); + const [inaccessible, setInaccessible] = useState(false); + const [loading, setLoading] = useState(true); const history = useHistory(); const { id } = useParams(); useEffect(() => { const updateSurveyUnit = async () => { - await surveyUnitDBService.getById(id).then(ue => { - setSurveyUnit({ ...ue }); - }); + setLoading(true); + const ue = await surveyUnitDBService.getById(id); + if (ue) setSurveyUnit({ ...ue }); + const isMissing = await surveyUnitMissingIdbService.getById(id); + if (isMissing) setInaccessible(true); + setLoading(false); }; if (shouldRefresh) { updateSurveyUnit(); @@ -50,13 +56,13 @@ const UEPage = ({ match, refresh: homeRefresh }) => { return ( <> - {surveyUnit && ( - + {surveyUnit && !loading && ( + )} - {!surveyUnit && ( + {!surveyUnit && !loading && ( <>