This repository has been archived by the owner on Jan 9, 2023. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(incidents): adds ability to view all incidents
- Loading branch information
1 parent
da2ea77
commit f11d8e9
Showing
7 changed files
with
202 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import createMockStore from 'redux-mock-store' | ||
import thunk from 'redux-thunk' | ||
import { AnyAction } from 'redux' | ||
import { RootState } from '../../store' | ||
import incidents, { | ||
fetchIncidents, | ||
fetchIncidentsStart, | ||
fetchIncidentsSuccess, | ||
} from '../../incidents/incidents-slice' | ||
import IncidentRepository from '../../clients/db/IncidentRepository' | ||
import Incident from '../../model/Incident' | ||
|
||
const mockStore = createMockStore<RootState, any>([thunk]) | ||
|
||
describe('Incidents Slice', () => { | ||
describe('actions', () => { | ||
it('should setup the default state correctly', () => { | ||
const incidentsStore = incidents(undefined, {} as AnyAction) | ||
expect(incidentsStore.status).toEqual('loading') | ||
expect(incidentsStore.incidents).toEqual([]) | ||
}) | ||
|
||
it('should handle fetch incidents start', () => { | ||
const incidentsStore = incidents(undefined, fetchIncidentsStart()) | ||
expect(incidentsStore.status).toEqual('loading') | ||
}) | ||
|
||
it('should handle fetch incidents success', () => { | ||
const expectedIncidents = [{ id: '123' }] as Incident[] | ||
const incidentsStore = incidents(undefined, fetchIncidentsSuccess(expectedIncidents)) | ||
expect(incidentsStore.status).toEqual('completed') | ||
expect(incidentsStore.incidents).toEqual(expectedIncidents) | ||
}) | ||
|
||
describe('fetch incidents', () => { | ||
it('should fetch all of the incidents', async () => { | ||
const expectedIncidents = [{ id: '123' }] as Incident[] | ||
jest.spyOn(IncidentRepository, 'findAll').mockResolvedValue(expectedIncidents) | ||
const store = mockStore() | ||
|
||
await store.dispatch(fetchIncidents()) | ||
|
||
expect(store.getActions()[0]).toEqual(fetchIncidentsStart()) | ||
expect(IncidentRepository.findAll).toHaveBeenCalledTimes(1) | ||
expect(store.getActions()[1]).toEqual(fetchIncidentsSuccess(expectedIncidents)) | ||
}) | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import { createSlice, PayloadAction } from '@reduxjs/toolkit' | ||
import { AppThunk } from 'store' | ||
import Incident from '../model/Incident' | ||
import IncidentRepository from '../clients/db/IncidentRepository' | ||
|
||
interface IncidentsState { | ||
incidents: Incident[] | ||
status: 'loading' | 'completed' | ||
} | ||
|
||
const initialState: IncidentsState = { | ||
incidents: [], | ||
status: 'loading', | ||
} | ||
|
||
function start(state: IncidentsState) { | ||
state.status = 'loading' | ||
} | ||
|
||
function finish(state: IncidentsState, { payload }: PayloadAction<Incident[]>) { | ||
state.status = 'completed' | ||
state.incidents = payload | ||
} | ||
|
||
const incidentSlice = createSlice({ | ||
name: 'lab', | ||
initialState, | ||
reducers: { | ||
fetchIncidentsStart: start, | ||
fetchIncidentsSuccess: finish, | ||
}, | ||
}) | ||
|
||
export const { fetchIncidentsStart, fetchIncidentsSuccess } = incidentSlice.actions | ||
|
||
export const fetchIncidents = (): AppThunk => async (dispatch) => { | ||
dispatch(fetchIncidentsStart()) | ||
|
||
const incidents = await IncidentRepository.findAll() | ||
|
||
dispatch(fetchIncidentsSuccess(incidents)) | ||
} | ||
|
||
export default incidentSlice.reducer |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,53 @@ | ||
import React from 'react' | ||
import React, { useEffect } from 'react' | ||
import { useTranslation } from 'react-i18next' | ||
import { useDispatch, useSelector } from 'react-redux' | ||
import format from 'date-fns/format' | ||
import { useHistory } from 'react-router' | ||
import useTitle from '../../page-header/useTitle' | ||
import { RootState } from '../../store' | ||
import { fetchIncidents } from '../incidents-slice' | ||
import Incident from '../../model/Incident' | ||
|
||
const ViewIncidents = () => { | ||
const { t } = useTranslation() | ||
const history = useHistory() | ||
const dispatch = useDispatch() | ||
useTitle(t('incidents.reports.label')) | ||
|
||
return <h1>Reported Incidents</h1> | ||
const { incidents } = useSelector((state: RootState) => state.incidents) | ||
|
||
useEffect(() => { | ||
dispatch(fetchIncidents()) | ||
}, [dispatch]) | ||
|
||
const onTableRowClick = (incident: Incident) => { | ||
history.push(`incidents/${incident.id}`) | ||
} | ||
|
||
return ( | ||
<table className="table table-hover"> | ||
<thead className="thead-light"> | ||
<tr> | ||
<th>{t('incidents.reports.code')}</th> | ||
<th>{t('incidents.reports.dateOfIncident')}</th> | ||
<th>{t('incidents.reports.reportedBy')}</th> | ||
<th>{t('incidents.reports.reportedOn')}</th> | ||
<th>{t('incidents.reports.status')}</th> | ||
</tr> | ||
</thead> | ||
<tbody> | ||
{incidents.map((incident: Incident) => ( | ||
<tr onClick={() => onTableRowClick(incident)} key={incident.id}> | ||
<td>{incident.code}</td> | ||
<td>{format(new Date(incident.date), 'yyyy-MM-dd hh:mm a')}</td> | ||
<td>{incident.reportedBy}</td> | ||
<td>{format(new Date(incident.reportedOn), 'yyyy-MM-dd hh:mm a')}</td> | ||
<td>{incident.status}</td> | ||
</tr> | ||
))} | ||
</tbody> | ||
</table> | ||
) | ||
} | ||
|
||
export default ViewIncidents |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters