Passed
Push — dev ( 40062f...b9fe17 )
by
unknown
05:00
created

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

Complexity

Total Complexity 3
Complexity/F 0

Size

Lines of Code 392
Function Count 0

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

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