Passed
Push — feature/micro-ref-email ( b987f2...6f6312 )
by Tristan
04:47
created

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

Complexity

Total Complexity 3
Complexity/F 0

Size

Lines of Code 211
Function Count 0

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
wmc 3
eloc 162
mnd 3
bc 3
fnc 0
dl 0
loc 211
rs 10
bpm 0
cpm 0
noi 0
c 0
b 0
f 0
1
import { ApplicationNormalized, ApplicationReview } from "../../models/types";
2
import {
3
  ApplicationAction,
4
  FETCH_APPLICATION_SUCCEEDED,
5
  FETCH_APPLICATION_FAILED,
6
  FETCH_APPLICATION_STARTED,
7
  FETCH_APPLICATIONS_FOR_JOB_SUCCEEDED,
8
  FETCH_APPLICATIONS_FOR_JOB_STARTED,
9
  FETCH_APPLICATIONS_FOR_JOB_FAILED,
10
  UPDATE_APPLICATION_REVIEW_SUCCEEDED,
11
  UPDATE_APPLICATION_REVIEW_STARTED,
12
  UPDATE_APPLICATION_REVIEW_FAILED,
13
} from "./applicationActions";
14
import { combineReducers } from "redux";
15
import {
16
  mapToObject,
17
  getId,
18
  notEmpty,
19
  mapToObjectTrans,
20
  deleteProperty,
21
} from "../../helpers/queries";
22
23
export interface EntityState {
24
  applications: {
25
    [id: number]: ApplicationNormalized;
26
  };
27
  applicationReviews: {
28
    byId: {
29
      [id: number]: ApplicationReview;
30
    };
31
    idByApplicationId: {
32
      [applicationId: number]: number;
33
    };
34
  };
35
}
36
37
export interface UiState {
38
  applicationIsUpdating: {
39
    [id: number]: boolean;
40
  };
41
  fetchingApplications: boolean;
42
}
43
44
export interface ApplicationState {
45
  entities: EntityState;
46
  ui: UiState;
47
}
48
49
export const initEntities = (): EntityState => ({
50
  applications: {},
51
  applicationReviews: {
52
    byId: {},
53
    idByApplicationId: {},
54
  },
55
});
56
57
export const initUi = (): UiState => ({
58
  applicationIsUpdating: {},
59
  fetchingApplications: false,
60
});
61
62
export const initApplicationState = (): ApplicationState => ({
63
  entities: initEntities(),
64
  ui: initUi(),
65
});
66
67
export const entitiesReducer = (
68
  state = initEntities(),
69
  action: ApplicationAction,
70
): EntityState => {
71
  switch (action.type) {
72
    case FETCH_APPLICATION_SUCCEEDED:
73
      return {
74
        ...state,
75
        applications: {
76
          ...state.applications,
77
          [action.payload.id]: deleteProperty(
78
            action.payload,
79
            "application_review",
80
          ),
81
        },
82
        applicationReviews:
83
          action.payload.application_review !== undefined
84
            ? {
85
                byId: {
86
                  ...state.applicationReviews.byId,
87
                  [action.payload.application_review.id]:
88
                    action.payload.application_review,
89
                },
90
                idByApplicationId: {
91
                  ...state.applicationReviews.idByApplicationId,
92
                  [action.payload.id]: action.payload.application_review.id,
93
                },
94
              }
95
            : state.applicationReviews,
96
      };
97
    case FETCH_APPLICATIONS_FOR_JOB_SUCCEEDED:
98
      return {
99
        ...state,
100
        applications: {
101
          ...state.applications,
102
          ...mapToObjectTrans(
103
            action.payload,
104
            getId,
105
            (application): ApplicationNormalized =>
106
              deleteProperty(application, "application_review"),
107
          ),
108
        },
109
        applicationReviews: {
110
          byId: {
111
            ...state.applicationReviews.byId,
112
            ...mapToObject(
113
              action.payload
114
                .map((application) => application.application_review)
115
                .filter(notEmpty),
116
              getId,
117
            ),
118
          },
119
          idByApplicationId: {
120
            ...state.applicationReviews.idByApplicationId,
121
            ...mapToObjectTrans(
122
              action.payload
123
                .map((application) => application.application_review)
124
                .filter(notEmpty),
125
              (review) => review.job_application_id,
126
              (review) => review.id,
127
            ),
128
          },
129
        },
130
      };
131
    case UPDATE_APPLICATION_REVIEW_SUCCEEDED:
132
      return {
133
        ...state,
134
        applicationReviews: {
135
          byId: {
136
            ...state.applicationReviews.byId,
137
            [action.payload.id]: action.payload,
138
          },
139
          idByApplicationId: {
140
            ...state.applicationReviews.idByApplicationId,
141
            [action.payload.job_application_id]: action.payload.id,
142
          },
143
        },
144
      };
145
    default:
146
      return state;
147
  }
148
};
149
150
export const uiReducer = (
151
  state = initUi(),
152
  action: ApplicationAction,
153
): UiState => {
154
  switch (action.type) {
155
    case FETCH_APPLICATION_STARTED:
156
      return {
157
        ...state,
158
        applicationIsUpdating: {
159
          ...state.applicationIsUpdating,
160
          [action.meta.id]: true,
161
        },
162
      };
163
    case FETCH_APPLICATION_SUCCEEDED:
164
    case FETCH_APPLICATION_FAILED:
165
      return {
166
        ...state,
167
        applicationIsUpdating: {
168
          ...state.applicationIsUpdating,
169
          [action.meta.id]: false,
170
        },
171
      };
172
    case FETCH_APPLICATIONS_FOR_JOB_STARTED:
173
      return {
174
        ...state,
175
        fetchingApplications: true,
176
      };
177
    case FETCH_APPLICATIONS_FOR_JOB_SUCCEEDED:
178
    case FETCH_APPLICATIONS_FOR_JOB_FAILED:
179
      return {
180
        ...state,
181
        fetchingApplications: false,
182
      };
183
    case UPDATE_APPLICATION_REVIEW_STARTED:
184
      return {
185
        ...state,
186
        applicationIsUpdating: {
187
          ...state.applicationIsUpdating,
188
          [action.meta.applicationId]: true,
189
        },
190
      };
191
    case UPDATE_APPLICATION_REVIEW_SUCCEEDED:
192
    case UPDATE_APPLICATION_REVIEW_FAILED:
193
      return {
194
        ...state,
195
        applicationIsUpdating: {
196
          ...state.applicationIsUpdating,
197
          [action.meta.applicationId]: false,
198
        },
199
      };
200
    default:
201
      return state;
202
  }
203
};
204
205
export const applicationReducer = combineReducers({
206
  entities: entitiesReducer,
207
  ui: uiReducer,
208
});
209
210
export default applicationReducer;
211