Skip to content

Commit

Permalink
Merge pull request #42 from InseeFrLab/feat/sprint16
Browse files Browse the repository at this point in the history
Feat/sprint16
  • Loading branch information
MichaelC67 authored Jan 17, 2024
2 parents e338276 + b8bec57 commit a9a4eb4
Show file tree
Hide file tree
Showing 56 changed files with 2,275 additions and 751 deletions.
4 changes: 2 additions & 2 deletions .env.development
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
REACT_APP_STROMAE_BACK_OFFICE_API_BASE_URL=https://stromae-edt-kc.demo.insee.io/
REACT_APP_EDT_ORGANISATION_API_BASE_URL=https://edt-api-kc.demo.insee.io/
REACT_APP_KEYCLOAK_AUTHORITY=https://auth.demo.insee.io/auth/realms/questionnaires-edt/
REACT_APP_KEYCLOAK_AUTHORITY_REVIEWER=https://auth.insee.io/auth/realms/questionnaires-particuliers/
REACT_APP_KEYCLOAK_AUTHORITY_REVIEWER=https://auth.insee.io/auth/realms/questionnaires-particuliers/?kc_idp_hint=insee-ssp
REACT_APP_KEYCLOAK_CLIENT_ID=client-edt
REACT_APP_KEYCLOAK_REDIRECT_URI=http://localhost:3000/
REACT_APP_HOUSE_REFERENCE_REGULAR_EXPRESSION=.\$
REACT_APP_SEPARATOR_SUGGESTER=;
REACT_APP_NODE_ENV="development"
REACT_APP_CHROMIUM_PATH=node_modules/chromium/lib/chromium/chrome-win/chrome.exe
REACT_APP_NUM_ACTIVITY_SURVEYS=6
REACT_APP_NUM_WORKTIME_SURVEYS=2
REACT_APP_NUM_WORKTIME_SURVEYS=3
4 changes: 2 additions & 2 deletions .env.production
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
REACT_APP_STROMAE_BACK_OFFICE_API_BASE_URL=https://stromae-edt-kc.demo.insee.io/
REACT_APP_EDT_ORGANISATION_API_BASE_URL=https://edt-api-kc.demo.insee.io/
REACT_APP_KEYCLOAK_AUTHORITY=https://auth.demo.insee.io/auth/realms/questionnaires-edt/
REACT_APP_KEYCLOAK_AUTHORITY_REVIEWER=https://auth.insee.io/auth/realms/questionnaires-particuliers/
REACT_APP_KEYCLOAK_AUTHORITY_REVIEWER=https://auth.insee.io/auth/realms/questionnaires-particuliers/?kc_idp_hint=insee-ssp
REACT_APP_KEYCLOAK_CLIENT_ID=client-edt
REACT_APP_KEYCLOAK_REDIRECT_URI=https://insee-recette-edt.k8s.keyconsulting.fr/
REACT_APP_HOUSE_REFERENCE_REGULAR_EXPRESSION=.\$
REACT_APP_SEPARATOR_SUGGESTER=;
REACT_APP_NODE_ENV="production"
REACT_APP_CHROMIUM_PATH=/builds/insee/edt/deploy/pwa-edt/node_modules/chromium/lib/chromium/chrome-linux/chrome
REACT_APP_NUM_ACTIVITY_SURVEYS=6
REACT_APP_NUM_WORKTIME_SURVEYS=2
REACT_APP_NUM_WORKTIME_SURVEYS=3
4 changes: 2 additions & 2 deletions .env.staging
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
REACT_APP_STROMAE_BACK_OFFICE_API_BASE_URL=https://stromae-edt-kc.demo.insee.io/
REACT_APP_EDT_ORGANISATION_API_BASE_URL=https://edt-api-kc.demo.insee.io/
REACT_APP_KEYCLOAK_AUTHORITY=https://auth.demo.insee.io/auth/realms/questionnaires-edt/
REACT_APP_KEYCLOAK_AUTHORITY_REVIEWER=https://auth.insee.io/auth/realms/questionnaires-particuliers/
REACT_APP_KEYCLOAK_AUTHORITY_REVIEWER=https://auth.insee.io/auth/realms/questionnaires-particuliers/?kc_idp_hint=insee-ssp
REACT_APP_KEYCLOAK_CLIENT_ID=client-edt
REACT_APP_KEYCLOAK_REDIRECT_URI=https://insee-edt.k8s.keyconsulting.fr/
REACT_APP_HOUSE_REFERENCE_REGULAR_EXPRESSION=.\$
REACT_APP_SEPARATOR_SUGGESTER=;
REACT_APP_NODE_ENV="staging"
REACT_APP_CHROMIUM_PATH=/builds/insee/edt/deploy/pwa-edt/node_modules/chromium/lib/chromium/chrome-linux/chrome
REACT_APP_NUM_ACTIVITY_SURVEYS=6
REACT_APP_NUM_WORKTIME_SURVEYS=2
REACT_APP_NUM_WORKTIME_SURVEYS=3
DISPLAY=:10.0
121 changes: 110 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -338,29 +338,35 @@ This information concerns the surveyer interface. A color code have been set to

Those states have been defined to ease the visibility of the ongoing current survey campain for the surveyer.

## Lifecycle state

![](https://imgur.com/Y3bjnVs.png)

### Project structure

![](https://i.imgur.com/Jt1FrnR.png)

`src` : Contains all the source code of the application. It also has the 2 surveys sources required by Lunatic and used by EDT.

`enumerations` : Contains all enumerations of the application.

`service` : Contains all the app services. Please refer to the [Services section](#services) for further information.
`assets` : Contains all app assets such as svg icons or fonts.

`components` : Contains two folders. `commons` which has all the components that could be reusable in another app that would work like EDT using Lunatic. `edt` that has all the EDT specific components.

`documentation` : Contains the app technical documentation. Including `LunaticSourceToEdt.xlsx` file that contains the links between the EDT pages, the Lunatic-EDT components used and the sources variables.

`enumerations` : Contains all enumerations of the application.

`i18n` : Contains i18n configuration and `fr.json` which is the file that holds all the app labels including accessility labels.

`interface` : Contains all the Typescript interfaces of the used entities, lunatic models etc...

`routes` : Contains `EdtRoutes.tsx` which holds the React BrowserRouter tag and all the navigation routes. `EdtRoutesMapping.ts` is holding the `mappingPageOrchestrator` (refer to the [Enumerations & Maps](#maps) section).
`orchestrator`: Contains orchestrator, which manages the communication of the app with lunatic, where we recover the Lunatic components, its data, etc.

`pages` : Contains all app pages. The `activity` folder holds the specific pages for the activity survey and `work-time` the ones for the work time survey. Other common pages are directly inside the `pages` folder.

`documentation` : Contains the app technical documentation. Including `LunaticSourceToEdt.xlsx` file that contains the links between the EDT pages, the Lunatic-EDT components used and the sources variables.

`i18n` : Contains i18n configuration and `fr.json` which is the file that holds all the app labels including accessility labels.
`routes` : Contains `EdtRoutes.tsx` which holds the React BrowserRouter tag and all the navigation routes. `EdtRoutesMapping.ts` is holding the `mappingPageOrchestrator` (refer to the [Enumerations & Maps](#maps) section).

`assets` : Contains all app assets such as svg icons or fonts.
`service` : Contains all the app services. Please refer to the [Services section](#services) for further information.

### Authentification

Expand All @@ -372,14 +378,15 @@ These two environment variables are used to setup the connection :

```
REACT_APP_KEYCLOAK_AUTHORITY=https://auth.demo.insee.io/auth/realms/questionnaires-edt/
REACT_APP_KEYCLOAK_AUTHORITY_REVIEWER=https://auth.insee.io/auth/realms/questionnaires-particuliers/?kc_idp_hint=insee-ssp
REACT_APP_KEYCLOAK_CLIENT_ID=client-edt
```

The user bearer token is used to call the secured APIs.

The accounts are created and managed by INSEE. It is not possible to sign up by yourself.

SSO is available using INSEE LDAP.
SSO is available using INSEE LDAP only with users with reviewer role. The reviewer is already authenticated when we enter with SSO, if he enter the url https://{URL_ENVIRO}/?kc_idp_hint=insee-ssp already authenticated, he is redirect to the main page of the app taking the current token and the information corresponding, without having to go through the authentication page again.

### APIs usage

Expand Down Expand Up @@ -969,7 +976,7 @@ The `.env.production` file is used when the builded app is hosted.
REACT_APP_STROMAE_BACK_OFFICE_API_BASE_URL=https://stromae-edt-kc.demo.insee.io/
REACT_APP_EDT_ORGANISATION_API_BASE_URL=https://edt-api-kc.demo.insee.io/
REACT_APP_KEYCLOAK_AUTHORITY=https://auth.demo.insee.io/auth/realms/questionnaires-edt/
REACT_APP_KEYCLOAK_AUTHORITY_REVIEWER=https://auth.insee.io/auth/realms/questionnaires-particuliers/
REACT_APP_KEYCLOAK_AUTHORITY_REVIEWER=https://auth.insee.io/auth/realms/questionnaires-particuliers/?kc_idp_hint=insee-ssp
REACT_APP_KEYCLOAK_CLIENT_ID=client-edt
REACT_APP_KEYCLOAK_REDIRECT_URI=https://insee-recette-edt.k8s.keyconsulting.fr/
REACT_APP_HOUSE_REFERENCE_REGULAR_EXPRESSION=.\$
Expand All @@ -982,7 +989,99 @@ REACT_APP_NUM_WORKTIME_SURVEYS=2
```
</details>

REACT_APP_NUM_ACTIVITY_SURVEYS and REACT_APP_NUM_WORKTIME_SURVEYS allows to change the amount of each survey kind for user.
`REACT_APP_NUM_ACTIVITY_SURVEYS` and `REACT_APP_NUM_WORKTIME_SURVEYS` allows to change the amount of each survey kind for user.

## Orchestrator


Orchestrator manages the communication of the app with lunatic, where we recover the Lunatic components, its data, etc.

Currently the application manages access modes (profiles): interviewer mode and reviewer mode which can save and consult data.

​The app manages the two modes using the different properties that exist in the database, for each variable.
For each variable, there are 5 usable properties: **COLLECTED, EDITED, FORCED, INPUTED, PREVIOUS**. In this app, we will use the **COLLECTED** property for the **interviewer mode** and the **EDITED** property for the **reviewer mode**.

Normally, the management of persistence modes is done on the lunatic side, unfortunately the current version that we use on the app does not take this option into account. To resolve this problem, we managed the recovery of data from the orchestrator.

### Updated variables

The orchestrator is summoned on each page of the application where we have displayed a lunatic component.

For each lunatic component, we have several variables attached. Each time we enter the corresponding page, we modify the corresponding variables; if we do not enter this page, no modification is made to the variables.

For example, for the creation of an activity, on the page for choosing a main activity (main_activity), we have attached the lunatic component "activity_selecter" and on this component we have the variables: **"MAINACTIVITY_ID", "MAINACTIVITY_SUGGESTERID" , "MAINACTIVITY_LABEL", "MAINACTIVITY_ISFULLYCOMPLETED", "INPUT_SUGGESTER", "ACTIVITY_SELECTER_HISTORY"**.

So, if you create an activity, when you arrive on the main_activity page, the values for these variables are updated, so we add a value to the array or we modify the corresponding value.
If you create an activity, but get to the previous step, you will never modify the values of these variables.
Even if you create a path, it never passes through this component, so we cannot modify the values.

### Orchestrator flow

The callbackHolder function recovers the data and the errors which give us lunatic.

![](https://imgur.com/SNpbvje.png)

The getData() function provided by lunatic, instead of returning it within callbackHolder, we proceed to process the data recovered by lunatic, to be able to transform that data, along with that of the database and obtain our data model filled with the COLLECTED and EDITED.

For this process,

First, the profile of the current user is obtained.

If the user is an interviewer, the data is treated as follows:

- getData(): data of lunatic,
- data: data in database,

For each existing property :

- **value of EDITED:** if mode EDITED exists in the database *(data[prop].EDITED)*, it is set, otherwise value is null .
- **value of COLLECTED:** data of lunatic *(callbackholder.getData()[prop].COLLECTED)*;



![](https://imgur.com/JCtEcUC.png)


If the user is a reviewer, the data is treated as follows:

- getData(): data of lunatic,
- data: data in database,

For each existing property :

value of lunatic for value[iteration], other -> value of bdd (EDITED)

- if (prop being modified in current component (prop in binding dependencies)) :

- if(exist data for property in lunatic) :

- if (data for property is array):


- **value of EDITED:** data of lunatic for data[iteration] *(callbackholder.getData()[prop].COLLECTED[iteration])* and for other values data of bbdd *(data[prop].EDITED[i])*.
- **value of COLLECTED:** data of bbdd *(data[prop].COLLECTED)*;

- else :

- **value of EDITED:** data of lunatic *(callbackholder.getData()[prop].COLLECTED)*.
- **value of COLLECTED:** data of bbdd *(data[prop].COLLECTED)*;

- else :

- **value of EDITED:** data of bbdd *(data[prop].EDITED)*;
- **value of COLLECTED:** data of bbdd *(data[prop].COLLECTED)*;

- else :

- **value of EDITED:** data of bbdd *(data[prop].EDITED)*;
- **value of COLLECTED:** data of bbdd *(data[prop].COLLECTED)*;

![](https://imgur.com/PNZL2hu.png)

Here a diagram of the flow of orchestrator data

![Orchestrator data flow](https://imgur.com/yYYqvSJ.png)


## Maintenance and evolution

Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
{
"name": "edt",
"version": "3.9.0",
"dateVersion": "12/12/2023",
"version": "3.10.3",
"dateVersion": "09/01/2024",
"licence": "MIT",
"dependencies": {
"@emotion/react": "^11.10.4",
"@emotion/styled": "^11.10.4",
"@inseefr/lunatic": "2.0.7-v2",
"@inseefrlab/lunatic-edt": "^0.11.3",
"@inseefrlab/lunatic-edt": "^0.11.7",
"@mui/material": "^5.10.7",
"@mui/styles": "^5.12.0",
"@react-pdf/font": "2.2.0",
Expand Down
14 changes: 14 additions & 0 deletions src/App.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,20 @@ jest.mock("oidc-react", () => ({
},
}));

Object.defineProperty(window, "matchMedia", {
writable: true,
value: jest.fn().mockImplementation(query => ({
matches: false,
media: query,
onchange: null,
addListener: jest.fn(), // Deprecated
removeListener: jest.fn(), // Deprecated
addEventListener: jest.fn(),
removeEventListener: jest.fn(),
dispatchEvent: jest.fn(),
})),
});

jest.mock("react-i18next", () => ({
// this mock makes sure any components using the translate hook can use it without a warning being shown
useTranslation: () => {
Expand Down
62 changes: 39 additions & 23 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,34 +33,50 @@ const App = () => {
if (auth?.userData?.access_token && getDatas().size === 0 && error === undefined) {
setUserToken(auth.userData?.access_token);
setUser(auth.userData);
setAuth(auth);
//keeps user token up to date after session renewal
auth.userManager.events.addUserLoaded(() => {
auth.userManager.getUser().then(user => {
setUserToken(user?.access_token || "");
});
}

setAuth(auth);
//keeps user token up to date after session renewal
auth.userManager?.events.addUserLoaded(() => {
auth.userManager.getUser().then(user => {
setUserToken(user?.access_token || "");
});
});

auth.userManager?.events.addSilentRenewError(() => {
if (navigator.onLine) {
auth.userManager
.signoutRedirect({
id_token_hint: getTokenHint(),
})
.then(() => auth.userManager.clearStaleState())
.then(() => auth.userManager.signoutRedirectCallback())
.then(() => {
sessionStorage.clear();
localStorage.clear();
})
.then(() => auth.userManager.clearStaleState())
.then(() => window.location.replace(process.env.REACT_APP_PUBLIC_URL || ""))
.catch(err => {
setErrorType(err);
});
}
});

auth.userManager.events.addSilentRenewError(() => {
if (navigator.onLine) {
auth.userManager
.signoutRedirect({
id_token_hint: getTokenHint(),
})
.then(() => auth.userManager.clearStaleState())
.then(() => auth.userManager.signoutRedirectCallback())
.then(() => {
sessionStorage.clear();
localStorage.clear();
})
.then(() => auth.userManager.clearStaleState())
.then(() => window.location.replace(process.env.REACT_APP_PUBLIC_URL || ""))
.catch(err => {
setErrorType(err);
});
auth.userManager?.settings.userStore.getAllKeys().then(keys => {
auth.userManager.settings.stateStore.getAllKeys().then(keysState => {
if (
window.location.search.includes("state") &&
auth.userData == null &&
keys.length == 0 &&
keysState.length == 0
) {
window.location.search = "";
}
});
});

if (auth.userData) {
initializeDatas(setError).then(() => {
setInitialized(true);
});
Expand Down
2 changes: 2 additions & 0 deletions src/activity-survey.json
Original file line number Diff line number Diff line change
Expand Up @@ -715,6 +715,8 @@
"OTHERPRIVATE",
"PUBLIC",
"WITHSECONDARYACTIVITY",
"SECONDARYACTIVITY_SUGGESTERID",
"SECONDARYACTIVITY_LABEL",
"SECONDARYACTIVITY",
"PLACE",
"WITHSOMEONE",
Expand Down
Loading

0 comments on commit a9a4eb4

Please sign in to comment.