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

Commit

Permalink
feat(patients): adds ability to remove related person (#1968)
Browse files Browse the repository at this point in the history
  • Loading branch information
jackcmeyer committed Apr 6, 2020
1 parent 89430f7 commit 6e08bab
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 36 deletions.
73 changes: 57 additions & 16 deletions src/__tests__/patients/related-persons/RelatedPersons.test.tsx
Expand Up @@ -16,6 +16,8 @@ import { Provider } from 'react-redux'
import Permissions from 'model/Permissions'
import { mocked } from 'ts-jest/utils'

import RelatedPerson from 'model/RelatedPerson'
import { Button } from '@hospitalrun/components'
import * as patientSlice from '../../../patients/patient-slice'

const mockStore = configureMockStore([thunk])
Expand Down Expand Up @@ -173,23 +175,29 @@ describe('Related Persons Tab', () => {
})
})

describe('List', () => {
describe('Table', () => {
const patient = {
id: '123',
rev: '123',
relatedPersons: [{ patientId: '123', type: 'type' }],
relatedPersons: [{ patientId: '123001', type: 'type' }],
} as Patient
const expectedRelatedPerson = {
givenName: 'test',
familyName: 'test',
fullName: 'test test',
id: '123001',
} as Patient

const user = {
permissions: [Permissions.WritePatients, Permissions.ReadPatients],
}

let patientSaveOrUpdateSpy: any

beforeEach(async () => {
patientSaveOrUpdateSpy = jest.spyOn(PatientRepository, 'saveOrUpdate')
jest.spyOn(PatientRepository, 'find')
mocked(PatientRepository.find).mockResolvedValue({
fullName: 'test test',
id: '123001',
} as Patient)
mocked(PatientRepository.find).mockResolvedValue(expectedRelatedPerson)

await act(async () => {
wrapper = await mount(
Expand All @@ -204,20 +212,53 @@ describe('Related Persons Tab', () => {
})

it('should render a list of related persons with their full name being displayed', () => {
const list = wrapper.find(components.List)
const listItems = wrapper.find(components.ListItem)
expect(list).toHaveLength(1)
expect(listItems).toHaveLength(1)
expect(listItems.at(0).text()).toEqual('test test')
const table = wrapper.find('table')
const tableHeader = wrapper.find('thead')
const tableHeaders = wrapper.find('th')
const tableBody = wrapper.find('tbody')
const tableData = wrapper.find('td')
const deleteButton = tableData.at(3).find(Button)
expect(table).toHaveLength(1)
expect(tableHeader).toHaveLength(1)
expect(tableBody).toHaveLength(1)
expect(tableHeaders.at(0).text()).toEqual('patient.givenName')
expect(tableHeaders.at(1).text()).toEqual('patient.familyName')
expect(tableHeaders.at(2).text()).toEqual('patient.relatedPersons.relationshipType')
expect(tableHeaders.at(3).text()).toEqual('actions.label')
expect(tableData.at(0).text()).toEqual(expectedRelatedPerson.givenName)
expect(tableData.at(1).text()).toEqual(expectedRelatedPerson.familyName)
expect(tableData.at(2).text()).toEqual((patient.relatedPersons as RelatedPerson[])[0].type)
expect(deleteButton).toHaveLength(1)
expect(deleteButton.text().trim()).toEqual('actions.delete')
expect(deleteButton.prop('color')).toEqual('danger')
})

it('should remove the related person when the delete button is clicked', async () => {
const eventPropagationSpy = jest.fn()

const table = wrapper.find('table')
const tableBody = table.find('tbody')
const tableData = tableBody.find('td')
const deleteButton = tableData.at(3).find(Button)

await act(async () => {
const onClick = deleteButton.prop('onClick')
onClick({ stopPropagation: eventPropagationSpy })
})

expect(eventPropagationSpy).toHaveBeenCalledTimes(1)
expect(patientSaveOrUpdateSpy).toHaveBeenLastCalledWith({ ...patient, relatedPersons: [] })
})

it('should navigate to related person patient profile on related person click', () => {
const list = wrapper.find(components.List)
const listItems = wrapper.find(components.ListItem)
const table = wrapper.find('table')
const tableBody = table.find('tbody')
const row = tableBody.find('tr')
act(() => {
;(listItems.at(0).prop('onClick') as any)()
const onClick = row.prop('onClick')
onClick()
})
expect(list).toHaveLength(1)
expect(listItems).toHaveLength(1)

expect(history.location.pathname).toEqual('/patients/123001')
})
})
Expand Down
1 change: 1 addition & 0 deletions src/locales/enUs/translations/actions/index.ts
@@ -1,5 +1,6 @@
export default {
actions: {
label: 'Actions',
edit: 'Edit',
save: 'Save',
update: 'Update',
Expand Down
73 changes: 53 additions & 20 deletions src/patients/related-persons/RelatedPersonTab.tsx
@@ -1,5 +1,5 @@
import React, { useState, useEffect } from 'react'
import { Button, Panel, List, ListItem, Alert, Spinner, Toast } from '@hospitalrun/components'
import { Button, Alert, Spinner, Toast } from '@hospitalrun/components'
import AddRelatedPersonModal from 'patients/related-persons/AddRelatedPersonModal'
import RelatedPerson from 'model/RelatedPerson'
import { useTranslation } from 'react-i18next'
Expand Down Expand Up @@ -44,7 +44,7 @@ const RelatedPersonTab = (props: Props) => {
await Promise.all(
patient.relatedPersons.map(async (person) => {
const fetchedRelatedPerson = await PatientRepository.find(person.patientId)
fetchedRelatedPersons.push(fetchedRelatedPerson)
fetchedRelatedPersons.push({ ...fetchedRelatedPerson, type: person.type })
}),
)
}
Expand Down Expand Up @@ -88,6 +88,20 @@ const RelatedPersonTab = (props: Props) => {
closeNewRelatedPersonModal()
}

const onRelatedPersonDelete = (
event: React.MouseEvent<HTMLButtonElement>,
relatedPerson: Patient,
) => {
event.stopPropagation()
const patientToUpdate = { ...patient }
const newRelatedPersons = patientToUpdate.relatedPersons?.filter(
(r) => r.patientId !== relatedPerson.id,
)
patientToUpdate.relatedPersons = newRelatedPersons

dispatch(updatePatient(patientToUpdate))
}

return (
<div>
<div className="row">
Expand All @@ -108,27 +122,46 @@ const RelatedPersonTab = (props: Props) => {
<br />
<div className="row">
<div className="col-md-12">
<Panel title={t('patient.relatedPersons.label')} color="primary" collapsible>
{relatedPersons ? (
relatedPersons.length > 0 ? (
<List>
{relatedPersons ? (
relatedPersons.length > 0 ? (
<table className="table table-hover">
<thead className="thead-light">
<tr>
<th>{t('patient.givenName')}</th>
<th>{t('patient.familyName')}</th>
<th>{t('patient.relatedPersons.relationshipType')}</th>
<th>{t('actions.label')}</th>
</tr>
</thead>
<tbody>
{relatedPersons.map((r) => (
<ListItem action key={r.id} onClick={() => onRelatedPersonClick(r.id)}>
{r.fullName}
</ListItem>
<tr key={r.id} onClick={() => onRelatedPersonClick(r.id)}>
<td>{r.givenName}</td>
<td>{r.familyName}</td>
<td>{r.type}</td>
<td>
<Button
icon="remove"
color="danger"
onClick={(e) => onRelatedPersonDelete(e, r)}
>
{t('actions.delete')}
</Button>
</td>
</tr>
))}
</List>
) : (
<Alert
color="warning"
title={t('patient.relatedPersons.warning.noRelatedPersons')}
message={t('patient.relatedPersons.addRelatedPersonAbove')}
/>
)
</tbody>
</table>
) : (
<Spinner color="blue" loading size={[10, 25]} type="ScaleLoader" />
)}
</Panel>
<Alert
color="warning"
title={t('patient.relatedPersons.warning.noRelatedPersons')}
message={t('patient.relatedPersons.addRelatedPersonAbove')}
/>
)
) : (
<Spinner color="blue" loading size={[10, 25]} type="ScaleLoader" />
)}
</div>
</div>

Expand Down

1 comment on commit 6e08bab

@vercel
Copy link

@vercel vercel bot commented on 6e08bab Apr 6, 2020

Choose a reason for hiding this comment

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

Failed to assign a domain to your deployment due to the following error:

We could not create a certificate for staging.hospitalrun.io because HTTP pretest failed. Please ensure the CNAME for staging.hospitalrun.io points to "alias.zeit.co". You can find more information at https://err.sh/now-cli/cant-solve-challenge.

(Learn more or visit the non-aliased deployment)

Please sign in to comment.