Passed
Push — feature/experience-skills-api ( f678ab...a72ddc )
by Chris
09:19 queued 02:59
created

resources/assets/js/store/Experience/experienceSelector.ts   A

Complexity

Total Complexity 16
Complexity/F 2.29

Size

Lines of Code 201
Function Count 7

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
wmc 16
eloc 175
mnd 9
bc 9
fnc 7
dl 0
loc 201
rs 10
bpm 1.2857
cpm 2.2857
noi 0
c 0
b 0
f 0

7 Functions

Rating   Name   Duplication   Size   Complexity  
A experienceSelector.ts ➔ getExperienceTypeByApplicant 0 9 1
A experienceSelector.ts ➔ experienceByApplication 0 9 2
A experienceSelector.ts ➔ experienceByApplicant 0 9 2
A experienceSelector.ts ➔ getStateOfType 0 5 1
A experienceSelector.ts ➔ getExperienceTypeById 0 5 1
A experienceSelector.ts ➔ experienceById 0 6 2
A experienceSelector.ts ➔ getExperienceTypeByApplication 0 8 1
1
import { createSelector } from "reselect";
2
import createCachedSelector from "re-reselect";
3
import { RootState } from "../store";
4
import { EntityState, UiState, ExperienceSection } from "./experienceReducer";
5
import {
6
  ExperienceWork,
7
  ExperienceEducation,
8
  ExperienceCommunity,
9
  ExperienceAward,
10
  ExperiencePersonal,
11
  Experience,
12
} from "../../models/types";
13
import { notEmpty, hasKey } from "../../helpers/queries";
14
15
const entities = (state: RootState): EntityState => state.experience.entities;
16
const ui = (state: RootState): UiState => state.experience.ui;
17
18
interface ExperienceSet {
19
  work: ExperienceWork[];
20
  education: ExperienceEducation[];
21
  community: ExperienceCommunity[];
22
  award: ExperienceAward[];
23
  personal: ExperiencePersonal[];
24
}
25
26
const getWorkState = (state: RootState): ExperienceSection<ExperienceWork> =>
27
  entities(state).work;
28
const getEducationState = (
29
  state: RootState,
30
): ExperienceSection<ExperienceEducation> => entities(state).education;
31
const getCommunityState = (
32
  state: RootState,
33
): ExperienceSection<ExperienceCommunity> => entities(state).community;
34
const getAwardState = (state: RootState): ExperienceSection<ExperienceAward> =>
35
  entities(state).award;
36
const getPersonalState = (
37
  state: RootState,
38
): ExperienceSection<ExperiencePersonal> => entities(state).personal;
39
40
const stateByType = {
41
  work: getWorkState,
42
  education: getEducationState,
43
  community: getCommunityState,
44
  award: getAwardState,
45
  personal: getPersonalState,
46
};
47
48
function getStateOfType<T extends keyof typeof stateByType>(
49
  type: T,
50
): typeof stateByType[T] {
51
  return stateByType[type];
52
}
53
54
const extractId = (state: RootState, ownProps: { id: number }): number =>
55
  ownProps.id;
56
const extractApplicantId = (
57
  state: RootState,
58
  ownProps: { applicantId: number },
59
): number => ownProps.applicantId;
60
const extractApplicationId = (
61
  state: RootState,
62
  ownProps: { applicationId: number },
63
): number => ownProps.applicationId;
64
65
function experienceByApplicant<T>(
66
  experienceState: ExperienceSection<T>,
67
  applicantId: number,
68
): T[] {
69
  const idsForApplicant = experienceState.idsByApplicant[applicantId];
70
  return idsForApplicant
71
    ? idsForApplicant.map((id) => experienceState.byId[id]).filter(notEmpty)
72
    : [];
73
}
74
75
function experienceByApplication<T>(
76
  experienceState: ExperienceSection<T>,
77
  applicationId: number,
78
): T[] {
79
  const idsForApplication = experienceState.idsByApplication[applicationId];
80
  return idsForApplication
81
    ? idsForApplication.map((id) => experienceState.byId[id]).filter(notEmpty)
82
    : [];
83
}
84
85
function experienceById<T>(
86
  experienceState: ExperienceSection<T>,
87
  id: number,
88
): T | null {
89
  return hasKey(experienceState.byId, id) ? experienceState.byId[id] : null;
90
}
91
92
function getExperienceTypeByApplicant<T>(
93
  getState: (state: RootState) => ExperienceSection<T>,
94
) {
95
  return createCachedSelector(
96
    getState,
97
    extractApplicantId,
98
    experienceByApplicant,
99
  )(extractApplicantId);
100
}
101
function getExperienceTypeByApplication<T>(
102
  getState: (state: RootState) => ExperienceSection<T>,
103
) {
104
  return createCachedSelector(
105
    getState,
106
    extractApplicationId,
107
    experienceByApplication,
108
  )(extractApplicationId);
109
}
110
111
export const getWorkByApplicant = getExperienceTypeByApplicant(getWorkState);
112
export const getEducationByApplicant = getExperienceTypeByApplicant(
113
  getEducationState,
114
);
115
export const getCommunityByApplicant = getExperienceTypeByApplicant(
116
  getCommunityState,
117
);
118
export const getAwardByApplicant = getExperienceTypeByApplicant(getAwardState);
119
export const getPersonalByApplicant = getExperienceTypeByApplicant(
120
  getPersonalState,
121
);
122
123
export const getExperienceByApplicant = createSelector(
124
  getWorkByApplicant,
125
  getEducationByApplicant,
126
  getCommunityByApplicant,
127
  getAwardByApplicant,
128
  getPersonalByApplicant,
129
  (work, education, community, award, personal) => ({
130
    work,
131
    education,
132
    community,
133
    award,
134
    personal,
135
  }),
136
);
137
138
export const getWorkByApplication = getExperienceTypeByApplication(
139
  getWorkState,
140
);
141
export const getEducationByApplication = getExperienceTypeByApplication(
142
  getEducationState,
143
);
144
export const getCommunityByApplication = getExperienceTypeByApplication(
145
  getCommunityState,
146
);
147
export const getAwardByApplication = getExperienceTypeByApplication(
148
  getAwardState,
149
);
150
export const getPersonalByApplication = getExperienceTypeByApplication(
151
  getPersonalState,
152
);
153
154
export const getExperienceByApplication = createSelector(
155
  getWorkByApplication,
156
  getEducationByApplication,
157
  getCommunityByApplication,
158
  getAwardByApplication,
159
  getPersonalByApplication,
160
  (work, education, community, award, personal) => ({
161
    work,
162
    education,
163
    community,
164
    award,
165
    personal,
166
  }),
167
);
168
169
function getExperienceTypeById<T>(
170
  getState: (state: RootState) => ExperienceSection<T>,
171
) {
172
  return createCachedSelector(getState, extractId, experienceById)(extractId);
173
}
174
175
export const getWorkById = getExperienceTypeById(getWorkState);
176
export const getEducationById = getExperienceTypeById(getEducationState);
177
export const getCommunityById = getExperienceTypeById(getCommunityState);
178
export const getAwardById = getExperienceTypeById(getAwardState);
179
export const getPersonalById = getExperienceTypeById(getPersonalState);
180
181
export const getUpdatingByApplicant = (
182
  state: RootState,
183
  { applicantId }: { applicantId: number },
184
): boolean => {
185
  return ui(state).updatingByApplicant[applicantId] ?? false;
186
};
187
188
export const getUpdatingByApplication = (
189
  state: RootState,
190
  { applicationId }: { applicationId: number },
191
): boolean => {
192
  return ui(state).updatingByApplication[applicationId] ?? false;
193
};
194
195
export const getUpdatingByTypeAndId = (
196
  state: RootState,
197
  { id, type }: { id: number; type: keyof UiState["updatingByTypeAndId"] },
198
): boolean => {
199
  return ui(state).updatingByTypeAndId[type][id] ?? false;
200
};
201