From b0e49cd358a904afd2c27c6a1720fe97ca2370de Mon Sep 17 00:00:00 2001
From: Laurent Caouissin <38245508+laurentC35@users.noreply.github.com>
Date: Wed, 8 Nov 2023 11:43:29 +0100
Subject: [PATCH] Feat/global runtime variables (#68)
* feat: create utils function to add external variables
* feat: add constants
* feat: global variables
- `GLOBAL_SURVEY_UNIT_ID`
- `GLOBAL_QUESTIONNAIRE_ID`
---
.../lightOrchestrator/lightOrchestrator.js | 7 ++-
.../orchestratorManager.js | 37 +++++++++++--
.../src/components/visualizer/visualizer.js | 55 +++++++++++--------
queen-v2/src/utils/constants/index.js | 5 ++
queen-v2/src/utils/hook/api.js | 2 +-
.../src/utils/questionnaire/questionnaire.js | 24 +++++++-
6 files changed, 96 insertions(+), 34 deletions(-)
diff --git a/queen-v2/src/components/lightOrchestrator/lightOrchestrator.js b/queen-v2/src/components/lightOrchestrator/lightOrchestrator.js
index e934d2a1..43d5ed20 100644
--- a/queen-v2/src/components/lightOrchestrator/lightOrchestrator.js
+++ b/queen-v2/src/components/lightOrchestrator/lightOrchestrator.js
@@ -27,7 +27,8 @@ const dontKnowButton = D.doesntKnowButton;
const refusedButton = D.refusalButton;
function LightOrchestrator({
- surveyUnit,
+ initialData,
+ lastReachedPage,
standalone,
readonly,
pagination,
@@ -68,8 +69,8 @@ function LightOrchestrator({
goNextPage();
});
- lunaticStateRef.current = useLunatic(source, surveyUnit?.data, {
- lastReachedPage: surveyUnit?.stateData?.currentPage ?? '1',
+ lunaticStateRef.current = useLunatic(source, initialData, {
+ lastReachedPage: lastReachedPage ?? '1',
features,
pagination,
onChange: lightCustomHandleChange,
diff --git a/queen-v2/src/components/orchestratorManager/orchestratorManager.js b/queen-v2/src/components/orchestratorManager/orchestratorManager.js
index 5fbaf99a..695ee599 100644
--- a/queen-v2/src/components/orchestratorManager/orchestratorManager.js
+++ b/queen-v2/src/components/orchestratorManager/orchestratorManager.js
@@ -1,6 +1,11 @@
import { useContext, useEffect, useMemo, useState } from 'react';
import { useHistory, useParams } from 'react-router-dom';
-import { ORCHESTRATOR_COLLECT, ORCHESTRATOR_READONLY, READ_ONLY } from 'utils/constants';
+import {
+ GLOBAL_QUEEN_VARIABLES,
+ ORCHESTRATOR_COLLECT,
+ ORCHESTRATOR_READONLY,
+ READ_ONLY,
+} from 'utils/constants';
import { EventsManager, INIT_ORCHESTRATOR_EVENT, INIT_SESSION_EVENT } from 'utils/events';
import { useAPI, useAPIRemoteData, useAuth, useGetReferentiel } from 'utils/hook';
import { COMPLETED, VALIDATED, useQuestionnaireState } from 'utils/hook/questionnaire';
@@ -13,12 +18,19 @@ import Preloader from 'components/shared/preloader';
import { sendCloseEvent } from 'utils/communication';
import { useConstCallback } from 'utils/hook/useConstCallback';
import surveyUnitIdbService from 'utils/indexedbb/services/surveyUnit-idb-service';
-import { checkQuestionnaire, getFullData, removeNullCollectedData } from 'utils/questionnaire';
+import {
+ addGlobalVariablesToData,
+ addGlobalVariablesToQuestionnaire,
+ checkQuestionnaire,
+ getFullData,
+ removeNullCollectedData,
+} from 'utils/questionnaire';
export const OrchestratorManager = () => {
const { standalone, apiUrl } = useContext(AppContext);
const { readonly: readonlyParam, idQ, idSU } = useParams();
const [surveyUnitData, setSurveyUnitData] = useState(null);
+ const [initalStateForLunatic, setInitalStateForLunatic] = useState(null);
const history = useHistory();
const readonly = readonlyParam === READ_ONLY;
@@ -65,8 +77,20 @@ export const OrchestratorManager = () => {
if (!init && questionnaire && surveyUnit) {
const { valid, error: questionnaireError } = checkQuestionnaire(questionnaire);
if (valid) {
- setSource(questionnaire);
- setSurveyUnitData(surveyUnit.data);
+ const globalQueenData = {
+ [GLOBAL_QUEEN_VARIABLES.GLOBAL_SURVEY_UNIT_ID]: surveyUnit.id,
+ [GLOBAL_QUEEN_VARIABLES.GLOBAL_QUESTIONNAIRE_ID]:
+ surveyUnit.questionnaireId ?? questionnaire.id,
+ };
+ const newQuestionnaire = addGlobalVariablesToQuestionnaire(questionnaire, globalQueenData);
+ setSource(newQuestionnaire);
+
+ const newData = addGlobalVariablesToData(surveyUnit?.data || {}, globalQueenData);
+ setSurveyUnitData(newData);
+ setInitalStateForLunatic({
+ initialData: newData,
+ lastReachedPage: surveyUnit?.stateData?.currentPage,
+ });
setInit(true);
LOGGER.log(INIT_ORCHESTRATOR_EVENT);
} else {
@@ -157,9 +181,10 @@ export const OrchestratorManager = () => {
{![READ_ONLY, undefined].includes(readonlyParam) && }
{loadingMessage && }
{error && }
- {!loadingMessage && !error && source && surveyUnit && (
+ {!loadingMessage && !error && source && initalStateForLunatic && (
{
const { apiUrl, standalone } = useContext(AppContext);
const [surveyUnitData, setSurveyUnitData] = useState(null);
- const [surveyUnit, setSurveyUnit] = useState(undefined);
+ const [initalStateForLunatic, setInitalStateForLunatic] = useState(null);
const [error, setError] = useState(null);
const [source, setSource] = useState(null);
const { questionnaireUrl, dataUrl, nomenclatures, readonly } = useVisuQuery();
- const {
- surveyUnit: suData,
- questionnaire,
- loadingMessage,
- errorMessage,
- } = useRemoteData(questionnaireUrl, dataUrl);
+ const { surveyUnit, questionnaire, loadingMessage, errorMessage } = useRemoteData(
+ questionnaireUrl,
+ dataUrl
+ );
const { getReferentielForVizu } = useGetReferentiel(nomenclatures);
const [getState, , onDataChange] = useQuestionnaireState(
surveyUnit?.id,
- suData?.stateData?.state
+ surveyUnit?.stateData?.state
);
const history = useHistory();
useEffect(() => {
- if (suData === null) return;
- const unit = {
- ...suData,
- id: '1234',
- };
+ if (surveyUnit === null) return;
const insertSuInIndexedDB = async su => {
- console.log('Initiating sudata in IDB', su);
+ console.log('Initiating fake surveyUnit in IDB', su);
await surveyUnitIdbService.addOrUpdateSU(su);
};
- insertSuInIndexedDB(unit);
- setSurveyUnit(unit);
- }, [suData]);
+ insertSuInIndexedDB(surveyUnit);
+ }, [surveyUnit]);
useEffect(() => {
- if (questionnaireUrl && questionnaire && suData) {
+ if (questionnaireUrl && questionnaire && surveyUnit) {
const { valid, error: questionnaireError } = checkQuestionnaire(questionnaire);
if (valid) {
- setSource(questionnaire);
- setSurveyUnitData(suData?.data || {});
+ const globalQueenData = {
+ [GLOBAL_QUEEN_VARIABLES.GLOBAL_SURVEY_UNIT_ID]: surveyUnit.id,
+ [GLOBAL_QUEEN_VARIABLES.GLOBAL_QUESTIONNAIRE_ID]:
+ surveyUnit.questionnaireId ?? questionnaire.id,
+ };
+ const newQuestionnaire = addGlobalVariablesToQuestionnaire(questionnaire, globalQueenData);
+ setSource(newQuestionnaire);
+
+ const newData = addGlobalVariablesToData(surveyUnit?.data || {}, globalQueenData);
+ setSurveyUnitData(newData);
+ setInitalStateForLunatic({
+ initialData: newData,
+ lastReachedPage: surveyUnit?.stateData?.currentPage,
+ });
} else {
setError(questionnaireError);
}
}
- }, [questionnaireUrl, questionnaire, suData, apiUrl]);
+ }, [questionnaireUrl, questionnaire, surveyUnit, apiUrl]);
useEffect(() => {
if (errorMessage) setError(errorMessage);
@@ -110,9 +118,10 @@ const Visualizer = () => {
<>
{loadingMessage && }
{error && }
- {questionnaireUrl && source && surveyUnit && (
+ {questionnaireUrl && source && initalStateForLunatic && (
{
setLoadingMessage(Dictionary.waintingData);
const dR = await API.getRequest(dataUrl || DEFAULT_DATA_URL)(fakeToken);
if (!dR.error) {
- setSurveyUnit(dR.data);
+ setSurveyUnit({ ...(dR.data || {}), id: '1234' });
setLoadingMessage(null);
} else setErrorMessage(getErrorMessage(dR, 'd'));
setLoadingMessage(null);
diff --git a/queen-v2/src/utils/questionnaire/questionnaire.js b/queen-v2/src/utils/questionnaire/questionnaire.js
index 95de5b10..0360407e 100644
--- a/queen-v2/src/utils/questionnaire/questionnaire.js
+++ b/queen-v2/src/utils/questionnaire/questionnaire.js
@@ -1,4 +1,4 @@
-import { MIN_LUNATIC_MODEL_VERSION, MIN_ENO_CORE_VERSION } from 'utils/constants';
+import { MIN_ENO_CORE_VERSION, MIN_LUNATIC_MODEL_VERSION } from 'utils/constants';
const checkVersion = (actualVersion, expectedVersion) => {
try {
@@ -54,3 +54,25 @@ export const checkQuestionnaire = ({
}
return { valid: true };
};
+
+/**
+ *
+ * @param {*} source questionnaire source
+ * @param {*} variables object of key, value
+ */
+export const addGlobalVariablesToQuestionnaire = (source = {}, globalVariables = {}) => {
+ const { variables } = source;
+ const newVariables = Object.entries(globalVariables).reduce((result, [name, value]) => {
+ return [...result, { variableType: 'EXTERNAL', name: name, value: null }];
+ }, variables);
+ return { ...source, variables: newVariables };
+};
+
+export const addGlobalVariablesToData = (lunaticData = {}, globalVariables = {}) => {
+ const { EXTERNAL } = lunaticData;
+ const newEXTERNAL = Object.entries(globalVariables).reduce((result, [name, value]) => {
+ return { ...result, [name]: value };
+ }, EXTERNAL || {});
+
+ return { ...lunaticData, EXTERNAL: newEXTERNAL };
+};