Passed
Push — feature/timeline-profile-page ( c237ae...94fe7b )
by Tristan
04:01
created

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

Complexity

Total Complexity 3
Complexity/F 0

Size

Lines of Code 350
Function Count 0

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

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