@coorpacademy/app-review 0.46.14-alpha.9 → 0.46.14-react18.79

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/es/reducers/data/corrections.d.ts +1 -1
  2. package/es/reducers/data/current-skill.d.ts +1 -1
  3. package/es/reducers/data/index.d.ts +3 -3
  4. package/es/reducers/data/progression.d.ts +1 -1
  5. package/es/reducers/data/rank.d.ts +1 -1
  6. package/es/reducers/data/slides.d.ts +1 -1
  7. package/es/reducers/data/token.d.ts +1 -1
  8. package/es/reducers/data/videos.d.ts +1 -1
  9. package/es/reducers/index.d.ts +3 -7
  10. package/es/reducers/ui/answers.d.ts +1 -1
  11. package/es/reducers/ui/current-slide-ref.d.ts +1 -1
  12. package/es/reducers/ui/index.d.ts +1 -5
  13. package/es/reducers/ui/navigation.d.ts +1 -1
  14. package/es/reducers/ui/positions.d.ts +1 -1
  15. package/es/reducers/ui/quit-popin.d.ts +1 -1
  16. package/es/reducers/ui/show-button-revising.d.ts +1 -1
  17. package/es/reducers/ui/show-congrats.d.ts +1 -1
  18. package/es/reducers/ui/slide.d.ts +1 -1
  19. package/lib/reducers/data/corrections.d.ts +1 -1
  20. package/lib/reducers/data/current-skill.d.ts +1 -1
  21. package/lib/reducers/data/index.d.ts +3 -3
  22. package/lib/reducers/data/progression.d.ts +1 -1
  23. package/lib/reducers/data/rank.d.ts +1 -1
  24. package/lib/reducers/data/slides.d.ts +1 -1
  25. package/lib/reducers/data/token.d.ts +1 -1
  26. package/lib/reducers/data/videos.d.ts +1 -1
  27. package/lib/reducers/index.d.ts +3 -7
  28. package/lib/reducers/ui/answers.d.ts +1 -1
  29. package/lib/reducers/ui/current-slide-ref.d.ts +1 -1
  30. package/lib/reducers/ui/index.d.ts +1 -5
  31. package/lib/reducers/ui/navigation.d.ts +1 -1
  32. package/lib/reducers/ui/positions.d.ts +1 -1
  33. package/lib/reducers/ui/quit-popin.d.ts +1 -1
  34. package/lib/reducers/ui/show-button-revising.d.ts +1 -1
  35. package/lib/reducers/ui/show-congrats.d.ts +1 -1
  36. package/lib/reducers/ui/slide.d.ts +1 -1
  37. package/package.json +19 -10
  38. package/es/actions/api/fetch-correction.js +0 -18
  39. package/es/actions/api/fetch-rank.js +0 -34
  40. package/es/actions/api/fetch-skill.js +0 -16
  41. package/es/actions/api/fetch-slide.js +0 -31
  42. package/es/actions/api/fetch-slides-to-review-by-skill-ref.js +0 -32
  43. package/es/actions/api/fetch-video-props.js +0 -34
  44. package/es/actions/api/post-answer.js +0 -36
  45. package/es/actions/api/post-progression.js +0 -25
  46. package/es/actions/data/token.js +0 -5
  47. package/es/actions/ui/answers.js +0 -54
  48. package/es/actions/ui/navigation.js +0 -26
  49. package/es/actions/ui/next-slide.js +0 -33
  50. package/es/actions/ui/quit-popin.js +0 -8
  51. package/es/actions/ui/show-button-revising.js +0 -6
  52. package/es/actions/ui/slides.js +0 -10
  53. package/es/common/index.js +0 -10
  54. package/es/configure-store.js +0 -26
  55. package/es/helpers/css-register.js +0 -2
  56. package/es/index.js +0 -48
  57. package/es/reducers/data/corrections.js +0 -25
  58. package/es/reducers/data/current-skill.js +0 -13
  59. package/es/reducers/data/index.js +0 -17
  60. package/es/reducers/data/progression.js +0 -20
  61. package/es/reducers/data/rank.js +0 -27
  62. package/es/reducers/data/slides.js +0 -20
  63. package/es/reducers/data/token.js +0 -11
  64. package/es/reducers/data/videos.js +0 -33
  65. package/es/reducers/index.js +0 -7
  66. package/es/reducers/ui/answers.js +0 -28
  67. package/es/reducers/ui/current-slide-ref.js +0 -21
  68. package/es/reducers/ui/index.js +0 -19
  69. package/es/reducers/ui/navigation.js +0 -18
  70. package/es/reducers/ui/positions.js +0 -30
  71. package/es/reducers/ui/quit-popin.js +0 -16
  72. package/es/reducers/ui/show-button-revising.js +0 -17
  73. package/es/reducers/ui/show-congrats.js +0 -20
  74. package/es/reducers/ui/slide.js +0 -52
  75. package/es/types/common.js +0 -1
  76. package/es/types/slides.js +0 -1
  77. package/es/views/slides/index.js +0 -387
  78. package/es/views/slides/map-api-slide-to-ui.js +0 -177
  79. package/lib/actions/api/fetch-correction.js +0 -25
  80. package/lib/actions/api/fetch-rank.js +0 -43
  81. package/lib/actions/api/fetch-skill.js +0 -23
  82. package/lib/actions/api/fetch-slide.js +0 -38
  83. package/lib/actions/api/fetch-slides-to-review-by-skill-ref.js +0 -39
  84. package/lib/actions/api/fetch-video-props.js +0 -43
  85. package/lib/actions/api/post-answer.js +0 -43
  86. package/lib/actions/api/post-progression.js +0 -32
  87. package/lib/actions/data/token.js +0 -9
  88. package/lib/actions/ui/answers.js +0 -61
  89. package/lib/actions/ui/navigation.js +0 -31
  90. package/lib/actions/ui/next-slide.js +0 -40
  91. package/lib/actions/ui/quit-popin.js +0 -11
  92. package/lib/actions/ui/show-button-revising.js +0 -10
  93. package/lib/actions/ui/slides.js +0 -14
  94. package/lib/common/index.js +0 -17
  95. package/lib/configure-store.js +0 -32
  96. package/lib/helpers/css-register.js +0 -7
  97. package/lib/index.js +0 -76
  98. package/lib/reducers/data/corrections.js +0 -30
  99. package/lib/reducers/data/current-skill.js +0 -15
  100. package/lib/reducers/data/index.js +0 -22
  101. package/lib/reducers/data/progression.js +0 -22
  102. package/lib/reducers/data/rank.js +0 -32
  103. package/lib/reducers/data/slides.js +0 -26
  104. package/lib/reducers/data/token.js +0 -13
  105. package/lib/reducers/data/videos.js +0 -36
  106. package/lib/reducers/index.js +0 -12
  107. package/lib/reducers/ui/answers.js +0 -31
  108. package/lib/reducers/ui/current-slide-ref.js +0 -23
  109. package/lib/reducers/ui/index.js +0 -24
  110. package/lib/reducers/ui/navigation.js +0 -20
  111. package/lib/reducers/ui/positions.js +0 -35
  112. package/lib/reducers/ui/quit-popin.js +0 -18
  113. package/lib/reducers/ui/show-button-revising.js +0 -19
  114. package/lib/reducers/ui/show-congrats.js +0 -22
  115. package/lib/reducers/ui/slide.js +0 -58
  116. package/lib/types/common.js +0 -2
  117. package/lib/types/slides.js +0 -2
  118. package/lib/views/slides/index.js +0 -395
  119. package/lib/views/slides/map-api-slide-to-ui.js +0 -182
@@ -1,20 +0,0 @@
1
- import { NEXT_SLIDE } from '../../actions/ui/next-slide';
2
- import { POST_PROGRESSION_REQUEST } from '../../actions/api/post-progression';
3
- const reducer = (
4
- // eslint-disable-next-line default-param-last
5
- state = false, action) => {
6
- switch (action.type) {
7
- case POST_PROGRESSION_REQUEST: {
8
- return false;
9
- }
10
- case NEXT_SLIDE: {
11
- const { nextSlideRef } = action.payload;
12
- if (nextSlideRef === 'successExitNode')
13
- return true;
14
- return false;
15
- }
16
- default:
17
- return state;
18
- }
19
- };
20
- export default reducer;
@@ -1,52 +0,0 @@
1
- import compact from 'lodash/fp/compact';
2
- import isEmpty from 'lodash/fp/isEmpty';
3
- import pipe from 'lodash/fp/pipe';
4
- import set from 'lodash/fp/set';
5
- import unset from 'lodash/fp/unset';
6
- import { EDIT_BASIC, EDIT_QCM, EDIT_QCM_DRAG, EDIT_QCM_GRAPHIC, EDIT_SLIDER, EDIT_TEMPLATE } from '../../actions/ui/answers';
7
- import { POST_ANSWER_REQUEST } from '../../actions/api/post-answer';
8
- import { CORRECTION_FETCH_SUCCESS } from '../../actions/api/fetch-correction';
9
- import { POST_PROGRESSION_REQUEST } from '../../actions/api/post-progression';
10
- import { SLIDE_FETCH_REQUEST } from '../../actions/api/fetch-slide';
11
- import { NEXT_SLIDE } from '../../actions/ui/next-slide';
12
- export const initialState = {};
13
- const reducer = (
14
- // eslint-disable-next-line default-param-last
15
- state = initialState, action) => {
16
- switch (action.type) {
17
- case SLIDE_FETCH_REQUEST: {
18
- return pipe(unset([action.meta.slideRef, 'animationType']), set([action.meta.slideRef], {
19
- validateButton: false,
20
- animateCorrectionPopin: false,
21
- showCorrectionPopin: false,
22
- pendingAnswerRequest: false
23
- }))(state);
24
- }
25
- case EDIT_QCM:
26
- case EDIT_QCM_GRAPHIC:
27
- case EDIT_QCM_DRAG:
28
- case EDIT_TEMPLATE:
29
- case EDIT_BASIC:
30
- case EDIT_SLIDER: {
31
- return set([action.meta.slideRef, 'validateButton'], !pipe(compact, isEmpty)(action.payload), state);
32
- }
33
- case POST_ANSWER_REQUEST: {
34
- return pipe(set([action.meta.slideRef, 'validateButton'], false), set([action.meta.slideRef, 'pendingAnswerRequest'], true))(state);
35
- }
36
- case CORRECTION_FETCH_SUCCESS: {
37
- return pipe(set([action.meta.slideRef, 'animateCorrectionPopin'], true), set([action.meta.slideRef, 'showCorrectionPopin'], true))(state);
38
- }
39
- case NEXT_SLIDE: {
40
- const { currentSlideRef, nextSlideRef } = action.payload;
41
- if (nextSlideRef === 'successExitNode')
42
- return state;
43
- return pipe(set([currentSlideRef, 'animateCorrectionPopin'], false), set([currentSlideRef, 'animationType'], action.payload.animationType), set([currentSlideRef, 'showCorrectionPopin'], false))(state);
44
- }
45
- case POST_PROGRESSION_REQUEST: {
46
- return initialState;
47
- }
48
- default:
49
- return state;
50
- }
51
- };
52
- export default reducer;
@@ -1 +0,0 @@
1
- export {};
@@ -1 +0,0 @@
1
- export {};
@@ -1,387 +0,0 @@
1
- import findLast from 'lodash/fp/findLast';
2
- import get from 'lodash/fp/get';
3
- import getOr from 'lodash/fp/getOr';
4
- import last from 'lodash/fp/last';
5
- import reduce from 'lodash/fp/reduce';
6
- import set from 'lodash/fp/set';
7
- import toInteger from 'lodash/fp/toInteger';
8
- import join from 'lodash/fp/join';
9
- import { closeQuitPopin, openQuitPopin } from '../../actions/ui/quit-popin';
10
- import { getProgressionSlidesRefs } from '../../common';
11
- import { postAnswer } from '../../actions/api/post-answer';
12
- import { postProgression } from '../../actions/api/post-progression';
13
- import { nextSlide } from '../../actions/ui/next-slide';
14
- import { mapApiSlideToUi } from './map-api-slide-to-ui';
15
- const ICON_VALUES = {
16
- right: 'right',
17
- wrong: 'wrong',
18
- 'no-answer': 'no-answer'
19
- };
20
- const buildConfettiAnimation = (translate) => ({
21
- 'aria-label': translate('Congratulations confetti animation'),
22
- 'data-name': 'default-lottie',
23
- className: undefined,
24
- animationSrc: 'https://static-staging.coorpacademy.com/animations/review/confetti.json',
25
- loop: undefined,
26
- autoplay: true,
27
- rendererSettings: {
28
- hideOnTransparent: false
29
- }
30
- });
31
- export const initialState = {
32
- '0': {
33
- position: 0,
34
- loading: true
35
- },
36
- '1': {
37
- position: 1,
38
- loading: true
39
- },
40
- '2': {
41
- position: 2,
42
- loading: true
43
- },
44
- '3': {
45
- position: 3,
46
- loading: true
47
- },
48
- '4': {
49
- position: 4,
50
- loading: true
51
- }
52
- };
53
- const getCurrentSlideRef = (state) => {
54
- const currentSlideRef = get(['ui', 'currentSlideRef'], state);
55
- const endReview = currentSlideRef === 'successExitNode';
56
- if (!endReview)
57
- return currentSlideRef;
58
- const progression = state.data.progression;
59
- const content = progression.state.content;
60
- return content.ref;
61
- };
62
- const isLastSlideAnswered = (slidesRef, slideRef) => {
63
- return last(slidesRef) === slideRef;
64
- };
65
- const getSlideMedia = (state, slideFromAPI) => {
66
- const media = get(['question', 'medias', '0'], slideFromAPI);
67
- if (!media)
68
- return;
69
- const { type } = media;
70
- const resource = get(['src', '0'], media);
71
- switch (type) {
72
- case 'img':
73
- case 'audio': {
74
- const mediaProps = {
75
- ...resource,
76
- type,
77
- url: get('url', resource)
78
- };
79
- return mediaProps;
80
- }
81
- case 'video': {
82
- const videoProps = get(['data', 'videos', slideFromAPI._id, 'src', '0'], state);
83
- return videoProps;
84
- }
85
- }
86
- };
87
- const buildStackSlides = (state, dispatch, options) => {
88
- const { translate } = options;
89
- const currentSlideRef = getCurrentSlideRef(state);
90
- const progression = state.data.progression;
91
- if (!currentSlideRef || !progression)
92
- return initialState;
93
- const slideRefs = getProgressionSlidesRefs(progression);
94
- // @ts-expect-error typescript does not support capped versions of lodash functions
95
- const stack = reduce.convert({ cap: false })((acc, uiSlide, _index) => {
96
- const index = toInteger(_index);
97
- const slideRef = slideRefs[index];
98
- const lastAnsweredSlideRef = isLastSlideAnswered(progression.state.slides, slideRef);
99
- const positions = state.ui.positions;
100
- // when unstack the last answered slide (position -1), we set the position to 0 only during the animation
101
- // to avoid to hide the slide (caused by the position -1).
102
- const position = lastAnsweredSlideRef && positions[index] === -1 ? 0 : positions[index];
103
- if (!slideRef)
104
- return set(index, { ...uiSlide, position }, acc);
105
- const slideFromAPI = get(slideRef, state.data.slides);
106
- if (!slideFromAPI)
107
- return set(index, { ...uiSlide, position }, acc);
108
- const answers = getOr([], ['ui', 'answers', slideRef], state);
109
- const media = getSlideMedia(state, slideFromAPI);
110
- const { questionText, answerUI } = mapApiSlideToUi(dispatch, translate)(slideFromAPI, answers, media);
111
- const { title: parentContentTitle, type: parentContentType } = slideFromAPI.parentContentTitle;
112
- const isCurrentSlideRef = currentSlideRef === slideRef;
113
- const slideUI = get(['ui', 'slide', slideRef], state);
114
- const animateCorrectionPopin = isCurrentSlideRef && slideUI.animateCorrectionPopin;
115
- const showCorrectionPopin = isCurrentSlideRef && slideUI.showCorrectionPopin;
116
- const animationType = lastAnsweredSlideRef ? slideUI.animationType : undefined;
117
- const disabledContent = get(['ui', 'slide', slideRef, 'pendingAnswerRequest'], state);
118
- const updatedUiSlide = {
119
- ...uiSlide,
120
- position,
121
- showCorrectionPopin,
122
- animateCorrectionPopin,
123
- loading: false,
124
- questionText,
125
- answerUI,
126
- disabledContent,
127
- parentContentTitle: translate('Content Parent Title', {
128
- contentTitle: parentContentTitle,
129
- contentType: parentContentType
130
- }),
131
- animationType
132
- };
133
- return set(index, updatedUiSlide, acc);
134
- }, initialState, initialState);
135
- return stack;
136
- };
137
- const getIconForCurrentStep = (slideRef, lastGivenAnswerForSlide, currentSlideRef, lastGivenAnswer) => {
138
- if (slideRef !== currentSlideRef)
139
- return lastGivenAnswerForSlide.isCorrect ? 'right' : 'wrong';
140
- if (lastGivenAnswer.slideRef !== slideRef)
141
- return 'no-answer';
142
- return lastGivenAnswerForSlide.isCorrect ? 'right' : 'wrong';
143
- };
144
- export const buildStepItems = (state) => {
145
- const { progression } = state.data;
146
- const { currentSlideRef } = state.ui;
147
- if (!progression)
148
- return [];
149
- const defaultProps = [
150
- {
151
- icon: 'no-answer',
152
- current: true,
153
- value: '1'
154
- },
155
- {
156
- icon: 'no-answer',
157
- current: false,
158
- value: '2'
159
- },
160
- {
161
- icon: 'no-answer',
162
- current: false,
163
- value: '3'
164
- },
165
- {
166
- icon: 'no-answer',
167
- current: false,
168
- value: '4'
169
- },
170
- {
171
- icon: 'no-answer',
172
- current: false,
173
- value: '5'
174
- }
175
- ];
176
- const slideRefs = getProgressionSlidesRefs(progression);
177
- const allAnswers = progression.state.allAnswers;
178
- const step = progression.state.step;
179
- const nextContentRef = progression.state.nextContent.ref;
180
- const lastGivenAnswer = last(allAnswers);
181
- if (!lastGivenAnswer)
182
- return defaultProps;
183
- const steps = defaultProps.map((stepItem, index) => {
184
- const slideRef = slideRefs[index];
185
- if (!slideRef)
186
- return stepItem; // non fecthed slide pour given index
187
- const lastGivenAnswerForSlide = findLast(answer => answer.slideRef === slideRef, allAnswers);
188
- // never answered slide
189
- if (!lastGivenAnswerForSlide) {
190
- return {
191
- ...stepItem,
192
- current: nextContentRef === currentSlideRef && step.current === index + 1
193
- };
194
- }
195
- // already answered slide, we computed based on the lastGivenAnswer
196
- return {
197
- ...stepItem,
198
- icon: getIconForCurrentStep(slideRef, lastGivenAnswerForSlide, currentSlideRef, lastGivenAnswer),
199
- current: lastGivenAnswerForSlide.slideRef === currentSlideRef
200
- };
201
- });
202
- return steps;
203
- };
204
- const getCorrectionPopinProps = (dispatch) => (isCorrect, correctAnswer, klf, translate, endReview) => {
205
- const nextLabel = endReview ? translate('Continue') : translate('Next Question');
206
- return {
207
- klf: isCorrect
208
- ? undefined
209
- : {
210
- label: translate('KLF'),
211
- tooltip: klf
212
- },
213
- resultLabel: isCorrect ? translate('Correct Answer') : translate('Wrong Answer'),
214
- information: {
215
- label: isCorrect ? translate('KLF') : translate('Correct Answer'),
216
- message: isCorrect ? klf : join(', ', correctAnswer)
217
- },
218
- next: {
219
- 'aria-label': nextLabel,
220
- label: nextLabel,
221
- onClick: () => {
222
- dispatch(nextSlide);
223
- }
224
- },
225
- type: isCorrect ? 'right' : 'wrong'
226
- };
227
- };
228
- const buildQuitPopinProps = (dispatch) => (onQuitClick, translate, skin) => {
229
- return {
230
- content: translate('Quit Title'),
231
- icon: `MoonRocket`,
232
- mode: 'alert',
233
- descriptionText: translate('Quit Description Text'),
234
- firstButton: {
235
- label: translate('Stop learning'),
236
- type: 'tertiary',
237
- customStyle: {
238
- color: '#ED3436'
239
- },
240
- handleOnclick: () => {
241
- dispatch(closeQuitPopin);
242
- onQuitClick();
243
- },
244
- 'aria-label': translate('Stop learning')
245
- },
246
- secondButton: {
247
- label: translate('Continue learning'),
248
- type: 'primary',
249
- customStyle: {
250
- backgroundColor: get(['common', 'primary'], skin)
251
- },
252
- handleOnclick: () => {
253
- dispatch(closeQuitPopin);
254
- },
255
- 'aria-label': translate('Continue learning')
256
- }
257
- };
258
- };
259
- const buildRankCard = (rank, translate) => {
260
- return {
261
- 'aria-label': 'Review Card Congrats Container',
262
- 'data-name': 'card-rank',
263
- animationLottie: {
264
- 'aria-label': translate('New rank animation'),
265
- 'data-name': 'default-lottie',
266
- animationSrc: 'https://static-staging.coorpacademy.com/animations/review/rank.json',
267
- loop: true,
268
- autoplay: true
269
- },
270
- cardType: 'card-rank',
271
- iconAriaLabel: 'Image without information',
272
- className: undefined,
273
- reviewCardTitle: translate('You are now'),
274
- reviewCardValue: `${rank}`,
275
- rankSuffix: 'th',
276
- timerAnimation: 200
277
- };
278
- };
279
- const buildCongratsProps = (state, dispatch, options) => {
280
- if (!state.ui.showCongrats)
281
- return;
282
- const { translate, onQuitClick } = options;
283
- const progression = state.data.progression;
284
- const stars = progression.state.stars;
285
- const cardCongratsStar = {
286
- 'aria-label': 'Review Card Congrats Container',
287
- 'data-name': 'card-star',
288
- animationLottie: {
289
- 'aria-label': translate('Acquired stars animation'),
290
- 'data-name': 'default-lottie',
291
- className: undefined,
292
- animationSrc: 'https://static-staging.coorpacademy.com/animations/review/star.json',
293
- loop: false,
294
- autoplay: undefined,
295
- rendererSettings: {
296
- hideOnTransparent: false
297
- }
298
- },
299
- iconAriaLabel: 'Image without information',
300
- className: undefined,
301
- cardType: 'card-star',
302
- reviewCardTitle: translate('You have won'),
303
- reviewCardValue: `${stars}`,
304
- timerAnimation: 200
305
- };
306
- const { start, end } = state.data.rank;
307
- const newRank = start - end;
308
- const cardCongratsRank = !Number.isNaN(newRank) && newRank > 0 ? buildRankCard(end, translate) : undefined;
309
- const skillRef = progression.content.ref;
310
- const buttonRevising = state.ui.showButtonRevising
311
- ? {
312
- 'aria-label': translate('Continue reviewing'),
313
- label: translate('Continue reviewing'),
314
- onClick: () => {
315
- dispatch(postProgression(skillRef));
316
- },
317
- type: 'tertiary'
318
- }
319
- : undefined;
320
- const buttonRevisingSkill = {
321
- 'aria-label': translate('Revise another skill'),
322
- label: translate('Revise another skill'),
323
- onClick: onQuitClick,
324
- type: 'primary'
325
- };
326
- return {
327
- 'aria-label': 'Review Congratulations',
328
- 'data-name': 'review-congrats',
329
- animationLottie: buildConfettiAnimation(translate),
330
- title: translate('Congratulations!'),
331
- cardCongratsStar,
332
- cardCongratsRank,
333
- buttonRevising,
334
- buttonRevisingSkill
335
- };
336
- };
337
- const isEndOfProgression = (progression) => {
338
- if (!progression)
339
- return false;
340
- return progression.state.nextContent.ref === 'successExitNode';
341
- };
342
- export const mapStateToSlidesProps = (state, dispatch, options) => {
343
- const { translate, onQuitClick, skin, backgroundImage } = options;
344
- const currentSlideRef = getCurrentSlideRef(state);
345
- const endReview = isEndOfProgression(state.data.progression);
346
- const correction = get(['data', 'corrections', currentSlideRef], state);
347
- const isCorrect = get(['data', 'progression', 'state', 'isCorrect'], state);
348
- const klf = getOr('', ['data', 'slides', currentSlideRef, 'klf'], state);
349
- const showQuitPopin = get(['ui', 'showQuitPopin'], state);
350
- const showCongrats = get(['ui', 'showCongrats'], state);
351
- const skillName = getOr('', ['data', 'currentSkill', 'name'], state);
352
- return {
353
- header: {
354
- mode: translate('Review Title'),
355
- skillName,
356
- onQuitClick: showCongrats
357
- ? onQuitClick
358
- : () => {
359
- dispatch(openQuitPopin);
360
- },
361
- 'aria-label': 'aria-header-wrapper',
362
- closeButtonAriaLabel: 'aria-close-button',
363
- steps: buildStepItems(state),
364
- hiddenSteps: showCongrats
365
- },
366
- stack: state.data.progression
367
- ? {
368
- slides: buildStackSlides(state, dispatch, options),
369
- validateButton: {
370
- label: translate('Validate'),
371
- disabled: !get(['ui', 'slide', currentSlideRef, 'validateButton'], state),
372
- onClick: () => {
373
- dispatch(postAnswer);
374
- }
375
- },
376
- correctionPopinProps: correction &&
377
- getCorrectionPopinProps(dispatch)(isCorrect, correction.correctAnswer, klf, translate, endReview),
378
- endReview: endReview && state.ui.showCongrats
379
- }
380
- : null,
381
- backgroundImage,
382
- congrats: buildCongratsProps(state, dispatch, options),
383
- quitPopin: showQuitPopin
384
- ? buildQuitPopinProps(dispatch)(onQuitClick, translate, skin)
385
- : undefined
386
- };
387
- };
@@ -1,177 +0,0 @@
1
- import { concat, constant, divide, get, getOr, head, includes, indexOf, isEmpty, isNil, map, multiply, pipe, rangeStep, round, set, size, times, toInteger, toString as _toString, __ } from 'lodash/fp';
2
- import { editAnswer } from '../../actions/ui/answers';
3
- const qcmProps = (dispatch) => (answers, question) => {
4
- return {
5
- type: 'qcm',
6
- answers: map(choice => {
7
- const label = getOr('', 'label', choice);
8
- return {
9
- title: label,
10
- selected: includes(label, answers),
11
- onClick: () => {
12
- dispatch(editAnswer([label]));
13
- },
14
- 'aria-label': label
15
- };
16
- }, question.content.choices)
17
- };
18
- };
19
- const qcmDragProps = (dispatch) => (answers, question) => {
20
- return {
21
- type: 'qcmDrag',
22
- answers: map(choice => {
23
- const label = getOr('', 'label', choice);
24
- const indexInAnswer = indexOf(label, answers);
25
- return {
26
- title: label,
27
- selected: includes(label, answers),
28
- order: indexInAnswer,
29
- onClick: () => {
30
- dispatch(editAnswer([label]));
31
- }
32
- };
33
- }, question.content.choices)
34
- };
35
- };
36
- const qcmGraphicProps = (dispatch) => (answers, question) => {
37
- return {
38
- type: 'qcmGraphic',
39
- answers: map(choice => {
40
- const label = getOr('', 'label', choice);
41
- return {
42
- title: label,
43
- image: get('media.src.0.url', choice),
44
- selected: includes(label, answers),
45
- onClick: () => {
46
- dispatch(editAnswer([label]));
47
- },
48
- ariaLabel: label
49
- };
50
- }, question.content.choices)
51
- };
52
- };
53
- const updateTemplateAnswer = (text, _answers, index, max) => {
54
- const answers = isEmpty(_answers) ? times(constant(undefined), max) : _answers;
55
- return map(a => (isNil(a) ? '' : a), set(index, text, answers));
56
- };
57
- const templateTextProps = (dispatch, translate, answers, choice, index, maxLength) => {
58
- return {
59
- type: 'text',
60
- name: getOr('', 'name', choice),
61
- placeholder: translate('Type here'),
62
- value: get(index, answers),
63
- onChange: (text) => {
64
- const newAnswers = updateTemplateAnswer(text, answers, index, maxLength);
65
- dispatch(editAnswer(newAnswers));
66
- }
67
- };
68
- };
69
- const templateSelectProps = (dispatch, translate, answers, choice, index, maxLength) => {
70
- const answer = get(index, answers);
71
- const temporaryOption = {
72
- name: translate('Select an answer'),
73
- value: '',
74
- validOption: false,
75
- selected: true
76
- };
77
- const selectOptions = choice.items.map((item) => {
78
- const itemText = getOr('', 'text', item);
79
- return {
80
- name: itemText,
81
- value: itemText,
82
- validOption: true,
83
- selected: itemText === answer
84
- };
85
- });
86
- return {
87
- type: 'select',
88
- name: getOr('', 'name', choice),
89
- onChange: (text) => {
90
- const newAnswers = updateTemplateAnswer(text, answers, index, maxLength);
91
- dispatch(editAnswer(newAnswers));
92
- },
93
- options: isEmpty(answer) ? concat([temporaryOption], selectOptions) : selectOptions,
94
- 'aria-label': translate('Select an answer')
95
- };
96
- };
97
- const templateProps = (dispatch, translate) => (answers, question) => {
98
- const choices = question.content.choices;
99
- const maxLength = size(choices);
100
- return {
101
- type: 'template',
102
- template: get('content.template', question),
103
- answers: choices.map((choice, index) => choice.type === 'text'
104
- ? templateTextProps(dispatch, translate, answers, choice, index, maxLength)
105
- : templateSelectProps(dispatch, translate, answers, choice, index, maxLength))
106
- };
107
- };
108
- const basicProps = (dispatch) => (answers, question) => {
109
- return {
110
- type: 'freeText',
111
- placeholder: getOr('', 'content.placeholder', question),
112
- value: getOr('', '0', answers),
113
- onChange: (text) => {
114
- dispatch(editAnswer([text]));
115
- }
116
- };
117
- };
118
- const sliderProps = (dispatch) => (answers, question) => {
119
- const values = rangeStep(getOr(1, 'content.step', question), get('content.min', question), get('content.max', question) + 1
120
- // Lodash doesn't infer the type very well here
121
- );
122
- const stateValue = head(answers) || question.content.min;
123
- const currentValue = toInteger(stateValue);
124
- const indexValue = indexOf(currentValue, values);
125
- const maxValue = size(values) - 1;
126
- const sliderPosition = divide(indexValue, maxValue);
127
- const unitLabel = get('content.unitLabel', question);
128
- return {
129
- type: 'slider',
130
- placeholder: question.explanation,
131
- minLabel: `${question.content.min} ${unitLabel}`,
132
- maxLabel: `${question.content.max} ${unitLabel}`,
133
- title: `${currentValue} ${question.content.unitLabel}`,
134
- value: sliderPosition,
135
- onChange: (position) => {
136
- // atom/range handler
137
- const newValue = pipe(multiply(maxValue), round, get(__, values), _toString)(position);
138
- dispatch(editAnswer([newValue]));
139
- },
140
- onSliderChange: (newValue) => {
141
- // mobile/slider handler
142
- dispatch(editAnswer([`${newValue}`]));
143
- }
144
- };
145
- };
146
- export const getQuestionType = (question) => question.type;
147
- const getHelp = (slide) => get('question.explanation', slide);
148
- const getAnswerUIModel = (question, answers, dispatch, translate) => {
149
- const type = getQuestionType(question);
150
- switch (type) {
151
- case 'qcm':
152
- return qcmProps(dispatch)(answers, question);
153
- case 'qcmGraphic':
154
- return qcmGraphicProps(dispatch)(answers, question);
155
- case 'qcmDrag':
156
- return qcmDragProps(dispatch)(answers, question);
157
- case 'basic':
158
- return basicProps(dispatch)(answers, question);
159
- case 'template':
160
- return templateProps(dispatch, translate)(answers, question);
161
- case 'slider':
162
- return sliderProps(dispatch)(answers, question);
163
- default:
164
- throw new Error(`${type} is not an handled question.type`);
165
- }
166
- };
167
- export const mapApiSlideToUi = (dispatch, translate) => (slide, answers, media) => {
168
- const questionText = getOr('', 'question.header', slide);
169
- return {
170
- questionText,
171
- answerUI: {
172
- model: getAnswerUIModel(slide.question, answers, dispatch, translate),
173
- help: getHelp(slide),
174
- media
175
- }
176
- };
177
- };
@@ -1,25 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.fetchCorrection = exports.CORRECTION_FETCH_FAILURE = exports.CORRECTION_FETCH_SUCCESS = exports.CORRECTION_FETCH_REQUEST = void 0;
7
- const redux_task_1 = __importDefault(require("@coorpacademy/redux-task"));
8
- const get_1 = __importDefault(require("lodash/fp/get"));
9
- exports.CORRECTION_FETCH_REQUEST = '@@correction/FETCH_REQUEST';
10
- exports.CORRECTION_FETCH_SUCCESS = '@@correction/FETCH_SUCCESS';
11
- exports.CORRECTION_FETCH_FAILURE = '@@correction/FETCH_FAILURE';
12
- const fetchCorrection = (dispatch, getState, { services }) => {
13
- const state = getState();
14
- const slideRef = (0, get_1.default)(['ui', 'currentSlideRef'], state);
15
- const token = (0, get_1.default)(['data', 'token'], state);
16
- const progressionId = (0, get_1.default)(['data', 'progression', '_id'], state);
17
- const answer = (0, get_1.default)(['ui', 'answers', slideRef], state);
18
- const action = (0, redux_task_1.default)({
19
- types: [exports.CORRECTION_FETCH_REQUEST, exports.CORRECTION_FETCH_SUCCESS, exports.CORRECTION_FETCH_FAILURE],
20
- meta: { slideRef },
21
- task: () => services.fetchCorrection(slideRef, token, progressionId, answer)
22
- });
23
- return dispatch(action);
24
- };
25
- exports.fetchCorrection = fetchCorrection;