Skip to content

Commit

Permalink
♻️ [open-formulieren/open-forms#4929] Refactor cosign <Routes> to not…
Browse files Browse the repository at this point in the history
… require any props

Split the state up in the components used to render each route/path,
which allows localizing the state. For the synchronization between
routes, React context is used.
  • Loading branch information
sergei-maertens committed Jan 8, 2025
1 parent 5070fa9 commit 9c37e4f
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 72 deletions.
4 changes: 3 additions & 1 deletion src/components/CoSign/Context.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@ import React, {useContext} from 'react';

const CosignContext = React.createContext({
reportDownloadUrl: '',
onCosignComplete: () => {},

Check warning on line 6 in src/components/CoSign/Context.js

View check run for this annotation

Codecov / codecov/patch

src/components/CoSign/Context.js#L6

Added line #L6 was not covered by tests
});

CosignContext.displayName = 'CosignContext';

const CosignProvider = ({reportDownloadUrl = '', children}) => (
const CosignProvider = ({reportDownloadUrl = '', onCosignComplete, children}) => (
<CosignContext.Provider
value={{
reportDownloadUrl,
onCosignComplete,
}}
>
{children}
Expand Down
76 changes: 5 additions & 71 deletions src/components/CoSign/Cosign.jsx
Original file line number Diff line number Diff line change
@@ -1,89 +1,23 @@
import {useContext} from 'react';
import {Outlet, Route, Routes, useNavigate} from 'react-router-dom';
import {useImmerReducer} from 'use-immer';
import {useState} from 'react';
import {Outlet, useNavigate} from 'react-router-dom';

import {ConfigContext} from 'Context';
import {destroy} from 'api';
import ErrorBoundary from 'components/Errors/ErrorBoundary';
import {CosignSummary} from 'components/Summary';
import useFormContext from 'hooks/useFormContext';

import {CosignProvider} from './Context';

const initialState = {
submission: null,
summaryData: [],
reportUrl: '',
cosignedSubmission: null,
};

const reducer = (draft, action) => {
switch (action.type) {
case 'SUBMISSION_LOADED': {
draft.submission = action.payload;
break;
}
case 'LOADED_SUMMARY_DATA': {
draft.summaryData = action.payload;
break;
}
case 'COSIGN_COMPLETE': {
return {...initialState, reportUrl: action.payload};
}
case 'RESET': {
return initialState;
}
default: {
throw new Error(`Unknown action ${action.type}`);
}
}
};

const Cosign = () => {
const form = useFormContext();
const [state, dispatch] = useImmerReducer(reducer, initialState);
const navigate = useNavigate();
const config = useContext(ConfigContext);
const [reportDownloadUrl, setReportDownloadUrl] = useState('');

Check warning on line 10 in src/components/CoSign/Cosign.jsx

View check run for this annotation

Codecov / codecov/patch

src/components/CoSign/Cosign.jsx#L10

Added line #L10 was not covered by tests

const onCosignComplete = reportUrl => {
dispatch({type: 'COSIGN_COMPLETE', payload: reportUrl});
setReportDownloadUrl(reportUrl);

Check warning on line 13 in src/components/CoSign/Cosign.jsx

View check run for this annotation

Codecov / codecov/patch

src/components/CoSign/Cosign.jsx#L13

Added line #L13 was not covered by tests
navigate('/cosign/done');
};

const onDestroySession = async () => {
await destroy(`${config.baseUrl}authentication/${state.submission.id}/session`);

dispatch({type: 'RESET'});
navigate('/');
};

return (
<ErrorBoundary useCard>
<CosignProvider reportDownloadUrl={state.reportUrl}>
<CosignProvider reportDownloadUrl={reportDownloadUrl} onCosignComplete={onCosignComplete}>
<Outlet />
<Routes>
<Route
path="check"
element={
<CosignSummary
form={form}
submission={state.submission}
summaryData={state.summaryData}
onSubmissionLoaded={submission =>
dispatch({
type: 'SUBMISSION_LOADED',
payload: submission,
})
}
onDataLoaded={({summaryData}) =>
dispatch({type: 'LOADED_SUMMARY_DATA', payload: summaryData})
}
onCosignComplete={onCosignComplete}
onDestroySession={onDestroySession}
/>
}
/>
</Routes>
</CosignProvider>
</ErrorBoundary>
);
Expand Down
46 changes: 46 additions & 0 deletions src/components/CoSign/CosignCheck.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import {useContext, useState} from 'react';
import {useNavigate} from 'react-router-dom';

import {ConfigContext} from 'Context';
import {destroy} from 'api';
import {CosignSummary} from 'components/Summary';
import useFormContext from 'hooks/useFormContext';

import {useCosignContext} from './Context';

/**
* Fetch the submission summary data and display it, together with the controls to
* confirm the submission and buttons to log out.
*/
const CosignCheck = () => {
const navigate = useNavigate();
const config = useContext(ConfigContext);
const form = useFormContext();
const {onCosignComplete} = useCosignContext();

Check warning on line 19 in src/components/CoSign/CosignCheck.jsx

View check run for this annotation

Codecov / codecov/patch

src/components/CoSign/CosignCheck.jsx#L16-L19

Added lines #L16 - L19 were not covered by tests

const [submission, setSubmission] = useState(null);
const [summaryData, setSummaryData] = useState([]);

Check warning on line 22 in src/components/CoSign/CosignCheck.jsx

View check run for this annotation

Codecov / codecov/patch

src/components/CoSign/CosignCheck.jsx#L21-L22

Added lines #L21 - L22 were not covered by tests

const onDestroySession = async () => {
await destroy(`${config.baseUrl}authentication/${submission.id}/session`);
setSubmission(null);
setSummaryData([]);
navigate('/');

Check warning on line 28 in src/components/CoSign/CosignCheck.jsx

View check run for this annotation

Codecov / codecov/patch

src/components/CoSign/CosignCheck.jsx#L24-L28

Added lines #L24 - L28 were not covered by tests
};

return (

Check warning on line 31 in src/components/CoSign/CosignCheck.jsx

View check run for this annotation

Codecov / codecov/patch

src/components/CoSign/CosignCheck.jsx#L31

Added line #L31 was not covered by tests
<CosignSummary
form={form}
submission={submission}
summaryData={summaryData}
onSubmissionLoaded={submission => setSubmission(submission)}
onDataLoaded={({summaryData}) => setSummaryData(summaryData)}

Check warning on line 37 in src/components/CoSign/CosignCheck.jsx

View check run for this annotation

Codecov / codecov/patch

src/components/CoSign/CosignCheck.jsx#L36-L37

Added lines #L36 - L37 were not covered by tests
onCosignComplete={onCosignComplete}
onDestroySession={onDestroySession}
/>
);
};

CosignCheck.propTypes = {};

export default CosignCheck;
5 changes: 5 additions & 0 deletions src/components/CoSign/routes.jsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import CosignCheck from './CosignCheck';
import CosignDone from './CosignDone';
import CosignStart from './CosignStart';

Expand All @@ -6,6 +7,10 @@ const routes = [
path: 'start',
element: <CosignStart />,
},
{
path: 'check',
element: <CosignCheck />,
},
{
path: 'done',
element: <CosignDone />,
Expand Down

0 comments on commit 9c37e4f

Please sign in to comment.