Skip to content

Commit

Permalink
[#36] Refactored appointments
Browse files Browse the repository at this point in the history
  • Loading branch information
vaszig committed Nov 10, 2023
1 parent e354b4b commit 2fa0f88
Show file tree
Hide file tree
Showing 11 changed files with 338 additions and 156 deletions.
140 changes: 48 additions & 92 deletions src/components/Form.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,15 @@ import SubmissionSummary from 'components/Summary';
import {START_FORM_QUERY_PARAM} from 'components/constants';
import {findNextApplicableStep} from 'components/utils';
import {createSubmission, flagActiveSubmission, flagNoActiveSubmission} from 'data/submissions';
import {IsFormDesigner} from 'headers';
import useAutomaticRedirect from 'hooks/useAutomaticRedirect';
import useFormContext from 'hooks/useFormContext';
import usePageViews from 'hooks/usePageViews';
import useQuery from 'hooks/useQuery';
import useRecycleSubmission from 'hooks/useRecycleSubmission';
import useSessionTimeout from 'hooks/useSessionTimeout';

import {STEP_LABELS, SUBMISSION_ALLOWED} from './constants';
import {checkMatchesPath} from './utils/routes';
import {addFixedSteps, getStepsInfo} from './ProgressIndicatorNew/utils';
import {SUBMISSION_ALLOWED} from './constants';

const initialState = {
submission: null,
Expand Down Expand Up @@ -102,7 +101,11 @@ const Form = () => {
const intl = useIntl();
const prevLocale = usePrevious(intl.locale);
const {pathname: currentPathname} = useLocation();

// TODO replace absolute path check with relative
const stepMatch = useMatch('/stap/:step');
const summaryMatch = useMatch('/overzicht');
const confirmationMatch = useMatch('/bevestiging');

// extract the declared properties and configuration
const {steps} = form;
Expand Down Expand Up @@ -268,116 +271,69 @@ const Form = () => {

// Progress Indicator

const isSummary = checkMatchesPath(currentPathname, 'overzicht');
const isStep = checkMatchesPath(currentPathname, 'stap/:step');
const isConfirmation = checkMatchesPath(currentPathname, 'bevestiging');
const isStartPage = !isSummary && !isStep && !isConfirmation;
const isStartPage = !summaryMatch && stepMatch == null && !confirmationMatch;
const submissionAllowedSpec = state.submission?.submissionAllowed ?? form.submissionAllowed;
const showOverview = submissionAllowedSpec !== SUBMISSION_ALLOWED.noWithoutOverview;
const showConfirmation = submissionAllowedSpec === SUBMISSION_ALLOWED.yes;
const submission = state.submission || state.submittedSubmission;
const hasSubmission = !!submission;

const applicableSteps = hasSubmission ? submission.steps.filter(step => step.isApplicable) : [];
const applicableAndCompletedSteps = applicableSteps.filter(step => step.completed);
const applicableCompleted =
hasSubmission && applicableSteps.length === applicableAndCompletedSteps.length;

// If any step cannot be submitted, there should NOT be an active link to the overview page.
const canSubmitSteps = hasSubmission
? submission.steps.filter(step => !step.canSubmit).length === 0
: false;
const isCompleted = state.completed;
const formName = form.name;

// figure out the slug from the currently active step IF we're looking at a step
// Figure out the slug from the currently active step IF we're looking at a step
const stepSlug = stepMatch ? stepMatch.params.step : '';

// figure out the title for the mobile menu based on the state
let activeStepTitle;
if (isStartPage) {
activeStepTitle = STEP_LABELS.login;
} else if (isSummary) {
activeStepTitle = STEP_LABELS.overview;
} else if (isConfirmation) {
activeStepTitle = STEP_LABELS.confirmation;
activeStepTitle = intl.formatMessage({
description: 'Start page title',
defaultMessage: 'Start page',
});
} else if (summaryMatch) {
activeStepTitle = intl.formatMessage({

Check warning on line 293 in src/components/Form.js

View check run for this annotation

Codecov / codecov/patch

src/components/Form.js#L292-L293

Added lines #L292 - L293 were not covered by tests
description: 'Summary page title',
defaultMessage: 'Summary',
});
} else if (confirmationMatch) {
activeStepTitle = intl.formatMessage({

Check warning on line 298 in src/components/Form.js

View check run for this annotation

Codecov / codecov/patch

src/components/Form.js#L297-L298

Added lines #L297 - L298 were not covered by tests
description: 'Confirmation page title',
defaultMessage: 'Confirmation',
});
} else {
const step = steps.find(step => step.slug === stepSlug);
activeStepTitle = step.formDefinition;

Check warning on line 304 in src/components/Form.js

View check run for this annotation

Codecov / codecov/patch

src/components/Form.js#L302-L304

Added lines #L302 - L304 were not covered by tests
}

const canNavigateToStep = index => {
// The user can navigate to a step when:
// 1. All previous steps have been completed
// 2. The user is a form designer
if (IsFormDesigner.getValue()) return true;

if (!submission) return false;

const previousSteps = submission.steps.slice(0, index);
const previousApplicableButNotCompletedSteps = previousSteps.filter(
step => step.isApplicable && !step.completed
);

return !previousApplicableButNotCompletedSteps.length;
};

// prepare steps - add the fixed steps-texts as well
const getStepsInfo = () => {
return form.steps.map((step, index) => ({
uuid: step.uuid,
slug: step.slug,
to: `/stap/${step.slug}` || '#',
formDefinition: step.formDefinition,
isCompleted: submission ? submission.steps[index].completed : false,
isApplicable: submission ? submission.steps[index].isApplicable : step.isApplicable ?? true,
isCurrent: checkMatchesPath(currentPathname, `/stap/${step.slug}`),
canNavigateTo: canNavigateToStep(index),
}));
};

const updatedSteps = getStepsInfo();

updatedSteps.splice(0, 0, {
slug: 'startpagina',
to: '#',
formDefinition: 'Start page',
isCompleted: hasSubmission,
isApplicable: true,
canNavigateTo: true,
isCurrent: checkMatchesPath(currentPathname, 'startpagina'),
fixedText: STEP_LABELS.login,
const ariaMobileIconLabel = intl.formatMessage({
description: 'Progress step indicator toggle icon (mobile)',
defaultMessage: 'Toggle the progress status display',
});

if (showOverview) {
updatedSteps.splice(updatedSteps.length, 0, {
slug: 'overzicht',
to: 'overzicht',
formDefinition: 'Summary',
isCompleted: isConfirmation,
isApplicable: applicableCompleted && canSubmitSteps,
isCurrent: checkMatchesPath(currentPathname, 'overzicht'),
fixedText: STEP_LABELS.overview,
});
const summaryPage = updatedSteps[updatedSteps.length - 1];
summaryPage.canNavigateTo = canNavigateToStep(updatedSteps.length - 1);
}

if (showConfirmation) {
updatedSteps.splice(updatedSteps.length, 0, {
slug: 'bevestiging',
to: 'bevestiging',
formDefinition: 'Confirmation',
isCompleted: state ? state.completed : false,
isCurrent: checkMatchesPath(currentPathname, 'bevestiging'),
fixedText: STEP_LABELS.confirmation,
});
}
const accessibleToggleStepsLabel = intl.formatMessage(
{
description: 'Active step accessible label in mobile progress indicator',
defaultMessage: 'Current step in form {formName}: {activeStepTitle}',
},
{formName, activeStepTitle}
);

const updatedSteps = getStepsInfo(form.steps, submission, currentPathname);
const stepsToRender = addFixedSteps(
updatedSteps,
submission,
currentPathname,
showOverview,
showConfirmation,
isCompleted
);
debugger;
const progressIndicatorNew = form.showProgressIndicator ? (
<ProgressIndicatorNew
progressIndicatorTitle="Progress"
formTitle={form.name}
steps={updatedSteps}
activeStepTitle={activeStepTitle}
formTitle={formName}
steps={stepsToRender}
ariaMobileIconLabel={ariaMobileIconLabel}
accessibleToggleStepsLabel={accessibleToggleStepsLabel}
/>
) : null;

Expand Down
15 changes: 7 additions & 8 deletions src/components/ProgressIndicatorNew/MobileButton.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import PropTypes from 'prop-types';
import {FormattedMessage} from 'react-intl';

import FAIcon from 'components/FAIcon';
import {getBEMClassName} from 'utils';

const MobileButton = ({
ariaIconLabel,
ariaMobileIconLabel,
accessibleToggleStepsLabel,
formTitle,
expanded,
Expand All @@ -20,7 +19,7 @@ const MobileButton = ({
<FAIcon
icon={expanded ? 'chevron-up' : 'chevron-down'}
modifiers={['normal']}
aria-label={ariaIconLabel}
aria-label={ariaMobileIconLabel}
/>
<span
className={getBEMClassName('progress-indicator__form-title')}
Expand All @@ -33,11 +32,11 @@ const MobileButton = ({
};

MobileButton.propTypes = {
ariaIconLabel: PropTypes.string.isRequired,
accessibleToggleStepsLabel: PropTypes.oneOfType([PropTypes.string, FormattedMessage]),
formTitle: PropTypes.string.isRequired,
expanded: PropTypes.bool.isRequired,
onExpandClick: PropTypes.func.isRequired,
ariaMobileIconLabel: PropTypes.string,
accessibleToggleStepsLabel: PropTypes.string,
formTitle: PropTypes.string,
expanded: PropTypes.bool,
onExpandClick: PropTypes.func,
};

export default MobileButton;
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ export default {
fixedText: STEP_LABELS.overview,
},
],
activeStepTitle: 'Stap 2',
ariaMobileIconLabel: 'Progress step indicator toggle icon (mobile)',
accessibleToggleStepsLabel: 'Current step in form Formulier: Stap 2',
},
};

Expand Down
35 changes: 14 additions & 21 deletions src/components/ProgressIndicatorNew/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import PropTypes from 'prop-types';
import React, {useEffect, useState} from 'react';
import {FormattedMessage, useIntl} from 'react-intl';
import {FormattedMessage} from 'react-intl';
import {useLocation} from 'react-router-dom';

import Caption from 'components/Caption';
Expand All @@ -11,24 +11,16 @@ import {STEP_LABELS} from 'components/constants';
import MobileButton from './MobileButton';
import ProgressIndicatorItem from './ProgressIndicatorItem';

const ProgressIndicatorNew = ({progressIndicatorTitle, formTitle, steps, activeStepTitle}) => {
const intl = useIntl();
const ProgressIndicatorNew = ({
progressIndicatorTitle,
formTitle,
steps,
ariaMobileIconLabel,
accessibleToggleStepsLabel,
}) => {
const {pathname: currentPathname} = useLocation();
const [expanded, setExpanded] = useState(false);

const ariaIconLabel = intl.formatMessage({
description: 'Progress step indicator toggle icon (mobile)',
defaultMessage: 'Toggle the progress status display',
});

const accessibleToggleStepsLabel = intl.formatMessage(
{
description: 'Active step accessible label in mobile progress indicator',
defaultMessage: 'Current step in form {formTitle}: {activeStepTitle}',
},
{formTitle, activeStepTitle}
);

const modifiers = [];
if (!expanded) {
modifiers.push('mobile-collapsed');
Expand All @@ -48,7 +40,7 @@ const ProgressIndicatorNew = ({progressIndicatorTitle, formTitle, steps, activeS
<Card blockClassName="progress-indicator" modifiers={modifiers}>
<nav>
<MobileButton
ariaIconLabel={ariaIconLabel}
ariaMobileIconLabel={ariaMobileIconLabel}
accessibleToggleStepsLabel={accessibleToggleStepsLabel}
formTitle={formTitle}
expanded={expanded}
Expand Down Expand Up @@ -81,22 +73,23 @@ const ProgressIndicatorNew = ({progressIndicatorTitle, formTitle, steps, activeS
};

ProgressIndicatorNew.propTypes = {
progressIndicatorTitle: PropTypes.string.isRequired,
progressIndicatorTitle: PropTypes.string,
formTitle: PropTypes.string,
steps: PropTypes.arrayOf(
PropTypes.shape({
uuid: PropTypes.string,
slug: PropTypes.string.isRequired,
slug: PropTypes.string,
to: PropTypes.string,
formDefinition: PropTypes.string.isRequired,
formDefinition: PropTypes.string,
isCompleted: PropTypes.bool,
isApplicable: PropTypes.bool,
isCurrent: PropTypes.bool,
canNavigateTo: PropTypes.bool,
fixedText: PropTypes.oneOf(Object.values(STEP_LABELS)),
})
).isRequired,
activeStepTitle: PropTypes.string,
ariaMobileIconLabel: PropTypes.string,
accessibleToggleStepsLabel: PropTypes.string,
};

export default ProgressIndicatorNew;
Loading

0 comments on commit 2fa0f88

Please sign in to comment.