diff --git a/compendium-frontend/src/components/sidebar/LinkWithHighlight.tsx b/compendium-frontend/src/components/sidebar/LinkWithHighlight.tsx index 11a9a2e2396f21fc9107677bf183025541924d6d..1df33eaeef39715b9b34581e30f8dd342ceaf1ad 100644 --- a/compendium-frontend/src/components/sidebar/LinkWithHighlight.tsx +++ b/compendium-frontend/src/components/sidebar/LinkWithHighlight.tsx @@ -1,4 +1,4 @@ -import React, { ReactElement, useRef } from "react"; +import React, { ReactElement, useRef, useEffect } from "react"; import { Link } from 'react-router-dom'; import { Row } from 'react-bootstrap'; @@ -11,10 +11,12 @@ function LinkWithHighlight({ to, children }: inputProps): ReactElement { const currentPageIsTo = window.location.pathname === to; const ref = useRef<HTMLAnchorElement>(null); - if (currentPageIsTo && ref.current) { - // scroll the link into view in the sidebar - ref.current.scrollIntoView({ behavior: "smooth", block: "center" }); - } + useEffect(() => { + if (currentPageIsTo && ref.current) { + // scroll the link into view in the sidebar + ref.current.scrollIntoView({ behavior: "smooth", block: "center" }); + } + }, [currentPageIsTo]); return ( <Row> diff --git a/compendium-frontend/src/survey/Landing.tsx b/compendium-frontend/src/survey/Landing.tsx index 5e721e70550bc5b917e82d281bc2f1ef4dc36e97..d4269f730388ff184c58f97b4c2cb4ec3b6f7745 100644 --- a/compendium-frontend/src/survey/Landing.tsx +++ b/compendium-frontend/src/survey/Landing.tsx @@ -1,4 +1,4 @@ -import React, { ReactElement, useContext, useState, useEffect } from "react"; +import { ReactElement, useContext, useState, useEffect } from "react"; import { useNavigate, Link } from "react-router-dom"; import { Table, Container, Row } from "react-bootstrap"; import { userContext } from "../providers/UserProvider"; @@ -8,6 +8,39 @@ import SurveySidebar from "./management/SurveySidebar"; import * as XLSX from "xlsx"; import useMatomo from "../matomo/UseMatomo"; +const SurveyTable = () => { + + const [survey, setSurvey] = useState<Survey>(); + + useEffect(() => { + fetchSurveys().then((surveyList) => { + // only show the latest survey + setSurvey(surveyList[0]); + }); + }, []); + + return (<Table striped bordered responsive> + <thead> + <tr> + <th>(N)REN</th> + <th>Link</th> + <th>Survey Status</th> + </tr> + </thead> + <tbody> + {survey && survey.responses.map(response => ( + <tr key={response.nren.id}> + <td>{response.nren.name}</td> + <td> + <Link to={`/survey/response/${survey.year}/${response.nren.name}`}><span>Navigate to survey</span></Link> + </td> + <td>{response.status}</td> + </tr> + ))} + + </tbody> + </Table>) +} function Landing(): ReactElement { @@ -119,45 +152,6 @@ function Landing(): ReactElement { }); } - - - - - - const SurveyTable = () => { - - const [survey, setSurvey] = useState<Survey>(); - - useEffect(() => { - fetchSurveys().then((surveyList) => { - // only show the latest survey - setSurvey(surveyList[0]); - }); - }, []); - - return (<Table striped bordered responsive> - <thead> - <tr> - <th>(N)REN</th> - <th>Link</th> - <th>Survey Status</th> - </tr> - </thead> - <tbody> - {survey && survey.responses.map(response => ( - <tr key={response.nren.id}> - <td>{response.nren.name}</td> - <td> - <Link to={`/survey/response/${survey.year}/${response.nren.name}`}><span>Navigate to survey</span></Link> - </td> - <td>{response.status}</td> - </tr> - ))} - - </tbody> - </Table>) - } - return ( <> {isAdmin && <SurveySidebar />} diff --git a/compendium-frontend/src/survey/SurveyComponent.tsx b/compendium-frontend/src/survey/SurveyComponent.tsx index bd8f21e2b4ce9a113e41dabc1f089a9afe263660..97e4cf7098091b7fe1120874025df94367c97db9 100644 --- a/compendium-frontend/src/survey/SurveyComponent.tsx +++ b/compendium-frontend/src/survey/SurveyComponent.tsx @@ -1,4 +1,4 @@ -import React, { useCallback } from "react"; +import { useCallback } from "react"; import { Question } from "survey-core"; import { Survey } from "survey-react-ui"; import { VerificationStatus } from './Schema'; @@ -166,11 +166,6 @@ function SurveyComponent({ surveyModel }) { } }, [surveyModel]) - if (!surveyModel.css.question.title.includes("sv-header-flex")) { - surveyModel.css.question.title = "sv-title sv-question__title sv-header-flex"; - surveyModel.css.question.titleOnError = "sv-question__title--error sv-error-color-fix"; - } - if (!surveyModel.onAfterRenderQuestion.hasFunc(alwaysSetVerify)) { surveyModel.onAfterRenderQuestion.add(alwaysSetVerify); surveyModel.onAfterRenderQuestion.add(fixTitleCss); diff --git a/compendium-frontend/src/survey/SurveyContainerComponent.tsx b/compendium-frontend/src/survey/SurveyContainerComponent.tsx index 8fbfd5953b786031949e91078dc5a6b29c4b9a04..a63e5a9ea4105ef4b17bc63e2c122bda2f6c1131 100644 --- a/compendium-frontend/src/survey/SurveyContainerComponent.tsx +++ b/compendium-frontend/src/survey/SurveyContainerComponent.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState, useCallback, useContext } from "react"; +import { useEffect, useState, useCallback, useContext } from "react"; import { Container } from "react-bootstrap"; import toast, { Toaster } from "react-hot-toast"; import { Model, Serializer } from "survey-core"; @@ -140,9 +140,9 @@ function SurveyContainerComponent({ loadFrom }) { survey.showNavigationButtons = false; survey.requiredText = ''; - survey.verificationStatus = new Map<string, VerificationStatus>(); + survey['verificationStatus'] = new Map<string, VerificationStatus>(); for (const questionName in json["verification_status"]) { - survey.verificationStatus.set(questionName, json["verification_status"][questionName]); + survey['verificationStatus'].set(questionName, json["verification_status"][questionName]); } survey.data = json['data']; @@ -150,9 +150,9 @@ function SurveyContainerComponent({ loadFrom }) { survey.currentPageNo = 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); } @@ -189,8 +189,8 @@ function SurveyContainerComponent({ loadFrom }) { return json['message']; } surveyModel.mode = json['mode']; - surveyModel.lockedBy = json['locked_by']; - surveyModel.status = json['status']; + surveyModel['lockedBy'] = json['locked_by']; + surveyModel['status'] = json['status']; } catch (e) { return "Unknown Error: " + (e as Error).message; } @@ -268,14 +268,14 @@ function SurveyContainerComponent({ loadFrom }) { addEventListener("pagehide", pageHideListener); addEventListener("beforeunload", beforeUnloadListener, { capture: true }); for (const questionName in json["verification_status"]) { - surveyModel.verificationStatus.set(questionName, json["verification_status"][questionName]); + surveyModel['verificationStatus'].set(questionName, json["verification_status"][questionName]); } 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']; + surveyModel['lockedBy'] = json['locked_by'] + surveyModel['lockUUID'] = json['lock_uuid']; + surveyModel['status'] = json['status']; // 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) { @@ -292,8 +292,8 @@ function SurveyContainerComponent({ loadFrom }) { return; } surveyModel.mode = json['mode']; - surveyModel.lockedBy = json['locked_by']; - surveyModel.status = json['status']; + surveyModel['lockedBy'] = json['locked_by']; + surveyModel['status'] = json['status']; }, 'validatePage': () => { const validSurvey = validateWithAnswerVerification(surveyModel.validatePage.bind(surveyModel)); @@ -303,13 +303,22 @@ function SurveyContainerComponent({ loadFrom }) { } } + if (!surveyModel.css.question.title.includes("sv-header-flex")) { + surveyModel.css.question.title = "sv-title sv-question__title sv-header-flex"; + surveyModel.css.question.titleOnError = "sv-question__title--error sv-error-color-fix"; + } + + const onPageChange = (page) => { + surveyModel.currentPageNo = page; + } + return ( <> {isAdmin ? <SurveySidebar /> : null} <Container className="survey-container"> <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}> + <SurveyNavigationComponent onPageChange={onPageChange} surveyModel={surveyModel} surveyActions={surveyActions} year={year} nren={nren}> <SurveyComponent surveyModel={surveyModel} /> </SurveyNavigationComponent> </Container> diff --git a/compendium-frontend/src/survey/SurveyNavigationComponent.tsx b/compendium-frontend/src/survey/SurveyNavigationComponent.tsx index 0d81f8132435b1e52ee899c1439c5340a704cb13..699153d14a7e6211b260e40d0c96bde3d6e83361 100644 --- a/compendium-frontend/src/survey/SurveyNavigationComponent.tsx +++ b/compendium-frontend/src/survey/SurveyNavigationComponent.tsx @@ -1,10 +1,10 @@ -import React, { useContext, useEffect, useState, useCallback } from "react"; +import { useContext, useEffect, useState, useCallback } from "react"; import ProgressBar from './ProgressBar'; import { Container, Row } from "react-bootstrap"; import { userContext } from "../providers/UserProvider"; -function SurveyNavigationComponent({ surveyModel, surveyActions, year, nren, children }) { +function SurveyNavigationComponent({ surveyModel, surveyActions, year, nren, children, onPageChange }) { // We use some state variables that are directly derived from the surveyModel to // ensure React rerenders properly. It would honestly be just as easy to remove the state // and force the rerender ourselves, because we know exactly when the rerender is necessary. @@ -28,7 +28,7 @@ function SurveyNavigationComponent({ surveyModel, surveyActions, year, nren, chi const pageNoSetter = (page) => { setPageNo(page); - surveyModel.currentPageNo = page; + onPageChange(page); } // const decrementPageNo = () => { pageNoSetter(surveyModel.currentPageNo - 1); }; const incrementPageNo = () => { pageNoSetter(surveyModel.currentPageNo + 1); };