diff --git a/src/applications/appeals/shared/tests/utils/focus.unit.spec.js b/src/applications/appeals/shared/tests/utils/focus.unit.spec.js index 6e450dbcdd83..e670b31b17b0 100644 --- a/src/applications/appeals/shared/tests/utils/focus.unit.spec.js +++ b/src/applications/appeals/shared/tests/utils/focus.unit.spec.js @@ -88,7 +88,7 @@ describe('focusRadioH3', () => { ) : (
We prefer that you upload the Veteran’s or Reservist’s DD214.
diff --git a/src/applications/simple-forms/40-0247/tests/e2e/fixtures/mocks/in-progress-forms-get.json b/src/applications/simple-forms/40-0247/tests/e2e/fixtures/mocks/in-progress-forms-get.json index f5290f91c216..df7f894aa5ff 100644 --- a/src/applications/simple-forms/40-0247/tests/e2e/fixtures/mocks/in-progress-forms-get.json +++ b/src/applications/simple-forms/40-0247/tests/e2e/fixtures/mocks/in-progress-forms-get.json @@ -1,8 +1,15 @@ { - "formData": {}, + "formData": { + "veteranFullName": { + "first": "John", + "last": "Veteran" + }, + "veteranDateOfBirth": "1985-01-01", + "veteranDateOfDeath": "2015-01-01" + }, "metadata": { "version": 0, "prefill": true, - "returnUrl": "/claim-ownership" + "returnUrl": "/veteran-personal-information" } } diff --git a/src/applications/simple-forms/40-0247/tests/e2e/fixtures/mocks/in-progress-forms-put.json b/src/applications/simple-forms/40-0247/tests/e2e/fixtures/mocks/in-progress-forms-put.json index 060084e36a74..43e29a3fe2bd 100644 --- a/src/applications/simple-forms/40-0247/tests/e2e/fixtures/mocks/in-progress-forms-put.json +++ b/src/applications/simple-forms/40-0247/tests/e2e/fixtures/mocks/in-progress-forms-put.json @@ -8,7 +8,7 @@ "updatedAt": "2023-06-22T00:09:26.698Z", "metadata": { "version": 0, - "returnUrl": "/introduction", + "returnUrl": "/veteran-personal-information", "savedAt": 1687392566385, "submission": { "status": false, diff --git a/src/applications/simple-forms/40-0247/tests/e2e/fixtures/mocks/local-mock-api-reponses.js b/src/applications/simple-forms/40-0247/tests/e2e/fixtures/mocks/local-mock-api-reponses.js index ad17ede7f3eb..9098632e6b52 100644 --- a/src/applications/simple-forms/40-0247/tests/e2e/fixtures/mocks/local-mock-api-reponses.js +++ b/src/applications/simple-forms/40-0247/tests/e2e/fixtures/mocks/local-mock-api-reponses.js @@ -2,12 +2,16 @@ const commonResponses = require('../../../../../../../platform/testing/local-dev-mock-api/common'); const mockFeatures = require('../../../../../shared/tests/e2e/fixtures/mocks/feature-toggles.json'); +const mockSipGet = require('./in-progress-forms-get.json'); +const mockSipPut = require('./in-progress-forms-put.json'); const mockUpload = require('./upload.json'); const mockSubmission = require('./submission.json'); const responses = { ...commonResponses, 'GET /v0/feature_toggles': mockFeatures, + 'GET /v0/in_progress_forms/40-0247': mockSipGet, + 'PUT /v0/in_progress_forms/40-0247': mockSipPut, 'POST /simple_forms_api/v1/simple_forms/submit_supporting_documents': mockUpload, 'POST /simple_forms_api/v1/simple_forms': mockSubmission, }; diff --git a/src/platform/forms-system/src/js/components/FormNav.jsx b/src/platform/forms-system/src/js/components/FormNav.jsx index ba1365010609..f8b1a8c2514a 100644 --- a/src/platform/forms-system/src/js/components/FormNav.jsx +++ b/src/platform/forms-system/src/js/components/FormNav.jsx @@ -2,20 +2,16 @@ import React, { useEffect, useState } from 'react'; import PropTypes from 'prop-types'; import uniq from 'lodash/uniq'; +import { scrollTo } from 'platform/utilities/ui/scroll'; import { getChaptersLengthDisplay, createFormPageList, createPageList, getActiveExpandedPages, getCurrentChapterDisplay, + handleFormNavFocus, } from '../helpers'; -import { - focusByOrder, - customScrollAndFocus, - defaultFocusSelector, -} from '../../../../utilities/ui'; - import { REVIEW_APP_DEFAULT_MESSAGE } from '../constants'; export default function FormNav(props) { @@ -111,35 +107,19 @@ export default function FormNav(props) { } else if (current === index) { setIndex(index - 1); } - - return () => { - // Check main toggle to enable custom focus; the unmounting of the page - // before the review & submit page may cause the customScrollAndFocus - // function to be called inadvertently - if ( - !( - page.chapterKey === 'review' || - window.location.pathname.endsWith('review-and-submit') - ) - ) { - if (formConfig.useCustomScrollAndFocus && page.scrollAndFocusTarget) { - customScrollAndFocus(page.scrollAndFocusTarget, index); - } else { - focusByOrder([defaultFocusSelector, 'h2']); - } - } else { - // h2 fallback for confirmation page - focusByOrder([defaultFocusSelector, 'h2']); - } - }; + if ( + !( + window.location.pathname.endsWith('introduction') || + window.location.pathname.endsWith('confirmation') + ) + ) { + scrollTo('vaSegmentedProgressBar', { offset: -20 }); + } + handleFormNavFocus(page, formConfig, index); }, - [ - current, - formConfig.useCustomScrollAndFocus, - index, - page.chapterKey, - page.scrollAndFocusTarget, - ], + // only current & index should be included in the dependency array. + // eslint-disable-next-line react-hooks/exhaustive-deps + [current, index], ); const v3SegmentedProgressBar = formConfig?.v3SegmentedProgressBar; @@ -152,7 +132,7 @@ export default function FormNav(props) { current={currentChapterDisplay} uswds={v3SegmentedProgressBar} heading-text={chapterName ?? ''} // functionality only available for v3 - name="v3SegmentedProgressBar" + name="vaSegmentedProgressBar" {...(v3SegmentedProgressBar ? { 'header-level': '2' } : {})} /> )} diff --git a/src/platform/forms-system/src/js/containers/FormPage.jsx b/src/platform/forms-system/src/js/containers/FormPage.jsx index a784127733d6..49c46b649eb8 100644 --- a/src/platform/forms-system/src/js/containers/FormPage.jsx +++ b/src/platform/forms-system/src/js/containers/FormPage.jsx @@ -5,12 +5,7 @@ import { withRouter } from 'react-router'; import classNames from 'classnames'; import environment from '@department-of-veterans-affairs/platform-utilities/environment'; import { getDefaultFormState } from '@department-of-veterans-affairs/react-jsonschema-form/lib/utils'; -import { - isReactComponent, - focusElement, - customScrollAndFocus, - defaultFocusSelector, -} from 'platform/utilities/ui'; +import { isReactComponent, customScrollAndFocus } from 'platform/utilities/ui'; import get from '../../../../utilities/data/get'; import set from '../../../../utilities/data/set'; @@ -23,22 +18,25 @@ import { checkValidPagePath, } from '../routing'; import { DevModeNavLinks } from '../components/dev/DevModeNavLinks'; -import { stringifyUrlParams } from '../helpers'; +import { handleFormNavFocus, stringifyUrlParams } from '../helpers'; -function focusForm(route, index) { +async function focusForm(route, index) { + const { formConfig, pageConfig } = route; // Check main toggle to enable custom focus - if (route.formConfig?.useCustomScrollAndFocus) { - customScrollAndFocus(route.pageConfig?.scrollAndFocusTarget, index); + if (formConfig?.useCustomScrollAndFocus) { + customScrollAndFocus(pageConfig?.scrollAndFocusTarget, index); } else { - focusElement(defaultFocusSelector); + handleFormNavFocus(pageConfig, formConfig, index); } } - class FormPage extends React.Component { componentDidMount() { this.prePopulateArrayData(); if (!this.props.blockScrollOnMount) { - focusForm(this.props.route, this.props?.params?.index); + focusForm(this.props.route, this.props?.params?.index).catch(error => { + // eslint-disable-next-line no-console + console.error('Error focusing on form:', error); + }); } } @@ -49,7 +47,10 @@ class FormPage extends React.Component { get('params.index', prevProps) !== get('params.index', this.props) ) { this.prePopulateArrayData(); - focusForm(this.props.route, this.props?.params?.index); + focusForm(this.props.route, this.props?.params?.index).catch(error => { + // eslint-disable-next-line no-console + console.error('Error focusing on form:', error); + }); } } diff --git a/src/platform/forms-system/src/js/helpers.js b/src/platform/forms-system/src/js/helpers.js index 96405fb1299d..9bf3bf599833 100644 --- a/src/platform/forms-system/src/js/helpers.js +++ b/src/platform/forms-system/src/js/helpers.js @@ -2,7 +2,14 @@ import { useEffect, useRef } from 'react'; import moment from 'moment'; import { intersection, matches, merge, uniq } from 'lodash'; import shouldUpdate from 'recompose/shouldUpdate'; + import { deepEquals } from '@department-of-veterans-affairs/react-jsonschema-form/lib/utils'; +import { + focusByOrder, + customScrollAndFocus, + defaultFocusSelector, +} from '../../../utilities/ui'; +import { querySelectorWithShadowRoot } from '../../../utilities/ui/webComponents'; import get from '../../../utilities/data/get'; import omit from '../../../utilities/data/omit'; import set from '../../../utilities/data/set'; @@ -134,6 +141,41 @@ export function createPageList(formConfig, formPages) { ); } +export async function getFormNavFocusTargetRoot(formConfig) { + if (formConfig.v3SegmentedProgressBar) { + // Need to provide shadowRoot for focusing on shadow-DOM elements + const shadowHost = await querySelectorWithShadowRoot( + 'va-segmented-progress-bar', + ); + return shadowHost.shadowRoot; + } + return document.querySelector('#react-root'); +} + +export function handleFormNavFocus(page, formConfig, index) { + // Check main toggle to enable custom focus; the unmounting of the page + // before the review & submit page may cause the customScrollAndFocus + // function to be called inadvertently + if ( + !( + page.chapterKey === 'review' || + window.location.pathname.endsWith('review-and-submit') + ) + ) { + if (formConfig.useCustomScrollAndFocus) { + customScrollAndFocus(page.scrollAndFocusTarget, index); + return Promise.resolve(); + } + return getFormNavFocusTargetRoot(formConfig).then(root => { + focusByOrder([defaultFocusSelector, 'h2'], root); + }); + } + // h2 fallback for review page + return getFormNavFocusTargetRoot(formConfig).then(root => { + focusByOrder([defaultFocusSelector, 'h2'], root); + }); +} + function formatDayMonth(val) { if (val) { const dayOrMonth = val.toString(); diff --git a/src/platform/forms-system/test/js/containers/FormPage.unit.spec.jsx b/src/platform/forms-system/test/js/containers/FormPage.unit.spec.jsx index fee398d3fbb3..3385776322e9 100644 --- a/src/platform/forms-system/test/js/containers/FormPage.unit.spec.jsx +++ b/src/platform/forms-system/test/js/containers/FormPage.unit.spec.jsx @@ -925,11 +925,11 @@ describe('Schemaform