Cancelled
Push — feature/application-basic-info... ( 98c9e5...88f9a8 )
by Tristan
05:35 queued 01:32
created

resources/assets/js/store/Assessment/assessmentSelector.ts   A

Complexity

Total Complexity 9
Complexity/F 0

Size

Lines of Code 213
Function Count 0

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 186
dl 0
loc 213
rs 10
c 0
b 0
f 0
wmc 9
mnd 9
bc 9
fnc 0
bpm 0
cpm 0
noi 0
1
import isEqual from "lodash/isEqual";
2
import { createSelector } from "reselect";
3
import createCachedSelector from "re-reselect";
4
import { RootState } from "../store";
5
import { Assessment, TempAssessment } from "../../models/types";
6
import { getId, hasKey, mapToObjectTrans } from "../../helpers/queries";
7
import { AssessmentState } from "./assessmentReducer";
8
import { deepEqualSelectorOptions } from "../cachedSelectors";
9
10
const stateSlice = (state: RootState): AssessmentState => state.assessment;
11
12
const getCanonAssessmentState = (
13
  state: RootState,
14
): { [id: number]: Assessment } => stateSlice(state).assessments;
15
16
const getEditedAssessmentState = (
17
  state: RootState,
18
): { [id: number]: Assessment } => stateSlice(state).editedAssessments;
19
20
const getTempAssessmentState = (
21
  state: RootState,
22
): { [id: number]: TempAssessment } => stateSlice(state).tempAssessments;
23
24
const getAssessmentDeletes = (state: RootState): { [id: number]: number } =>
25
  stateSlice(state).assessmentDeletes;
26
27
const getTempSavingState = (state: RootState): { [id: number]: boolean } =>
28
  stateSlice(state).tempAssessmentSaving;
29
30
const getAssessmentUpdatingState = (
31
  state: RootState,
32
): { [id: number]: number } => stateSlice(state).assessmentUpdates;
33
34
const getCurrentAssessmentState = createSelector(
35
  getCanonAssessmentState,
36
  getEditedAssessmentState,
37
  (canon, edited): { [id: number]: Assessment } => ({
38
    ...canon,
39
    ...edited,
40
  }),
41
);
42
43
/**
44
 * Returns current verisons of all assessments.
45
 * ie edited version if possible,
46
 * and not including those undergoing delete requests
47
 */
48
export const getCurrentAssessments = createSelector(
49
  getCurrentAssessmentState,
50
  getAssessmentDeletes,
51
  (currentAssessments, deleteCount): Assessment[] =>
52
    Object.values(currentAssessments).filter(
53
      (assessment): boolean =>
54
        !hasKey(deleteCount, assessment.id) || deleteCount[assessment.id] <= 0,
55
    ),
56
);
57
58
export const getTempAssessments = createSelector(
59
  getTempAssessmentState,
60
  (assessmentState): TempAssessment[] => Object.values(assessmentState),
61
);
62
63
/**
64
 * Returns current verisons of all assessments.
65
 * ie edited version if possible,
66
 * and not including those undergoing delete requests
67
 */
68
export const getAssessmentsByCriterion = createCachedSelector(
69
  getCurrentAssessments,
70
  (state: RootState, props: { criterionId: number }): number =>
71
    props.criterionId,
72
  (assessments, criterionId): Assessment[] =>
73
    assessments.filter(
74
      (assessment): boolean => assessment.criterion_id === criterionId,
75
    ),
76
)((state, props): number => props.criterionId);
77
78
export const getCachedAssessmentsByCriterion = createCachedSelector(
79
  getAssessmentsByCriterion,
80
  (assessments): Assessment[] => assessments,
81
)((state, props): number => props.criterionId, deepEqualSelectorOptions);
82
83
export const getAssessmentIdsByCriterion = createCachedSelector(
84
  getAssessmentsByCriterion,
85
  (assessments): number[] => assessments.map(getId),
86
)((state, props): number => props.criterionId);
87
88
export const getTempAssessmentsByCriterion = createCachedSelector(
89
  getTempAssessments,
90
  (state: RootState, props: { criterionId: number }): number =>
91
    props.criterionId,
92
  (assessments, criterionId): TempAssessment[] =>
93
    assessments.filter(
94
      (assessment): boolean => assessment.criterion_id === criterionId,
95
    ),
96
)((state, props): number => props.criterionId);
97
98
export const getTempAssessmentIdsByCriterion = createCachedSelector(
99
  getTempAssessmentsByCriterion,
100
  (assessments): number[] => assessments.map(getId),
101
)((state, props): number => props.criterionId);
102
103
export const tempAssessmentIsSaving = (state: RootState, id: number): boolean =>
104
  hasKey(stateSlice(state).tempAssessmentSaving, id)
105
    ? stateSlice(state).tempAssessmentSaving[id]
106
    : false;
107
108
export const tempAssessmentsAreSavingByCriterion = createCachedSelector(
109
  getTempAssessmentIdsByCriterion,
110
  getTempSavingState,
111
  (assessmentIds, savingState): { [id: number]: boolean } =>
112
    mapToObjectTrans(
113
      assessmentIds,
114
      (id): number => id,
115
      (assessmentId): boolean =>
116
        hasKey(savingState, assessmentId) ? savingState[assessmentId] : false,
117
    ),
118
)((state, props): number => props.criterionId);
119
120
/** Returns current (ie edited, if possible) verisons of assessment */
121
export const getAssessmentById = createCachedSelector(
122
  getCurrentAssessmentState,
123
  (state: RootState, props: { assessmentId: number }): number =>
124
    props.assessmentId,
125
  (assessments, assessmentId): Assessment | null =>
126
    hasKey(assessments, assessmentId) ? assessments[assessmentId] : null,
127
)((state, props): number => props.assessmentId);
128
129
export const getCanonAssessmentById = createCachedSelector(
130
  getCanonAssessmentState,
131
  (state: RootState, props: { assessmentId: number }): number =>
132
    props.assessmentId,
133
  (assessments, assessmentId): Assessment | null =>
134
    hasKey(assessments, assessmentId) ? assessments[assessmentId] : null,
135
)((state, props): number => props.assessmentId);
136
137
/** NOTE: this will return assessments assocaited with multiple jobs! */
138
export const getAssessmentsByType = createCachedSelector(
139
  getCurrentAssessments,
140
  (state: RootState, props: { assessmentTypeId: number }): number =>
141
    props.assessmentTypeId,
142
  (assessments, assessmentTypeId): Assessment[] =>
143
    assessments.filter(
144
      (assessment): boolean =>
145
        assessment.assessment_type_id === assessmentTypeId,
146
    ),
147
)((state, props): number => props.assessmentTypeId);
148
149
export const getEditAssessmentById = createCachedSelector(
150
  getEditedAssessmentState,
151
  (state: RootState, props: { assessmentId: number }): number =>
152
    props.assessmentId,
153
  (assessments, assessmentId): Assessment | null =>
154
    hasKey(assessments, assessmentId) ? assessments[assessmentId] : null,
155
)((state, props): number => props.assessmentId);
156
157
/** Returns true if there is an edited verision which differs from canonical version */
158
export const assessmentIsEdited = createCachedSelector(
159
  getCanonAssessmentById,
160
  getEditAssessmentById,
161
  (canon, edited): boolean => edited !== null && !isEqual(edited, canon),
162
)((state, props): number => props.assessmentId);
163
164
export const assessmentsAreEditedByCriteria = createCachedSelector(
165
  getAssessmentIdsByCriterion,
166
  getCanonAssessmentState,
167
  getEditedAssessmentState,
168
  (assessmentIds, canonState, editedState): { [id: number]: boolean } => {
169
    return mapToObjectTrans(
170
      assessmentIds,
171
      (id): number => id,
172
      (assessmentId): boolean => {
173
        const canon = hasKey(canonState, assessmentId)
174
          ? canonState[assessmentId]
175
          : null;
176
        const edited = hasKey(editedState, assessmentId)
177
          ? editedState[assessmentId]
178
          : null;
179
        return edited !== null && !isEqual(edited, canon);
180
      },
181
    );
182
  },
183
)((state, props): number => props.criterionId);
184
185
export const getCachedAssessmentsAreEditedByCriteria = createCachedSelector(
186
  assessmentsAreEditedByCriteria,
187
  (map): { [id: number]: boolean } => map,
188
)((state, props): number => props.criterionId, deepEqualSelectorOptions);
189
190
export const assessmentIsUpdating = (state: RootState, id: number): boolean =>
191
  hasKey(stateSlice(state).assessmentUpdates, id)
192
    ? stateSlice(state).assessmentUpdates[id] > 0
193
    : false;
194
195
export const assessmentsAreUpdatingByCriteria = createCachedSelector(
196
  getAssessmentIdsByCriterion,
197
  getAssessmentUpdatingState,
198
  (assessmentIds, updateState): { [id: number]: boolean } =>
199
    mapToObjectTrans(
200
      assessmentIds,
201
      (id): number => id,
202
      (assessmentId): boolean =>
203
        hasKey(updateState, assessmentId)
204
          ? updateState[assessmentId] > 0
205
          : false,
206
    ),
207
)((state, props): number => props.criterionId);
208
209
export const getCachedAssessmentsAreUpdatingByCriteria = createCachedSelector(
210
  assessmentsAreUpdatingByCriteria,
211
  (map): { [id: number]: boolean } => map,
212
)((state, props): number => props.criterionId, deepEqualSelectorOptions);
213