diff --git a/compendium-frontend/src/survey/SurveyComponent.tsx b/compendium-frontend/src/survey/SurveyComponent.tsx index 70c8033108286d711a342f28b81f850242c2bb79..93f503105cb7518239e43094d66379a2ce5218d3 100644 --- a/compendium-frontend/src/survey/SurveyComponent.tsx +++ b/compendium-frontend/src/survey/SurveyComponent.tsx @@ -143,7 +143,8 @@ function setVerifyButton(question: Question, state: VerificationStatus, surveyMo } } -function SurveyComponent({ surveyModel }) { +function SurveyComponent({ surveyModelContainer }) { + const { surveyModel } = surveyModelContainer; useEffect(() => { const updateFromUnverified = (_, options) => { diff --git a/compendium-frontend/src/survey/SurveyContainerComponent.tsx b/compendium-frontend/src/survey/SurveyContainerComponent.tsx index 9949120878be7d1db0e6eb8c5a1cfb0fefd6beca..dca6528fdd6806c7f1f63ced5859c28495665d95 100644 --- a/compendium-frontend/src/survey/SurveyContainerComponent.tsx +++ b/compendium-frontend/src/survey/SurveyContainerComponent.tsx @@ -1,3 +1,4 @@ +/* eslint-disable react-compiler/react-compiler */ import { useEffect, useState, useCallback, useContext } from "react"; import { Container } from "react-bootstrap"; import toast, { Toaster } from "react-hot-toast"; @@ -18,20 +19,13 @@ import { userContext } from "compendium/providers/UserProvider"; Serializer.addProperty("itemvalue", "customDescription:text"); Serializer.addProperty("question", "hideCheckboxLabels:boolean"); -function modifyModel(surveyModel: Model) { - // Used to create a new reference to the survey model to force a rerender. - // This is a hack to get around the fact that the survey model state is not part of the react state. - const newModel = Object.create(surveyModel); - - if (!newModel.css.question.title.includes("sv-header-flex")) { - newModel.css.question.title = "sv-title sv-question__title sv-header-flex"; - newModel.css.question.titleOnError = "sv-question__title--error sv-error-color-fix"; - } - return newModel +type surveyModelContainer = { + surveyModel: Model; } function SurveyContainerComponent({ loadFrom }) { - const [surveyModel, setSurveyModel] = useState<Model>(); // note that this is never updated and we abuse that fact by adding extra state to the surveyModel + const [surveyModelContainer, setSurveyModel] = useState<surveyModelContainer>(); // note that this is never updated and we abuse that fact by adding extra state to the surveyModel + const surveyModel = surveyModelContainer?.surveyModel; const { year, nren } = useParams(); // nren stays empty for inspect and try const [error, setError] = useState<string>('loading survey...'); const { user } = useContext(userContext); @@ -96,11 +90,11 @@ function SurveyContainerComponent({ loadFrom }) { // setPageNo(json['page']); survey.mode = json['mode']; - survey['lockedBy'] = json['locked_by']; - survey['status'] = json['status']; - survey['editAllowed'] = json['edit_allowed']; + survey.lockedBy = json['locked_by']; + survey.status = json['status']; + survey.editAllowed = json['edit_allowed']; - setSurveyModel(survey); + setSurveyModel({ surveyModel: survey }); } getModel().catch(error => setError('Error when loading survey: ' + error.message)).then(() => { @@ -134,11 +128,11 @@ function SurveyContainerComponent({ loadFrom }) { if (!response.ok) { return json['message']; } - const newModel = modifyModel(survey); - newModel.mode = json['mode']; - newModel['lockedBy'] = json['locked_by']; - newModel['status'] = json['status']; - setSurveyModel(newModel); + + surveyModel.mode = json['mode']; + surveyModel.lockedBy = json['locked_by']; + surveyModel.status = json['status']; + setSurveyModel({ surveyModel: surveyModel }); } catch (e) { return "Unknown Error: " + (e as Error).message; } @@ -218,14 +212,13 @@ function SurveyContainerComponent({ loadFrom }) { for (const questionName in json["verification_status"]) { surveyModel['verificationStatus'].set(questionName, json["verification_status"][questionName]); } - const newModel = modifyModel(surveyModel); - newModel.data = json['data']; - newModel.clearIncorrectValues(true); - newModel.mode = json['mode']; - newModel['lockedBy'] = json['locked_by'] - newModel['lockUUID'] = json['lock_uuid']; - newModel['status'] = json['status']; - setSurveyModel(newModel); + surveyModel.data = json['data']; + surveyModel.clearIncorrectValues(true); + surveyModel.mode = json['mode']; + surveyModel.lockedBy = json['locked_by'] + surveyModel.lockUUID = json['lock_uuid']; + surveyModel.status = json['status']; + setSurveyModel({ surveyModel: surveyModel }); // Validate when we start editing to ensure invalid fields are corrected by the user const allFieldsValid = validateWithAnswerVerification(surveyModel.validate.bind(surveyModel, true, true), false); if (!allFieldsValid) { @@ -241,11 +234,10 @@ function SurveyContainerComponent({ loadFrom }) { toast("Failed releasing lock: " + json['message']); return; } - const newModel = modifyModel(surveyModel); - newModel.mode = json['mode']; - newModel['lockedBy'] = json['locked_by']; - newModel['status'] = json['status']; - setSurveyModel(newModel); + surveyModel.mode = json['mode']; + surveyModel.lockedBy = json['locked_by']; + surveyModel.status = json['status']; + setSurveyModel({ surveyModel: surveyModel }); }, 'validatePage': () => { const validSurvey = validateWithAnswerVerification(surveyModel.validatePage.bind(surveyModel)); @@ -257,9 +249,8 @@ function SurveyContainerComponent({ loadFrom }) { const onPageChange = (page) => { if (!surveyModel) return; - const newModel = modifyModel(surveyModel); - newModel.currentPageNo = page; - setSurveyModel(newModel); + surveyModel.currentPageNo = page; + setSurveyModel({ surveyModel: surveyModel }); } return ( @@ -269,8 +260,8 @@ function SurveyContainerComponent({ loadFrom }) { <Toaster /> <Prompt message="Are you sure you want to leave this page? Information you've entered may not be saved." when={() => { return surveyModel.mode == 'edit' && !!nren; }} onPageExit={onPageExitThroughRouter} /> - <SurveyNavigationComponent surveyModel={surveyModel} surveyActions={surveyActions} year={year} nren={nren} onPageChange={onPageChange}> - <SurveyComponent surveyModel={surveyModel} /> + <SurveyNavigationComponent surveyModelContainer={surveyModelContainer} surveyActions={surveyActions} year={year} nren={nren} onPageChange={onPageChange}> + <SurveyComponent surveyModelContainer={surveyModelContainer} /> </SurveyNavigationComponent> </Container> </> diff --git a/compendium-frontend/src/survey/SurveyNavigationComponent.tsx b/compendium-frontend/src/survey/SurveyNavigationComponent.tsx index d03af8f4211f1492eeff32343a1a8f953433d1a1..846a23dbbbb460188fb8c93a849cb1d121af0a58 100644 --- a/compendium-frontend/src/survey/SurveyNavigationComponent.tsx +++ b/compendium-frontend/src/survey/SurveyNavigationComponent.tsx @@ -3,8 +3,9 @@ import ProgressBar from 'compendium/survey/ProgressBar'; import { Container, Row } from "react-bootstrap"; import { userContext } from "compendium/providers/UserProvider"; -function SurveyNavigationComponent({ surveyModel, surveyActions, year, nren, children, onPageChange - }) { +function SurveyNavigationComponent({ surveyModelContainer, surveyActions, year, nren, children, onPageChange + }) { + const { surveyModel } = surveyModelContainer; const { user: loggedInUser } = useContext(userContext); const pageNo = surveyModel?.currentPageNo ?? 0; const editing = surveyModel?.mode === 'edit'; @@ -15,8 +16,6 @@ function SurveyNavigationComponent({ surveyModel, surveyActions, year, nren, chi const doSurveyAction = async (action) => { await surveyActions[action](); - // onPageChange triggers a re-render, just keep the same page number - onPageChange(surveyModel.currentPageNo); } const renderButton = (text, action) => {