Passed
Push — dev ( dabde6...94b2f2 )
by Tristan
06:43 queued 19s
created

resources/assets/js/store/Job/jobReducer.ts   A

Complexity

Total Complexity 2
Complexity/F 0

Size

Lines of Code 375
Function Count 0

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
wmc 2
eloc 292
c 0
b 0
f 0
dl 0
loc 375
rs 10
mnd 2
bc 2
fnc 0
bpm 0
cpm 0
noi 0
1
import { combineReducers } from "redux";
2
import {
3
  Job,
4
  Criteria,
5
  JobPosterKeyTask,
6
  Comment,
7
  JobPosterQuestion,
8
} from "../../models/types";
9
import {
10
  JobAction,
11
  FETCH_JOB_STARTED,
12
  FETCH_JOB_SUCCEEDED,
13
  FETCH_JOB_FAILED,
14
  UPDATE_JOB_SUCCEEDED,
15
  UPDATE_JOB_STARTED,
16
  UPDATE_JOB_FAILED,
17
  EDIT_JOB,
18
  CLEAR_JOB_EDIT,
19
  CREATE_JOB_SUCCEEDED,
20
  CREATE_JOB_STARTED,
21
  CREATE_JOB_FAILED,
22
  SET_SELECTED_JOB,
23
  FETCH_JOB_TASKS_SUCCEEDED,
24
  BATCH_UPDATE_JOB_TASKS_SUCCEEDED,
25
  FETCH_CRITERIA_SUCCEEDED,
26
  BATCH_UPDATE_CRITERIA_SUCCEEDED,
27
  SUBMIT_JOB_FOR_REVIEW_SUCCEEDED,
28
  SUBMIT_JOB_FOR_REVIEW_STARTED,
29
  SUBMIT_JOB_FOR_REVIEW_FAILED,
30
  FETCH_CRITERIA_STARTED,
31
  FETCH_CRITERIA_FAILED,
32
  BATCH_UPDATE_CRITERIA_FAILED,
33
  BATCH_UPDATE_CRITERIA_STARTED,
34
  FETCH_JOB_TASKS_STARTED,
35
  BATCH_UPDATE_JOB_TASKS_STARTED,
36
  FETCH_JOB_TASKS_FAILED,
37
  BATCH_UPDATE_JOB_TASKS_FAILED,
38
  CREATE_COMMENT_SUCCEEDED,
39
  FETCH_COMMENTS_SUCCEEDED,
40
  FETCH_JOB_INDEX_SUCCEEDED,
41
  FETCH_JOB_INDEX_STARTED,
42
  FETCH_JOB_INDEX_FAILED,
43
  FETCH_COMMENTS_STARTED,
44
  FETCH_COMMENTS_FAILED,
45
} from "./jobActions";
46
import {
47
  mapToObject,
48
  getId,
49
  deleteProperty,
50
  filterObjectProps,
51
} from "../../helpers/queries";
52
53
export interface EntityState {
54
  jobs: {
55
    byId: {
56
      [id: number]: Job;
57
    };
58
  };
59
  criteria: {
60
    byId: {
61
      [id: number]: Criteria;
62
    };
63
  };
64
  tasks: {
65
    byJobId: {
66
      [id: number]: JobPosterKeyTask[];
67
    };
68
  };
69
  comments: {
70
    byJobId: {
71
      [id: number]: Comment;
72
    };
73
  };
74
  jobEdits: {
75
    [id: number]: Job;
76
  };
77
  jobPosterQuestions: {
78
    byId: {
79
      [id: number]: JobPosterQuestion;
80
    };
81
  };
82
}
83
84
export interface UiState {
85
  jobUpdating: {
86
    [id: number]: boolean;
87
  };
88
  jobIndexUpdating: boolean;
89
  criteriaUpdating: {
90
    [id: number]: boolean;
91
  };
92
  criteriaUpdatingByJob: {
93
    [jobId: number]: boolean;
94
  };
95
  tasksUpdatingByJob: {
96
    [jobId: number]: boolean;
97
  };
98
  creatingJob: boolean;
99
  selectedJobId: number | null;
100
  fetchingComments: boolean;
101
}
102
103
export interface JobState {
104
  entities: EntityState;
105
  ui: UiState;
106
}
107
108
export const initEntities = (): EntityState => ({
109
  jobs: { byId: {} },
110
  criteria: { byId: {} },
111
  tasks: { byJobId: {} },
112
  comments: { byJobId: {} },
113
  jobEdits: {},
114
  jobPosterQuestions: { byId: {} },
115
});
116
117
export const initUi = (): UiState => ({
118
  jobUpdating: {},
119
  jobIndexUpdating: false,
120
  criteriaUpdating: {},
121
  criteriaUpdatingByJob: {},
122
  tasksUpdatingByJob: {},
123
  creatingJob: false,
124
  selectedJobId: null,
125
  fetchingComments: false,
126
});
127
128
export const initState = (): JobState => ({
129
  entities: initEntities(),
130
  ui: initUi(),
131
});
132
133
export const entitiesReducer = (
134
  state = initEntities(),
135
  action: JobAction,
136
): EntityState => {
137
  switch (action.type) {
138
    case FETCH_JOB_SUCCEEDED:
139
      return {
140
        ...state,
141
        jobs: {
142
          byId: {
143
            ...state.jobs.byId,
144
            [action.payload.job.id]: action.payload.job,
145
          },
146
        },
147
        criteria: {
148
          byId: {
149
            ...filterObjectProps<Criteria>(
150
              state.criteria.byId,
151
              (criteria): boolean => criteria.job_poster_id !== action.meta.id,
152
            ),
153
            ...mapToObject(action.payload.criteria, getId),
154
          },
155
        },
156
        jobPosterQuestions: {
157
          byId: {
158
            ...mapToObject(action.payload.jobPosterQuestions, getId),
159
          },
160
        },
161
      };
162
    case FETCH_JOB_INDEX_SUCCEEDED:
163
      return {
164
        ...state,
165
        jobs: {
166
          byId: {
167
            ...state.jobs.byId,
168
            ...mapToObject(action.payload.jobs, getId),
169
          },
170
        },
171
      };
172
    case CREATE_JOB_SUCCEEDED:
173
      return {
174
        ...state,
175
        jobs: {
176
          byId: {
177
            ...state.jobs.byId,
178
            [action.payload.id]: action.payload,
179
          },
180
        },
181
      };
182
    case UPDATE_JOB_SUCCEEDED:
183
    case SUBMIT_JOB_FOR_REVIEW_SUCCEEDED:
184
      return {
185
        ...state,
186
        jobs: {
187
          byId: {
188
            ...state.jobs.byId,
189
            [action.meta.id]: action.payload,
190
          },
191
        },
192
      };
193
    case EDIT_JOB:
194
      return {
195
        ...state,
196
        jobEdits: {
197
          ...state.jobEdits,
198
          [action.payload.id]: action.payload,
199
        },
200
      };
201
    case CLEAR_JOB_EDIT:
202
      return {
203
        ...state,
204
        jobEdits: deleteProperty(state.jobEdits, action.payload),
205
      };
206
    case FETCH_JOB_TASKS_SUCCEEDED:
207
    case BATCH_UPDATE_JOB_TASKS_SUCCEEDED:
208
      return {
209
        ...state,
210
        tasks: {
211
          byJobId: {
212
            ...state.tasks.byJobId,
213
            [action.meta.jobId]: action.payload,
214
          },
215
        },
216
      };
217
    case FETCH_CRITERIA_SUCCEEDED:
218
    case BATCH_UPDATE_CRITERIA_SUCCEEDED:
219
      return {
220
        ...state,
221
        criteria: {
222
          byId: {
223
            ...filterObjectProps<Criteria>(
224
              state.criteria.byId,
225
              (criteria): boolean =>
226
                criteria.job_poster_id !== action.meta.jobId,
227
            ),
228
            ...mapToObject(action.payload, getId),
229
          },
230
        },
231
      };
232
    case FETCH_COMMENTS_SUCCEEDED:
233
      return {
234
        ...state,
235
        comments: {
236
          byJobId: {
237
            ...state.comments.byJobId,
238
            ...mapToObject(action.payload, getId),
239
          },
240
        },
241
      };
242
    case CREATE_COMMENT_SUCCEEDED:
243
      return {
244
        ...state,
245
        comments: {
246
          byJobId: {
247
            ...state.comments.byJobId,
248
            [action.payload.id]: action.payload,
249
          },
250
        },
251
      };
252
    default:
253
      return state;
254
  }
255
};
256
257
export const uiReducer = (state = initUi(), action: JobAction): UiState => {
258
  switch (action.type) {
259
    case CREATE_JOB_STARTED:
260
      return {
261
        ...state,
262
        creatingJob: true,
263
      };
264
    case CREATE_JOB_SUCCEEDED:
265
      return {
266
        ...state,
267
        creatingJob: false,
268
      };
269
    case CREATE_JOB_FAILED:
270
      return {
271
        ...state,
272
        creatingJob: false,
273
      };
274
    case FETCH_JOB_STARTED:
275
    case UPDATE_JOB_STARTED:
276
    case SUBMIT_JOB_FOR_REVIEW_STARTED:
277
      return {
278
        ...state,
279
        jobUpdating: {
280
          ...state.jobUpdating,
281
          [action.meta.id]: true,
282
        },
283
      };
284
    case FETCH_JOB_INDEX_STARTED:
285
      return {
286
        ...state,
287
        jobIndexUpdating: true,
288
      };
289
    case FETCH_JOB_SUCCEEDED:
290
    case FETCH_JOB_FAILED:
291
    case UPDATE_JOB_FAILED:
292
    case UPDATE_JOB_SUCCEEDED:
293
    case SUBMIT_JOB_FOR_REVIEW_SUCCEEDED:
294
    case SUBMIT_JOB_FOR_REVIEW_FAILED:
295
      return {
296
        ...state,
297
        jobUpdating: {
298
          ...state.jobUpdating,
299
          [action.meta.id]: false,
300
        },
301
      };
302
    case FETCH_JOB_INDEX_SUCCEEDED:
303
    case FETCH_JOB_INDEX_FAILED:
304
      return {
305
        ...state,
306
        jobIndexUpdating: false,
307
      };
308
    case SET_SELECTED_JOB:
309
      return {
310
        ...state,
311
        selectedJobId: action.payload.jobId,
312
      };
313
    case FETCH_JOB_TASKS_STARTED:
314
    case BATCH_UPDATE_JOB_TASKS_STARTED:
315
      return {
316
        ...state,
317
        tasksUpdatingByJob: {
318
          ...state.tasksUpdatingByJob,
319
          [action.meta.jobId]: true,
320
        },
321
      };
322
    case FETCH_JOB_TASKS_FAILED:
323
    case FETCH_JOB_TASKS_SUCCEEDED:
324
    case BATCH_UPDATE_JOB_TASKS_FAILED:
325
    case BATCH_UPDATE_JOB_TASKS_SUCCEEDED:
326
      return {
327
        ...state,
328
        tasksUpdatingByJob: {
329
          ...state.tasksUpdatingByJob,
330
          [action.meta.jobId]: false,
331
        },
332
      };
333
    case FETCH_CRITERIA_STARTED:
334
    case BATCH_UPDATE_CRITERIA_STARTED:
335
      return {
336
        ...state,
337
        criteriaUpdatingByJob: {
338
          ...state.criteriaUpdatingByJob,
339
          [action.meta.jobId]: true,
340
        },
341
      };
342
    case FETCH_CRITERIA_FAILED:
343
    case FETCH_CRITERIA_SUCCEEDED:
344
    case BATCH_UPDATE_CRITERIA_FAILED:
345
    case BATCH_UPDATE_CRITERIA_SUCCEEDED:
346
      return {
347
        ...state,
348
        criteriaUpdatingByJob: {
349
          ...state.criteriaUpdatingByJob,
350
          [action.meta.jobId]: false,
351
        },
352
      };
353
    case FETCH_COMMENTS_STARTED:
354
      return {
355
        ...state,
356
        fetchingComments: true,
357
      };
358
    case FETCH_COMMENTS_SUCCEEDED:
359
    case FETCH_COMMENTS_FAILED:
360
      return {
361
        ...state,
362
        fetchingComments: false,
363
      };
364
    default:
365
      return state;
366
  }
367
};
368
369
export const jobsReducer = combineReducers({
370
  entities: entitiesReducer,
371
  ui: uiReducer,
372
});
373
374
export default jobsReducer;
375