Passed
Push — feature/response-screening ( dc9872...83ee0e )
by Tristan
04:25
created

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

Complexity

Total Complexity 3
Complexity/F 0

Size

Lines of Code 205
Function Count 0

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

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