Skip to content

Commit

Permalink
Ref: use partial data to improve perf
Browse files Browse the repository at this point in the history
  • Loading branch information
laurentC35 committed Nov 3, 2023
1 parent 93ca82d commit 1a73fa7
Show file tree
Hide file tree
Showing 5 changed files with 173 additions and 202 deletions.
13 changes: 3 additions & 10 deletions queen-v2/src/components/lightOrchestrator/LoopPanel/component.js
Original file line number Diff line number Diff line change
@@ -1,32 +1,25 @@
import { memo, useEffect, useState } from 'react';
import { memo } from 'react';
import { useStyles } from './component.style';
import { Panel } from './panel';

const LoopPanelNotMemo = ({ loopVariables = [], getData, pager, goToPage }) => {
const LoopPanelNotMemo = ({ loopVariables = [], allData, pager, goToPage }) => {
const noLoopVariables = loopVariables.length === 0 || loopVariables[0] === undefined;

const classes = useStyles();

const [datas, setDatas] = useState(null);

const {
page: currentPage,
subPage: currentSubPage,
iteration: currentIteration,
lastReachedPage,
} = pager;

useEffect(() => {
if (!noLoopVariables) setDatas(getData());
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [noLoopVariables, loopVariables]);

if (noLoopVariables) return null;

// use page to select loopVariables depth
const depth = 0;
const targetVariable = loopVariables[depth];
const targetData = datas?.COLLECTED[targetVariable];
const targetData = allData?.COLLECTED[targetVariable];
const COLLECTED = targetData?.COLLECTED;
if (COLLECTED && (COLLECTED.length === 0 || COLLECTED[0] === null)) return null;

Expand Down
65 changes: 33 additions & 32 deletions queen-v2/src/components/lightOrchestrator/lightOrchestrator.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { useLunatic } from '@inseefr/lunatic';

import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { memo, useEffect, useMemo, useRef, useState } from 'react';
import ButtonContinue from './buttons/continue/index';

import D from 'i18n';
import { componentHasResponse } from 'utils/components/deduceState';
import { QUEEN_URL } from 'utils/constants';
import { useConstCallback } from 'utils/hook/useConstCallback';
import { LoopPanel } from './LoopPanel';
import { ComponentDisplayer } from './componentDisplayer';
import Header from './header';
Expand Down Expand Up @@ -36,6 +37,7 @@ function LightOrchestrator({
missing = true,
shortcut = true,
autoSuggesterLoading,
allData,
filterDescription,
onChange = onLogChange,
onDataChange = noDataChange,
Expand All @@ -47,7 +49,7 @@ function LightOrchestrator({
const classes = useStyles();
const lunaticStateRef = useRef();

const lightCustomHandleChange = useCallback(valueChange => {
const lightCustomHandleChange = useConstCallback(valueChange => {
if (lunaticStateRef === undefined) return;
const { getComponents, goNextPage } = lunaticStateRef.current;
const currentComponent = getComponents()?.[0];
Expand All @@ -60,13 +62,13 @@ function LightOrchestrator({
) {
goNextPage();
}
}, []);
});

const missingStrategy = useCallback(() => {
const missingStrategy = useConstCallback(() => {
if (lunaticStateRef === undefined) return;
const { goNextPage } = lunaticStateRef.current;
goNextPage();
}, []);
});

// TODO restore when lunatic handle object in missingButtons properties
// const dontKnowButton = <MissingButton shortcutLabel="F2" buttonLabel={D.doesntKnowButton} />;
Expand All @@ -89,6 +91,7 @@ function LightOrchestrator({
missingShortcut,
dontKnowButton,
refusedButton,
trackChanges: true,
workersBasePath: `${QUEEN_URL}/workers`,
});

Expand All @@ -106,7 +109,8 @@ function LightOrchestrator({
// getErrors,
// getModalErrors,
// getCurrentErrors,
getData,
// getData,
// getChangedData,
loopVariables = [],
Provider,
pageTag,
Expand All @@ -118,30 +122,30 @@ function LightOrchestrator({
useEffect(() => {
const savingTask = async () => {
if (lunaticStateRef.current === undefined) return;
const { getData: freshGetData, pageTag, pager } = lunaticStateRef.current;
const { getChangedData: freshGetChangedData, pageTag, pager } = lunaticStateRef.current;
if (previousPageTag.current === undefined) {
previousPageTag.current = pageTag;
return;
}
if (pageTag !== previousPageTag.current) {
previousPageTag.current = pageTag;
const allData = freshGetData();
onDataChange(allData.COLLECTED);
save(undefined, allData, pager.lastReachedPage);
const partialData = freshGetChangedData(true);
onDataChange(partialData);
save(undefined, partialData, pager.lastReachedPage);
}
};
savingTask();
}, [save, pager, onDataChange]);

const memoQuit = useCallback(() => {
const { getData: freshGetData, pager: freshPager } = lunaticStateRef.current;
quit(freshPager, freshGetData);
}, [quit]);
const memoQuit = useConstCallback(() => {
const { getChangedData: freshGetChangedData, pager: freshPager } = lunaticStateRef.current;
quit(freshPager, freshGetChangedData);
});

const memoDefinitiveQuit = useCallback(() => {
const { getData: freshGetData, pager: freshPager } = lunaticStateRef.current;
definitiveQuit(freshPager, freshGetData);
}, [definitiveQuit]);
const memoDefinitiveQuit = useConstCallback(() => {
const { getChangedData: freshGetChangedData, pager: freshPager } = lunaticStateRef.current;
definitiveQuit(freshPager, freshGetChangedData);
});

const [components, setComponents] = useState([]);

Expand All @@ -156,23 +160,20 @@ function LightOrchestrator({
// const modalErrors = getModalErrors();
// const currentErrors = typeof getCurrentErrors === 'function' ? getCurrentErrors() : [];

const trueGoToPage = useCallback(
targetPage => {
if (typeof targetPage === 'string') {
goToPage({ page: targetPage });
} else {
const { page, iteration, subPage } = targetPage;
goToPage({ page: page, iteration: iteration, subPage: subPage });
}
},
[goToPage]
);
const trueGoToPage = useConstCallback(targetPage => {
if (typeof targetPage === 'string') {
goToPage({ page: targetPage });
} else {
const { page, iteration, subPage } = targetPage;
goToPage({ page: page, iteration: iteration, subPage: subPage });
}
});

const goToLastReachedPage = useCallback(() => {
const goToLastReachedPage = useConstCallback(() => {
if (lunaticStateRef.current === undefined) return;
const { pager } = lunaticStateRef.current;
trueGoToPage(pager.lastReachedPage);
}, [trueGoToPage]);
});

const firstComponent = useMemo(() => [...components]?.[0], [components]);
const hasResponse = componentHasResponse(firstComponent);
Expand Down Expand Up @@ -228,7 +229,7 @@ function LightOrchestrator({
</Provider>
<LoopPanel
loopVariables={loopVariables}
getData={getData}
allData={allData}
pager={pager}
goToPage={trueGoToPage}
></LoopPanel>
Expand Down
146 changes: 70 additions & 76 deletions queen-v2/src/components/orchestratorManager/orchestratorManager.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useCallback, useContext, useEffect, useMemo, useState } from 'react';
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 { EventsManager, INIT_ORCHESTRATOR_EVENT, INIT_SESSION_EVENT } from 'utils/events';
Expand All @@ -11,12 +11,14 @@ import Error from 'components/shared/Error';
import NotFound from 'components/shared/not-found';
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 } from 'utils/questionnaire';
import { 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 history = useHistory();

const readonly = readonlyParam === READ_ONLY;
Expand All @@ -34,7 +36,6 @@ export const OrchestratorManager = () => {
const { surveyUnit, questionnaire, loadingMessage, errorMessage } = useAPIRemoteData(idSU, idQ);

const stateData = surveyUnit?.stateData;
const initialData = surveyUnit?.data;
const { oidcUser } = useAuth();
const isAuthenticated = !!oidcUser?.profile;

Expand All @@ -46,7 +47,6 @@ export const OrchestratorManager = () => {
const { putUeData /* postParadata */ } = useAPI();
const [getState, changeState, onDataChange] = useQuestionnaireState(
surveyUnit?.id,
initialData,
stateData?.state
);

Expand All @@ -66,6 +66,7 @@ export const OrchestratorManager = () => {
const { valid, error: questionnaireError } = checkQuestionnaire(questionnaire);
if (valid) {
setSource(questionnaire);
setSurveyUnitData(surveyUnit.data);
setInit(true);
LOGGER.log(INIT_ORCHESTRATOR_EVENT);
} else {
Expand All @@ -81,84 +82,76 @@ export const OrchestratorManager = () => {
/** take a survey-unit as parameter, then save it in IDB, then save paradatas in IDB
* If in standalone mode : make API calls to persist data in DB
*/
const saveData = useCallback(
async unit => {
if (!readonly) {
const putSurveyUnit = async unit => {
const { id, ...other } = unit;
await putUeData(id, other);
};

await surveyUnitIdbService.addOrUpdateSU(unit);

/**
* Disable temporaly paradata
*
* const paradatas = LOGGER.getEventsToSend();
*/
// TODO : make a true update of paradatas : currently adding additional completed arrays => SHOULD save one and only one array
// await paradataIdbService.update(paradatas);
if (standalone) {
// TODO managing errors
await putSurveyUnit(unit);
// await postParadata(paradatas);
}
const saveData = useConstCallback(async unit => {
if (!readonly) {
const putSurveyUnit = async unit => {
const { id, ...other } = unit;
await putUeData(id, other);
};

await surveyUnitIdbService.addOrUpdateSU(unit);

/**
* Disable temporaly paradata
*
* const paradatas = LOGGER.getEventsToSend();
*/
// TODO : make a true update of paradatas : currently adding additional completed arrays => SHOULD save one and only one array
// await paradataIdbService.update(paradatas);
if (standalone) {
// TODO managing errors
await putSurveyUnit(unit);
// await postParadata(paradatas);
}
},
[putUeData, readonly, standalone]
);

const saveQueen = useCallback(
async (newState, newData, lastReachedPage) => {
const currentState = getState();
saveData({
comment: {},
...surveyUnit,
stateData: {
state: newState ?? currentState,
date: new Date().getTime(),
currentPage: lastReachedPage,
},
data: newData ?? surveyUnit.data,
});
},
[getState, saveData, surveyUnit]
);

const closeOrchestrator = useCallback(() => {
}
});

const savePartialQueen = useConstCallback(async (newState, newPartialData, lastReachedPage) => {
const currentState = getState();

const newData = getFullData(surveyUnitData, removeNullCollectedData(newPartialData));
setSurveyUnitData(newData);
saveData({
comment: {},
...surveyUnit,
stateData: {
state: newState ?? currentState,
date: new Date().getTime(),
currentPage: lastReachedPage,
},
data: newData ?? surveyUnitData,
});
});

const closeOrchestrator = useConstCallback(() => {
if (standalone) {
history.push('/');
} else {
sendCloseEvent(surveyUnit.id);
}
}, [history, standalone, surveyUnit?.id]);

const quit = useCallback(
async (pager, getData) => {
const { page, maxPage, lastReachedPage } = pager;
const isLastPage = page === maxPage;
const newData = getData();
if (isLastPage) {
// TODO : make algo to calculate COMPLETED event
changeState(COMPLETED);
changeState(VALIDATED);
await saveQueen(VALIDATED, newData, lastReachedPage);
} else await saveQueen(undefined, newData, lastReachedPage);
closeOrchestrator();
},
[changeState, closeOrchestrator, saveQueen]
);

const definitiveQuit = useCallback(
async (pager, getData) => {
const { lastReachedPage } = pager;
const newData = getData();
});

const quit = useConstCallback(async (pager, getChangedData) => {
const { page, maxPage, lastReachedPage } = pager;
const isLastPage = page === maxPage;
const newData = getChangedData(true);
if (isLastPage) {
// TODO : make algo to calculate COMPLETED event
changeState(COMPLETED);
changeState(VALIDATED);
await saveQueen(VALIDATED, newData, lastReachedPage);
closeOrchestrator();
},
[changeState, closeOrchestrator, saveQueen]
);
await savePartialQueen(VALIDATED, newData, lastReachedPage);
} else await savePartialQueen(undefined, newData, lastReachedPage);
closeOrchestrator();
});

const definitiveQuit = useConstCallback(async (pager, getChangedData) => {
const { lastReachedPage } = pager;
const newData = getChangedData(true);
changeState(VALIDATED);
await savePartialQueen(VALIDATED, newData, lastReachedPage);
closeOrchestrator();
});

return (
<>
{![READ_ONLY, undefined].includes(readonlyParam) && <NotFound />}
Expand All @@ -169,6 +162,7 @@ export const OrchestratorManager = () => {
surveyUnit={surveyUnit}
source={source}
getReferentiel={getReferentiel}
allData={surveyUnitData}
autoSuggesterLoading={true}
standalone={standalone}
readonly={readonly}
Expand All @@ -177,7 +171,7 @@ export const OrchestratorManager = () => {
missing={true}
shortcut={true}
filterDescription={false}
save={saveQueen}
save={savePartialQueen}
onDataChange={onDataChange}
close={closeOrchestrator}
quit={quit}
Expand Down
Loading

0 comments on commit 1a73fa7

Please sign in to comment.