@coorpacademy/app-review 0.4.5 → 0.5.1-alpha.26

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 (87) hide show
  1. package/es/actions/ui/next-slide.d.ts +4 -2
  2. package/es/actions/ui/next-slide.js +7 -4
  3. package/es/actions/ui/quit-popin.d.ts +8 -0
  4. package/es/actions/ui/quit-popin.js +8 -0
  5. package/es/actions/ui/slides.d.ts +2 -3
  6. package/es/common/index.d.ts +2 -0
  7. package/es/common/index.js +9 -0
  8. package/es/reducers/index.d.ts +7 -1
  9. package/es/reducers/ui/answers.d.ts +2 -2
  10. package/es/reducers/ui/current-slide-ref.d.ts +3 -2
  11. package/es/reducers/ui/current-slide-ref.js +3 -0
  12. package/es/reducers/ui/index.d.ts +11 -1
  13. package/es/reducers/ui/index.js +5 -1
  14. package/es/reducers/ui/positions.d.ts +5 -0
  15. package/es/reducers/ui/positions.js +25 -0
  16. package/es/reducers/ui/quit-popin.d.ts +4 -0
  17. package/es/reducers/ui/quit-popin.js +16 -0
  18. package/es/reducers/ui/slide.d.ts +2 -2
  19. package/es/views/slides/index.d.ts +19 -2
  20. package/es/views/slides/index.js +45 -25
  21. package/lib/actions/ui/next-slide.d.ts +4 -2
  22. package/lib/actions/ui/next-slide.js +7 -4
  23. package/lib/actions/ui/quit-popin.d.ts +8 -0
  24. package/lib/actions/ui/quit-popin.js +8 -0
  25. package/lib/actions/ui/slides.d.ts +2 -3
  26. package/lib/common/index.d.ts +2 -0
  27. package/lib/common/index.js +9 -0
  28. package/lib/reducers/index.d.ts +7 -1
  29. package/lib/reducers/ui/answers.d.ts +2 -2
  30. package/lib/reducers/ui/current-slide-ref.d.ts +3 -2
  31. package/lib/reducers/ui/current-slide-ref.js +3 -0
  32. package/lib/reducers/ui/index.d.ts +11 -1
  33. package/lib/reducers/ui/index.js +5 -1
  34. package/lib/reducers/ui/positions.d.ts +5 -0
  35. package/lib/reducers/ui/positions.js +26 -0
  36. package/lib/reducers/ui/quit-popin.d.ts +4 -0
  37. package/lib/reducers/ui/quit-popin.js +17 -0
  38. package/lib/reducers/ui/slide.d.ts +2 -2
  39. package/lib/views/slides/index.d.ts +19 -2
  40. package/lib/views/slides/index.js +47 -26
  41. package/package.json +10 -11
  42. package/src/actions/api/test/fetch-correction.test.ts +3 -1
  43. package/src/actions/api/test/fetch-rank.test.ts +3 -1
  44. package/src/actions/api/test/fetch-skills.test.ts +3 -1
  45. package/src/actions/api/test/fetch-slide.test.ts +3 -1
  46. package/src/actions/api/test/post-answer.test.ts +6 -2
  47. package/src/actions/api/test/post-progression.test.ts +3 -1
  48. package/src/actions/data/test/token.test.ts +3 -1
  49. package/src/actions/ui/next-slide.ts +15 -9
  50. package/src/actions/ui/quit-popin.ts +10 -0
  51. package/src/actions/ui/slides.ts +2 -4
  52. package/src/actions/ui/test/answers.test.ts +3 -1
  53. package/src/actions/ui/test/next-slide.test.ts +9 -3
  54. package/src/actions/ui/test/quit-popin.test.ts +38 -0
  55. package/src/actions/ui/test/slides.test.ts +3 -1
  56. package/src/common/index.ts +12 -0
  57. package/src/common/test/get-progression-slide-ref.test.ts +35 -0
  58. package/src/reducers/ui/answers.ts +2 -2
  59. package/src/reducers/ui/current-slide-ref.ts +5 -2
  60. package/src/reducers/ui/index.ts +7 -1
  61. package/src/reducers/ui/positions.ts +32 -0
  62. package/src/reducers/ui/quit-popin.ts +22 -0
  63. package/src/reducers/ui/slide.ts +7 -2
  64. package/src/reducers/ui/test/answers.test.ts +3 -1
  65. package/src/reducers/ui/test/current-slide-ref.test.ts +2 -2
  66. package/src/reducers/ui/test/positions.test.ts +68 -0
  67. package/src/reducers/ui/test/quit-popin.test.ts +24 -0
  68. package/src/reducers/ui/test/slide.test.ts +3 -1
  69. package/src/types/common.ts +0 -1
  70. package/src/views/skills/test/skills.test.ts +6 -2
  71. package/src/views/slides/index.ts +70 -32
  72. package/src/views/slides/test/header.on-click.test.ts +42 -0
  73. package/src/views/slides/test/index.test.ts +90 -42
  74. package/src/views/slides/test/on-quit-popin.on-click.test.ts +64 -0
  75. package/src/views/slides/test/slide.free-text.on-change.test.ts +3 -2
  76. package/src/views/slides/test/slide.next-slide.on-click.test.ts +10 -2
  77. package/src/views/slides/test/slide.qcm-drag.on-click.test.ts +3 -2
  78. package/src/views/slides/test/slide.qcm-graphic.on-click.test.ts +3 -2
  79. package/src/views/slides/test/slide.qcm.on-click.test.ts +3 -2
  80. package/src/views/slides/test/slide.slider.on-change.test.ts +3 -2
  81. package/src/views/slides/test/slide.slider.on-slider-change.test.ts +17 -4
  82. package/src/views/slides/test/slide.template.on-change.test.ts +11 -11
  83. package/es/actions/ui/is-fetching.d.ts +0 -10
  84. package/es/actions/ui/is-fetching.js +0 -4
  85. package/lib/actions/ui/is-fetching.d.ts +0 -10
  86. package/lib/actions/ui/is-fetching.js +0 -4
  87. package/src/actions/ui/is-fetching.ts +0 -13
@@ -5,10 +5,12 @@ declare type NextSlidePayload = {
5
5
  currentSlideRef: string;
6
6
  nextSlideRef: string;
7
7
  animationType: string;
8
+ totalCorrectAnswers: number;
9
+ answeredSlides: string[];
8
10
  };
9
- export declare type NextSlide = {
11
+ export declare type NextSlideAction = {
10
12
  type: typeof NEXT_SLIDE;
11
13
  payload: NextSlidePayload;
12
14
  };
13
- export declare const nextSlide: (dispatch: Dispatch, getState: () => StoreState) => NextSlide;
15
+ export declare const nextSlide: (dispatch: Dispatch, getState: () => StoreState) => NextSlideAction;
14
16
  export {};
@@ -1,14 +1,17 @@
1
+ import filter from 'lodash/fp/filter';
1
2
  import get from 'lodash/fp/get';
2
- import getOr from 'lodash/fp/getOr';
3
3
  export const NEXT_SLIDE = '@@slide/NEXT_SLIDE';
4
4
  export const nextSlide = (dispatch, getState) => {
5
5
  const state = getState();
6
+ const progression = state.data.progression;
7
+ const { isCorrect, allAnswers, slides } = progression.state;
8
+ const correctAnswers = filter((answer) => answer.isCorrect, allAnswers);
6
9
  const payload = {
7
10
  currentSlideRef: get(['ui', 'currentSlideRef'], state),
8
11
  nextSlideRef: get(['state', 'nextContent', 'ref'], state.data.progression),
9
- animationType: getOr(false, ['state', 'isCorrect'], state.data.progression)
10
- ? 'unstack'
11
- : 'restack'
12
+ animationType: isCorrect ? 'unstack' : 'restack',
13
+ totalCorrectAnswers: correctAnswers.length,
14
+ answeredSlides: slides
12
15
  };
13
16
  const action = {
14
17
  type: NEXT_SLIDE,
@@ -0,0 +1,8 @@
1
+ export declare const OPEN_POPIN: "@@ui/OPEN_POPIN";
2
+ export declare const CLOSE_POPIN: "@@ui/CLOSE_POPIN";
3
+ export declare const openQuitPopin: {
4
+ type: "@@ui/OPEN_POPIN";
5
+ };
6
+ export declare const closeQuitPopin: {
7
+ type: "@@ui/CLOSE_POPIN";
8
+ };
@@ -0,0 +1,8 @@
1
+ export const OPEN_POPIN = '@@ui/OPEN_POPIN';
2
+ export const CLOSE_POPIN = '@@ui/CLOSE_POPIN';
3
+ export const openQuitPopin = {
4
+ type: OPEN_POPIN
5
+ };
6
+ export const closeQuitPopin = {
7
+ type: CLOSE_POPIN
8
+ };
@@ -12,10 +12,9 @@ export declare type Slide = {
12
12
  nextContent?: Omit<Slide, 'endReview' | 'hidden' | 'position' | 'nextContent'>;
13
13
  };
14
14
  export declare const SET_CURRENT_SLIDE: "@@slide/SET_CURRENT_SLIDE";
15
- export declare type SetCurrentSlide = {
15
+ export declare type SetCurrentSlideAction = {
16
16
  type: typeof SET_CURRENT_SLIDE;
17
17
  payload: SlideFromAPI;
18
18
  };
19
- export declare const setCurrentSlide: (payload: SlideFromAPI) => SetCurrentSlide;
20
- export declare type UISlidesAction = SetCurrentSlide;
19
+ export declare const setCurrentSlide: (payload: SlideFromAPI) => SetCurrentSlideAction;
21
20
  export {};
@@ -1,3 +1,4 @@
1
+ import type { ProgressionFromAPI } from '../types/common';
1
2
  export declare const VIEWS: {
2
3
  readonly skills: 'skills';
3
4
  readonly onboarding: 'onboarding';
@@ -5,3 +6,4 @@ export declare const VIEWS: {
5
6
  };
6
7
  export declare const slideIndexes: readonly ["0", "1", "2", "3", "4"];
7
8
  export declare type SlideIndexes = typeof slideIndexes[number];
9
+ export declare const getProgressionSlidesRefs: (progression: ProgressionFromAPI) => string[];
@@ -1,6 +1,15 @@
1
+ import concat from 'lodash/fp/concat';
2
+ import slice from 'lodash/fp/slice';
1
3
  export const VIEWS = {
2
4
  skills: 'skills',
3
5
  onboarding: 'onboarding',
4
6
  slides: 'slides'
5
7
  };
6
8
  export const slideIndexes = ['0', '1', '2', '3', '4'];
9
+ export const getProgressionSlidesRefs = (progression) => {
10
+ if (progression.state.step.current <= 5) {
11
+ const slideRef = progression.state.nextContent.ref;
12
+ return concat(progression.state.slides, [slideRef]);
13
+ }
14
+ return slice(0, 5, progression.state.slides);
15
+ };
@@ -18,6 +18,12 @@ declare const _default: import("redux").Reducer<import("redux").CombinedState<{
18
18
  navigation: import("./ui/navigation").NavigationState;
19
19
  answers: import("./ui/answers").UIAnswerState;
20
20
  slide: import("./ui/slide").UISlideState;
21
+ positions: import("./ui/positions").UIPositionState;
22
+ showQuitPopin: boolean;
21
23
  }>;
22
- }>, import("./data/corrections").CorrectionsAction | import("../actions/ui/slides").SetCurrentSlide | import("../actions/api/fetch-rank").RankAction | import("../actions/api/post-answer").PostAnswerRequestAction | import("../actions/api/post-answer").PostAnswerSuccessAction | import("../actions/api/post-progression").ReceivedProgression | import("../actions/api/fetch-skills").ReceivedSkills | import("./data/slides").SlidesAction | import("../actions/data/token").StoreToken | import("../actions/ui/navigation").NavigateTo | import("../actions/ui/navigation").NavigateBack | import("../actions/ui/answers").EditAnswerAction | import("../actions/ui/next-slide").NextSlide>;
24
+ }>, import("./data/corrections").CorrectionsAction | import("../actions/ui/slides").SetCurrentSlideAction | import("../actions/api/fetch-rank").RankAction | import("../actions/api/post-answer").PostAnswerRequestAction | import("../actions/api/post-answer").PostAnswerSuccessAction | import("../actions/api/post-progression").ReceivedProgression | import("../actions/api/fetch-skills").ReceivedSkills | import("./data/slides").SlidesAction | import("../actions/data/token").StoreToken | import("../actions/ui/next-slide").NextSlideAction | import("../actions/ui/navigation").NavigateTo | import("../actions/ui/navigation").NavigateBack | import("../actions/ui/answers").EditAnswerAction | {
25
+ type: "@@ui/OPEN_POPIN";
26
+ } | {
27
+ type: "@@ui/CLOSE_POPIN";
28
+ }>;
23
29
  export default _default;
@@ -1,7 +1,7 @@
1
1
  import { EditAnswerAction } from '../../actions/ui/answers';
2
- import { NextSlide } from '../../actions/ui/next-slide';
2
+ import { NextSlideAction } from '../../actions/ui/next-slide';
3
3
  export declare type UISlideAnswer = string[];
4
4
  export declare type UIAnswerState = Record<string, UISlideAnswer>;
5
5
  export declare const initialState: UIAnswerState;
6
- declare const reducer: (state: UIAnswerState | undefined, action: EditAnswerAction | NextSlide) => UIAnswerState;
6
+ declare const reducer: (state: UIAnswerState | undefined, action: EditAnswerAction | NextSlideAction) => UIAnswerState;
7
7
  export default reducer;
@@ -1,4 +1,5 @@
1
- import { UISlidesAction } from '../../actions/ui/slides';
1
+ import { NextSlideAction } from '../../actions/ui/next-slide';
2
+ import { SetCurrentSlideAction } from '../../actions/ui/slides';
2
3
  export declare type CurrentSlideRefState = string;
3
- declare const reducer: (state: string | undefined, action: UISlidesAction) => CurrentSlideRefState;
4
+ declare const reducer: (state: string | undefined, action: SetCurrentSlideAction | NextSlideAction) => CurrentSlideRefState;
4
5
  export default reducer;
@@ -1,8 +1,11 @@
1
+ import { NEXT_SLIDE } from '../../actions/ui/next-slide';
1
2
  import { SET_CURRENT_SLIDE } from '../../actions/ui/slides';
2
3
  const reducer = (
3
4
  // eslint-disable-next-line default-param-last
4
5
  state = '', action) => {
5
6
  switch (action.type) {
7
+ case NEXT_SLIDE:
8
+ return action.payload.nextSlideRef;
6
9
  case SET_CURRENT_SLIDE: {
7
10
  return action.payload._id;
8
11
  }
@@ -1,17 +1,27 @@
1
1
  import { CurrentSlideRefState } from './current-slide-ref';
2
2
  import { NavigationState } from './navigation';
3
3
  import { UIAnswerState } from './answers';
4
+ import { UIPositionState } from './positions';
4
5
  import { UISlideState } from './slide';
6
+ import { type ShowQuitPopinState } from './quit-popin';
5
7
  export declare type UIState = {
6
8
  currentSlideRef: CurrentSlideRefState;
7
9
  navigation: NavigationState;
8
10
  answers: UIAnswerState;
9
11
  slide: UISlideState;
12
+ positions: UIPositionState;
13
+ showQuitPopin: ShowQuitPopinState;
10
14
  };
11
15
  declare const _default: import("redux").Reducer<import("redux").CombinedState<{
12
16
  currentSlideRef: string;
13
17
  navigation: NavigationState;
14
18
  answers: UIAnswerState;
15
19
  slide: UISlideState;
16
- }>, import("../../actions/api/fetch-correction").ReceivedCorrection | import("../../actions/ui/slides").SetCurrentSlide | import("../../actions/api/fetch-slide").FetchSlide | import("../../actions/api/post-answer").PostAnswerRequestAction | import("../../actions/ui/navigation").NavigateTo | import("../../actions/ui/navigation").NavigateBack | import("../../actions/ui/answers").EditAnswerAction | import("../../actions/ui/next-slide").NextSlide>;
20
+ positions: UIPositionState;
21
+ showQuitPopin: boolean;
22
+ }>, import("../../actions/api/fetch-correction").ReceivedCorrection | import("../../actions/ui/slides").SetCurrentSlideAction | import("../../actions/api/fetch-slide").FetchSlide | import("../../actions/api/post-answer").PostAnswerRequestAction | import("../../actions/api/post-progression").ReceivedProgression | import("../../actions/ui/next-slide").NextSlideAction | import("../../actions/ui/navigation").NavigateTo | import("../../actions/ui/navigation").NavigateBack | import("../../actions/ui/answers").EditAnswerAction | {
23
+ type: "@@ui/OPEN_POPIN";
24
+ } | {
25
+ type: "@@ui/CLOSE_POPIN";
26
+ }>;
17
27
  export default _default;
@@ -2,10 +2,14 @@ import { combineReducers } from 'redux';
2
2
  import currentSlideRef from './current-slide-ref';
3
3
  import navigation from './navigation';
4
4
  import answers from './answers';
5
+ import positions from './positions';
5
6
  import slide from './slide';
7
+ import showQuitPopin from './quit-popin';
6
8
  export default combineReducers({
7
9
  currentSlideRef,
8
10
  navigation,
9
11
  answers,
10
- slide
12
+ slide,
13
+ positions,
14
+ showQuitPopin
11
15
  });
@@ -0,0 +1,5 @@
1
+ import { ReceivedProgression } from '../../actions/api/post-progression';
2
+ import { NextSlideAction } from '../../actions/ui/next-slide';
3
+ export declare type UIPositionState = number[];
4
+ declare const reducer: (state: UIPositionState | undefined, action: NextSlideAction | ReceivedProgression) => UIPositionState;
5
+ export default reducer;
@@ -0,0 +1,25 @@
1
+ import findIndex from 'lodash/fp/findIndex';
2
+ import map from 'lodash/fp/map';
3
+ import set from 'lodash/fp/set';
4
+ import { POST_PROGRESSION_SUCCESS } from '../../actions/api/post-progression';
5
+ import { NEXT_SLIDE } from '../../actions/ui/next-slide';
6
+ const initialState = [0, 1, 2, 3, 4];
7
+ const reducer = (
8
+ // eslint-disable-next-line default-param-last
9
+ state = initialState, action) => {
10
+ switch (action.type) {
11
+ case POST_PROGRESSION_SUCCESS: {
12
+ return initialState;
13
+ }
14
+ case NEXT_SLIDE: {
15
+ const { totalCorrectAnswers, answeredSlides, currentSlideRef, animationType } = action.payload;
16
+ const nextCurrentSlidePosition = animationType === 'unstack' ? -1 : 4 - totalCorrectAnswers;
17
+ const currentSlideIndex = findIndex(ref => ref === currentSlideRef, answeredSlides);
18
+ const newState = map(position => (position === -1 ? position : position - 1), state);
19
+ return set([`${currentSlideIndex}`], nextCurrentSlidePosition)(newState);
20
+ }
21
+ default:
22
+ return state;
23
+ }
24
+ };
25
+ export default reducer;
@@ -0,0 +1,4 @@
1
+ import { closeQuitPopin, openQuitPopin } from '../../actions/ui/quit-popin';
2
+ export declare type ShowQuitPopinState = boolean;
3
+ declare const reducer: (state: boolean | undefined, action: typeof openQuitPopin | typeof closeQuitPopin) => ShowQuitPopinState;
4
+ export default reducer;
@@ -0,0 +1,16 @@
1
+ import { CLOSE_POPIN, OPEN_POPIN } from '../../actions/ui/quit-popin';
2
+ const reducer = (
3
+ // eslint-disable-next-line default-param-last
4
+ state = false, action) => {
5
+ switch (action.type) {
6
+ case OPEN_POPIN: {
7
+ return true;
8
+ }
9
+ case CLOSE_POPIN: {
10
+ return false;
11
+ }
12
+ default:
13
+ return state;
14
+ }
15
+ };
16
+ export default reducer;
@@ -2,7 +2,7 @@ import { EditAnswerAction } from '../../actions/ui/answers';
2
2
  import { PostAnswerRequestAction } from '../../actions/api/post-answer';
3
3
  import { ReceivedCorrection } from '../../actions/api/fetch-correction';
4
4
  import { FetchSlide } from '../../actions/api/fetch-slide';
5
- import { NextSlide } from '../../actions/ui/next-slide';
5
+ import { NextSlideAction } from '../../actions/ui/next-slide';
6
6
  import { SlideUIAnimations } from '../../types/slides';
7
7
  export declare type UISlide = {
8
8
  validateButton: boolean;
@@ -12,5 +12,5 @@ export declare type UISlide = {
12
12
  };
13
13
  export declare type UISlideState = Record<string, UISlide>;
14
14
  export declare const initialState: UISlideState;
15
- declare const reducer: (state: UISlideState | undefined, action: FetchSlide | PostAnswerRequestAction | EditAnswerAction | ReceivedCorrection | NextSlide) => UISlideState;
15
+ declare const reducer: (state: UISlideState | undefined, action: FetchSlide | PostAnswerRequestAction | EditAnswerAction | ReceivedCorrection | NextSlideAction) => UISlideState;
16
16
  export default reducer;
@@ -1,5 +1,5 @@
1
1
  import type { Dispatch } from 'redux';
2
- import type { SlideIndexes } from '../../common';
2
+ import { type SlideIndexes } from '../../common';
3
3
  import type { StoreState } from '../../reducers';
4
4
  import type { AnswerUI } from '../../types/slides';
5
5
  declare const ICON_VALUES: {
@@ -15,7 +15,6 @@ declare type StepItem = {
15
15
  };
16
16
  declare type SlideUIAnimations = 'unstack' | 'restack';
17
17
  export declare type ReviewSlide = {
18
- hidden: boolean;
19
18
  position: number;
20
19
  loading: boolean;
21
20
  showCorrectionPopin?: boolean;
@@ -41,6 +40,15 @@ declare type CorrectionPopinNext = {
41
40
  ariaLabel: string;
42
41
  onClick: Function;
43
42
  };
43
+ declare type QuitPopinButton = {
44
+ label: string;
45
+ type: string;
46
+ customStyle?: {
47
+ color: string;
48
+ };
49
+ handleOnclick: Function;
50
+ ariaLabel: string;
51
+ };
44
52
  export declare type CorrectionPopinProps = {
45
53
  klf?: CorrectionPopinKlf;
46
54
  information: CorrectionPopinInformation;
@@ -48,6 +56,14 @@ export declare type CorrectionPopinProps = {
48
56
  resultLabel: string;
49
57
  type: 'right' | 'wrong';
50
58
  };
59
+ export declare type QuitPopinProps = {
60
+ content: string;
61
+ icon: string;
62
+ mode: string;
63
+ descriptionText: string;
64
+ firstButton: QuitPopinButton;
65
+ secondButton: QuitPopinButton;
66
+ };
51
67
  export declare type SlidesViewProps = {
52
68
  header: {
53
69
  mode: string;
@@ -88,6 +104,7 @@ export declare type SlidesViewProps = {
88
104
  type: string;
89
105
  };
90
106
  };
107
+ quitPopin?: QuitPopinProps;
91
108
  };
92
109
  export declare const initialState: SlidesStack;
93
110
  export declare const buildStepItems: (state: StoreState) => StepItem[];
@@ -1,13 +1,13 @@
1
- import concat from 'lodash/fp/concat';
2
1
  import findLast from 'lodash/fp/findLast';
3
2
  import get from 'lodash/fp/get';
4
3
  import getOr from 'lodash/fp/getOr';
5
4
  import last from 'lodash/fp/last';
6
5
  import reduce from 'lodash/fp/reduce';
7
6
  import set from 'lodash/fp/set';
8
- import slice from 'lodash/fp/slice';
9
7
  import toInteger from 'lodash/fp/toInteger';
10
8
  import join from 'lodash/fp/join';
9
+ import { closeQuitPopin, openQuitPopin } from '../../actions/ui/quit-popin';
10
+ import { getProgressionSlidesRefs } from '../../common';
11
11
  import { postAnswer } from '../../actions/api/post-answer';
12
12
  import { nextSlide } from '../../actions/ui/next-slide';
13
13
  import { mapApiSlideToUi } from './map-api-slide-to-ui';
@@ -16,40 +16,29 @@ const ICON_VALUES = {
16
16
  wrong: 'wrong',
17
17
  'no-answer': 'no-answer'
18
18
  };
19
+ // TODO replace this, position no more needed
19
20
  export const initialState = {
20
21
  '0': {
21
- hidden: false,
22
22
  position: 0,
23
23
  loading: true
24
24
  },
25
25
  '1': {
26
- hidden: false,
27
26
  position: 1,
28
27
  loading: true
29
28
  },
30
29
  '2': {
31
- hidden: false,
32
30
  position: 2,
33
31
  loading: true
34
32
  },
35
33
  '3': {
36
- hidden: false,
37
34
  position: 3,
38
35
  loading: true
39
36
  },
40
37
  '4': {
41
- hidden: false,
42
38
  position: 4,
43
39
  loading: true
44
40
  }
45
41
  };
46
- const getProgressionSlidesRefs = (progression) => {
47
- if (progression.state.step.current < 5) {
48
- const slideRef = progression.state.nextContent.ref;
49
- return concat(progression.state.slides, [slideRef]);
50
- }
51
- return slice(0, 5, progression.state.slides);
52
- };
53
42
  const buildStackSlides = (state, dispatch) => {
54
43
  const currentSlideRef = state.ui.currentSlideRef;
55
44
  const progression = state.data.progression;
@@ -57,23 +46,27 @@ const buildStackSlides = (state, dispatch) => {
57
46
  return initialState;
58
47
  const slideRefs = getProgressionSlidesRefs(progression);
59
48
  // @ts-expect-error typescript does not support capped versions of lodash functions
60
- const stack = reduce.convert({ cap: false })((acc, uiSlide, index) => {
61
- const slideRef = slideRefs[toInteger(index)];
49
+ const stack = reduce.convert({ cap: false })((acc, uiSlide, _index) => {
50
+ const index = toInteger(_index);
51
+ const positions = state.ui.positions;
52
+ const position = positions[index];
53
+ const slideRef = slideRefs[index];
62
54
  if (!slideRef)
63
- return set(index, uiSlide, acc);
55
+ return set(index, { ...uiSlide, position }, acc);
64
56
  const slideFromAPI = get(slideRef, state.data.slides);
65
57
  if (!slideFromAPI)
66
- return set(index, uiSlide, acc);
58
+ return set(index, { ...uiSlide, position }, acc);
67
59
  const answers = getOr([], ['ui', 'answers', slideRef], state);
68
60
  const { questionText, answerUI } = mapApiSlideToUi(dispatch)(slideFromAPI, answers);
69
- const parentContentTitle = getOr('', 'parentContentTitle.title', slideFromAPI);
70
- const parentContentType = getOr('', 'parentContentTitle.type', slideFromAPI);
61
+ const { title: parentContentTitle, type: parentContentType } = slideFromAPI.parentContentTitle;
71
62
  const isCurrentSlideRef = currentSlideRef === slideRef;
72
- const animateCorrectionPopin = isCurrentSlideRef && get(['ui', 'slide', slideRef, 'animateCorrectionPopin'], state);
73
- const showCorrectionPopin = isCurrentSlideRef && get(['ui', 'slide', slideRef, 'showCorrectionPopin'], state);
74
- const animationType = get(['ui', 'slide', slideRef, 'animationType'], state);
63
+ const slideUI = get(['ui', 'slide', slideRef], state);
64
+ const animateCorrectionPopin = isCurrentSlideRef && slideUI.animateCorrectionPopin;
65
+ const showCorrectionPopin = isCurrentSlideRef && slideUI.showCorrectionPopin;
66
+ const animationType = slideUI.animationType;
75
67
  const updatedUiSlide = {
76
68
  ...uiSlide,
69
+ position,
77
70
  showCorrectionPopin,
78
71
  animateCorrectionPopin,
79
72
  loading: false,
@@ -176,16 +169,42 @@ const getCorrectionPopinProps = (dispatch) => (isCorrect, correctAnswer, klf) =>
176
169
  type: isCorrect ? 'right' : 'wrong'
177
170
  };
178
171
  };
172
+ const buildQuitPopinProps = (dispatch) => (onQuitClick) => {
173
+ return {
174
+ content: `Tu t'en vas déjà ?`,
175
+ icon: `MoonRocket`,
176
+ mode: 'alert',
177
+ descriptionText: `Tu vas t'en sortir ! Si tu arrêtes maintenant, tu vas perdre ta progression.`,
178
+ firstButton: {
179
+ label: 'Arrêter ma session',
180
+ type: 'tertiary',
181
+ customStyle: {
182
+ color: '#ED3436'
183
+ },
184
+ handleOnclick: onQuitClick,
185
+ ariaLabel: 'Stop session'
186
+ },
187
+ secondButton: {
188
+ label: `Continuer d'apprendre`,
189
+ type: 'primary',
190
+ handleOnclick: () => {
191
+ dispatch(closeQuitPopin);
192
+ },
193
+ ariaLabel: 'Continue review'
194
+ }
195
+ };
196
+ };
179
197
  export const mapStateToSlidesProps = (state, dispatch, onQuitClick) => {
180
198
  const currentSlideRef = get(['ui', 'currentSlideRef'], state);
181
199
  const correction = get(['data', 'corrections', currentSlideRef], state);
182
200
  const isCorrect = get(['data', 'progression', 'state', 'isCorrect'], state);
183
201
  const klf = getOr('', ['data', 'slides', currentSlideRef, 'klf'], state);
202
+ const showQuitPopin = get(['ui', 'showQuitPopin'], state);
184
203
  return {
185
204
  header: {
186
205
  mode: '__revision_mode',
187
206
  skillName: '__agility',
188
- onQuitClick,
207
+ onQuitClick: () => dispatch(openQuitPopin),
189
208
  'aria-label': 'aria-header-wrapper',
190
209
  closeButtonAriaLabel: 'aria-close-button',
191
210
  steps: buildStepItems(state)
@@ -202,6 +221,7 @@ export const mapStateToSlidesProps = (state, dispatch, onQuitClick) => {
202
221
  correctionPopinProps: correction && getCorrectionPopinProps(dispatch)(isCorrect, correction.correctAnswer, klf),
203
222
  endReview: false
204
223
  },
205
- congrats: undefined
224
+ congrats: undefined,
225
+ quitPopin: showQuitPopin === true ? buildQuitPopinProps(dispatch)(onQuitClick) : undefined
206
226
  };
207
227
  };
@@ -5,10 +5,12 @@ declare type NextSlidePayload = {
5
5
  currentSlideRef: string;
6
6
  nextSlideRef: string;
7
7
  animationType: string;
8
+ totalCorrectAnswers: number;
9
+ answeredSlides: string[];
8
10
  };
9
- export declare type NextSlide = {
11
+ export declare type NextSlideAction = {
10
12
  type: typeof NEXT_SLIDE;
11
13
  payload: NextSlidePayload;
12
14
  };
13
- export declare const nextSlide: (dispatch: Dispatch, getState: () => StoreState) => NextSlide;
15
+ export declare const nextSlide: (dispatch: Dispatch, getState: () => StoreState) => NextSlideAction;
14
16
  export {};
@@ -1,14 +1,17 @@
1
+ import filter from 'lodash/fp/filter';
1
2
  import get from 'lodash/fp/get';
2
- import getOr from 'lodash/fp/getOr';
3
3
  export var NEXT_SLIDE = '@@slide/NEXT_SLIDE';
4
4
  export var nextSlide = function (dispatch, getState) {
5
5
  var state = getState();
6
+ var progression = state.data.progression;
7
+ var _a = progression.state, isCorrect = _a.isCorrect, allAnswers = _a.allAnswers, slides = _a.slides;
8
+ var correctAnswers = filter(function (answer) { return answer.isCorrect; }, allAnswers);
6
9
  var payload = {
7
10
  currentSlideRef: get(['ui', 'currentSlideRef'], state),
8
11
  nextSlideRef: get(['state', 'nextContent', 'ref'], state.data.progression),
9
- animationType: getOr(false, ['state', 'isCorrect'], state.data.progression)
10
- ? 'unstack'
11
- : 'restack'
12
+ animationType: isCorrect ? 'unstack' : 'restack',
13
+ totalCorrectAnswers: correctAnswers.length,
14
+ answeredSlides: slides
12
15
  };
13
16
  var action = {
14
17
  type: NEXT_SLIDE,
@@ -0,0 +1,8 @@
1
+ export declare const OPEN_POPIN: "@@ui/OPEN_POPIN";
2
+ export declare const CLOSE_POPIN: "@@ui/CLOSE_POPIN";
3
+ export declare const openQuitPopin: {
4
+ type: "@@ui/OPEN_POPIN";
5
+ };
6
+ export declare const closeQuitPopin: {
7
+ type: "@@ui/CLOSE_POPIN";
8
+ };
@@ -0,0 +1,8 @@
1
+ export var OPEN_POPIN = '@@ui/OPEN_POPIN';
2
+ export var CLOSE_POPIN = '@@ui/CLOSE_POPIN';
3
+ export var openQuitPopin = {
4
+ type: OPEN_POPIN
5
+ };
6
+ export var closeQuitPopin = {
7
+ type: CLOSE_POPIN
8
+ };
@@ -12,10 +12,9 @@ export declare type Slide = {
12
12
  nextContent?: Omit<Slide, 'endReview' | 'hidden' | 'position' | 'nextContent'>;
13
13
  };
14
14
  export declare const SET_CURRENT_SLIDE: "@@slide/SET_CURRENT_SLIDE";
15
- export declare type SetCurrentSlide = {
15
+ export declare type SetCurrentSlideAction = {
16
16
  type: typeof SET_CURRENT_SLIDE;
17
17
  payload: SlideFromAPI;
18
18
  };
19
- export declare const setCurrentSlide: (payload: SlideFromAPI) => SetCurrentSlide;
20
- export declare type UISlidesAction = SetCurrentSlide;
19
+ export declare const setCurrentSlide: (payload: SlideFromAPI) => SetCurrentSlideAction;
21
20
  export {};
@@ -1,3 +1,4 @@
1
+ import type { ProgressionFromAPI } from '../types/common';
1
2
  export declare const VIEWS: {
2
3
  readonly skills: 'skills';
3
4
  readonly onboarding: 'onboarding';
@@ -5,3 +6,4 @@ export declare const VIEWS: {
5
6
  };
6
7
  export declare const slideIndexes: readonly ["0", "1", "2", "3", "4"];
7
8
  export declare type SlideIndexes = typeof slideIndexes[number];
9
+ export declare const getProgressionSlidesRefs: (progression: ProgressionFromAPI) => string[];
@@ -1,6 +1,15 @@
1
+ import concat from 'lodash/fp/concat';
2
+ import slice from 'lodash/fp/slice';
1
3
  export var VIEWS = {
2
4
  skills: 'skills',
3
5
  onboarding: 'onboarding',
4
6
  slides: 'slides'
5
7
  };
6
8
  export var slideIndexes = ['0', '1', '2', '3', '4'];
9
+ export var getProgressionSlidesRefs = function (progression) {
10
+ if (progression.state.step.current <= 5) {
11
+ var slideRef = progression.state.nextContent.ref;
12
+ return concat(progression.state.slides, [slideRef]);
13
+ }
14
+ return slice(0, 5, progression.state.slides);
15
+ };
@@ -18,6 +18,12 @@ declare const _default: import("redux").Reducer<import("redux").CombinedState<{
18
18
  navigation: import("./ui/navigation").NavigationState;
19
19
  answers: import("./ui/answers").UIAnswerState;
20
20
  slide: import("./ui/slide").UISlideState;
21
+ positions: import("./ui/positions").UIPositionState;
22
+ showQuitPopin: boolean;
21
23
  }>;
22
- }>, import("./data/corrections").CorrectionsAction | import("../actions/ui/slides").SetCurrentSlide | import("../actions/api/fetch-rank").RankAction | import("../actions/api/post-answer").PostAnswerRequestAction | import("../actions/api/post-answer").PostAnswerSuccessAction | import("../actions/api/post-progression").ReceivedProgression | import("../actions/api/fetch-skills").ReceivedSkills | import("./data/slides").SlidesAction | import("../actions/data/token").StoreToken | import("../actions/ui/navigation").NavigateTo | import("../actions/ui/navigation").NavigateBack | import("../actions/ui/answers").EditAnswerAction | import("../actions/ui/next-slide").NextSlide>;
24
+ }>, import("./data/corrections").CorrectionsAction | import("../actions/ui/slides").SetCurrentSlideAction | import("../actions/api/fetch-rank").RankAction | import("../actions/api/post-answer").PostAnswerRequestAction | import("../actions/api/post-answer").PostAnswerSuccessAction | import("../actions/api/post-progression").ReceivedProgression | import("../actions/api/fetch-skills").ReceivedSkills | import("./data/slides").SlidesAction | import("../actions/data/token").StoreToken | import("../actions/ui/next-slide").NextSlideAction | import("../actions/ui/navigation").NavigateTo | import("../actions/ui/navigation").NavigateBack | import("../actions/ui/answers").EditAnswerAction | {
25
+ type: "@@ui/OPEN_POPIN";
26
+ } | {
27
+ type: "@@ui/CLOSE_POPIN";
28
+ }>;
23
29
  export default _default;
@@ -1,7 +1,7 @@
1
1
  import { EditAnswerAction } from '../../actions/ui/answers';
2
- import { NextSlide } from '../../actions/ui/next-slide';
2
+ import { NextSlideAction } from '../../actions/ui/next-slide';
3
3
  export declare type UISlideAnswer = string[];
4
4
  export declare type UIAnswerState = Record<string, UISlideAnswer>;
5
5
  export declare const initialState: UIAnswerState;
6
- declare const reducer: (state: UIAnswerState | undefined, action: EditAnswerAction | NextSlide) => UIAnswerState;
6
+ declare const reducer: (state: UIAnswerState | undefined, action: EditAnswerAction | NextSlideAction) => UIAnswerState;
7
7
  export default reducer;
@@ -1,4 +1,5 @@
1
- import { UISlidesAction } from '../../actions/ui/slides';
1
+ import { NextSlideAction } from '../../actions/ui/next-slide';
2
+ import { SetCurrentSlideAction } from '../../actions/ui/slides';
2
3
  export declare type CurrentSlideRefState = string;
3
- declare const reducer: (state: string | undefined, action: UISlidesAction) => CurrentSlideRefState;
4
+ declare const reducer: (state: string | undefined, action: SetCurrentSlideAction | NextSlideAction) => CurrentSlideRefState;
4
5
  export default reducer;
@@ -1,9 +1,12 @@
1
+ import { NEXT_SLIDE } from '../../actions/ui/next-slide';
1
2
  import { SET_CURRENT_SLIDE } from '../../actions/ui/slides';
2
3
  var reducer = function (
3
4
  // eslint-disable-next-line default-param-last
4
5
  state, action) {
5
6
  if (state === void 0) { state = ''; }
6
7
  switch (action.type) {
8
+ case NEXT_SLIDE:
9
+ return action.payload.nextSlideRef;
7
10
  case SET_CURRENT_SLIDE: {
8
11
  return action.payload._id;
9
12
  }