Skip to content
This repository has been archived by the owner on Jan 9, 2023. It is now read-only.

feat(allergies): ability to click on allergy and view an allergy #2224

Merged
merged 7 commits into from
Jul 12, 2020
7 changes: 6 additions & 1 deletion src/__tests__/patients/allergies/Allergies.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,14 @@ const expectedPatient = {
let user: any
let store: any

const setup = (patient = expectedPatient, permissions = [Permissions.AddAllergy]) => {
const setup = (
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there should be a test that ensures the functionality of clicking on a list element navigates to the allergy.

patient = expectedPatient,
permissions = [Permissions.AddAllergy],
route = '/patients/123/allergies',
) => {
user = { permissions }
store = mockStore({ patient, user } as any)
history.push(route)
const wrapper = mount(
<Router history={history}>
<Provider store={store}>
Expand Down
46 changes: 46 additions & 0 deletions src/__tests__/patients/allergies/ViewAllergy.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { mount } from 'enzyme'
import { createMemoryHistory } from 'history'
import React from 'react'
import { Provider } from 'react-redux'
import { Route, Router } from 'react-router-dom'
import createMockStore from 'redux-mock-store'
import thunk from 'redux-thunk'

import ViewAllergy from '../../../patients/allergies/viewAllergy'
import TextInputWithLabelFormGroup from '../../../shared/components/input/TextInputWithLabelFormGroup'
import Patient from '../../../shared/model/Patient'
import { RootState } from '../../../shared/store'

const mockStore = createMockStore<RootState, any>([thunk])

describe('View Care Plan', () => {
const patient = {
id: 'patientId',
allergies: [{ id: '123', name: 'some name' }],
} as Patient

const setup = () => {
const store = mockStore({ patient: { patient }, user: { user: { id: '123' } } } as any)
const history = createMemoryHistory()
history.push(`/patients/${patient.id}/allergies/${patient.allergies![0].id}`)
const wrapper = mount(
<Provider store={store}>
<Router history={history}>
<Route path="/patients/:id/allergies/:allergyId">
<ViewAllergy />
</Route>
</Router>
</Provider>,
)

return { wrapper }
}

it('should render a allergy input with the correct data', () => {
const { wrapper } = setup()

const allergyName = wrapper.find(TextInputWithLabelFormGroup)
expect(allergyName).toHaveLength(1)
expect(allergyName.prop('value')).toEqual(patient.allergies![0].name)
})
})
25 changes: 20 additions & 5 deletions src/patients/allergies/Allergies.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Button, List, ListItem, Alert } from '@hospitalrun/components'
import React, { useState } from 'react'
import { useSelector } from 'react-redux'
import { Route, Switch, useHistory } from 'react-router-dom'

import useAddBreadcrumbs from '../../page-header/breadcrumbs/useAddBreadcrumbs'
import useTranslator from '../../shared/hooks/useTranslator'
Expand All @@ -9,6 +10,7 @@ import Patient from '../../shared/model/Patient'
import Permissions from '../../shared/model/Permissions'
import { RootState } from '../../shared/store'
import NewAllergyModal from './NewAllergyModal'
import ViewAllergy from './viewAllergy'

interface AllergiesProps {
patient: Patient
Expand All @@ -19,6 +21,7 @@ const Allergies = (props: AllergiesProps) => {
const { patient } = props
const { permissions } = useSelector((state: RootState) => state.user)
const [showNewAllergyModal, setShowNewAllergyModal] = useState(false)
const history = useHistory()

const breadcrumbs = [
{
Expand Down Expand Up @@ -46,18 +49,30 @@ const Allergies = (props: AllergiesProps) => {
</div>
</div>
<br />
<Switch>
<Route exact path="/patients/:id/allergies">
<List>
{patient.allergies?.map((a: Allergy) => (
<ListItem
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should indicate that the list item is clickable. We can do this by adding action as a prop to ListItem

key={a.id}
onClick={() => history.push(`/patients/${patient.id}/allergies/${a.id}`)}
>
{a.name}
</ListItem>
))}
</List>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should extract this to its own component

</Route>
<Route exact path="/patients/:id/allergies/:allergyId">
<ViewAllergy />
</Route>
</Switch>
{(!patient.allergies || patient.allergies.length === 0) && (
<Alert
color="warning"
title={t('patient.allergies.warning.noAllergies')}
message={t('patient.allergies.addAllergyAbove')}
/>
)}
<List>
{patient.allergies?.map((a: Allergy) => (
<ListItem key={a.id}>{a.name}</ListItem>
))}
</List>
<NewAllergyModal
show={showNewAllergyModal}
onCloseButtonClick={() => setShowNewAllergyModal(false)}
Expand Down
41 changes: 41 additions & 0 deletions src/patients/allergies/viewAllergy.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import findLast from 'lodash/findLast'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

convention for file naming is PascalCase.

So for this file, src/patients/allergies/ViewAllergy.tsx

import React, { useEffect, useState } from 'react'
import { useSelector } from 'react-redux'
import { useParams } from 'react-router-dom'

import TextInputWithLabelFormGroup from '../../shared/components/input/TextInputWithLabelFormGroup'
import useTranslator from '../../shared/hooks/useTranslator'
import Allergy from '../../shared/model/Allergy'
import { RootState } from '../../shared/store'

const ViewAllergy = () => {
const { t } = useTranslator()
const { patient } = useSelector((root: RootState) => root.patient)
const { allergyId } = useParams()

const [allergy, setAllergy] = useState<Allergy | undefined>()

useEffect(() => {
if (patient && allergyId) {
const currentAllergy = findLast(patient.allergies, (a: Allergy) => a.id === allergyId)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

setAllergy(currentAllergy)
}
}, [setAllergy, allergyId, patient])

if (allergy) {
return (
<>
<TextInputWithLabelFormGroup
name="name"
label={t('patient.allergies.allergyName')}
isEditable={false}
placeholder={t('patient.allergies.allergyName')}
value={allergy.name}
/>
</>
)
}
return <></>
}

export default ViewAllergy
2 changes: 1 addition & 1 deletion src/patients/view/ViewPatient.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ const ViewPatient = () => {
<Route exact path={`${path}/appointments`}>
<AppointmentsList patientId={patient.id} />
</Route>
<Route exact path={`${path}/allergies`}>
<Route path={`${path}/allergies`}>
<Allergies patient={patient} />
</Route>
<Route exact path={`${path}/diagnoses`}>
Expand Down