From 4a4a6821838982f51b94ff050ff5e614a95d8839 Mon Sep 17 00:00:00 2001 From: Jack Meyer Date: Thu, 30 Apr 2020 21:54:01 -0500 Subject: [PATCH] feat(incidents): adds ability to report incident --- src/__tests__/incidents/Incidents.test.tsx | 1 + .../incidents/incident-slice.test.ts | 147 ++++++++++++++ .../incidents/report/ReportIncident.test.tsx | 192 +++++++++++++++++- src/clients/db/IncidentRepository.ts | 11 + .../DateTimePickerWithLabelFormGroup.tsx | 9 +- src/config/pouchdb.ts | 1 + src/incidents/incident-slice.ts | 111 ++++++++++ src/incidents/report/ReportIncident.tsx | 130 +++++++++++- .../enUs/translations/incidents/index.ts | 16 ++ src/model/Incident.ts | 12 ++ src/model/User.ts | 5 + src/store/index.ts | 2 + src/user/user-slice.ts | 7 + 13 files changed, 631 insertions(+), 13 deletions(-) create mode 100644 src/__tests__/incidents/incident-slice.test.ts create mode 100644 src/clients/db/IncidentRepository.ts create mode 100644 src/incidents/incident-slice.ts create mode 100644 src/model/Incident.ts create mode 100644 src/model/User.ts diff --git a/src/__tests__/incidents/Incidents.test.tsx b/src/__tests__/incidents/Incidents.test.tsx index 2646be6a36..e66656549d 100644 --- a/src/__tests__/incidents/Incidents.test.tsx +++ b/src/__tests__/incidents/Incidents.test.tsx @@ -22,6 +22,7 @@ describe('Incidents', () => { user: { permissions: [Permissions.ReportIncident] }, breadcrumbs: { breadcrumbs: [] }, components: { sidebarCollapsed: false }, + incident: {}, }) const wrapper = mount( diff --git a/src/__tests__/incidents/incident-slice.test.ts b/src/__tests__/incidents/incident-slice.test.ts new file mode 100644 index 0000000000..4239431596 --- /dev/null +++ b/src/__tests__/incidents/incident-slice.test.ts @@ -0,0 +1,147 @@ +import { AnyAction } from 'redux' +import createMockStore from 'redux-mock-store' +import thunk from 'redux-thunk' +import shortid from 'shortid' +import { addDays } from 'date-fns' +import incident, { + reportIncidentStart, + reportIncidentSuccess, + reportIncidentError, + reportIncident, +} from '../../incidents/incident-slice' +import Incident from '../../model/Incident' +import { RootState } from '../../store' +import IncidentRepository from '../../clients/db/IncidentRepository' + +const mockStore = createMockStore([thunk]) + +describe('incident slice', () => { + describe('actions', () => { + it('should default the store correctly', () => { + const incidentStore = incident(undefined, {} as AnyAction) + expect(incidentStore.status).toEqual('loading') + expect(incidentStore.incident).toBeUndefined() + expect(incidentStore.error).toBeUndefined() + }) + + it('should handle the report incident start', () => { + const incidentStore = incident(undefined, reportIncidentStart) + expect(incidentStore.status).toEqual('loading') + }) + + it('should handle the report incident success', () => { + const expectedIncident = { + id: 'some id', + reportedOn: new Date().toISOString(), + reportedBy: 'some user id', + description: 'description', + date: new Date().toISOString(), + department: 'some department', + category: 'category', + categoryItem: 'categoryItem', + code: 'some code', + } as Incident + + const incidentStore = incident(undefined, reportIncidentSuccess(expectedIncident)) + expect(incidentStore.status).toEqual('completed') + expect(incidentStore.incident).toEqual(expectedIncident) + expect(incidentStore.error).toBeUndefined() + }) + + it('should handle the report incident error', () => { + const expectedError = { + date: 'some description error', + description: 'some description error', + } + + const incidentStore = incident(undefined, reportIncidentError(expectedError)) + expect(incidentStore.status).toEqual('error') + expect(incidentStore.error).toEqual(expectedError) + }) + }) + + describe('report incident', () => { + beforeEach(() => { + jest.restoreAllMocks() + }) + + it('should successfully create an incident', async () => { + const expectedDate = new Date() + const expectedShortId = '123456' + Date.now = jest.fn().mockReturnValue(expectedDate) + jest.spyOn(shortid, 'generate').mockReturnValue(expectedShortId) + const onSuccessSpy = jest.fn() + const newIncident = { + description: 'description', + date: expectedDate.toISOString(), + department: 'some department', + category: 'category', + categoryItem: 'categoryItem', + } as Incident + + const expectedIncident = { + ...newIncident, + code: `I-${expectedShortId}`, + reportedOn: expectedDate.toISOString(), + reportedBy: 'some user id', + } + + jest.spyOn(IncidentRepository, 'save').mockResolvedValue(expectedIncident) + + const store = mockStore({ user: { user: { id: expectedIncident.reportedBy } } }) + + await store.dispatch(reportIncident(newIncident, onSuccessSpy)) + + expect(store.getActions()[0]).toEqual(reportIncidentStart()) + expect(store.getActions()[1]).toEqual(reportIncidentSuccess(expectedIncident)) + expect(IncidentRepository.save).toHaveBeenCalledWith(expectedIncident) + expect(onSuccessSpy).toHaveBeenLastCalledWith(expectedIncident) + }) + + it('should validate the required fields apart of an incident', async () => { + const onSuccessSpy = jest.fn() + const newIncident = {} as Incident + jest.spyOn(IncidentRepository, 'save') + const expectedError = { + date: 'incidents.reports.error.dateRequired', + department: 'incidents.reports.error.departmentRequired', + category: 'incidents.reports.error.categoryRequired', + categoryItem: 'incidents.reports.error.categoryItemRequired', + description: 'incidents.reports.error.descriptionRequired', + } + + const store = mockStore({ user: { user: { id: 'some id' } } }) + + await store.dispatch(reportIncident(newIncident, onSuccessSpy)) + + expect(store.getActions()[0]).toEqual(reportIncidentStart()) + expect(store.getActions()[1]).toEqual(reportIncidentError(expectedError)) + expect(IncidentRepository.save).not.toHaveBeenCalled() + expect(onSuccessSpy).not.toHaveBeenCalled() + }) + + it('should validate that the incident date is not a date in the future', async () => { + const onSuccessSpy = jest.fn() + const newIncident = { + description: 'description', + date: addDays(new Date(), 4), + department: 'some department', + category: 'category', + categoryItem: 'categoryItem', + } as Incident + jest.spyOn(IncidentRepository, 'save') + const expectedError = { + date: 'incidents.reports.error.dateMustBeInThePast', + } + + const store = mockStore({ user: { user: { id: 'some id' } } }) + + await store.dispatch(reportIncident(newIncident, onSuccessSpy)) + + expect(store.getActions()[0]).toEqual(reportIncidentStart()) + expect(store.getActions()[1]).toEqual(reportIncidentError(expectedError)) + expect(IncidentRepository.save).not.toHaveBeenCalled() + expect(onSuccessSpy).not.toHaveBeenCalled() + }) + }) +}) diff --git a/src/__tests__/incidents/report/ReportIncident.test.tsx b/src/__tests__/incidents/report/ReportIncident.test.tsx index 5cad7b542c..a1824b77e9 100644 --- a/src/__tests__/incidents/report/ReportIncident.test.tsx +++ b/src/__tests__/incidents/report/ReportIncident.test.tsx @@ -7,11 +7,13 @@ import { Provider } from 'react-redux' import { Route, Router } from 'react-router' import createMockStore from 'redux-mock-store' import thunk from 'redux-thunk' +import { Button } from '@hospitalrun/components' import Permissions from '../../../model/Permissions' import * as titleUtil from '../../../page-header/useTitle' import * as ButtonBarProvider from '../../../page-header/ButtonBarProvider' import * as breadcrumbUtil from '../../../breadcrumbs/useAddBreadcrumbs' import ReportIncident from '../../../incidents/report/ReportIncident' +import IncidentRepository from '../../../clients/db/IncidentRepository' const mockStore = createMockStore([thunk]) @@ -19,7 +21,7 @@ describe('Report Incident', () => { let history: any let setButtonToolBarSpy: any - const setup = async (permissions: Permissions[]) => { + const setup = async (permissions: Permissions[], error: any = {}) => { jest.resetAllMocks() jest.spyOn(breadcrumbUtil, 'default') setButtonToolBarSpy = jest.fn() @@ -32,6 +34,12 @@ describe('Report Incident', () => { title: '', user: { permissions, + user: { + id: 'some id', + }, + }, + incident: { + error, }, }) @@ -53,17 +61,183 @@ describe('Report Incident', () => { return wrapper } - it('should set the title', async () => { - await setup([Permissions.ReportIncident]) + describe('layout', () => { + it('should set the title', async () => { + await setup([Permissions.ReportIncident]) + + expect(titleUtil.default).toHaveBeenCalledWith('incidents.reports.new') + }) + + it('should set the breadcrumbs properly', async () => { + await setup([Permissions.ReportIncident]) + + expect(breadcrumbUtil.default).toHaveBeenCalledWith([ + { i18nKey: 'incidents.reports.new', location: '/incidents/new' }, + ]) + }) + + it('should have a date input', async () => { + const wrapper = await setup([Permissions.ReportIncident]) - expect(titleUtil.default).toHaveBeenCalledWith('incidents.reports.new') + const dateInput = wrapper.findWhere((w) => w.prop('name') === 'dateOfIncident') + + expect(dateInput).toHaveLength(1) + expect(dateInput.prop('label')).toEqual('incidents.reports.dateOfIncident') + expect(dateInput.prop('isEditable')).toBeTruthy() + expect(dateInput.prop('isRequired')).toBeTruthy() + }) + + it('should have a department input', async () => { + const wrapper = await setup([Permissions.ReportIncident]) + + const departmentInput = wrapper.findWhere((w) => w.prop('name') === 'department') + + expect(departmentInput).toHaveLength(1) + expect(departmentInput.prop('label')).toEqual('incidents.reports.department') + expect(departmentInput.prop('isEditable')).toBeTruthy() + expect(departmentInput.prop('isRequired')).toBeTruthy() + }) + + it('should have a category input', async () => { + const wrapper = await setup([Permissions.ReportIncident]) + + const categoryInput = wrapper.findWhere((w) => w.prop('name') === 'category') + + expect(categoryInput).toHaveLength(1) + expect(categoryInput.prop('label')).toEqual('incidents.reports.category') + expect(categoryInput.prop('isEditable')).toBeTruthy() + expect(categoryInput.prop('isRequired')).toBeTruthy() + }) + + it('should have a category item input', async () => { + const wrapper = await setup([Permissions.ReportIncident]) + + const categoryInput = wrapper.findWhere((w) => w.prop('name') === 'categoryItem') + + expect(categoryInput).toHaveLength(1) + expect(categoryInput.prop('label')).toEqual('incidents.reports.categoryItem') + expect(categoryInput.prop('isEditable')).toBeTruthy() + expect(categoryInput.prop('isRequired')).toBeTruthy() + }) + + it('should have a description input', async () => { + const wrapper = await setup([Permissions.ReportIncident]) + + const descriptionInput = wrapper.findWhere((w) => w.prop('name') === 'description') + + expect(descriptionInput).toHaveLength(1) + expect(descriptionInput.prop('label')).toEqual('incidents.reports.description') + expect(descriptionInput.prop('isEditable')).toBeTruthy() + expect(descriptionInput.prop('isRequired')).toBeTruthy() + }) }) - it('should set the breadcrumbs properly', async () => { - await setup([Permissions.ReportIncident]) + describe('error handling', () => { + it('should display the error messages', async () => { + const error = { + date: 'some date error', + department: 'some department error', + category: 'some category error', + categoryItem: 'some category item error', + description: 'some description error', + } - expect(breadcrumbUtil.default).toHaveBeenCalledWith([ - { i18nKey: 'incidents.reports.new', location: '/incidents/new' }, - ]) + const wrapper = await setup([Permissions.ReportIncident], error) + + const dateInput = wrapper.findWhere((w) => w.prop('name') === 'dateOfIncident') + const departmentInput = wrapper.findWhere((w) => w.prop('name') === 'department') + const categoryInput = wrapper.findWhere((w) => w.prop('name') === 'category') + const categoryItemInput = wrapper.findWhere((w) => w.prop('name') === 'categoryItem') + const descriptionInput = wrapper.findWhere((w) => w.prop('name') === 'description') + + expect(dateInput.prop('isInvalid')).toBeTruthy() + expect(dateInput.prop('feedback')).toEqual(error.date) + + expect(departmentInput.prop('isInvalid')).toBeTruthy() + expect(departmentInput.prop('feedback')).toEqual(error.department) + + expect(categoryInput.prop('isInvalid')).toBeTruthy() + expect(categoryInput.prop('feedback')).toEqual(error.category) + + expect(categoryItemInput.prop('isInvalid')).toBeTruthy() + expect(categoryItemInput.prop('feedback')).toEqual(error.categoryItem) + + expect(descriptionInput.prop('isInvalid')).toBeTruthy() + expect(descriptionInput.prop('feedback')).toEqual(error.description) + }) + }) + + describe('on save', () => { + it('should dispatch the report incident action', async () => { + const wrapper = await setup([Permissions.ReportIncident]) + const expectedIncident = { + date: new Date().toISOString(), + department: 'some department', + category: 'some category', + categoryItem: 'some category item', + description: 'some description', + } + jest + .spyOn(IncidentRepository, 'save') + .mockResolvedValue({ id: 'someId', ...expectedIncident }) + + const dateInput = wrapper.findWhere((w) => w.prop('name') === 'dateOfIncident') + act(() => { + const onChange = dateInput.prop('onChange') + onChange(new Date(expectedIncident.date)) + }) + + const departmentInput = wrapper.findWhere((w) => w.prop('name') === 'department') + act(() => { + const onChange = departmentInput.prop('onChange') + onChange({ currentTarget: { value: expectedIncident.department } }) + }) + + const categoryInput = wrapper.findWhere((w) => w.prop('name') === 'category') + act(() => { + const onChange = categoryInput.prop('onChange') + onChange({ currentTarget: { value: expectedIncident.category } }) + }) + + const categoryItemInput = wrapper.findWhere((w) => w.prop('name') === 'categoryItem') + act(() => { + const onChange = categoryItemInput.prop('onChange') + onChange({ currentTarget: { value: expectedIncident.categoryItem } }) + }) + + const descriptionInput = wrapper.findWhere((w) => w.prop('name') === 'description') + act(() => { + const onChange = descriptionInput.prop('onChange') + onChange({ currentTarget: { value: expectedIncident.description } }) + }) + wrapper.update() + + const saveButton = wrapper.find(Button).at(0) + await act(async () => { + const onClick = saveButton.prop('onClick') + onClick() + }) + + expect(IncidentRepository.save).toHaveBeenCalledTimes(1) + expect(IncidentRepository.save).toHaveBeenCalledWith( + expect.objectContaining(expectedIncident), + ) + expect(history.location.pathname).toEqual(`/incidents/someId`) + }) + }) + + describe('on cancel', () => { + it('should navigate to /incidents', async () => { + const wrapper = await setup([Permissions.ReportIncident]) + + const cancelButton = wrapper.find(Button).at(1) + + act(() => { + const onClick = cancelButton.prop('onClick') as any + onClick() + }) + + expect(history.location.pathname).toEqual('/incidents') + }) }) }) diff --git a/src/clients/db/IncidentRepository.ts b/src/clients/db/IncidentRepository.ts new file mode 100644 index 0000000000..ca3cfd6894 --- /dev/null +++ b/src/clients/db/IncidentRepository.ts @@ -0,0 +1,11 @@ +import Repository from './Repository' +import { incidents } from '../../config/pouchdb' +import Incident from '../../model/Incident' + +export class IncidentRepository extends Repository { + constructor() { + super(incidents) + } +} + +export default new IncidentRepository() diff --git a/src/components/input/DateTimePickerWithLabelFormGroup.tsx b/src/components/input/DateTimePickerWithLabelFormGroup.tsx index cd38d51dac..dbae9b97c2 100644 --- a/src/components/input/DateTimePickerWithLabelFormGroup.tsx +++ b/src/components/input/DateTimePickerWithLabelFormGroup.tsx @@ -6,15 +6,18 @@ interface Props { label: string value: Date | undefined isEditable?: boolean + isRequired?: boolean onChange?: (date: Date) => void + feedback?: string + isInvalid?: boolean } const DateTimePickerWithLabelFormGroup = (props: Props) => { - const { onChange, label, name, isEditable, value } = props + const { onChange, label, name, isEditable, value, isRequired, feedback, isInvalid } = props const id = `${name}DateTimePicker` return (
-
) diff --git a/src/config/pouchdb.ts b/src/config/pouchdb.ts index a4b0a13bae..b951e8f6ed 100644 --- a/src/config/pouchdb.ts +++ b/src/config/pouchdb.ts @@ -29,3 +29,4 @@ function createDb(name: string) { export const patients = createDb('patients') export const appointments = createDb('appointments') export const labs = createDb('labs') +export const incidents = createDb('incidents') diff --git a/src/incidents/incident-slice.ts b/src/incidents/incident-slice.ts new file mode 100644 index 0000000000..4d005cfa7f --- /dev/null +++ b/src/incidents/incident-slice.ts @@ -0,0 +1,111 @@ +import { createSlice, PayloadAction } from '@reduxjs/toolkit' +import { AppThunk } from 'store' +import { isAfter } from 'date-fns' +import { isEmpty } from 'lodash' +import shortid from 'shortid' +import Incident from '../model/Incident' +import IncidentRepository from '../clients/db/IncidentRepository' + +interface Error { + date?: string + department?: string + category?: string + categoryItem?: string + description?: string +} + +interface IncidentState { + error?: Error + incident?: Incident + status: 'loading' | 'error' | 'completed' +} + +const initialState: IncidentState = { + error: undefined, + incident: undefined, + status: 'loading', +} + +function start(state: IncidentState) { + state.status = 'loading' +} + +function finish(state: IncidentState, { payload }: PayloadAction) { + state.status = 'completed' + state.incident = payload + state.error = undefined +} + +function error(state: IncidentState, { payload }: PayloadAction) { + state.status = 'error' + state.error = payload +} + +const incidentSlice = createSlice({ + name: 'incident', + initialState, + reducers: { + reportIncidentStart: start, + reportIncidentSuccess: finish, + reportIncidentError: error, + }, +}) + +export const { + reportIncidentStart, + reportIncidentSuccess, + reportIncidentError, +} = incidentSlice.actions + +function validateIncident(incident: Incident): Error { + const newError: Error = {} + + if (!incident.date) { + newError.date = 'incidents.reports.error.dateRequired' + } else if (isAfter(new Date(incident.date), new Date(Date.now()))) { + newError.date = 'incidents.reports.error.dateMustBeInThePast' + } + + if (!incident.department) { + newError.department = 'incidents.reports.error.departmentRequired' + } + + if (!incident.category) { + newError.category = 'incidents.reports.error.categoryRequired' + } + + if (!incident.categoryItem) { + newError.categoryItem = 'incidents.reports.error.categoryItemRequired' + } + + if (!incident.description) { + newError.description = 'incidents.reports.error.descriptionRequired' + } + + return newError +} + +const formatIncidentCode = (prefix: string, sequenceNumber: string) => `${prefix}${sequenceNumber}` +const getIncidentCode = (): string => formatIncidentCode('I-', shortid.generate()) + +export const reportIncident = ( + incident: Incident, + onSuccess?: (incident: Incident) => void, +): AppThunk => async (dispatch, getState) => { + dispatch(reportIncidentStart()) + const incidentError = validateIncident(incident) + if (isEmpty(incidentError)) { + incident.reportedOn = new Date(Date.now()).toISOString() + incident.code = getIncidentCode() + incident.reportedBy = getState().user.user.id + const newIncident = await IncidentRepository.save(incident) + await dispatch(reportIncidentSuccess(newIncident)) + if (onSuccess) { + onSuccess(newIncident) + } + } else { + dispatch(reportIncidentError(incidentError)) + } +} + +export default incidentSlice.reducer diff --git a/src/incidents/report/ReportIncident.tsx b/src/incidents/report/ReportIncident.tsx index 70f22c861a..a80b984af3 100644 --- a/src/incidents/report/ReportIncident.tsx +++ b/src/incidents/report/ReportIncident.tsx @@ -1,9 +1,20 @@ -import React from 'react' +import React, { useState } from 'react' import { useTranslation } from 'react-i18next' +import { Button, Row, Column } from '@hospitalrun/components' +import { useHistory } from 'react-router' +import { useDispatch, useSelector } from 'react-redux' import useTitle from '../../page-header/useTitle' import useAddBreadcrumbs from '../../breadcrumbs/useAddBreadcrumbs' +import DateTimePickerWithLabelFormGroup from '../../components/input/DateTimePickerWithLabelFormGroup' +import TextFieldWithLabelFormGroup from '../../components/input/TextFieldWithLabelFormGroup' +import TextInputWithLabelFormGroup from '../../components/input/TextInputWithLabelFormGroup' +import { reportIncident } from '../incident-slice' +import Incident from '../../model/Incident' +import { RootState } from '../../store' const ReportIncident = () => { + const dispatch = useDispatch() + const history = useHistory() const { t } = useTranslation() useTitle(t('incidents.reports.new')) const breadcrumbs = [ @@ -14,7 +25,122 @@ const ReportIncident = () => { ] useAddBreadcrumbs(breadcrumbs) - return

Report Incident

+ const { error } = useSelector((root: RootState) => root.incident) + const [incident, setIncident] = useState({ + date: new Date().toISOString(), + department: '', + category: '', + categoryItem: '', + description: '', + }) + + const onDateChange = (newDate: Date) => { + setIncident((prevState) => ({ + ...prevState, + date: newDate.toISOString(), + })) + } + + const onTextInputChange = (text: string, name: string) => { + setIncident((prevState) => ({ + ...prevState, + [name]: text, + })) + } + + const onSave = () => { + const onSuccess = (newIncident: Incident) => { + history.push(`/incidents/${newIncident.id}`) + } + + dispatch(reportIncident(incident as Incident, onSuccess)) + } + + const onCancel = () => { + history.push('/incidents') + } + + return ( +
+ + + + + + onTextInputChange(event.currentTarget.value, 'department')} + isInvalid={!!error?.department} + feedback={t(error?.department as string)} + /> + + + + + onTextInputChange(event.currentTarget.value, 'category')} + isInvalid={!!error?.category} + feedback={t(error?.category as string)} + /> + + + onTextInputChange(event.currentTarget.value, 'categoryItem')} + isInvalid={!!error?.categoryItem} + feedback={t(error?.categoryItem as string)} + /> + + + + + onTextInputChange(event.currentTarget.value, 'description')} + isInvalid={!!error?.description} + feedback={t(error?.description as string)} + /> + + + +
+
+ + +
+
+
+ ) } export default ReportIncident diff --git a/src/locales/enUs/translations/incidents/index.ts b/src/locales/enUs/translations/incidents/index.ts index 97cf559d13..c62b6897f9 100644 --- a/src/locales/enUs/translations/incidents/index.ts +++ b/src/locales/enUs/translations/incidents/index.ts @@ -1,10 +1,26 @@ export default { incidents: { label: 'Incidents', + actions: { + report: 'Report', + }, reports: { label: 'Reported Incidents', new: 'Report Incident', view: 'View Incident', + dateOfIncident: 'Date of Incident', + department: 'Department', + category: 'Category', + categoryItem: 'Category Item', + description: 'Description of Incident', + error: { + dateRequired: 'Date is required.', + dateMustBeInThePast: 'Date must be in the past.', + departmentRequired: 'Department is required.', + categoryRequired: 'Category is required', + categoryItemRequired: 'Category Item is required', + descriptionRequired: 'Description is required', + }, }, }, } diff --git a/src/model/Incident.ts b/src/model/Incident.ts new file mode 100644 index 0000000000..194949f63b --- /dev/null +++ b/src/model/Incident.ts @@ -0,0 +1,12 @@ +import AbstractDBModel from './AbstractDBModel' + +export default interface Incident extends AbstractDBModel { + reportedBy: string + reportedOn: string + code: string + date: string + department: string + category: string + categoryItem: string + description: string +} diff --git a/src/model/User.ts b/src/model/User.ts new file mode 100644 index 0000000000..5525ec917e --- /dev/null +++ b/src/model/User.ts @@ -0,0 +1,5 @@ +import Name from './Name' + +export default interface User extends Name { + id: string +} diff --git a/src/store/index.ts b/src/store/index.ts index 77ec4087cc..036746fdd5 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -7,6 +7,7 @@ import appointments from '../scheduling/appointments/appointments-slice' import title from '../page-header/title-slice' import user from '../user/user-slice' import lab from '../labs/lab-slice' +import incident from '../incidents/incident-slice' import breadcrumbs from '../breadcrumbs/breadcrumbs-slice' import components from '../components/component-slice' @@ -20,6 +21,7 @@ const reducer = combineReducers({ breadcrumbs, components, lab, + incident, }) const store = configureStore({ diff --git a/src/user/user-slice.ts b/src/user/user-slice.ts index 22af27f53e..acf7c27201 100644 --- a/src/user/user-slice.ts +++ b/src/user/user-slice.ts @@ -1,8 +1,10 @@ import { createSlice, PayloadAction } from '@reduxjs/toolkit' import Permissions from '../model/Permissions' +import User from '../model/User' interface UserState { permissions: Permissions[] + user: User } const initialState: UserState = { @@ -23,6 +25,11 @@ const initialState: UserState = { Permissions.ViewIncidents, Permissions.ReportIncident, ], + user: { + id: 'some-hardcoded-id', + givenName: 'HospitalRun', + familyName: 'Fake User', + } as User, } const userSlice = createSlice({