From 886163aafe30de2c66d41e0491600f00749ca682 Mon Sep 17 00:00:00 2001
From: Fibii <38106876+Fibii@users.noreply.github.com>
Date: Wed, 5 Aug 2020 04:45:09 +0200
Subject: [PATCH] feat(patients): add no patients exist (#2235)
---
.../patients/list/ViewPatients.test.tsx | 38 +++++++++++++++++--
src/__tests__/patients/patients-slice.test.ts | 3 +-
.../patients/view/NoPatientsExist.test.tsx | 33 ++++++++++++++++
src/patients/list/ViewPatients.tsx | 34 ++++++++++-------
src/patients/patients-slice.ts | 11 +++++-
src/patients/view/NoPatientsExist.tsx | 38 +++++++++++++++++++
src/shared/db/Repository.ts | 5 +++
.../locales/ar/translations/patients/index.ts | 1 +
.../locales/de/translations/patients/index.ts | 1 +
.../enUs/translations/patients/index.ts | 1 +
.../locales/fr/translations/patients/index.ts | 1 +
.../locales/ru/translations/patients/index.ts | 1 +
12 files changed, 147 insertions(+), 20 deletions(-)
create mode 100644 src/__tests__/patients/view/NoPatientsExist.test.tsx
create mode 100644 src/patients/view/NoPatientsExist.tsx
diff --git a/src/__tests__/patients/list/ViewPatients.test.tsx b/src/__tests__/patients/list/ViewPatients.test.tsx
index 35a8afdcae..ebdb3effde 100644
--- a/src/__tests__/patients/list/ViewPatients.test.tsx
+++ b/src/__tests__/patients/list/ViewPatients.test.tsx
@@ -11,6 +11,7 @@ import { mocked } from 'ts-jest/utils'
import * as ButtonBarProvider from '../../../page-header/button-toolbar/ButtonBarProvider'
import ViewPatients from '../../../patients/list/ViewPatients'
import * as patientSlice from '../../../patients/patients-slice'
+import NoPatientsExist from '../../../patients/view/NoPatientsExist'
import { UnpagedRequest } from '../../../shared/db/PageRequest'
import PatientRepository from '../../../shared/db/PatientRepository'
@@ -35,12 +36,13 @@ describe('Patients', () => {
},
]
- const setup = (isLoading?: boolean) => {
+ const setup = (isLoading?: boolean, currentPatients = patients, count = patients.length) => {
const store = mockStore({
patients: {
- patients,
+ patients: currentPatients,
isLoading,
pageRequest: UnpagedRequest,
+ count,
},
})
return mount(
@@ -80,6 +82,13 @@ describe('Patients', () => {
expect(wrapper.find(Spinner)).toHaveLength(1)
})
+ it('should render no patients exists when no patients exist', () => {
+ const wrapper = setup(false, [], 0)
+
+ const addNewPatient = wrapper.find(NoPatientsExist)
+ expect(addNewPatient).toHaveLength(1)
+ })
+
it('should render a table of patients', () => {
const wrapper = setup()
@@ -121,7 +130,10 @@ describe('Patients', () => {
describe('search functionality', () => {
beforeEach(() => jest.useFakeTimers())
- afterEach(() => jest.useRealTimers())
+ afterEach(() => {
+ jest.useRealTimers()
+ jest.restoreAllMocks()
+ })
it('should search for patients after the search text has not changed for 500 milliseconds', () => {
const searchPatientsSpy = jest.spyOn(patientSlice, 'searchPatients')
@@ -145,5 +157,25 @@ describe('Patients', () => {
sorts: [{ field: 'index', direction: 'asc' }],
})
})
+
+ it("shound't display NoPatientsFound if a search result has no results", () => {
+ const searchPatientsSpy = jest.spyOn(patientSlice, 'searchPatients')
+ const wrapper = setup()
+ searchPatientsSpy.mockClear()
+ const expectedSearchText = '$$$not a patient$$$'
+
+ act(() => {
+ const onChange = wrapper.find(TextInput).prop('onChange') as any
+ onChange({ target: { value: expectedSearchText } })
+ })
+
+ act(() => {
+ jest.advanceTimersByTime(500)
+ })
+
+ wrapper.update()
+
+ expect(NoPatientsExist).toHaveLength(0)
+ })
})
})
diff --git a/src/__tests__/patients/patients-slice.test.ts b/src/__tests__/patients/patients-slice.test.ts
index 84565aedd2..1fea4c6a66 100644
--- a/src/__tests__/patients/patients-slice.test.ts
+++ b/src/__tests__/patients/patients-slice.test.ts
@@ -81,7 +81,8 @@ describe('patients slice', () => {
await searchPatients('')(dispatch, getState, null)
- expect(PatientRepository.findAll).toHaveBeenCalledTimes(1)
+ // expecting 2 here because searchPatients uses PatientRepository.count() which calls #findAll
+ expect(PatientRepository.findAll).toHaveBeenCalledTimes(2)
})
it('should dispatch the FETCH_PATIENTS_SUCCESS action', async () => {
diff --git a/src/__tests__/patients/view/NoPatientsExist.test.tsx b/src/__tests__/patients/view/NoPatientsExist.test.tsx
new file mode 100644
index 0000000000..398434c475
--- /dev/null
+++ b/src/__tests__/patients/view/NoPatientsExist.test.tsx
@@ -0,0 +1,33 @@
+import { Icon, Typography, Button } from '@hospitalrun/components'
+import { mount } from 'enzyme'
+import React from 'react'
+
+import NoPatientsExist from '../../../patients/view/NoPatientsExist'
+
+describe('NoPatientsExist', () => {
+ const setup = () => mount()
+
+ it('should render an icon and a button with typography', () => {
+ const wrapper = setup()
+
+ const addNewPatient = wrapper.find(NoPatientsExist)
+ expect(addNewPatient).toHaveLength(1)
+
+ const icon = wrapper.find(Icon).first()
+ const typography = wrapper.find(Typography)
+ const button = wrapper.find(Button)
+ const iconType = icon.prop('icon')
+ const iconSize = icon.prop('size')
+ const typographyText = typography.prop('children')
+ const typographyVariant = typography.prop('variant')
+ const buttonIcon = button.prop('icon')
+ const buttonText = button.prop('children')
+
+ expect(iconType).toEqual('patients')
+ expect(iconSize).toEqual('6x')
+ expect(typographyText).toEqual('patients.noPatients')
+ expect(typographyVariant).toEqual('h5')
+ expect(buttonIcon).toEqual('patient-add')
+ expect(buttonText).toEqual('patients.newPatient')
+ })
+})
diff --git a/src/patients/list/ViewPatients.tsx b/src/patients/list/ViewPatients.tsx
index 4dafd5543d..ad985f488f 100644
--- a/src/patients/list/ViewPatients.tsx
+++ b/src/patients/list/ViewPatients.tsx
@@ -13,6 +13,7 @@ import useTranslator from '../../shared/hooks/useTranslator'
import useUpdateEffect from '../../shared/hooks/useUpdateEffect'
import { RootState } from '../../shared/store'
import { searchPatients } from '../patients-slice'
+import NoPatientsExist from '../view/NoPatientsExist'
const breadcrumbs = [{ i18nKey: 'patients.label', location: '/patients' }]
@@ -22,7 +23,7 @@ const ViewPatients = () => {
useTitle(t('patients.label'))
useAddBreadcrumbs(breadcrumbs, true)
const dispatch = useDispatch()
- const { patients, isLoading } = useSelector((state: RootState) => state.patients)
+ const { patients, isLoading, count } = useSelector((state: RootState) => state.patients)
const setButtonToolBar = useButtonToolbarSetter()
@@ -48,22 +49,23 @@ const ViewPatients = () => {
}, [dispatch, debouncedSearchText])
useEffect(() => {
- setButtonToolBar([
- ,
- ])
-
+ if (patients && patients.length > 0) {
+ setButtonToolBar([
+ ,
+ ])
+ }
return () => {
setButtonToolBar([])
}
- }, [dispatch, setButtonToolBar, t, history])
+ }, [dispatch, setButtonToolBar, t, history, patients])
const loadingIndicator =
const table = (
@@ -91,6 +93,10 @@ const ViewPatients = () => {
setSearchText(event.target.value)
}
+ if (count === 0) {
+ return
+ }
+
return (
diff --git a/src/patients/patients-slice.ts b/src/patients/patients-slice.ts
index e3daa42d56..15c910b9f4 100644
--- a/src/patients/patients-slice.ts
+++ b/src/patients/patients-slice.ts
@@ -8,11 +8,13 @@ import { AppThunk } from '../shared/store'
interface PatientsState {
isLoading: boolean
patients: Patient[]
+ count: number
}
const initialState: PatientsState = {
isLoading: false,
patients: [],
+ count: 0,
}
function startLoading(state: PatientsState) {
@@ -28,9 +30,13 @@ const patientsSlice = createSlice({
state.isLoading = false
state.patients = payload
},
+ fetchCountSuccess(state, { payload }: PayloadAction) {
+ state.count = payload
+ },
},
})
-export const { fetchPatientsStart, fetchPatientsSuccess } = patientsSlice.actions
+
+export const { fetchPatientsStart, fetchPatientsSuccess, fetchCountSuccess } = patientsSlice.actions
export const fetchPatients = (sortRequest: SortRequest = Unsorted): AppThunk => async (
dispatch,
@@ -53,7 +59,8 @@ export const searchPatients = (
} else {
patients = await PatientRepository.search(searchString)
}
-
+ const count = await PatientRepository.count()
+ dispatch(fetchCountSuccess(count))
dispatch(fetchPatientsSuccess(patients))
}
diff --git a/src/patients/view/NoPatientsExist.tsx b/src/patients/view/NoPatientsExist.tsx
new file mode 100644
index 0000000000..f255e38805
--- /dev/null
+++ b/src/patients/view/NoPatientsExist.tsx
@@ -0,0 +1,38 @@
+import { Button, Icon, Typography } from '@hospitalrun/components'
+import React from 'react'
+import { useHistory } from 'react-router-dom'
+
+import useTranslator from '../../shared/hooks/useTranslator'
+
+const NoPatientsExist = () => {
+ const history = useHistory()
+ const { t } = useTranslator()
+
+ return (
+
+
+
+
+
+
+
+ {t('patients.noPatients')}
+
+
+
+
+
+
+
+ )
+}
+
+export default NoPatientsExist
diff --git a/src/shared/db/Repository.ts b/src/shared/db/Repository.ts
index a77ad08d72..ba3f287dc8 100644
--- a/src/shared/db/Repository.ts
+++ b/src/shared/db/Repository.ts
@@ -132,6 +132,11 @@ export default class Repository {
// return pagedResult
// }
+ async count(): Promise {
+ const result = await this.findAll()
+ return result.length
+ }
+
async search(criteria: any): Promise {
const response = await this.db.find(criteria)
const data = await this.db.rel.parseRelDocs(this.type, response.docs)
diff --git a/src/shared/locales/ar/translations/patients/index.ts b/src/shared/locales/ar/translations/patients/index.ts
index e2b9ef8c32..753a035674 100644
--- a/src/shared/locales/ar/translations/patients/index.ts
+++ b/src/shared/locales/ar/translations/patients/index.ts
@@ -2,6 +2,7 @@ export default {
patients: {
label: 'المرضى',
viewPatients: 'عرض المرضى',
+ noPatients: 'لا يوجد مرضى حاليا, قم بانشاء اول مريض حالا !',
viewPatient: 'عرض المريض',
editPatient: 'تغيير المريض',
newPatient: 'مريض جديد',
diff --git a/src/shared/locales/de/translations/patients/index.ts b/src/shared/locales/de/translations/patients/index.ts
index 47d71277f0..01dc40787a 100644
--- a/src/shared/locales/de/translations/patients/index.ts
+++ b/src/shared/locales/de/translations/patients/index.ts
@@ -2,6 +2,7 @@ export default {
patients: {
label: 'Patienten',
viewPatients: 'Patienten anzeigen',
+ noPatients: 'Es sind noch keine Patienten vorhanden, fügen Sie den Ersten hinzu',
viewPatient: 'Patient anzeigen',
editPatient: 'Patient bearbeiten',
newPatient: 'Neuer Patient',
diff --git a/src/shared/locales/enUs/translations/patients/index.ts b/src/shared/locales/enUs/translations/patients/index.ts
index 8f8703b423..e8d3a2c2ff 100644
--- a/src/shared/locales/enUs/translations/patients/index.ts
+++ b/src/shared/locales/enUs/translations/patients/index.ts
@@ -4,6 +4,7 @@ export default {
warning: 'Warning!',
patientsList: 'Patients List',
viewPatients: 'View Patients',
+ noPatients: "There are no patients yet, let's add the first one!",
viewPatient: 'View Patient',
newPatient: 'New Patient',
editPatient: 'Edit Patient',
diff --git a/src/shared/locales/fr/translations/patients/index.ts b/src/shared/locales/fr/translations/patients/index.ts
index 02cabc76a7..2462ae46f9 100644
--- a/src/shared/locales/fr/translations/patients/index.ts
+++ b/src/shared/locales/fr/translations/patients/index.ts
@@ -3,6 +3,7 @@ export default {
label: 'Patients',
patientsList: 'Liste des patients',
viewPatients: 'Voir les patients',
+ noPatients: "Il n'y a aucun patient ici, voilà donc le premier",
viewPatient: 'Voir le patient',
editPatient: 'Modifier le patient',
newPatient: 'Nouveau patient',
diff --git a/src/shared/locales/ru/translations/patients/index.ts b/src/shared/locales/ru/translations/patients/index.ts
index 43c675bad4..47a9701562 100644
--- a/src/shared/locales/ru/translations/patients/index.ts
+++ b/src/shared/locales/ru/translations/patients/index.ts
@@ -2,6 +2,7 @@ export default {
patients: {
label: 'Пациенты',
viewPatients: 'Просмотр пациентов',
+ noPatients: 'Пациентов еще нет, давайте добавим первого!',
viewPatient: 'Просмотр пациента',
editPatient: 'Редактировать пациента',
newPatient: 'Новый пациент',