diff --git a/package.json b/package.json index 677a3387ea..434fa429ca 100644 --- a/package.json +++ b/package.json @@ -127,7 +127,6 @@ "lint-staged": { "**/*.{js,jsx,ts,tsx}": [ "npm run lint:fix", - "npm run test:ci", "git add ." ] } diff --git a/src/HospitalRun.tsx b/src/HospitalRun.tsx index 944dc40017..b9ccb22ffb 100644 --- a/src/HospitalRun.tsx +++ b/src/HospitalRun.tsx @@ -5,7 +5,7 @@ import { Toaster } from '@hospitalrun/components' import Appointments from 'scheduling/appointments/Appointments' import NewAppointment from 'scheduling/appointments/new/NewAppointment' import ViewAppointment from 'scheduling/appointments/view/ViewAppointment' -import Breadcrumb from 'components/breadcrumb/Breadcrumb' +import Breadcrumbs from 'breadcrumbs/Breadcrumbs' import Sidebar from './components/Sidebar' import Permissions from './model/Permissions' import Dashboard from './dashboard/Dashboard' @@ -23,7 +23,6 @@ const HospitalRun = () => { return (
-
@@ -31,6 +30,7 @@ const HospitalRun = () => {

{title}

+
diff --git a/src/__tests__/HospitalRun.test.tsx b/src/__tests__/HospitalRun.test.tsx index dc22f7a248..532d6cc395 100644 --- a/src/__tests__/HospitalRun.test.tsx +++ b/src/__tests__/HospitalRun.test.tsx @@ -29,6 +29,7 @@ describe('HospitalRun', () => { store={mockStore({ title: 'test', user: { permissions: [Permissions.WritePatients] }, + breadcrumbs: { breadcrumbs: [] }, })} > @@ -46,6 +47,7 @@ describe('HospitalRun', () => { store={mockStore({ title: 'test', user: { permissions: [] }, + breadcrumbs: { breadcrumbs: [] }, })} > @@ -79,6 +81,7 @@ describe('HospitalRun', () => { title: 'test', user: { permissions: [Permissions.WritePatients, Permissions.ReadPatients] }, patient: { patient: {} as Patient }, + breadcrumbs: { breadcrumbs: [] }, })} > @@ -96,7 +99,7 @@ describe('HospitalRun', () => { store={mockStore({ title: 'test', user: { permissions: [Permissions.WritePatients] }, - patient: { patient: {} }, + breadcrumbs: { breadcrumbs: [] }, })} > @@ -114,7 +117,7 @@ describe('HospitalRun', () => { store={mockStore({ title: 'test', user: { permissions: [Permissions.ReadPatients] }, - patient: { patient: {} }, + breadcrumbs: { breadcrumbs: [] }, })} > @@ -148,6 +151,7 @@ describe('HospitalRun', () => { title: 'test', user: { permissions: [Permissions.ReadPatients] }, patient: { patient }, + breadcrumbs: { breadcrumbs: [] }, })} > @@ -165,7 +169,7 @@ describe('HospitalRun', () => { store={mockStore({ title: 'test', user: { permissions: [] }, - patient: { patient: {} }, + breadcrumbs: { breadcrumbs: [] }, })} > @@ -186,6 +190,7 @@ describe('HospitalRun', () => { title: 'test', user: { permissions: [Permissions.ReadAppointments] }, appointments: { appointments: [] }, + breadcrumbs: { breadcrumbs: [] }, })} > @@ -203,8 +208,7 @@ describe('HospitalRun', () => { store={mockStore({ title: 'test', user: { permissions: [] }, - appointments: { appointments: [] }, - appointment: { appointment: {} }, + breadcrumbs: { breadcrumbs: [] }, })} > @@ -225,6 +229,7 @@ describe('HospitalRun', () => { store={mockStore({ title: 'test', user: { permissions: [Permissions.WriteAppointments] }, + breadcrumbs: { breadcrumbs: [] }, })} > @@ -242,6 +247,7 @@ describe('HospitalRun', () => { store={mockStore({ title: 'test', user: { permissions: [] }, + breadcrumbs: { breadcrumbs: [] }, })} > @@ -261,6 +267,7 @@ describe('HospitalRun', () => { store={mockStore({ title: 'test', user: { permissions: [Permissions.WritePatients] }, + breadcrumbs: { breadcrumbs: [] }, })} > diff --git a/src/__tests__/components/breadcrumb/Appointmentbreadcrumb.test.tsx b/src/__tests__/components/breadcrumb/Appointmentbreadcrumb.test.tsx deleted file mode 100644 index 93a04fcc98..0000000000 --- a/src/__tests__/components/breadcrumb/Appointmentbreadcrumb.test.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import '../../../__mocks__/matchMediaMock' -import React from 'react' -import { Router } from 'react-router' -import { Provider } from 'react-redux' -import { mount } from 'enzyme' -import configureMockStore from 'redux-mock-store' -import { createMemoryHistory } from 'history' -import { BreadcrumbItem as HrBreadcrumbItem } from '@hospitalrun/components' -import AppointmentBreadcrumb from 'components/breadcrumb/AppointmentBreadcrumb' - -const mockStore = configureMockStore() - -describe('Breadcrumb', () => { - const history = createMemoryHistory() - history.push('/appointments/1234') - const wrapper = mount( - - - - - , - ) - - it('should render 2 breadcrumb items', () => { - expect(wrapper.find(HrBreadcrumbItem)).toHaveLength(2) - }) -}) diff --git a/src/__tests__/components/breadcrumb/Breadcrumb.test.tsx b/src/__tests__/components/breadcrumb/Breadcrumb.test.tsx deleted file mode 100644 index 9d05a7f604..0000000000 --- a/src/__tests__/components/breadcrumb/Breadcrumb.test.tsx +++ /dev/null @@ -1,61 +0,0 @@ -import '../../../__mocks__/matchMediaMock' -import React from 'react' -import { Router } from 'react-router' -import { Provider } from 'react-redux' -import { mount } from 'enzyme' -import configureMockStore from 'redux-mock-store' -import { createMemoryHistory } from 'history' -import DefaultBreadcrumb from 'components/breadcrumb/DefaultBreadcrumb' -import PatientBreadcrumb from 'components/breadcrumb/PatientBreadcrumb' -import AppointmentBreadcrumb from 'components/breadcrumb/AppointmentBreadcrumb' -import Breadcrumb from 'components/breadcrumb/Breadcrumb' - -const mockStore = configureMockStore() - -describe('Breadcrumb', () => { - const setup = (location: string) => { - const history = createMemoryHistory() - history.push(location) - return mount( - - - - - , - ) - } - it('should render the patient breadcrumb when /patients/:id is accessed', () => { - const wrapper = setup('/patients/1234') - expect(wrapper.find(PatientBreadcrumb)).toHaveLength(1) - }) - it('should render the appointment breadcrumb when /appointments/:id is accessed', () => { - const wrapper = setup('/appointments/1234') - expect(wrapper.find(AppointmentBreadcrumb)).toHaveLength(1) - }) - - it('should render the default breadcrumb when /patients/new is accessed', () => { - const wrapper = setup('/patients/new') - expect(wrapper.find(DefaultBreadcrumb)).toHaveLength(1) - }) - - it('should render the default breadcrumb when /appointments/new is accessed', () => { - const wrapper = setup('/appointments/new') - expect(wrapper.find(DefaultBreadcrumb)).toHaveLength(1) - }) - - it('should render the default breadcrumb when any other path is accessed', () => { - let wrapper = setup('/appointments') - expect(wrapper.find(DefaultBreadcrumb)).toHaveLength(1) - - wrapper = setup('/patients') - expect(wrapper.find(DefaultBreadcrumb)).toHaveLength(1) - - wrapper = setup('/') - expect(wrapper.find(DefaultBreadcrumb)).toHaveLength(1) - }) -}) diff --git a/src/__tests__/components/breadcrumb/DefaultBreadcrumb.test.tsx b/src/__tests__/components/breadcrumb/DefaultBreadcrumb.test.tsx deleted file mode 100644 index 0632dc3820..0000000000 --- a/src/__tests__/components/breadcrumb/DefaultBreadcrumb.test.tsx +++ /dev/null @@ -1,54 +0,0 @@ -import '../../../__mocks__/matchMediaMock' -import React from 'react' -import { mount } from 'enzyme' -import { createMemoryHistory } from 'history' -import { Router } from 'react-router' -import DefaultBreadcrumb, { getItems } from 'components/breadcrumb/DefaultBreadcrumb' -import { BreadcrumbItem as HrBreadcrumbItem } from '@hospitalrun/components' - -describe('DefaultBreadcrumb', () => { - describe('getItems', () => { - it('should return valid items for pathname /', () => { - expect(getItems('/')).toEqual([{ url: '/', active: true }]) - }) - - it('should return valid items for pathname /patients', () => { - expect(getItems('/patients')).toEqual([{ url: '/patients', active: true }]) - }) - - it('should return valid items for pathname /appointments', () => { - expect(getItems('/appointments')).toEqual([{ url: '/appointments', active: true }]) - }) - - it('should return valid items for pathname /patients/new', () => { - expect(getItems('/patients/new')).toEqual([ - { url: '/patients', active: false }, - { url: '/patients/new', active: true }, - ]) - }) - - it('should return valid items for pathname /appointments/new', () => { - expect(getItems('/appointments/new')).toEqual([ - { url: '/appointments', active: false }, - { url: '/appointments/new', active: true }, - ]) - }) - }) - - describe('rendering', () => { - const setup = (location: string) => { - const history = createMemoryHistory() - history.push(location) - return mount( - - - , - ) - } - - it('should render one breadcrumb item for the path /', () => { - const wrapper = setup('/') - expect(wrapper.find(HrBreadcrumbItem)).toHaveLength(1) - }) - }) -}) diff --git a/src/__tests__/components/breadcrumb/PatientBreadcrumb.test.tsx b/src/__tests__/components/breadcrumb/PatientBreadcrumb.test.tsx deleted file mode 100644 index 1a33139245..0000000000 --- a/src/__tests__/components/breadcrumb/PatientBreadcrumb.test.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import '../../../__mocks__/matchMediaMock' -import React from 'react' -import { Router } from 'react-router' -import { Provider } from 'react-redux' -import { mount } from 'enzyme' -import configureMockStore from 'redux-mock-store' -import { createMemoryHistory } from 'history' -import { BreadcrumbItem as HrBreadcrumbItem } from '@hospitalrun/components' -import PatientBreadcrumb from 'components/breadcrumb/PatientBreadcrumb' - -const mockStore = configureMockStore() - -describe('Breadcrumb', () => { - const history = createMemoryHistory() - history.push('/patients/1234') - const wrapper = mount( - - - - - , - ) - - it('should render 2 breadcrumb items', () => { - expect(wrapper.find(HrBreadcrumbItem)).toHaveLength(2) - }) -}) diff --git a/src/breadcrumbs/Breadcrumbs.tsx b/src/breadcrumbs/Breadcrumbs.tsx new file mode 100644 index 0000000000..a7116c57f1 --- /dev/null +++ b/src/breadcrumbs/Breadcrumbs.tsx @@ -0,0 +1,32 @@ +import React from 'react' +import { useHistory } from 'react-router' +import { useSelector } from 'react-redux' +import { useTranslation } from 'react-i18next' +import { + Breadcrumb as HrBreadcrumb, + BreadcrumbItem as HrBreadcrumbItem, +} from '@hospitalrun/components' +import { RootState } from '../store' + +const Breadcrumbs = () => { + const history = useHistory() + const { t } = useTranslation() + const { breadcrumbs } = useSelector((state: RootState) => state.breadcrumbs) + + return ( + + {breadcrumbs.map(({ i18nKey, text, location }, index) => { + const isLast = index === breadcrumbs.length - 1 + const onClick = !isLast ? () => history.push(location) : undefined + + return ( + + {i18nKey ? t(i18nKey) : text} + + ) + })} + + ) +} + +export default Breadcrumbs diff --git a/src/breadcrumbs/breadcrumbs-slice.ts b/src/breadcrumbs/breadcrumbs-slice.ts new file mode 100644 index 0000000000..80d0c7adef --- /dev/null +++ b/src/breadcrumbs/breadcrumbs-slice.ts @@ -0,0 +1,30 @@ +import { createSlice, PayloadAction } from '@reduxjs/toolkit' +import Breadcrumb from 'model/Breadcrumb' + +interface BreadcrumbsState { + breadcrumbs: Breadcrumb[] +} + +const initialState: BreadcrumbsState = { + breadcrumbs: [], +} + +const breadcrumbsSlice = createSlice({ + name: 'breadcrumbs', + initialState, + reducers: { + setBreadcrumbs(state, { payload }: PayloadAction) { + state.breadcrumbs = payload + }, + addBreadcrumb(state, { payload }: PayloadAction) { + state.breadcrumbs = [...state.breadcrumbs, payload] + }, + removeBreadcrumb(state) { + state.breadcrumbs = state.breadcrumbs.slice(0, -1) + }, + }, +}) + +export const { setBreadcrumbs, addBreadcrumb, removeBreadcrumb } = breadcrumbsSlice.actions + +export default breadcrumbsSlice.reducer diff --git a/src/breadcrumbs/useAddBreadcrumb.ts b/src/breadcrumbs/useAddBreadcrumb.ts new file mode 100644 index 0000000000..7838e134af --- /dev/null +++ b/src/breadcrumbs/useAddBreadcrumb.ts @@ -0,0 +1,16 @@ +import { useEffect } from 'react' +import { useDispatch } from 'react-redux' +import Breadcrumb from 'model/Breadcrumb' +import { addBreadcrumb, removeBreadcrumb } from './breadcrumbs-slice' + +export default function useAddBreadcrumb(breadcrumb: Breadcrumb): void { + const dispatch = useDispatch() + + useEffect(() => { + dispatch(addBreadcrumb(breadcrumb)) + + return () => { + dispatch(removeBreadcrumb()) + } + }, [dispatch, breadcrumb]) +} diff --git a/src/breadcrumbs/useSetBreadcrumbs.ts b/src/breadcrumbs/useSetBreadcrumbs.ts new file mode 100644 index 0000000000..e48434cade --- /dev/null +++ b/src/breadcrumbs/useSetBreadcrumbs.ts @@ -0,0 +1,16 @@ +import { useEffect } from 'react' +import { useDispatch } from 'react-redux' +import Breadcrumb from 'model/Breadcrumb' +import { setBreadcrumbs } from './breadcrumbs-slice' + +export default function useSetBreadcrumbs(breadcrumbs: Breadcrumb[]): void { + const dispatch = useDispatch() + + useEffect(() => { + dispatch(setBreadcrumbs(breadcrumbs)) + + return () => { + dispatch(setBreadcrumbs([])) + } + }, [dispatch, breadcrumbs]) +} diff --git a/src/components/breadcrumb/AppointmentBreadcrumb.tsx b/src/components/breadcrumb/AppointmentBreadcrumb.tsx deleted file mode 100644 index 5c0aa386f3..0000000000 --- a/src/components/breadcrumb/AppointmentBreadcrumb.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import React from 'react' -import { useHistory } from 'react-router' -import { useSelector } from 'react-redux' -import { useTranslation } from 'react-i18next' -import { - Breadcrumb as HrBreadcrumb, - BreadcrumbItem as HrBreadcrumbItem, -} from '@hospitalrun/components' -import { RootState } from '../../store' - -const AppointmentBreacrumb = () => { - const { t } = useTranslation() - const { appointment } = useSelector((state: RootState) => state.appointment) - const history = useHistory() - let appointmentLabel = '' - - if (appointment.startDateTime && appointment.endDateTime) { - const startDateLabel = new Date(appointment.startDateTime).toLocaleString() - const endDateLabel = new Date(appointment.endDateTime).toLocaleString() - appointmentLabel = `${startDateLabel} - ${endDateLabel}` - } - - return ( - - history.push('/appointments')}> - {t('scheduling.appointments.label')} - - {appointmentLabel} - - ) -} - -export default AppointmentBreacrumb diff --git a/src/components/breadcrumb/Breadcrumb.tsx b/src/components/breadcrumb/Breadcrumb.tsx deleted file mode 100644 index e2a53d6f77..0000000000 --- a/src/components/breadcrumb/Breadcrumb.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import React from 'react' -import { Switch, Route } from 'react-router' -import DefaultBreadcrumb from 'components/breadcrumb/DefaultBreadcrumb' -import PatientBreadcrumb from 'components/breadcrumb/PatientBreadcrumb' -import AppointmentBreadcrumb from 'components/breadcrumb/AppointmentBreadcrumb' - -const Breadcrumb = () => ( - - - - - - -) - -export default Breadcrumb diff --git a/src/components/breadcrumb/DefaultBreadcrumb.tsx b/src/components/breadcrumb/DefaultBreadcrumb.tsx deleted file mode 100644 index f9d1e54d6c..0000000000 --- a/src/components/breadcrumb/DefaultBreadcrumb.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import React from 'react' -import { useLocation, useHistory } from 'react-router' -import { useTranslation } from 'react-i18next' -import { - Breadcrumb as HrBreadcrumb, - BreadcrumbItem as HrBreadcrumbItem, -} from '@hospitalrun/components' - -interface Item { - url: string - active: boolean -} - -const urlToi18nKey: { [url: string]: string } = { - '/': 'dashboard.label', - '/patients': 'patients.label', - '/patients/new': 'patients.newPatient', - '/appointments': 'scheduling.appointments.label', - '/appointments/new': 'scheduling.appointments.new', -} - -export function getItems(pathname: string): Item[] { - let url = '' - const paths = pathname.substring(1).split('/') - - return paths.map((path, index) => { - url += `/${path}` - return { url, active: index === paths.length - 1 } - }) -} - -const DefaultBreadcrumb = () => { - const { t } = useTranslation() - const { pathname } = useLocation() - const history = useHistory() - const items = getItems(pathname) - - return ( - - {items.map((item) => { - const onClick = !item.active ? () => history.push(item.url) : undefined - - return ( - - {t(urlToi18nKey[item.url])} - - ) - })} - - ) -} - -export default DefaultBreadcrumb diff --git a/src/components/breadcrumb/PatientBreadcrumb.tsx b/src/components/breadcrumb/PatientBreadcrumb.tsx deleted file mode 100644 index 32c5c71d98..0000000000 --- a/src/components/breadcrumb/PatientBreadcrumb.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import React from 'react' -import { useHistory } from 'react-router' -import { useSelector } from 'react-redux' -import { useTranslation } from 'react-i18next' -import { - Breadcrumb as HrBreadcrumb, - BreadcrumbItem as HrBreadcrumbItem, -} from '@hospitalrun/components' -import { getPatientFullName } from 'patients/util/patient-name-util' -import { RootState } from '../../store' - -const PatientBreacrumb = () => { - const { t } = useTranslation() - const { patient } = useSelector((state: RootState) => state.patient) - const history = useHistory() - - return ( - - history.push('/patients')}> - {t('patients.label')} - - {getPatientFullName(patient)} - - ) -} - -export default PatientBreacrumb diff --git a/src/dashboard/Dashboard.tsx b/src/dashboard/Dashboard.tsx index bf295875dc..2b46dee8cf 100644 --- a/src/dashboard/Dashboard.tsx +++ b/src/dashboard/Dashboard.tsx @@ -1,10 +1,14 @@ import React from 'react' import { useTranslation } from 'react-i18next' import useTitle from '../page-header/useTitle' +import useSetBreadcrumbs from '../breadcrumbs/useSetBreadcrumbs' + +const breadcrumbs = [{ i18nKey: 'dashboard.label', location: '/' }] const Dashboard: React.FC = () => { const { t } = useTranslation() useTitle(t('dashboard.label')) + useSetBreadcrumbs(breadcrumbs) return

Example

} diff --git a/src/index.css b/src/index.css index 9ad2e9496a..417dbe2316 100644 --- a/src/index.css +++ b/src/index.css @@ -24,7 +24,7 @@ code { bottom: 0; left: 0; z-index: 0; /* Behind the navbar */ - padding: 75px 0 0; /* Height of navbar */ + padding: 48px 0 0; /* Height of navbar */ box-shadow: inset -1px 0 0 rgba(0, 0, 0, .1); } @@ -90,8 +90,6 @@ code { } .breadcrumb { - z-index: 1; - position: relative; - padding: .2rem 1rem; - background-color: white; + padding: 0; + background-color: white; } diff --git a/src/model/Breadcrumb.ts b/src/model/Breadcrumb.ts new file mode 100644 index 0000000000..b93f41ed41 --- /dev/null +++ b/src/model/Breadcrumb.ts @@ -0,0 +1,5 @@ +export default interface Breadcrumb { + i18nKey?: string + text?: string + location: string +} diff --git a/src/patients/edit/EditPatient.tsx b/src/patients/edit/EditPatient.tsx index b47de7491c..d68590e8ac 100644 --- a/src/patients/edit/EditPatient.tsx +++ b/src/patients/edit/EditPatient.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from 'react' +import React, { useEffect, useState, useMemo } from 'react' import { useHistory, useParams } from 'react-router-dom' import { useTranslation } from 'react-i18next' import { useDispatch, useSelector } from 'react-redux' @@ -10,6 +10,7 @@ import Patient from '../../model/Patient' import { updatePatient, fetchPatient } from '../patient-slice' import { RootState } from '../../store' import { getPatientFullName, getPatientName } from '../util/patient-name-util' +import useSetBreadcrumbs from '../../breadcrumbs/useSetBreadcrumbs' const getFriendlyId = (p: Patient): string => { if (p) { @@ -34,6 +35,16 @@ const EditPatient = () => { )})`, ) + const breadcrumbs = useMemo( + () => [ + { i18nKey: 'patients.label', location: '/patients' }, + { text: getPatientFullName(patient), location: `/patients/${patient.id}` }, + { i18nKey: 'patients.editPatient', location: `/patients/${patient.id}/edit` }, + ], + [patient], + ) + useSetBreadcrumbs(breadcrumbs) + useEffect(() => { setPatient(reduxPatient) }, [reduxPatient]) diff --git a/src/patients/list/Patients.tsx b/src/patients/list/Patients.tsx index 307727e6ab..30d327ac73 100644 --- a/src/patients/list/Patients.tsx +++ b/src/patients/list/Patients.tsx @@ -6,11 +6,15 @@ import { Spinner, TextInput, Button, List, ListItem, Container, Row } from '@hos import { RootState } from '../../store' import { fetchPatients, searchPatients } from '../patients-slice' import useTitle from '../../page-header/useTitle' +import useSetBreadcrumbs from '../../breadcrumbs/useSetBreadcrumbs' + +const breadcrumbs = [{ i18nKey: 'patients.label', location: '/patients' }] const Patients = () => { const { t } = useTranslation() const history = useHistory() useTitle(t('patients.label')) + useSetBreadcrumbs(breadcrumbs) const dispatch = useDispatch() const { patients, isLoading } = useSelector((state: RootState) => state.patients) diff --git a/src/patients/new/NewPatient.tsx b/src/patients/new/NewPatient.tsx index 070470b7eb..ecfe2aa2d3 100644 --- a/src/patients/new/NewPatient.tsx +++ b/src/patients/new/NewPatient.tsx @@ -9,6 +9,12 @@ import useTitle from '../../page-header/useTitle' import Patient from '../../model/Patient' import { createPatient } from '../patient-slice' import { getPatientName } from '../util/patient-name-util' +import useSetBreadcrumbs from '../../breadcrumbs/useSetBreadcrumbs' + +const breadcrumbs = [ + { i18nKey: 'patients.label', location: '/patients' }, + { i18nKey: 'patients.newPatient', location: '/patients/new' }, +] const NewPatient = () => { const { t } = useTranslation() @@ -19,6 +25,7 @@ const NewPatient = () => { const [errorMessage, setErrorMessage] = useState('') useTitle(t('patients.newPatient')) + useSetBreadcrumbs(breadcrumbs) const onCancel = () => { history.push('/patients') diff --git a/src/patients/view/ViewPatient.tsx b/src/patients/view/ViewPatient.tsx index 9b0d53fa15..ca7105cdc8 100644 --- a/src/patients/view/ViewPatient.tsx +++ b/src/patients/view/ViewPatient.tsx @@ -1,4 +1,4 @@ -import React, { useEffect } from 'react' +import React, { useEffect, useMemo } from 'react' import { useDispatch, useSelector } from 'react-redux' import { useParams, withRouter, Route, useHistory, useLocation } from 'react-router-dom' import { Panel, Spinner, TabsHeader, Tab, Button } from '@hospitalrun/components' @@ -11,6 +11,7 @@ import { getPatientFullName } from '../util/patient-name-util' import Patient from '../../model/Patient' import GeneralInformation from '../GeneralInformation' import RelatedPerson from '../related-persons/RelatedPersonTab' +import useSetBreadcrumbs from '../../breadcrumbs/useSetBreadcrumbs' const getFriendlyId = (p: Patient): string => { if (p) { @@ -30,6 +31,15 @@ const ViewPatient = () => { useTitle(`${getPatientFullName(patient)} (${getFriendlyId(patient)})`) + const breadcrumbs = useMemo( + () => [ + { i18nKey: 'patients.label', location: '/patients' }, + { text: getPatientFullName(patient), location: `/patients/${patient.id}` }, + ], + [patient], + ) + useSetBreadcrumbs(breadcrumbs) + const { id } = useParams() useEffect(() => { if (id) { diff --git a/src/store/index.ts b/src/store/index.ts index 60176dfc5c..b226815116 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -6,6 +6,7 @@ import appointment from '../scheduling/appointments/appointment-slice' import appointments from '../scheduling/appointments/appointments-slice' import title from '../page-header/title-slice' import user from '../user/user-slice' +import breadcrumbs from '../breadcrumbs/breadcrumbs-slice' const reducer = combineReducers({ patient, @@ -14,6 +15,7 @@ const reducer = combineReducers({ user, appointment, appointments, + breadcrumbs, }) const store = configureStore({