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

feat(labs): support list of notes for lab requests #2325

Merged
merged 13 commits into from
Sep 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/__tests__/labs/Labs.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ describe('Labs', () => {
breadcrumbs: { breadcrumbs: [] },
components: { sidebarCollapsed: false },
lab: {
lab: { id: 'labId', patientId: 'patientId' } as Lab,
lab: { id: 'labId', patient: 'patientId' } as Lab,
patient: { id: 'patientId', fullName: 'some name' },
error: {},
},
Expand Down Expand Up @@ -83,7 +83,7 @@ describe('Labs', () => {
lab: {
lab: {
id: 'labId',
patientId: 'patientId',
patient: 'patientId',
requestedOn: new Date().toISOString(),
} as Lab,
patient: { id: 'patientId', fullName: 'some name' },
Expand Down
66 changes: 55 additions & 11 deletions src/__tests__/labs/ViewLab.test.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Badge, Button, Alert } from '@hospitalrun/components'
import { act } from '@testing-library/react'
import format from 'date-fns/format'
import { mount } from 'enzyme'
import { mount, ReactWrapper } from 'enzyme'
import { createMemoryHistory } from 'history'
import React from 'react'
import { Provider } from 'react-redux'
Expand Down Expand Up @@ -31,7 +31,7 @@ describe('View Lab', () => {
status: 'requested',
patient: '1234',
type: 'lab type',
notes: 'lab notes',
notes: ['lab notes'],
requestedOn: '2020-03-30T04:43:20.102Z',
} as Lab

Expand Down Expand Up @@ -150,15 +150,31 @@ describe('View Lab', () => {
expect(resultTextField.prop('value')).toEqual(expectedLab.result)
})

it('should display the notes in the notes text field', async () => {
const expectedLab = { ...mockLab, notes: 'expected notes' } as Lab
it('should display the past notes', async () => {
const expectedNotes = 'expected notes'
const expectedLab = { ...mockLab, notes: [expectedNotes] } as Lab
const wrapper = await setup(expectedLab, [Permissions.ViewLab])

const notes = wrapper.find('[data-test="note"]')
const pastNotesIndex = notes.reduce(
(result: number, item: ReactWrapper, index: number) =>
item.text().trim() === expectedNotes ? index : result,
-1,
)

expect(pastNotesIndex).not.toBe(-1)
expect(notes.length).toBe(1)
})

it('should display the notes text field empty', async () => {
const expectedNotes = 'expected notes'
const expectedLab = { ...mockLab, notes: [expectedNotes] } as Lab
const wrapper = await setup(expectedLab, [Permissions.ViewLab])

const notesTextField = wrapper.find(TextFieldWithLabelFormGroup).at(1)

expect(notesTextField).toBeDefined()
expect(notesTextField.prop('label')).toEqual('labs.lab.notes')
expect(notesTextField.prop('value')).toEqual(expectedLab.notes)
expect(notesTextField.prop('value')).toEqual('')
})

it('should display errors', async () => {
Expand Down Expand Up @@ -188,9 +204,7 @@ describe('View Lab', () => {
})

it('should display a update lab, complete lab, and cancel lab button if the lab is in a requested state', async () => {
const expectedLab = { ...mockLab, notes: 'expected notes' } as Lab

const wrapper = await setup(expectedLab, [
const wrapper = await setup(mockLab, [
Permissions.ViewLab,
Permissions.CompleteLab,
Permissions.CancelLab,
Expand Down Expand Up @@ -254,6 +268,18 @@ describe('View Lab', () => {
const updateButton = wrapper.find(Button)
expect(updateButton).toHaveLength(0)
})

it('should not display notes text field if the status is canceled', async () => {
const expectedLab = { ...mockLab, status: 'canceled' } as Lab

const wrapper = await setup(expectedLab, [Permissions.ViewLab])

const textsField = wrapper.find(TextFieldWithLabelFormGroup)
const notesTextField = wrapper.find('notesTextField')

expect(textsField.length).toBe(1)
expect(notesTextField).toHaveLength(0)
})
})

describe('completed lab request', () => {
Expand Down Expand Up @@ -297,14 +323,30 @@ describe('View Lab', () => {
const buttons = wrapper.find(Button)
expect(buttons).toHaveLength(0)
})

it('should not display notes text field if the status is completed', async () => {
const expectedLab = { ...mockLab, status: 'completed' } as Lab

const wrapper = await setup(expectedLab, [
Permissions.ViewLab,
Permissions.CompleteLab,
Permissions.CancelLab,
])

const textsField = wrapper.find(TextFieldWithLabelFormGroup)
const notesTextField = wrapper.find('notesTextField')

expect(textsField.length).toBe(1)
expect(notesTextField).toHaveLength(0)
})
})
})

describe('on update', () => {
it('should update the lab with the new information', async () => {
const wrapper = await setup(mockLab, [Permissions.ViewLab])
const expectedResult = 'expected result'
const expectedNotes = 'expected notes'
const newNotes = 'expected notes'

const resultTextField = wrapper.find(TextFieldWithLabelFormGroup).at(0)
act(() => {
Expand All @@ -316,7 +358,7 @@ describe('View Lab', () => {
const notesTextField = wrapper.find(TextFieldWithLabelFormGroup).at(1)
act(() => {
const onChange = notesTextField.prop('onChange')
onChange({ currentTarget: { value: expectedNotes } })
onChange({ currentTarget: { value: newNotes } })
})
wrapper.update()
const updateButton = wrapper.find(Button)
Expand All @@ -325,6 +367,8 @@ describe('View Lab', () => {
onClick()
})

const expectedNotes = mockLab.notes ? [...mockLab.notes, newNotes] : [newNotes]

expect(labRepositorySaveSpy).toHaveBeenCalledTimes(1)
expect(labRepositorySaveSpy).toHaveBeenCalledWith(
expect.objectContaining({ ...mockLab, result: expectedResult, notes: expectedNotes }),
Expand Down
5 changes: 3 additions & 2 deletions src/__tests__/labs/requests/NewLabRequest.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -177,11 +177,12 @@ describe('New Lab Request', () => {
const history = createMemoryHistory()
let labRepositorySaveSpy: any
const expectedDate = new Date()
const expectedNotes = 'expected notes'
const expectedLab = {
patient: '12345',
type: 'expected type',
status: 'requested',
notes: 'expected notes',
notes: [expectedNotes],
id: '1234',
requestedOn: expectedDate.toISOString(),
} as Lab
Expand Down Expand Up @@ -226,7 +227,7 @@ describe('New Lab Request', () => {
const notesTextField = wrapper.find(TextFieldWithLabelFormGroup)
act(() => {
const onChange = notesTextField.prop('onChange') as any
onChange({ currentTarget: { value: expectedLab.notes } })
onChange({ currentTarget: { value: expectedNotes } })
})
wrapper.update()

Expand Down
43 changes: 32 additions & 11 deletions src/labs/ViewLab.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Row, Column, Badge, Button, Alert, Toast } from '@hospitalrun/components'
import { Row, Column, Badge, Button, Alert, Toast, Callout, Label } from '@hospitalrun/components'
import format from 'date-fns/format'
import React, { useEffect, useState } from 'react'
import { useSelector, useDispatch } from 'react-redux'
Expand All @@ -12,6 +12,7 @@ import Lab from '../shared/model/Lab'
import Patient from '../shared/model/Patient'
import Permissions from '../shared/model/Permissions'
import { RootState } from '../shared/store'
import { uuid } from '../shared/util/uuid'
import { cancelLab, completeLab, updateLab, fetchLab } from './lab-slice'

const getTitle = (patient: Patient | undefined, lab: Lab | undefined) =>
Expand All @@ -26,6 +27,7 @@ const ViewLab = () => {
const { lab, patient, status, error } = useSelector((state: RootState) => state.lab)

const [labToView, setLabToView] = useState<Lab>()
const [newNotes, setNewNotes] = useState<string>()
const [isEditable, setIsEditable] = useState<boolean>(true)

useTitle(getTitle(patient, labToView))
Expand Down Expand Up @@ -59,8 +61,7 @@ const ViewLab = () => {

const onNotesChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {
const notes = event.currentTarget.value
const newLab = labToView as Lab
setLabToView({ ...newLab, notes })
setNewNotes(notes)
}

const onUpdate = async () => {
Expand All @@ -73,7 +74,12 @@ const ViewLab = () => {
)
}
if (labToView) {
dispatch(updateLab(labToView, onSuccess))
const newLab = labToView as Lab
if (newNotes) {
newLab.notes = newLab.notes ? [...newLab.notes, newNotes] : [newNotes]
setNewNotes('')
}
dispatch(updateLab(newLab, onSuccess))
}
}
const onComplete = async () => {
Expand Down Expand Up @@ -167,6 +173,18 @@ const ViewLab = () => {
return <></>
}

const getPastNotes = () => {
if (labToView.notes && labToView.notes[0] !== '') {
return labToView.notes.map((note: string) => (
<Callout key={uuid()} data-test="note" color="info">
<p>{note}</p>
</Callout>
))
}

return <></>
}

return (
<>
{status === 'error' && (
Expand Down Expand Up @@ -212,13 +230,16 @@ const ViewLab = () => {
feedback={t(error.result as string)}
onChange={onResultChange}
/>
<TextFieldWithLabelFormGroup
name="notes"
label={t('labs.lab.notes')}
value={labToView.notes}
isEditable={isEditable}
onChange={onNotesChange}
/>
<Label text={t('labs.lab.notes')} htmlFor="notesTextField" />
{getPastNotes()}
{isEditable && (
<TextFieldWithLabelFormGroup
name="notes"
value={newNotes}
isEditable={isEditable}
onChange={onNotesChange}
/>
)}
{isEditable && (
<div className="row float-right">
<div className="btn-group btn-group-lg mt-3">{getButtons()}</div>
Expand Down
8 changes: 5 additions & 3 deletions src/labs/requests/NewLabRequest.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,11 @@ const NewLabRequest = () => {
const [newLabRequest, setNewLabRequest] = useState({
patient: '',
type: '',
notes: '',
status: 'requested',
})

const [newNote, setNewNote] = useState('')

useEffect(() => {
dispatch(resetLab())
}, [dispatch])
Expand Down Expand Up @@ -58,9 +59,10 @@ const NewLabRequest = () => {

const onNoteChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {
const notes = event.currentTarget.value
setNewNote(notes)
setNewLabRequest((previousNewLabRequest) => ({
...previousNewLabRequest,
notes,
notes: [notes],
}))
}

Expand Down Expand Up @@ -114,7 +116,7 @@ const NewLabRequest = () => {
name="labNotes"
label={t('labs.lab.notes')}
isEditable
value={newLabRequest.notes}
value={newNote}
onChange={onNoteChange}
/>
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/shared/model/Lab.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export default interface Lab extends AbstractDBModel {
patient: string
type: string
requestedBy: string
notes?: string
notes?: string[]
result?: string
status: 'requested' | 'completed' | 'canceled'
requestedOn: string
Expand Down