From d08a14208751c90d0acd4a187ae682f3a7252667 Mon Sep 17 00:00:00 2001 From: vasileios Date: Wed, 8 Nov 2023 17:05:37 +0100 Subject: [PATCH 01/17] [#36] Added new progress indicator --- src/components/Form.js | 132 ++++++++++++++++-- .../ProgressIndicatorNew/CompletionMark.js | 31 ++++ .../ProgressIndicatorNew/MobileButton.js | 43 ++++++ .../ProgressIndicatorItem.js | 76 ++++++++++ .../ProgressIndicatorItem.stories.js | 20 +++ .../ProgressIndicatorNew.stories.js | 70 ++++++++++ src/components/ProgressIndicatorNew/index.js | 102 ++++++++++++++ src/components/constants.js | 12 +- src/components/utils/routes.js | 11 ++ 9 files changed, 485 insertions(+), 12 deletions(-) create mode 100644 src/components/ProgressIndicatorNew/CompletionMark.js create mode 100644 src/components/ProgressIndicatorNew/MobileButton.js create mode 100644 src/components/ProgressIndicatorNew/ProgressIndicatorItem.js create mode 100644 src/components/ProgressIndicatorNew/ProgressIndicatorItem.stories.js create mode 100644 src/components/ProgressIndicatorNew/ProgressIndicatorNew.stories.js create mode 100644 src/components/ProgressIndicatorNew/index.js create mode 100644 src/components/utils/routes.js diff --git a/src/components/Form.js b/src/components/Form.js index ef46d593d..dbd6a3809 100644 --- a/src/components/Form.js +++ b/src/components/Form.js @@ -1,6 +1,6 @@ import React, {useContext, useEffect} from 'react'; import {useIntl} from 'react-intl'; -import {Navigate, Route, Routes, useMatch, useNavigate} from 'react-router-dom'; +import {Navigate, Route, Routes, useLocation, useMatch, useNavigate} from 'react-router-dom'; import {usePrevious} from 'react-use'; import {useImmerReducer} from 'use-immer'; @@ -12,7 +12,7 @@ import FormStart from 'components/FormStart'; import FormStep from 'components/FormStep'; import Loader from 'components/Loader'; import PaymentOverview from 'components/PaymentOverview'; -import ProgressIndicator from 'components/ProgressIndicator'; +import ProgressIndicatorNew from 'components/ProgressIndicatorNew/index'; import RequireSubmission from 'components/RequireSubmission'; import {RequireSession} from 'components/Sessions'; import SubmissionConfirmation from 'components/SubmissionConfirmation'; @@ -20,6 +20,7 @@ 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'; @@ -27,6 +28,9 @@ 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'; + const initialState = { submission: null, submittedSubmission: null, @@ -97,6 +101,8 @@ const Form = () => { usePageViews(); const intl = useIntl(); const prevLocale = usePrevious(intl.locale); + const {pathname: currentPathname} = useLocation(); + const stepMatch = useMatch('/stap/:step'); // extract the declared properties and configuration const {steps} = form; @@ -260,14 +266,118 @@ const Form = () => { return ; } - const progressIndicator = form.showProgressIndicator ? ( - 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; + + // 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; + } else { + const step = steps.find(step => step.slug === stepSlug); + activeStepTitle = step.formDefinition; + } + + 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, + }); + + 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 progressIndicatorNew = form.showProgressIndicator ? ( + ) : null; @@ -366,7 +476,7 @@ const Form = () => { return ( diff --git a/src/components/ProgressIndicatorNew/CompletionMark.js b/src/components/ProgressIndicatorNew/CompletionMark.js new file mode 100644 index 000000000..a244d16f6 --- /dev/null +++ b/src/components/ProgressIndicatorNew/CompletionMark.js @@ -0,0 +1,31 @@ +import PropTypes from 'prop-types'; +import {useIntl} from 'react-intl'; + +import FAIcon from 'components/FAIcon'; + +const CompletionMark = ({completed = false}) => { + const intl = useIntl(); + // Wrapper may be a DOM element, which can't handle + const ariaLabel = intl.formatMessage({ + description: 'Step completion marker icon label', + defaultMessage: 'Completed', + }); + + if (!completed) return null; + + // provide a text alternative with aria-hidden="true" attribute on the icon and include text with an + // additional element, such as a , with appropriate CSS to visually hide the element while keeping it + // accessible to assistive technologies. Only here where the Completion mark icon actually has a meaning. + return ( + <> + + {ariaLabel} + + ); +}; + +CompletionMark.propTypes = { + completed: PropTypes.bool, +}; + +export default CompletionMark; diff --git a/src/components/ProgressIndicatorNew/MobileButton.js b/src/components/ProgressIndicatorNew/MobileButton.js new file mode 100644 index 000000000..d769cfce0 --- /dev/null +++ b/src/components/ProgressIndicatorNew/MobileButton.js @@ -0,0 +1,43 @@ +import PropTypes from 'prop-types'; +import {FormattedMessage} from 'react-intl'; + +import FAIcon from 'components/FAIcon'; +import {getBEMClassName} from 'utils'; + +const MobileButton = ({ + ariaIconLabel, + accessibleToggleStepsLabel, + formTitle, + expanded, + onExpandClick, +}) => { + return ( + + ); +}; + +MobileButton.propTypes = { + ariaIconLabel: PropTypes.string.isRequired, + accessibleToggleStepsLabel: PropTypes.oneOfType([PropTypes.string, FormattedMessage]), + formTitle: PropTypes.string.isRequired, + expanded: PropTypes.bool.isRequired, + onExpandClick: PropTypes.func.isRequired, +}; + +export default MobileButton; diff --git a/src/components/ProgressIndicatorNew/ProgressIndicatorItem.js b/src/components/ProgressIndicatorNew/ProgressIndicatorItem.js new file mode 100644 index 000000000..054c041bc --- /dev/null +++ b/src/components/ProgressIndicatorNew/ProgressIndicatorItem.js @@ -0,0 +1,76 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import {FormattedMessage} from 'react-intl'; + +import Body from 'components/Body'; +import Link from 'components/Link'; +import {STEP_LABELS} from 'components/constants'; +import {getBEMClassName} from 'utils'; + +import CompletionMark from './CompletionMark'; + +const ProgressIndicatorItem = ({ + text, + href, + isActive, + isCompleted, + canNavigateTo, + isApplicable, + fixedText = null, +}) => { + const getLinkModifiers = (isActive, isApplicable) => { + return [ + 'inherit', + 'hover', + isActive ? 'active' : undefined, + isApplicable ? undefined : 'muted', + ].filter(mod => mod !== undefined); + }; + + return ( +
+
+ +
+
+ {isApplicable && canNavigateTo ? ( + + + + ) : ( + + {fixedText || text} + + )} +
+
+ ); +}; + +ProgressIndicatorItem.propTypes = { + text: PropTypes.string.isRequired, + href: PropTypes.string, + isActive: PropTypes.bool, + isCompleted: PropTypes.bool, + canNavigateTo: PropTypes.bool, + isApplicable: PropTypes.bool, + fixedText: PropTypes.oneOf(Object.values(STEP_LABELS)), +}; + +export default ProgressIndicatorItem; diff --git a/src/components/ProgressIndicatorNew/ProgressIndicatorItem.stories.js b/src/components/ProgressIndicatorNew/ProgressIndicatorItem.stories.js new file mode 100644 index 000000000..a4e89fa87 --- /dev/null +++ b/src/components/ProgressIndicatorNew/ProgressIndicatorItem.stories.js @@ -0,0 +1,20 @@ +import {withRouter} from 'storybook-addon-react-router-v6'; + +import ProgressIndicatorItem from './ProgressIndicatorItem'; + +export default { + title: 'Private API / ProgressIndicatorNew / ProgressIndicatorItem', + component: ProgressIndicatorItem, + decorators: [withRouter], + args: { + text: 'Stap 1', + href: '#', + isActive: false, + isCompleted: true, + canNavigateTo: false, + isApplicable: true, + fixedText: null, + }, +}; + +export const Default = {}; diff --git a/src/components/ProgressIndicatorNew/ProgressIndicatorNew.stories.js b/src/components/ProgressIndicatorNew/ProgressIndicatorNew.stories.js new file mode 100644 index 000000000..aa1afd223 --- /dev/null +++ b/src/components/ProgressIndicatorNew/ProgressIndicatorNew.stories.js @@ -0,0 +1,70 @@ +import {withRouter} from 'storybook-addon-react-router-v6'; + +import {STEP_LABELS} from 'components/constants'; + +import ProgressIndicatorNew from '.'; + +export default { + title: 'Private API / ProgressIndicatorNew', + component: ProgressIndicatorNew, + decorators: [withRouter], + args: { + progressIndicatorTitle: 'Progress', + formTitle: 'Formulier', + steps: [ + { + slug: 'start-page', + to: 'start-page', + formDefinition: 'Start page', + isCompleted: true, + isApplicable: true, + isCurrent: false, + canNavigateTo: true, + fixedText: STEP_LABELS.login, + }, + { + uuid: 'd6cab0dd', + slug: 'first-step', + to: 'first-step', + formDefinition: 'Stap 1', + isCompleted: true, + isApplicable: true, + isCurrent: false, + canNavigateTo: true, + }, + { + uuid: '8e62d7cf', + slug: 'second-step', + to: 'second-step', + formDefinition: 'Stap 2', + isCompleted: false, + isApplicable: true, + isCurrent: true, + canNavigateTo: true, + }, + { + slug: 'confirmation-page', + to: 'confirmation-page', + formDefinition: 'Confirmation', + isCompleted: false, + isApplicable: false, + isCurrent: false, + canNavigateTo: true, + fixedText: STEP_LABELS.confirmation, + }, + { + slug: 'summary-page', + to: 'summary-page', + formDefinition: 'Summary', + isCompleted: false, + isApplicable: false, + isCurrent: false, + canNavigateTo: true, + fixedText: STEP_LABELS.overview, + }, + ], + activeStepTitle: 'Stap 2', + }, +}; + +export const Default = {}; diff --git a/src/components/ProgressIndicatorNew/index.js b/src/components/ProgressIndicatorNew/index.js new file mode 100644 index 000000000..60879ef07 --- /dev/null +++ b/src/components/ProgressIndicatorNew/index.js @@ -0,0 +1,102 @@ +import PropTypes from 'prop-types'; +import React, {useEffect, useState} from 'react'; +import {FormattedMessage, useIntl} from 'react-intl'; +import {useLocation} from 'react-router-dom'; + +import Caption from 'components/Caption'; +import Card from 'components/Card'; +import List from 'components/List'; +import {STEP_LABELS} from 'components/constants'; + +import MobileButton from './MobileButton'; +import ProgressIndicatorItem from './ProgressIndicatorItem'; + +const ProgressIndicatorNew = ({progressIndicatorTitle, formTitle, steps, activeStepTitle}) => { + const intl = useIntl(); + 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'); + } + + // collapse the expanded progress indicator if nav occurred, see + // open-formulieren/open-forms#2673. It's important that *only* the pathname triggers + // the effect, which is why exhaustive deps is ignored. + useEffect(() => { + if (expanded) { + setExpanded(false); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [currentPathname]); + + return ( + + + + ); +}; + +ProgressIndicatorNew.propTypes = { + progressIndicatorTitle: PropTypes.string.isRequired, + formTitle: PropTypes.string, + steps: PropTypes.arrayOf( + PropTypes.shape({ + uuid: PropTypes.string, + slug: PropTypes.string.isRequired, + to: PropTypes.string, + formDefinition: PropTypes.string.isRequired, + isCompleted: PropTypes.bool, + isApplicable: PropTypes.bool, + isCurrent: PropTypes.bool, + canNavigateTo: PropTypes.bool, + fixedText: PropTypes.oneOf(Object.values(STEP_LABELS)), + }) + ).isRequired, + activeStepTitle: PropTypes.string, +}; + +export default ProgressIndicatorNew; diff --git a/src/components/constants.js b/src/components/constants.js index 9823078be..444ddc31e 100644 --- a/src/components/constants.js +++ b/src/components/constants.js @@ -1,11 +1,21 @@ +import {FormattedMessage} from 'react-intl'; + const SUBMISSION_ALLOWED = { yes: 'yes', noWithOverview: 'no_with_overview', noWithoutOverview: 'no_without_overview', }; +const STEP_LABELS = { + login: , + overview: , + confirmation: ( + + ), +}; + const START_FORM_QUERY_PARAM = '_start'; const SUBMISSION_UUID_QUERY_PARAM = 'submission_uuid'; -export {SUBMISSION_ALLOWED, START_FORM_QUERY_PARAM, SUBMISSION_UUID_QUERY_PARAM}; +export {SUBMISSION_ALLOWED, START_FORM_QUERY_PARAM, SUBMISSION_UUID_QUERY_PARAM, STEP_LABELS}; diff --git a/src/components/utils/routes.js b/src/components/utils/routes.js new file mode 100644 index 000000000..d62a3a66c --- /dev/null +++ b/src/components/utils/routes.js @@ -0,0 +1,11 @@ +import {matchPath} from 'react-router-dom'; + +/** + * Check if a given relative path from the routes matches the current location. + * @param currentPathname The current router location.pathname, from useLocation. + * @param path The relative path to check for matches + */ +export const checkMatchesPath = (currentPathname, path) => { + const match = matchPath(path, currentPathname); + return match !== null; +}; From 87f4f35571c4c640e00a18a7b2cafb9dd1c8ef43 Mon Sep 17 00:00:00 2001 From: vasileios Date: Fri, 10 Nov 2023 14:55:23 +0100 Subject: [PATCH 02/17] [#36] Refactored appointments --- src/components/Form.js | 140 ++++++------------ .../ProgressIndicatorNew/MobileButton.js | 15 +- .../ProgressIndicatorNew.stories.js | 3 +- src/components/ProgressIndicatorNew/index.js | 35 ++--- src/components/ProgressIndicatorNew/utils.js | 93 ++++++++++++ .../CreateAppointment/AppointmentProgress.js | 83 ++++++++--- src/components/utils/routes.js | 11 -- src/i18n/compiled/en.json | 42 ++++++ src/i18n/compiled/nl.json | 42 ++++++ src/i18n/messages/en.json | 15 ++ src/i18n/messages/nl.json | 15 ++ 11 files changed, 338 insertions(+), 156 deletions(-) create mode 100644 src/components/ProgressIndicatorNew/utils.js delete mode 100644 src/components/utils/routes.js diff --git a/src/components/Form.js b/src/components/Form.js index dbd6a3809..d2cd2becc 100644 --- a/src/components/Form.js +++ b/src/components/Form.js @@ -20,7 +20,6 @@ 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'; @@ -28,8 +27,8 @@ 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, @@ -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; @@ -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({ + description: 'Summary page title', + defaultMessage: 'Summary', + }); + } else if (confirmationMatch) { + activeStepTitle = intl.formatMessage({ + description: 'Confirmation page title', + defaultMessage: 'Confirmation', + }); } else { const step = steps.find(step => step.slug === stepSlug); activeStepTitle = step.formDefinition; } - 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 ? ( ) : null; diff --git a/src/components/ProgressIndicatorNew/MobileButton.js b/src/components/ProgressIndicatorNew/MobileButton.js index d769cfce0..81114f934 100644 --- a/src/components/ProgressIndicatorNew/MobileButton.js +++ b/src/components/ProgressIndicatorNew/MobileButton.js @@ -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, @@ -20,7 +19,7 @@ const MobileButton = ({ { - 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'); @@ -48,7 +40,7 @@ const ProgressIndicatorNew = ({progressIndicatorTitle, formTitle, steps, activeS