From 6b9206c1d5f812d0fc763a9236f3fc3d9d4bf259 Mon Sep 17 00:00:00 2001 From: MickaelMenet Date: Mon, 10 Jul 2023 09:46:36 +0200 Subject: [PATCH 1/6] feat: add lunatic version with lunatic gotopage fixed --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index fb72dac7..b351a6e8 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "license": "MIT", "dependencies": { "@craco/craco": "^6.4.0", - "@inseefr/lunatic": "2.4.9", + "@inseefr/lunatic": "2.4.7-gotopage", "@material-ui/core": "^4.11.2", "@material-ui/icons": "^4.11.2", "@material-ui/lab": "^4.0.0-alpha.57", diff --git a/yarn.lock b/yarn.lock index 161ce62b..95b2131a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1446,10 +1446,10 @@ resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== -"@inseefr/lunatic@2.4.9": - version "2.4.9" - resolved "https://registry.yarnpkg.com/@inseefr/lunatic/-/lunatic-2.4.9.tgz#788892acc94e3a52dd4f1b4a02ea702b2ab4405f" - integrity sha512-qQDnARkPVHjMD/xlIRVPdizTjqZKNFT9Ws4P9Yy6hfEELnOrUemMBgKqmydiHazNhYX4BN5Kdn1dn0AbfBCYjQ== +"@inseefr/lunatic@2.4.7-gotopage": + version "2.4.7-gotopage" + resolved "https://registry.yarnpkg.com/@inseefr/lunatic/-/lunatic-2.4.7-gotopage.tgz#ec5dab8ba21a2bc59997854f53c5b56829a2f2a4" + integrity sha512-MmhQHVkHu50ZYoxBz+iNXvw/wfYnvpcjmOw7Su7BJZVpMS1j5p+b5t7MKuO7zIhmq4+dYE9yXfyxy5ds/FFDgA== dependencies: "@inseefr/trevas" "^0.1.17" "@inseefr/vtl-2.0-antlr-tools" "^0.1.0-bundle" From 12b1d6fb36793cf50ddff0a876e4d5808e7d81b0 Mon Sep 17 00:00:00 2001 From: MickaelMenet Date: Wed, 19 Jul 2023 12:01:27 +0200 Subject: [PATCH 2/6] fix: bug with currentpage & page --- .../orchestrator/collector/index.js | 37 +++++++++++-------- src/utils/pagination/index.js | 2 +- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/components/orchestrator/collector/index.js b/src/components/orchestrator/collector/index.js index b93679f1..08acbccb 100644 --- a/src/components/orchestrator/collector/index.js +++ b/src/components/orchestrator/collector/index.js @@ -51,7 +51,13 @@ export const Orchestrator = ({ stateData.state === 'EXTRACTED' || stateData.state === 'TOEXTRACT') ); - + const [currentPage, setCurrentPage] = useState(() => { + if (validated) return END_PAGE; + if (stateData?.currentPage) { + return stateData?.currentPage; + } + return WELCOME_PAGE; + }); const logFunction = (e) => simpleLog({ ...e, page: currentPage }); const { getComponents, @@ -66,7 +72,7 @@ export const Orchestrator = ({ getData, } = lunatic.useLunatic(source, data, { // ToDo : initial page - //initialPage, + initialPage: isLunaticPage(currentPage) ? stateData?.currentPage : '1', features, preferences, autoSuggesterLoading, @@ -75,15 +81,6 @@ export const Orchestrator = ({ }); const components = getComponents(); - - const [currentPage, setCurrentPage] = useState(() => { - if (validated) return END_PAGE; - if (stateData?.currentPage) { - return page; - } - return WELCOME_PAGE; - }); - const updateStateData = useCallback( (newState) => { const newStateData = { @@ -187,11 +184,12 @@ export const Orchestrator = ({ } }; - useEffect(() => { - if (isLunaticPage(currentPage)) { - setCurrentPage(page); - } - }, [currentPage, page]); + // useEffect(() => { + // if (isLunaticPage(currentPage)) { + // setCurrentPage(page); + // } + // // eslint-disable-next-line react-hooks/exhaustive-deps + // }, [page]); const lunaticDisplay = () => ( )} {isLunaticPage(currentPage) && lunaticDisplay()} + { +
+ + Page : {page} - CurrentPage : {currentPage} + +
+ } {currentPage === VALIDATION_PAGE && ( - ![WELCOME_PAGE, VALIDATION_PAGE, END_PAGE].includes(page); + page && ![WELCOME_PAGE, VALIDATION_PAGE, END_PAGE].includes(page); From 18f071c68b4960c5d1e2c1822ba981dfe3c63a1b Mon Sep 17 00:00:00 2001 From: Jonathan Date: Thu, 20 Jul 2023 15:44:13 +0200 Subject: [PATCH 3/6] fix: page persistence --- package.json | 3 + public/static/questionnaire/famille/data.json | 2 +- src/components/genericPages/end.js | 4 +- src/components/genericPages/validation.js | 4 +- .../modals/welcomeBack/welcomeBack.js | 5 +- .../orchestrator/collector/index.js | 140 +++++++++--------- src/utils/pagination/index.js | 1 + 7 files changed, 84 insertions(+), 75 deletions(-) diff --git a/package.json b/package.json index b351a6e8..eda6692d 100644 --- a/package.json +++ b/package.json @@ -88,5 +88,8 @@ "husky": "^8.0.1", "lint-staged": "^13.0.3", "prettier": "^2.7.1" + }, + "volta": { + "node": "16.20.1" } } diff --git a/public/static/questionnaire/famille/data.json b/public/static/questionnaire/famille/data.json index ea67dc4f..b081e9ae 100644 --- a/public/static/questionnaire/famille/data.json +++ b/public/static/questionnaire/famille/data.json @@ -3661,6 +3661,6 @@ "stateData": { "state": "INIT", "date": 1668677099410, - "currentPage": "2" + "currentPage": "2.1#1" } } diff --git a/src/components/genericPages/end.js b/src/components/genericPages/end.js index 902e363c..cbbfe0d0 100644 --- a/src/components/genericPages/end.js +++ b/src/components/genericPages/end.js @@ -22,6 +22,7 @@ import { import { interpret } from '@inseefr/trevas'; import { MarkdownTypo } from 'components/designSystem'; import { paradataHandler, SIMPLE_CLICK_EVENT } from 'utils/events'; +import { END_PAGE } from '../../utils/pagination'; const useStyles = makeStyles((theme) => ({ card: { marginLeft: '1em', marginRight: '1em' }, @@ -44,7 +45,6 @@ const EndPage = ({ metadata: { inseeContext, variables, genericPages }, personalization, stateData: { date }, - currentPage, }) => { const classes = useStyles(); @@ -52,7 +52,7 @@ const EndPage = ({ return { ...SIMPLE_CLICK_EVENT, idParadataObject: `${type}-button`, - page: currentPage, + page: END_PAGE, }; }; const finalDate = date || 0; diff --git a/src/components/genericPages/validation.js b/src/components/genericPages/validation.js index e430273f..db1630a6 100644 --- a/src/components/genericPages/validation.js +++ b/src/components/genericPages/validation.js @@ -9,6 +9,7 @@ import Send from '@material-ui/icons/Send'; import { validationPageDictionary, buttonDictionary } from 'i18n'; import { MarkdownTypo } from 'components/designSystem'; import { paradataHandler, SIMPLE_CLICK_EVENT } from 'utils/events'; +import { VALIDATION_PAGE } from '../../utils/pagination'; const useStyles = makeStyles((theme) => ({ card: { marginLeft: '1em', marginRight: '1em' }, @@ -25,7 +26,6 @@ const useStyles = makeStyles((theme) => ({ const ValidationPage = ({ metadata: { inseeContext, genericPages }, setValidationConfirmation, - currentPage, }) => { const classes = useStyles(); const { title, body } = @@ -33,7 +33,7 @@ const ValidationPage = ({ const utilInfo = { ...SIMPLE_CLICK_EVENT, idParadataObject: 'validate-button', - page: currentPage, + page: VALIDATION_PAGE, }; return ( diff --git a/src/components/modals/welcomeBack/welcomeBack.js b/src/components/modals/welcomeBack/welcomeBack.js index 6cfabbb0..eb29553f 100644 --- a/src/components/modals/welcomeBack/welcomeBack.js +++ b/src/components/modals/welcomeBack/welcomeBack.js @@ -15,13 +15,14 @@ const utilInfo = (type) => { }; }; -const WelcomeBack = ({ open, setOpen, goToFirstPage }) => { +const WelcomeBack = ({ open, setOpen, goToFirstPage, goBackToSavedPage }) => { const goToCurrentPage = () => { + goBackToSavedPage?.(); setOpen(false); }; const goToFirst = () => { - goToFirstPage(); + goToFirstPage?.(); setOpen(false); }; diff --git a/src/components/orchestrator/collector/index.js b/src/components/orchestrator/collector/index.js index 08acbccb..845653cb 100644 --- a/src/components/orchestrator/collector/index.js +++ b/src/components/orchestrator/collector/index.js @@ -9,15 +9,15 @@ import { WelcomeBack } from 'components/modals/welcomeBack'; import { AppBar } from 'components/navigation/appBar'; import { BurgerMenu } from 'components/navigation/burgerMenu'; import { LoaderSimple } from 'components/shared/loader'; -import { useCallback, useEffect, useRef, useState } from 'react'; +import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { simpleLog } from 'utils/events'; import { END_PAGE, + FORM_PAGE, + isLunaticPage, VALIDATION_PAGE, WELCOME_PAGE, - isLunaticPage, } from 'utils/pagination'; -import { isNewSequence } from 'utils/questionnaire'; import { INIT, VALIDATED } from 'utils/questionnaire/stateData'; import '../custom-lunatic.scss'; import { ButtonsNavigation } from '../navigation'; @@ -43,7 +43,6 @@ export const Orchestrator = ({ const [validationConfirmation, setValidationConfirmation] = useState(false); const { stateData, data, personalization } = stromaeData; - const [currentStateData, setCurrentStateData] = useState(stateData); const [validated, setValidated] = useState( stateData && @@ -51,19 +50,12 @@ export const Orchestrator = ({ stateData.state === 'EXTRACTED' || stateData.state === 'TOEXTRACT') ); - const [currentPage, setCurrentPage] = useState(() => { - if (validated) return END_PAGE; - if (stateData?.currentPage) { - return stateData?.currentPage; - } - return WELCOME_PAGE; - }); - const logFunction = (e) => simpleLog({ ...e, page: currentPage }); const { getComponents, waiting, pageTag, pager: { page }, + goToPage, goNextPage, goPreviousPage, isFirstPage, @@ -71,8 +63,6 @@ export const Orchestrator = ({ compileControls, getData, } = lunatic.useLunatic(source, data, { - // ToDo : initial page - initialPage: isLunaticPage(currentPage) ? stateData?.currentPage : '1', features, preferences, autoSuggesterLoading, @@ -80,19 +70,47 @@ export const Orchestrator = ({ activeControls, }); - const components = getComponents(); - const updateStateData = useCallback( - (newState) => { - const newStateData = { - state: newState ?? INIT, - date: new Date().getTime(), - currentPage: currentPage, - }; - setCurrentStateData(newStateData); - return newStateData; - }, - [currentPage] + const logFunction = (e) => simpleLog({ ...e, page: currentPage }); + + // Control whether to display the modal to go back to the previous state + const showBackModal = !init && !validated && !!stateData?.currentPage; + + // Indicate in which state the orchestrator is, with stromae we need a welcome page before the form and an end page after + const [orchestratorState, setOrchestratorState] = useState(() => { + if (validated) { + return END_PAGE; + } + if (showBackModal) { + return WELCOME_PAGE; + } + if (stateData?.currentPage) { + return FORM_PAGE; + } + return WELCOME_PAGE; + }); + + const currentStateData = useMemo( + () => ({ + state: orchestratorState === END_PAGE ? VALIDATED : INIT, + date: new Date().getTime(), + currentPage: + orchestratorState === FORM_PAGE ? pageTag : orchestratorState, + }), + [pageTag, orchestratorState] ); + const currentPage = + orchestratorState === FORM_PAGE ? pageTag : orchestratorState; + + // Persist state data on every change so the user can come back to where he was + useEffect(() => { + // Do not save before the user start the questionnaire + if (showBackModal) { + return; + } + save(currentStateData); + }, [currentStateData, save, showBackModal]); + + const components = getComponents(); const logoutAndClose = async () => { let dataToSave = { stateData: currentStateData, data: getData() }; @@ -102,8 +120,9 @@ export const Orchestrator = ({ quit(dataToSave); }; + // Scroll at the top of the form const goToTop = () => { - if (topRef && topRef.current) { + if (topRef.current) { topRef.current.tabIndex = -1; topRef.current.focus(); topRef.current.blur(); @@ -113,13 +132,7 @@ export const Orchestrator = ({ }; const validateQuestionnaire = () => { setValidated(true); - const validateUpdateState = updateStateData(VALIDATED); - const dataToSave = { - stateData: validateUpdateState, - data: getData(), - }; - save(dataToSave); - setCurrentPage(END_PAGE); + setOrchestratorState(END_PAGE); }; const [errorActive, setErrorActive] = useState({}); @@ -143,21 +156,15 @@ export const Orchestrator = ({ const onNext = useCallback( (event, skipValidation = false) => { closeErrorsModal(); - if (currentPage === WELCOME_PAGE) setCurrentPage(page); - else { - const onNextUpdateState = updateStateData(); - const dataToSave = { - stateData: onNextUpdateState, - data: getData(), - }; + if (orchestratorState === WELCOME_PAGE) { + setOrchestratorState(FORM_PAGE); + } else { if (!isLastPage) { - if (isNewSequence(components)) { - save(dataToSave); - } handleGoNext(skipValidation, goNextPage); } else { - save(dataToSave); - handleGoNext(skipValidation, () => setCurrentPage(VALIDATION_PAGE)); + handleGoNext(skipValidation, () => + setOrchestratorState(VALIDATION_PAGE) + ); } } goToTop(); @@ -165,31 +172,32 @@ export const Orchestrator = ({ [ closeErrorsModal, components, - currentPage, + orchestratorState, getData, goNextPage, handleGoNext, isLastPage, page, - save, - updateStateData, ] ); const onPrevious = () => { - if (currentPage === VALIDATION_PAGE) setCurrentPage(page); + if (orchestratorState === VALIDATION_PAGE) setOrchestratorState(FORM_PAGE); else { if (!isFirstPage) goPreviousPage(); - else setCurrentPage(WELCOME_PAGE); + else setOrchestratorState(WELCOME_PAGE); } }; - // useEffect(() => { - // if (isLunaticPage(currentPage)) { - // setCurrentPage(page); - // } - // // eslint-disable-next-line react-hooks/exhaustive-deps - // }, [page]); + const restoreSavedPage = () => { + // stateData currentPage can be "welcomePage" instead of a normal page number + if (isLunaticPage(stateData?.currentPage)) { + goToPage({ page: stateData?.currentPage }); + setOrchestratorState(FORM_PAGE); + } else { + setOrchestratorState(stateData?.currentPage); + } + }; const lunaticDisplay = () => ( - {currentPage === WELCOME_PAGE && ( + {orchestratorState === WELCOME_PAGE && ( )} - {isLunaticPage(currentPage) && lunaticDisplay()} + {orchestratorState === FORM_PAGE && lunaticDisplay()} {
- Page : {page} - CurrentPage : {currentPage} + PageTag : {pageTag} - CurrentPage : {currentPage}
} - {currentPage === VALIDATION_PAGE && ( + {orchestratorState === VALIDATION_PAGE && ( )} - {currentPage === END_PAGE && ( + {orchestratorState === END_PAGE && ( )} @@ -286,11 +292,9 @@ export const Orchestrator = ({ /> )} setInit(!o)} - goToFirstPage={() => { - setCurrentPage(WELCOME_PAGE); - }} + goBackToSavedPage={restoreSavedPage} /> page && ![WELCOME_PAGE, VALIDATION_PAGE, END_PAGE].includes(page); From 52ffba966f44d4751e2dde0259b3bf2b64c533d6 Mon Sep 17 00:00:00 2001 From: MickaelMenet Date: Thu, 20 Jul 2023 16:32:16 +0200 Subject: [PATCH 4/6] fix: remove useless dependency --- src/components/orchestrator/collector/index.js | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/components/orchestrator/collector/index.js b/src/components/orchestrator/collector/index.js index 845653cb..f726e877 100644 --- a/src/components/orchestrator/collector/index.js +++ b/src/components/orchestrator/collector/index.js @@ -169,16 +169,7 @@ export const Orchestrator = ({ } goToTop(); }, - [ - closeErrorsModal, - components, - orchestratorState, - getData, - goNextPage, - handleGoNext, - isLastPage, - page, - ] + [closeErrorsModal, orchestratorState, goNextPage, handleGoNext, isLastPage] ); const onPrevious = () => { From 250c15faddbba85051dd29a27bf72b6fad37eaf4 Mon Sep 17 00:00:00 2001 From: MickaelMenet Date: Thu, 20 Jul 2023 16:38:23 +0200 Subject: [PATCH 5/6] fix: remove pager uselunatic --- src/components/orchestrator/collector/index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/orchestrator/collector/index.js b/src/components/orchestrator/collector/index.js index f726e877..96c9dbf7 100644 --- a/src/components/orchestrator/collector/index.js +++ b/src/components/orchestrator/collector/index.js @@ -54,7 +54,6 @@ export const Orchestrator = ({ getComponents, waiting, pageTag, - pager: { page }, goToPage, goNextPage, goPreviousPage, From 31c58b7d523ad1ec130e2fd615f14fe96f8bd2ef Mon Sep 17 00:00:00 2001 From: Laurent Caouissin Date: Tue, 17 Oct 2023 17:01:09 +0200 Subject: [PATCH 6/6] fix: save at new sequence only --- .../orchestrator/collector/index.js | 36 +++++++++---------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/src/components/orchestrator/collector/index.js b/src/components/orchestrator/collector/index.js index 2735929a..cf45e536 100644 --- a/src/components/orchestrator/collector/index.js +++ b/src/components/orchestrator/collector/index.js @@ -2,7 +2,7 @@ import * as lunatic from '@inseefr/lunatic'; import Card from '@material-ui/core/Card'; import Container from '@material-ui/core/Container'; import { makeStyles } from '@material-ui/core/styles'; -import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react'; +import { memo, useCallback, useMemo, useRef, useState } from 'react'; import { simpleLog } from '../../../utils/events'; import { END_PAGE, @@ -11,6 +11,7 @@ import { WELCOME_PAGE, isLunaticPage, } from '../../../utils/pagination'; +import { isNewSequence } from '../../../utils/questionnaire'; import { INIT, VALIDATED } from '../../../utils/questionnaire/stateData'; import { EndPage, ValidationPage, WelcomePage } from '../../genericPages'; import { ErrorsModal } from '../../modals/errors'; @@ -100,15 +101,6 @@ const OrchestratorComponent = ({ const currentPage = orchestratorState === FORM_PAGE ? pageTag : orchestratorState; - // Persist state data on every change so the user can come back to where he was - useEffect(() => { - // Do not save before the user start the questionnaire - if (showBackModal) { - return; - } - save(currentStateData); - }, [currentStateData, save, showBackModal]); - const components = getComponents(); const logoutAndClose = async () => { @@ -159,6 +151,10 @@ const OrchestratorComponent = ({ setOrchestratorState(FORM_PAGE); } else { if (!isLastPage) { + if (isNewSequence(components)) { + let dataToSave = { stateData: currentStateData, data: getData() }; + save(dataToSave); + } handleGoNext(skipValidation, goNextPage); } else { handleGoNext(skipValidation, () => @@ -168,7 +164,17 @@ const OrchestratorComponent = ({ } goToTop(); }, - [closeErrorsModal, orchestratorState, goNextPage, handleGoNext, isLastPage] + [ + closeErrorsModal, + orchestratorState, + isLastPage, + components, + handleGoNext, + goNextPage, + currentStateData, + getData, + save, + ] ); const onPrevious = () => { @@ -188,7 +194,6 @@ const OrchestratorComponent = ({ setOrchestratorState(stateData?.currentPage); } }; - const lunaticDisplay = () => ( )} {orchestratorState === FORM_PAGE && lunaticDisplay()} - { -
- - PageTag : {pageTag} - CurrentPage : {currentPage} - -
- } {orchestratorState === VALIDATION_PAGE && (