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 }; +};