Skip to content

Commit

Permalink
feat(lab): link visit to labs
Browse files Browse the repository at this point in the history
Add functionality to link visit to lab, and updated the schema to have a visitId in the Lab model.

fix HospitalRun#2184
  • Loading branch information
DrewGregory committed Nov 6, 2020
1 parent 4a2392a commit d38322f
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 14 deletions.
10 changes: 10 additions & 0 deletions src/__tests__/labs/requests/NewLabRequest.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import NewLabRequest from '../../../labs/requests/NewLabRequest'
import * as validationUtil from '../../../labs/utils/validate-lab'
import { LabError } from '../../../labs/utils/validate-lab'
import * as titleUtil from '../../../page-header/title/TitleContext'
import SelectWithLabelFormGroup from '../../../shared/components/input/SelectWithLabelFormGroup'
import TextFieldWithLabelFormGroup from '../../../shared/components/input/TextFieldWithLabelFormGroup'
import TextInputWithLabelFormGroup from '../../../shared/components/input/TextInputWithLabelFormGroup'
import LabRepository from '../../../shared/db/LabRepository'
Expand Down Expand Up @@ -90,6 +91,15 @@ describe('New Lab Request', () => {
expect(notesTextField.prop('isEditable')).toBeTruthy()
})

it('should render a visit select', async () => {
const { wrapper } = await setup()
const visitSelect = wrapper.find(SelectWithLabelFormGroup)

expect(visitSelect).toBeDefined()
expect(visitSelect.prop('label') as string).toEqual('patient.visit')
expect(visitSelect.prop('isRequired')).toBeTruthy()
})

it('should render a save button', async () => {
const { wrapper } = await setup()
const saveButton = wrapper.find(Button).at(0)
Expand Down
75 changes: 61 additions & 14 deletions src/labs/requests/NewLabRequest.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import { Typeahead, Label, Button, Alert, Toast } from '@hospitalrun/components'
import { Typeahead, Label, Button, Alert, Toast, Column, Row } from '@hospitalrun/components'
import format from 'date-fns/format'
import React, { useState, useEffect } from 'react'
import { useSelector } from 'react-redux'
import { useHistory } from 'react-router-dom'

import useAddBreadcrumbs from '../../page-header/breadcrumbs/useAddBreadcrumbs'
import { useUpdateTitle } from '../../page-header/title/TitleContext'
import SelectWithLabelFormGroup, {
Option,
} from '../../shared/components/input/SelectWithLabelFormGroup'
import TextFieldWithLabelFormGroup from '../../shared/components/input/TextFieldWithLabelFormGroup'
import TextInputWithLabelFormGroup from '../../shared/components/input/TextInputWithLabelFormGroup'
import PatientRepository from '../../shared/db/PatientRepository'
Expand All @@ -22,6 +26,8 @@ const NewLabRequest = () => {
const [mutate] = useRequestLab()
const [newNote, setNewNote] = useState('')
const [error, setError] = useState<LabError | undefined>(undefined)
const [visitOptions, setVisitOptions] = useState([] as Option[])

const updateTitle = useUpdateTitle()
useEffect(() => {
updateTitle(t('labs.requests.new'))
Expand All @@ -31,6 +37,8 @@ const NewLabRequest = () => {
type: '',
status: 'requested',
requestedBy: user?.id || '',
requestedOn: '',
visitId: '',
})

const breadcrumbs = [
Expand All @@ -42,6 +50,12 @@ const NewLabRequest = () => {
useAddBreadcrumbs(breadcrumbs)

const onPatientChange = (patient: Patient) => {
const visits = patient.visits?.map((v) => ({
label: `${v.type} at ${format(new Date(v.startDateTime), 'yyyy-MM-dd hh:mm a')}`,
value: v.id,
})) as Option[]
setVisitOptions(visits)

setNewLabRequest((previousNewLabRequest) => ({
...previousNewLabRequest,
patient: patient.id,
Expand Down Expand Up @@ -83,27 +97,60 @@ const NewLabRequest = () => {
}
}

const onVisitChange = (value: string) => {
setNewLabRequest((previousNewLabRequest) => ({
...previousNewLabRequest,
visitId: value,
}))
}

const onCancel = () => {
history.push('/labs')
}

const defaultSelectedVisitsOption = () => {
if (visitOptions !== undefined) {
return visitOptions.filter(({ value }) => value === newLabRequest.visitId)
}
return []
}

return (
<>
{error && <Alert color="danger" title={t('states.error')} message={t(error.message || '')} />}
<form>
<div className="form-group patient-typeahead">
<Label htmlFor="patientTypeahead" isRequired text={t('labs.lab.patient')} />
<Typeahead
id="patientTypeahead"
placeholder={t('labs.lab.patient')}
onChange={(p: Patient[]) => onPatientChange(p[0])}
onSearch={async (query: string) => PatientRepository.search(query)}
searchAccessor="fullName"
renderMenuItemChildren={(p: Patient) => <div>{`${p.fullName} (${p.code})`}</div>}
isInvalid={!!error?.patient}
feedback={t(error?.patient as string)}
/>
</div>
<Row>
<Column>
<div className="form-group patient-typeahead">
<Label htmlFor="patientTypeahead" isRequired text={t('labs.lab.patient')} />
<Typeahead
id="patientTypeahead"
placeholder={t('labs.lab.patient')}
onChange={(p: Patient[]) => onPatientChange(p[0])}
onSearch={async (query: string) => PatientRepository.search(query)}
searchAccessor="fullName"
renderMenuItemChildren={(p: Patient) => <div>{`${p.fullName} (${p.code})`}</div>}
isInvalid={!!error?.patient}
feedback={t(error?.patient as string)}
/>
</div>
</Column>
<Column>
<div className="form-group">
<SelectWithLabelFormGroup
name="visit"
label={t('patient.visit')}
isRequired
isEditable={newLabRequest.patient !== undefined}
options={visitOptions || []}
defaultSelected={defaultSelectedVisitsOption()}
onChange={(values) => {
onVisitChange(values[0])
}}
/>
</div>
</Column>
</Row>
<TextInputWithLabelFormGroup
name="labType"
label={t('labs.lab.type')}
Expand Down
1 change: 1 addition & 0 deletions src/shared/model/Lab.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ export default interface Lab extends AbstractDBModel {
requestedOn: string
completedOn?: string
canceledOn?: string
visitId?: string
}

0 comments on commit d38322f

Please sign in to comment.