diff --git a/src/applications/mhv/medications/actions/breadcrumbs.js b/src/applications/mhv/medications/actions/breadcrumbs.js deleted file mode 100644 index 5f760dfabf4b..000000000000 --- a/src/applications/mhv/medications/actions/breadcrumbs.js +++ /dev/null @@ -1,14 +0,0 @@ -import { Actions } from '../util/actionTypes'; - -export const setBreadcrumbs = crumbs => async dispatch => { - dispatch({ - type: Actions.Breadcrumbs.SET_BREAD_CRUMBS, - payload: { crumbs }, - }); -}; - -export const removeBreadcrumbs = () => async dispatch => { - dispatch({ - type: Actions.Breadcrumbs.REMOVE_BREAD_CRUMB, - }); -}; diff --git a/src/applications/mhv/medications/components/MedicationsList/MedicationsListCard.jsx b/src/applications/mhv/medications/components/MedicationsList/MedicationsListCard.jsx index 7304d354291e..e5749af1ab41 100644 --- a/src/applications/mhv/medications/components/MedicationsList/MedicationsListCard.jsx +++ b/src/applications/mhv/medications/components/MedicationsList/MedicationsListCard.jsx @@ -9,15 +9,11 @@ import { dispStatusForRefillsLeft, DD_ACTIONS_PAGE_TYPE, } from '../../util/constants'; -import { setBreadcrumbs } from '../../actions/breadcrumbs'; import { setPrescriptionDetails } from '../../actions/prescriptions'; import { selectRefillContentFlag } from '../../util/selectors'; const MedicationsListCard = ({ rx }) => { const dispatch = useDispatch(); - const pagination = useSelector( - state => state.rx.prescriptions?.prescriptionsPagination, - ); const showRefillContent = useSelector(selectRefillContentFlag); let showRefillRemaining = false; @@ -31,12 +27,6 @@ const MedicationsListCard = ({ rx }) => { return

{rx.refillRemaining} refills left

; }; const handleLinkClick = () => { - dispatch( - setBreadcrumbs({ - url: `/?page=${pagination?.currentPage || 1}`, - label: 'Medications', - }), - ); dispatch(setPrescriptionDetails(rx)); }; return ( diff --git a/src/applications/mhv/medications/components/RefillPrescriptions/RenewablePrescriptions.jsx b/src/applications/mhv/medications/components/RefillPrescriptions/RenewablePrescriptions.jsx index 463d38e06958..52576df72b63 100644 --- a/src/applications/mhv/medications/components/RefillPrescriptions/RenewablePrescriptions.jsx +++ b/src/applications/mhv/medications/components/RefillPrescriptions/RenewablePrescriptions.jsx @@ -4,7 +4,6 @@ import { Link } from 'react-router-dom'; import { useDispatch } from 'react-redux'; import { VaPagination } from '@department-of-veterans-affairs/component-library/dist/react-bindings'; import { waitForRenderThenFocus } from '@department-of-veterans-affairs/platform-utilities/ui'; -import { setBreadcrumbs } from '../../actions/breadcrumbs'; import { setPrescriptionDetails } from '../../actions/prescriptions'; import { DD_ACTIONS_PAGE_TYPE, medicationsUrls } from '../../util/constants'; import { dateFormat, fromToNumbs } from '../../util/helpers'; @@ -50,12 +49,6 @@ const RenewablePrescriptions = ({ renewablePrescriptionsList = [] }) => { // Functions const onRxLinkClick = rx => { - dispatch( - setBreadcrumbs({ - url: medicationsUrls.subdirectories.REFILL, - label: 'Refill prescriptions', - }), - ); dispatch(setPrescriptionDetails(rx)); }; diff --git a/src/applications/mhv/medications/containers/Prescriptions.jsx b/src/applications/mhv/medications/containers/Prescriptions.jsx index 819d81ab76bb..e8ce899303ea 100644 --- a/src/applications/mhv/medications/containers/Prescriptions.jsx +++ b/src/applications/mhv/medications/containers/Prescriptions.jsx @@ -20,7 +20,6 @@ import { getAllergiesList, clearAllergiesError, } from '../actions/prescriptions'; -import { setBreadcrumbs } from '../actions/breadcrumbs'; import MedicationsList from '../components/MedicationsList/MedicationsList'; import MedicationsListSort from '../components/MedicationsList/MedicationsListSort'; import { @@ -476,22 +475,11 @@ const Prescriptions = () => { dispatch(clearAllergiesError()); }; - const handletoRefillLink = () => { - dispatch( - setBreadcrumbs({ - url: medicationsUrls.subdirectories.BASE, - label: 'Medications', - }), - ); - }; - const content = () => { if (!isLoading) { return (
-

- Medications -

+

Medications

{ className="vads-c-action-link--green vads-u-margin--0" to={medicationsUrls.subdirectories.REFILL} data-testid="prescriptions-nav-link-to-refill" - onClick={handletoRefillLink} > Refill prescriptions diff --git a/src/applications/mhv/medications/containers/RxBreadcrumbs.jsx b/src/applications/mhv/medications/containers/RxBreadcrumbs.jsx index 138469a612c6..f4a4a18fffb6 100644 --- a/src/applications/mhv/medications/containers/RxBreadcrumbs.jsx +++ b/src/applications/mhv/medications/containers/RxBreadcrumbs.jsx @@ -1,56 +1,55 @@ import React, { useEffect } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; -// import { replaceWithStagingDomain } from '~/platform/utilities/environment/stagingDomains'; -import { Link, useLocation } from 'react-router-dom'; -import { removeBreadcrumbs, setBreadcrumbs } from '../actions/breadcrumbs'; +import { useSelector } from 'react-redux'; +import { VaBreadcrumbs } from '@department-of-veterans-affairs/web-components/react-bindings'; +import { useLocation } from 'react-router-dom'; +import { createBreadcrumbs } from '../util/helpers'; import { medicationsUrls } from '../util/constants'; const RxBreadcrumbs = () => { const location = useLocation(); - const dispatch = useDispatch(); - const crumbs = useSelector(state => state.rx.breadcrumbs?.list); - const oneLevelDeepCrumb = crumbs?.length - 1; - + const prescription = useSelector( + state => state.rx.prescriptions?.prescriptionDetails, + ); + const pagination = useSelector( + state => state.rx.prescriptions?.prescriptionsPagination, + ); + const [breadcrumbs, setBreadcrumbs] = React.useState([]); useEffect( () => { - if (!crumbs?.length && !location.pathname.includes('/about')) { - dispatch( - setBreadcrumbs({ - url: medicationsUrls.subdirectories.ABOUT, - label: 'About medications', - }), - ); - } + setBreadcrumbs( + createBreadcrumbs(location, prescription, pagination?.currentPage), + ); }, - [dispatch, crumbs, location.pathname], + [location, prescription, pagination?.currentPage], ); - const backLink = () => { - dispatch(removeBreadcrumbs()); - }; return ( <> - {crumbs.length > 0 && - crumbs[0]?.url && ( -
-
0 && ( + <> + {!location.pathname.includes( + medicationsUrls.subdirectories.DETAILS, + ) ? ( + - - {'\u2039'}{' '} - - - Back to {crumbs[oneLevelDeepCrumb]?.label} - + home-veterans-affairs="false" + breadcrumbList={breadcrumbs} + className="no-print va-breadcrumbs-li vads-u-margin-bottom--neg1p5 vads-u-display--block" + /> + ) : ( +
+
-
- )} + )} + + )} ); }; diff --git a/src/applications/mhv/medications/reducers/breadcrumbs.js b/src/applications/mhv/medications/reducers/breadcrumbs.js deleted file mode 100644 index e17bba794cb2..000000000000 --- a/src/applications/mhv/medications/reducers/breadcrumbs.js +++ /dev/null @@ -1,26 +0,0 @@ -import { Actions } from '../util/actionTypes'; - -const initialState = { - list: [], -}; - -export const breadcrumbsReducer = (state = initialState, action) => { - switch (action.type) { - case Actions.Breadcrumbs.SET_BREAD_CRUMBS: { - const newCrumbList = [...state.list]; - newCrumbList.push(action.payload.crumbs); - return { - list: newCrumbList, - }; - } - case Actions.Breadcrumbs.REMOVE_BREAD_CRUMB: { - const newCrumbList = [...state.list]; - newCrumbList.pop(); - return { - list: newCrumbList, - }; - } - default: - return state; - } -}; diff --git a/src/applications/mhv/medications/reducers/index.js b/src/applications/mhv/medications/reducers/index.js index bb0a53ed972e..39aa1e91ae6e 100644 --- a/src/applications/mhv/medications/reducers/index.js +++ b/src/applications/mhv/medications/reducers/index.js @@ -1,13 +1,11 @@ import { combineReducers } from 'redux'; import { prescriptionsReducer } from './prescriptions'; -import { breadcrumbsReducer } from './breadcrumbs'; import { allergiesReducer } from './allergies'; const rootReducer = { rx: combineReducers({ prescriptions: prescriptionsReducer, - breadcrumbs: breadcrumbsReducer, // TODO: consider re-using this from medical-records allergies: allergiesReducer, }), diff --git a/src/applications/mhv/medications/sass/medications.scss b/src/applications/mhv/medications/sass/medications.scss index be677e54fa97..ba8f5570a206 100644 --- a/src/applications/mhv/medications/sass/medications.scss +++ b/src/applications/mhv/medications/sass/medications.scss @@ -39,17 +39,6 @@ margin-top: 70px; } -.rx-breadcrumbs { - .breadcrumb-angle { - color: var(--vads-color-link); - } - a { - &:visited { - color: var(--vads-color-link); - } - } -} - .renew-pagination-container { width: 100%; display: flex; @@ -325,4 +314,28 @@ va-checkbox.select-all-checkbox::part(label) { .hide-visited-link:visited { color: var(--vads-color-link) !important; -} \ No newline at end of file +} + +.va-breadcrumbs-li { + padding: 5px 0 !important; +} + +.include-back-arrow { + &::before { + content: ""; + display: inline-block; + width: 2ex; + height: 2ex; + mask-image: url("data:image/svg+xml,%3Csvg xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22 width%3D%2224%22 height%3D%2224%22 viewBox%3D%220 0 24 24%22%3E%3Cpath d%3D%22M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z%22%2F%3E%3C%2Fsvg%3E"), linear-gradient(transparent, transparent); + -webkit-mask-size: contain; + mask-size: 2ex 2ex; + -webkit-mask-repeat: no-repeat; + mask-repeat: no-repeat; + mask-position: center center; + bottom: -0.2em; + position: relative; + font-size: 16.96px; + color: rgb(27, 27, 27); + background: var(--vads-color-gray-medium); + } +} diff --git a/src/applications/mhv/medications/tests/actions/Breadcrumbs.unit.spec.jsx b/src/applications/mhv/medications/tests/actions/Breadcrumbs.unit.spec.jsx deleted file mode 100644 index 2a1528709d55..000000000000 --- a/src/applications/mhv/medications/tests/actions/Breadcrumbs.unit.spec.jsx +++ /dev/null @@ -1,31 +0,0 @@ -import { expect } from 'chai'; -import sinon from 'sinon'; -import { Actions } from '../../util/actionTypes'; -import { setBreadcrumbs } from '../../actions/breadcrumbs'; -import { medicationsUrls } from '../../util/constants'; - -describe('Set breadcrumbs action', () => { - it('should dispatch a set breadcrumbs action', () => { - const dispatch = sinon.spy(); - return setBreadcrumbs([ - { - url: medicationsUrls.MEDICATIONS_ABOUT, - label: 'About medications', - }, - { - url: `${medicationsUrls.MEDICATIONS_URL}/1`, - label: 'Medications', - }, - ])(dispatch).then(() => { - expect(dispatch.firstCall.args[0].type).to.equal( - Actions.Breadcrumbs.SET_BREAD_CRUMBS, - ); - expect(dispatch.firstCall.args[0].payload.crumbs[0].label).to.equal( - 'About medications', - ); - expect(dispatch.firstCall.args[0].payload.crumbs[1].label).to.equal( - 'Medications', - ); - }); - }); -}); diff --git a/src/applications/mhv/medications/tests/containers/RxBreadcrumbs.unit.spec.jsx b/src/applications/mhv/medications/tests/containers/RxBreadcrumbs.unit.spec.jsx index 1512195bcd68..4ef57909d756 100644 --- a/src/applications/mhv/medications/tests/containers/RxBreadcrumbs.unit.spec.jsx +++ b/src/applications/mhv/medications/tests/containers/RxBreadcrumbs.unit.spec.jsx @@ -1,36 +1,35 @@ import { expect } from 'chai'; import React from 'react'; import { renderWithStoreAndRouter } from '@department-of-veterans-affairs/platform-testing/react-testing-library-helpers'; -import { fireEvent } from '@testing-library/dom'; import reducers from '../../reducers'; import RxBreadcrumbs from '../../containers/RxBreadcrumbs'; import { medicationsUrls } from '../../util/constants'; describe('Medications Breadcrumbs', () => { - const initialState = { - rx: { - breadcrumbs: { - list: [ - { - url: `${medicationsUrls.MEDICATIONS_ABOUT}`, - label: 'About medications', - }, - { - url: `${medicationsUrls.MEDICATIONS_URL}/1`, - label: 'Medications', + const setup = () => { + return renderWithStoreAndRouter(, { + initialState: { + rx: { + breadcrumbs: { + list: [ + { + url: `${medicationsUrls.MEDICATIONS_ABOUT}`, + label: 'About medications', + }, + { + url: `${medicationsUrls.MEDICATIONS_URL}/1`, + label: 'Medications', + }, + ], + location: { + url: `${medicationsUrls.PRESCRIPTION_DETAILS}/000`, + label: 'Prescription Name', + }, }, - ], + }, }, - }, - }; - const setup = ( - path = '/medications/prescription/000', - state = initialState, - ) => { - return renderWithStoreAndRouter(, { - initialState: state, reducers, - path, + path: '/medications/prescription/000', }); }; @@ -41,26 +40,7 @@ describe('Medications Breadcrumbs', () => { it('Make sure breadcrumbs render', () => { const screen = setup(); - const breadcrumbs = screen.getByTestId('rx-breadcrumb'); + const breadcrumbs = screen.findByTestId('rx-breadcrumb'); expect(breadcrumbs).to.exist; }); - - it('should render just one crumb(1 level deep) and not the whole crumb history', () => { - const screen = setup(); - expect(screen.getByText('Back to Medications')).to.exist; - expect(screen.queryByText('Back to About medications')).to.be.null; - }); - - it('should be able to click on back link and render previous crumb', () => { - const screen = setup(); - const linkButton = screen.getByText('Back to Medications'); - fireEvent.click(linkButton); - expect(screen.getByText('Back to About medications')).to.exist; - expect(screen.queryByText('Back to Medications')).to.be.null; - }); - - it('should not render any crumbs when path is /about', () => { - const screen = setup('/about', []); - expect(screen.queryByText('Back to About medications')).to.be.null; - }); }); diff --git a/src/applications/mhv/medications/tests/e2e/med_site/MedicationsSite.js b/src/applications/mhv/medications/tests/e2e/med_site/MedicationsSite.js index a947d25dda42..a783bec59082 100644 --- a/src/applications/mhv/medications/tests/e2e/med_site/MedicationsSite.js +++ b/src/applications/mhv/medications/tests/e2e/med_site/MedicationsSite.js @@ -89,16 +89,17 @@ class MedicationsSite { .shadow() .find('[aria-label="Next page"]') .click({ waitForAnimations: true }); + cy.wait(`@Prescriptions${interceptedPage}`); }; loadVAPaginationPreviousPrescriptions = ( interceptedPage = 2, mockRx, - PerPage = 10, + PerPage = 20, ) => { cy.intercept( 'POST', - `/my_health/v1/prescriptions?page=1&per_page=${PerPage}`, + `/my_health/v1/prescriptions?page=1&per_page=${PerPage}&sort[]=disp_status&sort[]=prescription_name&sort[]=dispensed_date`, mockRx, ).as(`Prescriptions${interceptedPage}`); cy.get('[id="pagination"]') diff --git a/src/applications/mhv/medications/tests/e2e/medications-breadcrumbs-details-page.cypress.spec.js b/src/applications/mhv/medications/tests/e2e/medications-breadcrumbs-details-page.cypress.spec.js index eda14b5cf1b6..c635c474564c 100644 --- a/src/applications/mhv/medications/tests/e2e/medications-breadcrumbs-details-page.cypress.spec.js +++ b/src/applications/mhv/medications/tests/e2e/medications-breadcrumbs-details-page.cypress.spec.js @@ -13,6 +13,7 @@ describe('Medications Details Page Breadcrumbs', () => { site.login(); landingPage.visitLandingPageURL(); listPage.clickGotoMedicationsLink(); + detailsPage.clickMedicationHistoryAndDetailsLink(mockPrescriptionDetails); detailsPage.clickMedicationsListPageBreadcrumbsOnDetailsPage(); listPage.verifyNavigationToListPageAfterClickingBreadcrumbMedications(); diff --git a/src/applications/mhv/medications/tests/e2e/medications-refill-page-verify-breadcrumbs-to-landing-page.cypress.spec.js b/src/applications/mhv/medications/tests/e2e/medications-refill-page-verify-breadcrumbs-to-landing-page.cypress.spec.js index 072f3e3f4abc..cf3214c3ae1b 100644 --- a/src/applications/mhv/medications/tests/e2e/medications-refill-page-verify-breadcrumbs-to-landing-page.cypress.spec.js +++ b/src/applications/mhv/medications/tests/e2e/medications-refill-page-verify-breadcrumbs-to-landing-page.cypress.spec.js @@ -12,7 +12,7 @@ describe('Medications Refill Page Breadcrumb', () => { refillPage.loadRefillPage(refillPrescriptions); cy.injectAxe(); cy.axeCheck('main'); - refillPage.clickBackToMedicationsBreadcrumbOnRefillPage(); + refillPage.clickMedicationsLandingPageBreadcrumbsOnRefillPage(); landingPage.verifyNavigationToLandingPageAfterClickingBreadcrumb(); }); }); diff --git a/src/applications/mhv/medications/tests/e2e/medications-validate-breadcrumb-list-page-navigation.cypress.spec.js b/src/applications/mhv/medications/tests/e2e/medications-validate-breadcrumb-list-page-navigation.cypress.spec.js index 463a602527e1..653d84334005 100644 --- a/src/applications/mhv/medications/tests/e2e/medications-validate-breadcrumb-list-page-navigation.cypress.spec.js +++ b/src/applications/mhv/medications/tests/e2e/medications-validate-breadcrumb-list-page-navigation.cypress.spec.js @@ -26,7 +26,7 @@ describe('Medications Breadcrumb Navigation To List Page', () => { cy.injectAxe(); cy.axeCheck('main'); - listPage.clickGotoMedicationsLink(); + listPage.clickGotoMedicationsLink(true); site.verifyPaginationPrescriptionsDisplayed(1, 20, listLength); site.loadVAPaginationNextPrescriptions(2, mockRxPageTwo); site.verifyPaginationPrescriptionsDisplayed(21, 29, listLength); diff --git a/src/applications/mhv/medications/tests/e2e/pages/MedicationsDetailsPage.js b/src/applications/mhv/medications/tests/e2e/pages/MedicationsDetailsPage.js index ea1d60d4f70d..1401846e55b6 100644 --- a/src/applications/mhv/medications/tests/e2e/pages/MedicationsDetailsPage.js +++ b/src/applications/mhv/medications/tests/e2e/pages/MedicationsDetailsPage.js @@ -1,6 +1,5 @@ import rxTracking from '../fixtures/prescription-tracking-details.json'; import expiredRx from '../fixtures/expired-prescription-details.json'; -import { medicationsUrls } from '../../../util/constants'; class MedicationsDetailsPage { verifyTextInsideDropDownOnDetailsPage = () => { @@ -119,33 +118,36 @@ class MedicationsDetailsPage { clickMedicationsLandingPageBreadcrumbsOnListPage = () => { cy.get('[data-testid="rx-breadcrumb"]').should('be.visible'); - cy.get(`[href="${medicationsUrls.MEDICATIONS_ABOUT}"]`).click({ - waitForAnimations: true, - }); - }; - clickMedicationsListPageBreadcrumbsOnDetailsPage = (interceptedPage = 1) => { - cy.get('[data-testid="rx-breadcrumb"]').should('be.visible'); - cy.get( - `[href="${medicationsUrls.MEDICATIONS_URL}/?page=${interceptedPage}"]`, - ).click({ - waitForAnimations: true, - }); - // cy.get('[data-testid="rx-breadcrumb"] > :nth-child(2) > a').should('exist'); - // cy.get('[data-testid="rx-breadcrumb"]').click({ - // waitForAnimations: true, - // }); - }; - - clickMedicationsListPageTwoBreadcrumbsOnDetailsPage = ( - interceptedPage = 2, - ) => { - cy.get('[data-testid="rx-breadcrumb"]').should('be.visible'); - cy.get( - `[href="${medicationsUrls.MEDICATIONS_URL}/?page=${interceptedPage}"]`, - ).click({ - waitForAnimations: true, - }); + cy.get('[data-testid="rx-breadcrumb"]') + .shadow() + .find('a') + .eq(1) + .click({ + waitForAnimations: true, + }); + }; + + clickMedicationsListPageBreadcrumbsOnDetailsPage = (_interceptedPage = 1) => { + cy.get('[data-testid="rx-breadcrumb-link"]').should('be.visible'); + cy.get('[data-testid="rx-breadcrumb-link"]') + .shadow() + .find('a') + .eq(0) + .click({ + waitForAnimations: true, + }); + // http://localhost:3001/my-health/medications?page=1 << previous + }; + + clickMedicationsListPageTwoBreadcrumbsOnDetailsPage = () => { + cy.get('[data-testid="rx-breadcrumb-link"]') + .shadow() + .find('a') + .eq(0) + .click({ + waitForAnimations: true, + }); // cy.get('[data-testid="rx-breadcrumb"] > :nth-child(2) > a').should('exist'); // cy.get('[data-testid="rx-breadcrumb"]').click({ // waitForAnimations: true, diff --git a/src/applications/mhv/medications/tests/e2e/pages/MedicationsRefillPage.js b/src/applications/mhv/medications/tests/e2e/pages/MedicationsRefillPage.js index ae58eb4ac408..5306b28e9843 100644 --- a/src/applications/mhv/medications/tests/e2e/pages/MedicationsRefillPage.js +++ b/src/applications/mhv/medications/tests/e2e/pages/MedicationsRefillPage.js @@ -118,6 +118,14 @@ class MedicationsRefillPage { }); }; + clickMedicationsLandingPageBreadcrumbsOnRefillPage = () => { + cy.get('[data-testid="rx-breadcrumb"]').should('be.visible'); + + cy.get(`[href="${medicationsUrls.MEDICATIONS_ABOUT}"]`).click({ + waitForAnimations: true, + }); + }; + verifyShippedMedicationOnRefillPage = () => { cy.get('[data-testid="medications-last-shipped-3"]').should( 'contain', diff --git a/src/applications/mhv/medications/tests/reducers/breadcrumbs.unit.spec.jsx b/src/applications/mhv/medications/tests/reducers/breadcrumbs.unit.spec.jsx deleted file mode 100644 index 045e3633668b..000000000000 --- a/src/applications/mhv/medications/tests/reducers/breadcrumbs.unit.spec.jsx +++ /dev/null @@ -1,55 +0,0 @@ -import { expect } from 'chai'; -import { Actions } from '../../util/actionTypes'; -import { breadcrumbsReducer } from '../../reducers/breadcrumbs'; -import { medicationsUrls } from '../../util/constants'; - -const breadcrumbs = { - crumbs: [ - { - url: `${medicationsUrls.MEDICATIONS_ABOUT}`, - label: 'About medications', - }, - { - url: `${medicationsUrls.MEDICATIONS_URL}/1`, - label: 'Medications', - }, - ], -}; - -describe('Breadcrumbs reducer', () => { - const initialState = { - list: [], - location: '', - }; - it('should update the breadcrumbs list', () => { - const action = { - type: Actions.Breadcrumbs.SET_BREAD_CRUMBS, - payload: breadcrumbs, - }; - const nextState = breadcrumbsReducer(initialState, action); - expect(nextState.list).to.exist; - }); - it('remove breadcrumb should update the breadcrumbs list', () => { - const stateWithList = { - list: [ - { - url: '/about', - label: 'About medications', - }, - { - url: '/', - label: 'Medications', - }, - { - url: '/refill', - label: 'Refill prescriptions', - }, - ], - }; - const action = { - type: Actions.Breadcrumbs.REMOVE_BREAD_CRUMB, - }; - const nextState = breadcrumbsReducer(stateWithList, action); - expect(nextState.list.length).to.equal(2); - }); -}); diff --git a/src/applications/mhv/medications/tests/util/helpers.unit.spec.jsx b/src/applications/mhv/medications/tests/util/helpers.unit.spec.jsx index 16d04af0596f..1784f82419ad 100644 --- a/src/applications/mhv/medications/tests/util/helpers.unit.spec.jsx +++ b/src/applications/mhv/medications/tests/util/helpers.unit.spec.jsx @@ -1,5 +1,9 @@ import { expect } from 'chai'; -import { EMPTY_FIELD, imageRootUri } from '../../util/constants'; +import { + EMPTY_FIELD, + imageRootUri, + medicationsUrls, +} from '../../util/constants'; import { dateFormat, extractContainedResource, @@ -11,6 +15,7 @@ import { createNoDescriptionText, createVAPharmacyText, fromToNumbs, + createBreadcrumbs, } from '../../util/helpers'; describe('Date Format function', () => { @@ -165,3 +170,125 @@ describe('fromToNumbs', () => { expect(numbers[1]).to.eq(2); }); }); + +describe('createBreadcrumbs', () => { + const locationMock = pathname => ({ pathname }); + const prescriptionMock = { + prescriptionId: '123', + prescriptionName: 'Aspirin', + }; + + const defaultBreadcrumb = { + href: medicationsUrls.MHV_HOME, + label: 'My HealtheVet home', + }; + + it('should return empty array for an unknown path', () => { + const breadcrumbs = createBreadcrumbs( + locationMock('/unknown/path'), + null, + 1, + ); + expect(breadcrumbs).to.deep.equal([]); + }); + + it('should return breadcrumbs for the ABOUT path', () => { + const breadcrumbs = createBreadcrumbs( + locationMock(medicationsUrls.subdirectories.ABOUT), + null, + 1, + ); + expect(breadcrumbs).to.deep.equal([ + defaultBreadcrumb, + { href: medicationsUrls.MEDICATIONS_ABOUT, label: 'About medications' }, + ]); + }); + + it('should return breadcrumbs for the BASE path', () => { + const breadcrumbs = createBreadcrumbs( + locationMock(medicationsUrls.subdirectories.BASE), + null, + 2, + ); + expect(breadcrumbs).to.deep.equal([ + defaultBreadcrumb, + { href: medicationsUrls.MEDICATIONS_ABOUT, label: 'About medications' }, + { + href: `${medicationsUrls.MEDICATIONS_URL}?page=2`, + label: 'Medications', + }, + ]); + }); + + it('should return breadcrumbs for the BASE path with empty currentPage', () => { + const breadcrumbs = createBreadcrumbs( + locationMock(medicationsUrls.subdirectories.BASE), + null, + undefined, + ); + expect(breadcrumbs).to.deep.equal([ + defaultBreadcrumb, + { href: medicationsUrls.MEDICATIONS_ABOUT, label: 'About medications' }, + { + href: `${medicationsUrls.MEDICATIONS_URL}?page=1`, + label: 'Medications', + }, + ]); + }); + + it('should return breadcrumbs for the REFILL path', () => { + const breadcrumbs = createBreadcrumbs( + locationMock(medicationsUrls.subdirectories.REFILL), + null, + 1, + ); + expect(breadcrumbs).to.deep.equal([ + defaultBreadcrumb, + { href: medicationsUrls.MEDICATIONS_ABOUT, label: 'About medications' }, + { + href: medicationsUrls.MEDICATIONS_REFILL, + label: 'Refill prescriptions', + }, + ]); + }); + + it('should return breadcrumbs for the DETAILS path with a prescription', () => { + const breadcrumbs = createBreadcrumbs( + locationMock(medicationsUrls.subdirectories.DETAILS), + prescriptionMock, + 3, + ); + expect(breadcrumbs).to.deep.equal([ + defaultBreadcrumb, + { href: medicationsUrls.MEDICATIONS_ABOUT, label: 'About medications' }, + { + href: `${medicationsUrls.MEDICATIONS_URL}?page=3`, + label: 'Medications', + }, + { + href: `/${prescriptionMock.prescriptionId}`, + label: prescriptionMock.prescriptionName, + }, + ]); + }); + + it('should return breadcrumbs for the DETAILS path with a prescription and empty currentPage', () => { + const breadcrumbs = createBreadcrumbs( + locationMock(medicationsUrls.subdirectories.DETAILS), + prescriptionMock, + undefined, + ); + expect(breadcrumbs).to.deep.equal([ + defaultBreadcrumb, + { href: medicationsUrls.MEDICATIONS_ABOUT, label: 'About medications' }, + { + href: `${medicationsUrls.MEDICATIONS_URL}?page=1`, + label: 'Medications', + }, + { + href: `/${prescriptionMock.prescriptionId}`, + label: prescriptionMock.prescriptionName, + }, + ]); + }); +}); diff --git a/src/applications/mhv/medications/util/actionTypes.js b/src/applications/mhv/medications/util/actionTypes.js index 457bebbf2438..68b9d943d6e8 100644 --- a/src/applications/mhv/medications/util/actionTypes.js +++ b/src/applications/mhv/medications/util/actionTypes.js @@ -1,8 +1,4 @@ export const Actions = { - Breadcrumbs: { - SET_BREAD_CRUMBS: 'SM_SET_BREAD_CRUMBS', - REMOVE_BREAD_CRUMB: 'RX_REMOVE_BREAD_CRUMB', - }, Prescriptions: { CLEAR_DETAILS: 'RX_PRESCRIPTION_DETAILS_CLEAR', CLEAR_ERROR: 'RX_PRESCRIPTIONS_CLEAR_ERROR', diff --git a/src/applications/mhv/medications/util/constants.js b/src/applications/mhv/medications/util/constants.js index 3b1089fd439a..0da1c8a81d45 100644 --- a/src/applications/mhv/medications/util/constants.js +++ b/src/applications/mhv/medications/util/constants.js @@ -15,6 +15,7 @@ export const rxListSortingOptions = { }; export const medicationsUrls = { + MHV_HOME: '/../../my-health', MEDICATIONS_URL: '/my-health/medications', MEDICATIONS_LOGIN: '/my-health/medications?next=loginModal&oauth=true', MEDICATIONS_ABOUT: '/my-health/medications/about', diff --git a/src/applications/mhv/medications/util/helpers.js b/src/applications/mhv/medications/util/helpers.js index 107c201ca95d..d38bf1dff382 100644 --- a/src/applications/mhv/medications/util/helpers.js +++ b/src/applications/mhv/medications/util/helpers.js @@ -1,7 +1,7 @@ import moment from 'moment-timezone'; import { generatePdf } from '@department-of-veterans-affairs/platform-pdf/exports'; import * as Sentry from '@sentry/browser'; -import { EMPTY_FIELD, imageRootUri } from './constants'; +import { EMPTY_FIELD, imageRootUri, medicationsUrls } from './constants'; /** * @param {*} timestamp @@ -205,3 +205,65 @@ export const fromToNumbs = (page, total, listLength, maxPerPage) => { const to = Math.min(page * maxPerPage, total); return [from, to]; }; + +/** + * Creates the breadcrumb state based on the current location path. + * This function returns an array of breadcrumb objects for rendering in UI component. + * It should be called whenever the route changes if breadcrumb updates are needed. + * + * @param {Object} location - The location object from React Router, containing the current pathname. + * @param {String} prescriptionId - A prescription object, used for the details page. + * @param {Object} pagination - The pagination object used for the prescription list page. + * @returns {Array} An array of breadcrumb objects with `url` and `label` properties. + */ +export const createBreadcrumbs = (location, prescription, currentPage) => { + const { pathname } = location; + const defaultBreadcrumbs = [ + { + href: medicationsUrls.MHV_HOME, + label: 'My HealtheVet home', + }, + ]; + const { + subdirectories, + MEDICATIONS_ABOUT, + MEDICATIONS_URL, + MEDICATIONS_REFILL, + } = medicationsUrls; + + if (pathname.includes(subdirectories.ABOUT)) { + return [ + ...defaultBreadcrumbs, + { href: MEDICATIONS_ABOUT, label: 'About medications' }, + ]; + } + if (pathname === subdirectories.BASE) { + return defaultBreadcrumbs.concat([ + { href: MEDICATIONS_ABOUT, label: 'About medications' }, + { + href: `${MEDICATIONS_URL}?page=${currentPage || 1}`, + label: 'Medications', + }, + ]); + } + if (pathname === subdirectories.REFILL) { + return defaultBreadcrumbs.concat([ + { href: MEDICATIONS_ABOUT, label: 'About medications' }, + { href: MEDICATIONS_REFILL, label: 'Refill prescriptions' }, + ]); + } + if (prescription && pathname.includes(subdirectories.DETAILS)) { + return defaultBreadcrumbs.concat([ + { href: MEDICATIONS_ABOUT, label: 'About medications' }, + { + href: `${MEDICATIONS_URL}?page=${currentPage || 1}`, + label: 'Medications', + }, + { + href: `/${prescription.prescriptionId}`, + label: prescription.prescriptionName, + }, + ]); + } + return []; +};