Passed
Push — dev ( af6b45...e39771 )
by
unknown
05:12
created

resources/assets/js/store/Application/applicationReducer.ts   A

Complexity

Total Complexity 3
Complexity/F 0

Size

Lines of Code 418
Function Count 0

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
wmc 3
eloc 323
mnd 3
bc 3
fnc 0
dl 0
loc 418
rs 10
bpm 0
cpm 0
noi 0
c 0
b 0
f 0
1
import { combineReducers } from "redux";
2
import {
3
  ApplicationNormalized,
4
  ApplicationReview,
5
  Email,
6
  JobApplicationAnswer,
7
} from "../../models/types";
8
import {
9
  ApplicationAction,
10
  FETCH_APPLICATION_SUCCEEDED,
11
  FETCH_APPLICATION_FAILED,
12
  FETCH_APPLICATION_STARTED,
13
  FETCH_APPLICATIONS_FOR_JOB_SUCCEEDED,
14
  FETCH_APPLICATIONS_FOR_JOB_STARTED,
15
  FETCH_APPLICATIONS_FOR_JOB_FAILED,
16
  UPDATE_APPLICATION_SUCCEEDED,
17
  UPDATE_APPLICATION_STARTED,
18
  UPDATE_APPLICATION_FAILED,
19
  UPDATE_APPLICATION_REVIEW_SUCCEEDED,
20
  UPDATE_APPLICATION_REVIEW_STARTED,
21
  UPDATE_APPLICATION_REVIEW_FAILED,
22
  BATCH_UPDATE_APPLICATION_REVIEWS_SUCCEEDED,
23
  FETCH_REFERENCE_EMAILS_SUCCEEDED,
24
  FETCH_REFERENCE_EMAILS_STARTED,
25
  FETCH_REFERENCE_EMAILS_FAILED,
26
  SEND_REFERENCE_EMAIL_STARTED,
27
  SEND_REFERENCE_EMAIL_SUCCEEDED,
28
  SEND_REFERENCE_EMAIL_FAILED,
29
  TOUCH_JOB_APPLICATION_STEP_SUCCEEDED,
30
  TOUCH_JOB_APPLICATION_STEP_STARTED,
31
  TOUCH_JOB_APPLICATION_STEP_FAILED,
32
  SUBMIT_APPLICATION_SUCCEEDED,
33
} from "./applicationActions";
34
import {
35
  mapToObject,
36
  getId,
37
  notEmpty,
38
  mapToObjectTrans,
39
  deleteProperty,
40
} from "../../helpers/queries";
41
import {
42
  CREATE_JOB_APPLICATION_ANSWER_SUCCEEDED,
43
  UPDATE_JOB_APPLICATION_ANSWER_SUCCEEDED,
44
} from "../JobApplicationAnswer/jobApplicationAnswerActions";
45
import {
46
  ApplicationStep,
47
  ProgressBarStatus,
48
} from "../../models/lookupConstants";
49
50
export interface EntityState {
51
  applications: {
52
    [id: number]: ApplicationNormalized;
53
  };
54
  jobApplicationAnswers: {
55
    [id: number]: JobApplicationAnswer;
56
  };
57
  jobApplicationSteps: { [step in ApplicationStep]: ProgressBarStatus };
58
  applicationReviews: {
59
    byId: {
60
      [id: number]: ApplicationReview;
61
    };
62
    idByApplicationId: {
63
      [applicationId: number]: number;
64
    };
65
  };
66
  microReferenceEmails: {
67
    director: {
68
      byApplicationId: {
69
        [applicationId: number]: Email;
70
      };
71
    };
72
    secondary: {
73
      byApplicationId: {
74
        [applicationId: number]: Email;
75
      };
76
    };
77
  };
78
}
79
80
export interface UiState {
81
  applicationIsUpdating: {
82
    [id: number]: boolean;
83
  };
84
  fetchingApplications: boolean;
85
  fetchingReferenceEmailsForApplication: {
86
    [applicationId: number]: boolean;
87
  };
88
  sendingReferenceEmailForApplication: {
89
    [applicationId: number]: boolean;
90
  };
91
  updatingSteps: boolean;
92
}
93
94
export interface ApplicationState {
95
  entities: EntityState;
96
  ui: UiState;
97
}
98
99
export const initEntities = (): EntityState => ({
100
  applications: {},
101
  jobApplicationAnswers: {},
102
  jobApplicationSteps: {
103
    basic: "default",
104
    experience: "default",
105
    skills: "default",
106
    fit: "default",
107
    review: "default",
108
    submission: "default",
109
  },
110
  applicationReviews: {
111
    byId: {},
112
    idByApplicationId: {},
113
  },
114
  microReferenceEmails: {
115
    director: {
116
      byApplicationId: {},
117
    },
118
    secondary: {
119
      byApplicationId: {},
120
    },
121
  },
122
});
123
124
export const initUi = (): UiState => ({
125
  applicationIsUpdating: {},
126
  fetchingApplications: false,
127
  fetchingReferenceEmailsForApplication: {},
128
  sendingReferenceEmailForApplication: {},
129
  updatingSteps: false,
130
});
131
132
export const initApplicationState = (): ApplicationState => ({
133
  entities: initEntities(),
134
  ui: initUi(),
135
});
136
137
export const entitiesReducer = (
138
  state = initEntities(),
139
  action: ApplicationAction,
140
): EntityState => {
141
  switch (action.type) {
142
    case FETCH_APPLICATION_SUCCEEDED:
143
      return {
144
        ...state,
145
        applications: {
146
          ...state.applications,
147
          [action.payload.application.id]: deleteProperty(
148
            action.payload.application,
149
            "application_review",
150
          ),
151
        },
152
        applicationReviews: action.payload.application.application_review
153
          ? {
154
              byId: {
155
                ...state.applicationReviews.byId,
156
                [action.payload.application.application_review.id]:
157
                  action.payload.application.application_review,
158
              },
159
              idByApplicationId: {
160
                ...state.applicationReviews.idByApplicationId,
161
                [action.payload.application.id]:
162
                  action.payload.application.application_review.id,
163
              },
164
            }
165
          : state.applicationReviews,
166
        jobApplicationAnswers: {
167
          ...mapToObject(action.payload.jobApplicationAnswers, getId),
168
        },
169
        jobApplicationSteps: action.payload.jobApplicationSteps,
170
      };
171
    case FETCH_APPLICATIONS_FOR_JOB_SUCCEEDED:
172
      return {
173
        ...state,
174
        applications: {
175
          ...state.applications,
176
          ...mapToObjectTrans(
177
            action.payload,
178
            getId,
179
            (application): ApplicationNormalized =>
180
              deleteProperty(application, "application_review"),
181
          ),
182
        },
183
        applicationReviews: {
184
          byId: {
185
            ...state.applicationReviews.byId,
186
            ...mapToObject(
187
              action.payload
188
                .map((application) => application.application_review)
189
                .filter(notEmpty),
190
              getId,
191
            ),
192
          },
193
          idByApplicationId: {
194
            ...state.applicationReviews.idByApplicationId,
195
            ...mapToObjectTrans(
196
              action.payload
197
                .map((application) => application.application_review)
198
                .filter(notEmpty),
199
              (review) => review.job_application_id,
200
              (review) => review.id,
201
            ),
202
          },
203
        },
204
      };
205
    case UPDATE_APPLICATION_SUCCEEDED:
206
    case SUBMIT_APPLICATION_SUCCEEDED:
207
      return {
208
        ...state,
209
        applications: {
210
          ...state.applications,
211
          [action.payload.id]: {
212
            ...state.applications[action.payload.id],
213
            ...action.payload,
214
          },
215
        },
216
      };
217
    case UPDATE_APPLICATION_REVIEW_SUCCEEDED:
218
      return {
219
        ...state,
220
        applicationReviews: {
221
          byId: {
222
            ...state.applicationReviews.byId,
223
            [action.payload.id]: action.payload,
224
          },
225
          idByApplicationId: {
226
            ...state.applicationReviews.idByApplicationId,
227
            [action.payload.job_application_id]: action.payload.id,
228
          },
229
        },
230
      };
231
    case BATCH_UPDATE_APPLICATION_REVIEWS_SUCCEEDED:
232
      return {
233
        ...state,
234
        applicationReviews: {
235
          byId: {
236
            ...state.applicationReviews.byId,
237
            ...mapToObjectTrans(
238
              action.payload,
239
              getId,
240
              (applicationReview => applicationReview),
241
            ),
242
          },
243
          idByApplicationId: {
244
            ...state.applicationReviews.idByApplicationId,
245
            ...mapToObjectTrans(
246
              action.payload,
247
              (applicationReview => applicationReview.job_application_id),
248
              getId,
249
            ),
250
          }
251
        },
252
      };
253
    case FETCH_REFERENCE_EMAILS_SUCCEEDED:
254
      return {
255
        ...state,
256
        microReferenceEmails: {
257
          director: {
258
            byApplicationId: {
259
              ...state.microReferenceEmails.director.byApplicationId,
260
              [action.meta.applicationId]: action.payload.director,
261
            },
262
          },
263
          secondary: {
264
            byApplicationId: {
265
              ...state.microReferenceEmails.secondary.byApplicationId,
266
              [action.meta.applicationId]: action.payload.secondary,
267
            },
268
          },
269
        },
270
      };
271
    case CREATE_JOB_APPLICATION_ANSWER_SUCCEEDED:
272
    case UPDATE_JOB_APPLICATION_ANSWER_SUCCEEDED:
273
      return {
274
        ...state,
275
        jobApplicationAnswers: {
276
          ...state.jobApplicationAnswers,
277
          [action.payload.id]: action.payload,
278
        },
279
      };
280
    case TOUCH_JOB_APPLICATION_STEP_SUCCEEDED:
281
      return {
282
        ...state,
283
        jobApplicationSteps: {
284
          ...state.jobApplicationSteps,
285
          ...action.payload,
286
        },
287
      };
288
    default:
289
      return state;
290
  }
291
};
292
293
export const uiReducer = (
294
  state = initUi(),
295
  action: ApplicationAction,
296
): UiState => {
297
  switch (action.type) {
298
    case FETCH_APPLICATION_STARTED:
299
      return {
300
        ...state,
301
        applicationIsUpdating: {
302
          ...state.applicationIsUpdating,
303
          [action.meta.id]: true,
304
        },
305
        updatingSteps: true,
306
      };
307
    case FETCH_APPLICATION_SUCCEEDED:
308
    case FETCH_APPLICATION_FAILED:
309
      return {
310
        ...state,
311
        applicationIsUpdating: {
312
          ...state.applicationIsUpdating,
313
          [action.meta.id]: false,
314
        },
315
        updatingSteps: false,
316
      };
317
    case FETCH_APPLICATIONS_FOR_JOB_STARTED:
318
      return {
319
        ...state,
320
        fetchingApplications: true,
321
      };
322
    case FETCH_APPLICATIONS_FOR_JOB_SUCCEEDED:
323
    case FETCH_APPLICATIONS_FOR_JOB_FAILED:
324
      return {
325
        ...state,
326
        fetchingApplications: false,
327
      };
328
    case UPDATE_APPLICATION_STARTED:
329
      return {
330
        ...state,
331
        applicationIsUpdating: {
332
          ...state.applicationIsUpdating,
333
          [action.meta.id]: true,
334
        },
335
      };
336
    case UPDATE_APPLICATION_SUCCEEDED:
337
    case UPDATE_APPLICATION_FAILED:
338
      return {
339
        ...state,
340
        applicationIsUpdating: {
341
          ...state.applicationIsUpdating,
342
          [action.meta.id]: false,
343
        },
344
      };
345
    case UPDATE_APPLICATION_REVIEW_STARTED:
346
      return {
347
        ...state,
348
        applicationIsUpdating: {
349
          ...state.applicationIsUpdating,
350
          [action.meta.applicationId]: true,
351
        },
352
      };
353
    case UPDATE_APPLICATION_REVIEW_SUCCEEDED:
354
    case UPDATE_APPLICATION_REVIEW_FAILED:
355
      return {
356
        ...state,
357
        applicationIsUpdating: {
358
          ...state.applicationIsUpdating,
359
          [action.meta.applicationId]: false,
360
        },
361
      };
362
    case FETCH_REFERENCE_EMAILS_STARTED:
363
      return {
364
        ...state,
365
        fetchingReferenceEmailsForApplication: {
366
          ...state.fetchingReferenceEmailsForApplication,
367
          [action.meta.applicationId]: true,
368
        },
369
      };
370
    case FETCH_REFERENCE_EMAILS_SUCCEEDED:
371
    case FETCH_REFERENCE_EMAILS_FAILED:
372
      return {
373
        ...state,
374
        fetchingReferenceEmailsForApplication: {
375
          ...state.fetchingReferenceEmailsForApplication,
376
          [action.meta.applicationId]: false,
377
        },
378
      };
379
    case SEND_REFERENCE_EMAIL_STARTED:
380
      return {
381
        ...state,
382
        sendingReferenceEmailForApplication: {
383
          ...state.sendingReferenceEmailForApplication,
384
          [action.meta.applicationId]: true,
385
        },
386
      };
387
    case SEND_REFERENCE_EMAIL_SUCCEEDED:
388
    case SEND_REFERENCE_EMAIL_FAILED:
389
      return {
390
        ...state,
391
        sendingReferenceEmailForApplication: {
392
          ...state.sendingReferenceEmailForApplication,
393
          [action.meta.applicationId]: false,
394
        },
395
      };
396
    case TOUCH_JOB_APPLICATION_STEP_STARTED:
397
      return {
398
        ...state,
399
        updatingSteps: true,
400
      };
401
    case TOUCH_JOB_APPLICATION_STEP_SUCCEEDED:
402
    case TOUCH_JOB_APPLICATION_STEP_FAILED:
403
      return {
404
        ...state,
405
        updatingSteps: false,
406
      };
407
    default:
408
      return state;
409
  }
410
};
411
412
export const applicationReducer = combineReducers({
413
  entities: entitiesReducer,
414
  ui: uiReducer,
415
});
416
417
export default applicationReducer;
418