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
/
incident-slice.ts
122 lines (103 loc) · 3.22 KB
/
incident-slice.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
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<Incident>) {
state.status = 'completed'
state.incident = payload
state.error = undefined
}
function error(state: IncidentState, { payload }: PayloadAction<Error>) {
state.status = 'error'
state.error = payload
}
const incidentSlice = createSlice({
name: 'incident',
initialState,
reducers: {
fetchIncidentStart: start,
fetchIncidentSuccess: finish,
reportIncidentStart: start,
reportIncidentSuccess: finish,
reportIncidentError: error,
},
})
export const {
fetchIncidentStart,
fetchIncidentSuccess,
reportIncidentStart,
reportIncidentSuccess,
reportIncidentError,
} = incidentSlice.actions
export const fetchIncident = (id: string): AppThunk => async (dispatch) => {
dispatch(fetchIncidentStart())
const incident = await IncidentRepository.find(id)
dispatch(fetchIncidentSuccess(incident))
}
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
incident.status = 'reported'
const newIncident = await IncidentRepository.save(incident)
await dispatch(reportIncidentSuccess(newIncident))
if (onSuccess) {
onSuccess(newIncident)
}
} else {
dispatch(reportIncidentError(incidentError))
}
}
export default incidentSlice.reducer