Passed
Push — feature/screen-candidates-emai... ( a0a58c...49e0ac )
by Yonathan
07:48 queued 04:01
created

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

Complexity

Total Complexity 3
Complexity/F 0

Size

Lines of Code 301
Function Count 0

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

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