@coorpacademy/app-review 0.1.5 → 0.1.8
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.
- package/es/actions/api/fetch-skills.d.ts +10 -0
- package/es/actions/api/fetch-skills.js +8 -0
- package/es/actions/api/fetch-slide.d.ts +10 -0
- package/es/actions/api/fetch-slide.js +8 -0
- package/es/actions/api/post-progression.d.ts +10 -0
- package/es/actions/api/post-progression.js +15 -0
- package/es/actions/data/slides.d.ts +7 -24
- package/es/actions/data/slides.js +0 -6
- package/es/actions/data/token.d.ts +2 -2
- package/es/actions/data/token.js +1 -1
- package/es/actions/index.d.ts +5 -3
- package/es/actions/ui/navigation.d.ts +0 -1
- package/es/actions/ui/navigation.js +0 -4
- package/es/actions/ui/step-items.d.ts +2 -8
- package/es/actions/ui/step-items.js +0 -6
- package/es/configure-store.d.ts +3 -34
- package/es/configure-store.js +4 -4
- package/es/fixtures/qcm-slide.d.ts +2 -2
- package/es/index.d.ts +1 -1
- package/es/index.js +78 -42
- package/es/reducers/data/index.d.ts +16 -5
- package/es/reducers/data/progression.d.ts +14 -9
- package/es/reducers/data/progression.js +18 -58
- package/es/reducers/data/skills.d.ts +4 -5
- package/es/reducers/data/skills.js +3 -6
- package/es/reducers/data/slides.d.ts +2 -1
- package/es/reducers/data/slides.js +14 -9
- package/es/reducers/data/token.d.ts +0 -1
- package/es/reducers/data/token.js +1 -5
- package/es/reducers/index.d.ts +9 -3
- package/es/reducers/ui/finished-slides.d.ts +0 -1
- package/es/reducers/ui/finished-slides.js +1 -3
- package/es/reducers/ui/index.d.ts +14 -4
- package/es/reducers/ui/navigation.d.ts +0 -1
- package/es/reducers/ui/navigation.js +1 -3
- package/es/reducers/ui/review-status.d.ts +0 -1
- package/es/reducers/ui/review-status.js +1 -4
- package/es/reducers/ui/step-items.d.ts +5 -5
- package/es/reducers/ui/step-items.js +0 -1
- package/es/services/fetch-skills.d.ts +2 -8
- package/es/services/fetch-skills.js +3 -16
- package/es/services/fetch-slide.d.ts +2 -0
- package/es/services/fetch-slide.js +11 -0
- package/es/services/index.d.ts +2 -0
- package/es/services/index.js +8 -0
- package/es/services/post-progression.d.ts +2 -0
- package/es/services/post-progression.js +21 -0
- package/es/services/test/fetch-skills.test.js +29 -0
- package/es/services/test/post-progression.test.js +35 -0
- package/es/services/tools/fetch-responses.d.ts +1 -1
- package/es/services/tools/sleep.d.ts +1 -0
- package/es/services/tools/sleep.js +3 -0
- package/es/{index.test.js → test/index.test.js} +18 -7
- package/es/test/util/services.mock.d.ts +2 -0
- package/es/test/util/services.mock.js +68 -0
- package/es/types/common.d.ts +66 -2
- package/es/types/common.js +5 -0
- package/es/types/slides.d.ts +1 -1
- package/es/types/ui-progression.d.ts +10 -0
- package/es/types/views/slides.d.ts +1 -1
- package/lib/actions/api/fetch-skills.d.ts +10 -0
- package/lib/actions/api/fetch-skills.js +13 -0
- package/lib/actions/api/fetch-slide.d.ts +10 -0
- package/lib/actions/api/fetch-slide.js +13 -0
- package/lib/actions/api/post-progression.d.ts +10 -0
- package/lib/actions/api/post-progression.js +18 -0
- package/lib/actions/data/slides.d.ts +7 -24
- package/lib/actions/data/slides.js +0 -6
- package/lib/actions/data/token.d.ts +2 -2
- package/lib/actions/data/token.js +1 -1
- package/lib/actions/index.d.ts +5 -3
- package/lib/actions/ui/navigation.d.ts +0 -1
- package/lib/actions/ui/navigation.js +0 -4
- package/lib/actions/ui/step-items.d.ts +2 -8
- package/lib/actions/ui/step-items.js +0 -6
- package/lib/configure-store.d.ts +3 -34
- package/lib/configure-store.js +4 -4
- package/lib/fixtures/qcm-slide.d.ts +2 -2
- package/lib/index.d.ts +1 -1
- package/lib/index.js +78 -86
- package/lib/reducers/data/index.d.ts +16 -5
- package/lib/reducers/data/progression.d.ts +14 -9
- package/lib/reducers/data/progression.js +18 -58
- package/lib/reducers/data/skills.d.ts +4 -5
- package/lib/reducers/data/skills.js +3 -6
- package/lib/reducers/data/slides.d.ts +2 -1
- package/lib/reducers/data/slides.js +14 -9
- package/lib/reducers/data/token.d.ts +0 -1
- package/lib/reducers/data/token.js +1 -5
- package/lib/reducers/index.d.ts +9 -3
- package/lib/reducers/ui/finished-slides.d.ts +0 -1
- package/lib/reducers/ui/finished-slides.js +1 -3
- package/lib/reducers/ui/index.d.ts +14 -4
- package/lib/reducers/ui/navigation.d.ts +0 -1
- package/lib/reducers/ui/navigation.js +1 -3
- package/lib/reducers/ui/review-status.d.ts +0 -1
- package/lib/reducers/ui/review-status.js +1 -4
- package/lib/reducers/ui/step-items.d.ts +5 -5
- package/lib/reducers/ui/step-items.js +0 -1
- package/lib/services/fetch-skills.d.ts +2 -8
- package/lib/services/fetch-skills.js +5 -20
- package/lib/services/fetch-slide.d.ts +2 -0
- package/lib/services/fetch-slide.js +57 -0
- package/lib/services/index.d.ts +2 -0
- package/lib/services/index.js +8 -0
- package/lib/services/post-progression.d.ts +2 -0
- package/lib/services/post-progression.js +65 -0
- package/lib/services/{fetch-skills.test.js → test/fetch-skills.test.js} +23 -16
- package/lib/services/test/post-progression.test.js +89 -0
- package/lib/services/tools/fetch-responses.d.ts +1 -1
- package/lib/services/tools/sleep.d.ts +1 -0
- package/lib/services/tools/sleep.js +5 -0
- package/lib/test/index.test.d.ts +1 -0
- package/lib/{index.test.js → test/index.test.js} +23 -15
- package/lib/test/util/services.mock.d.ts +2 -0
- package/lib/test/util/services.mock.js +68 -0
- package/lib/types/common.d.ts +66 -2
- package/lib/types/common.js +5 -0
- package/lib/types/slides.d.ts +1 -1
- package/lib/types/ui-progression.d.ts +10 -0
- package/lib/types/ui-progression.js +1 -0
- package/lib/types/views/slides.d.ts +1 -1
- package/package.json +6 -5
- package/readme.md +4 -5
- package/src/actions/api/fetch-skills.ts +20 -0
- package/src/actions/api/fetch-slide.ts +20 -0
- package/src/actions/api/post-progression.ts +26 -0
- package/src/actions/data/slides.ts +8 -32
- package/src/actions/data/token.ts +2 -2
- package/src/actions/index.ts +7 -10
- package/src/actions/ui/navigation.ts +0 -5
- package/src/actions/ui/step-items.ts +2 -14
- package/src/configure-store.ts +6 -45
- package/src/fixtures/qcm-slide.ts +2 -2
- package/src/index.tsx +94 -45
- package/src/reducers/data/index.ts +12 -4
- package/src/reducers/data/progression.ts +34 -79
- package/src/reducers/data/skills.ts +5 -10
- package/src/reducers/data/slides.ts +16 -15
- package/src/reducers/data/token.ts +1 -11
- package/src/reducers/index.ts +7 -2
- package/src/reducers/ui/finished-slides.ts +1 -7
- package/src/reducers/ui/index.ts +11 -4
- package/src/reducers/ui/navigation.ts +1 -6
- package/src/reducers/ui/review-status.ts +1 -8
- package/src/reducers/ui/step-items.ts +5 -14
- package/src/services/fetch-skills.ts +4 -30
- package/src/services/fetch-slide.ts +15 -0
- package/src/services/index.ts +10 -0
- package/src/services/post-progression.ts +28 -0
- package/src/services/test/fetch-skills.test.ts +39 -0
- package/src/services/test/post-progression.test.ts +45 -0
- package/src/services/tools/fetch-responses.ts +1 -1
- package/src/services/tools/sleep.ts +4 -0
- package/src/{index.test.tsx → test/index.test.tsx} +16 -10
- package/src/test/util/services.mock.ts +70 -0
- package/src/types/common.ts +78 -2
- package/src/types/globals.d.ts +2 -0
- package/src/types/slides.ts +1 -1
- package/src/types/ui-progression.ts +25 -0
- package/src/types/views/slides.ts +1 -1
- package/es/actions/data/skills.d.ts +0 -13
- package/es/actions/data/skills.js +0 -10
- package/es/middlewares/on-start-app.d.ts +0 -5
- package/es/middlewares/on-start-app.js +0 -29
- package/es/services/fetch-skills.mock.d.ts +0 -3
- package/es/services/fetch-skills.mock.js +0 -17
- package/es/services/fetch-skills.test.js +0 -22
- package/es/services/tools/fetch.mocks.d.ts +0 -8
- package/es/services/tools/fetch.mocks.js +0 -13
- package/es/types/skills.d.ts +0 -7
- package/lib/actions/data/skills.d.ts +0 -13
- package/lib/actions/data/skills.js +0 -10
- package/lib/middlewares/on-start-app.d.ts +0 -5
- package/lib/middlewares/on-start-app.js +0 -34
- package/lib/services/fetch-skills.mock.d.ts +0 -3
- package/lib/services/fetch-skills.mock.js +0 -17
- package/lib/services/tools/fetch.mocks.d.ts +0 -8
- package/lib/services/tools/fetch.mocks.js +0 -35
- package/lib/types/skills.d.ts +0 -7
- package/src/actions/data/skills.ts +0 -24
- package/src/middlewares/on-start-app.ts +0 -42
- package/src/services/fetch-skills.mock.ts +0 -21
- package/src/services/fetch-skills.test.ts +0 -32
- package/src/services/tools/fetch.mocks.ts +0 -41
- package/src/types/skills.ts +0 -8
- /package/es/services/{fetch-skills.test.d.ts → test/fetch-skills.test.d.ts} +0 -0
- /package/es/{index.test.d.ts → services/test/post-progression.test.d.ts} +0 -0
- /package/{lib → es/test}/index.test.d.ts +0 -0
- /package/es/types/{skills.js → ui-progression.js} +0 -0
- /package/lib/services/{fetch-skills.test.d.ts → test/fetch-skills.test.d.ts} +0 -0
- /package/lib/{types/skills.js → services/test/post-progression.test.d.ts} +0 -0
|
@@ -1,20 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
// -----------------------------------------------------------------------------
|
|
1
|
+
import {FinishedSlides, IconValue} from '../../types/common';
|
|
4
2
|
|
|
5
3
|
export const UPDATE_STEP_ITEMS_ON_VALIDATION = '@@step-items/UPDATE_STEP_ITEMS_ON_VALIDATION';
|
|
6
4
|
export const UPDATE_STEP_ITEMS_ON_NEXT = '@@step-items/UPDATE_STEP_ITEMS_ON_NEXT';
|
|
7
5
|
|
|
8
|
-
const ICON_VALUES = {
|
|
9
|
-
right: 'right',
|
|
10
|
-
wrong: 'wrong',
|
|
11
|
-
'no-answer': 'no-answer'
|
|
12
|
-
} as const;
|
|
13
|
-
|
|
14
|
-
// -----------------------------------------------------------------------------
|
|
15
|
-
|
|
16
|
-
export type IconValue = keyof typeof ICON_VALUES;
|
|
17
|
-
|
|
18
6
|
type UpdateStepItemsOnValidationClickPayload = {
|
|
19
7
|
stepNumber: number;
|
|
20
8
|
icon: IconValue;
|
|
@@ -22,7 +10,7 @@ type UpdateStepItemsOnValidationClickPayload = {
|
|
|
22
10
|
|
|
23
11
|
type UpdateStepItemsOnNextClickPayload = {
|
|
24
12
|
stepNumber: number;
|
|
25
|
-
finishedSlides:
|
|
13
|
+
finishedSlides: FinishedSlides;
|
|
26
14
|
current: boolean;
|
|
27
15
|
};
|
|
28
16
|
|
package/src/configure-store.ts
CHANGED
|
@@ -1,51 +1,11 @@
|
|
|
1
1
|
import {AnyAction, applyMiddleware, compose, createStore, Store} from 'redux';
|
|
2
2
|
import thunk from 'redux-thunk';
|
|
3
|
+
import rootReducer, {StoreState} from './reducers';
|
|
4
|
+
import {getServices} from './services';
|
|
3
5
|
|
|
4
|
-
import
|
|
5
|
-
import onStartApp from './middlewares/on-start-app';
|
|
6
|
+
import {AppOptions} from './types/common';
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
import {SlidesState} from './reducers/data/slides';
|
|
9
|
-
import {TokenState} from './reducers/data/token';
|
|
10
|
-
import {NavigationState} from './reducers/ui/navigation';
|
|
11
|
-
import {ReviewStatusState} from './reducers/ui/review-status';
|
|
12
|
-
import {StepItemsState} from './reducers/ui/step-items';
|
|
13
|
-
import {FinishedSlidesState} from './reducers/ui/finished-slides';
|
|
14
|
-
|
|
15
|
-
import {AnswerUI} from './types/slides';
|
|
16
|
-
|
|
17
|
-
// -----------------------------------------------------------------------------
|
|
18
|
-
|
|
19
|
-
type DataState = {
|
|
20
|
-
isFetching?: boolean;
|
|
21
|
-
progression?: {
|
|
22
|
-
slideNumber: number;
|
|
23
|
-
isCorrect?: boolean;
|
|
24
|
-
// pass down the successExitNode if all slides are finished, not before
|
|
25
|
-
exitNode?: 'successExitNode' | 'failExitNode';
|
|
26
|
-
nextSlide?: {
|
|
27
|
-
questionText?: string;
|
|
28
|
-
answerUI?: AnswerUI;
|
|
29
|
-
};
|
|
30
|
-
} | null;
|
|
31
|
-
skills: SkillsState;
|
|
32
|
-
slides: SlidesState;
|
|
33
|
-
token?: TokenState;
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
export type StoreState = {
|
|
37
|
-
ui: {
|
|
38
|
-
navigation: NavigationState;
|
|
39
|
-
stepItems: StepItemsState;
|
|
40
|
-
finishedSlides: FinishedSlidesState;
|
|
41
|
-
reviewStatus: ReviewStatusState;
|
|
42
|
-
};
|
|
43
|
-
data: DataState;
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
// -----------------------------------------------------------------------------
|
|
47
|
-
|
|
48
|
-
export default function configureStore(): Store<StoreState, AnyAction> {
|
|
8
|
+
export default function configureStore(options: AppOptions): Store<StoreState, AnyAction> {
|
|
49
9
|
const _compose = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
|
|
50
10
|
? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({
|
|
51
11
|
name: 'app-review',
|
|
@@ -54,7 +14,8 @@ export default function configureStore(): Store<StoreState, AnyAction> {
|
|
|
54
14
|
})
|
|
55
15
|
: compose;
|
|
56
16
|
|
|
57
|
-
const
|
|
17
|
+
const thunkMiddleware = thunk.withExtraArgument({services: options.services || getServices()});
|
|
18
|
+
const enhancer = _compose(applyMiddleware(thunkMiddleware));
|
|
58
19
|
const store = createStore(rootReducer, undefined, enhancer);
|
|
59
20
|
|
|
60
21
|
return store;
|
package/src/index.tsx
CHANGED
|
@@ -2,27 +2,33 @@ import React, {useEffect, useState} from 'react';
|
|
|
2
2
|
import {AnyAction, Store} from 'redux';
|
|
3
3
|
import {connect, Provider} from 'react-redux';
|
|
4
4
|
import AppReviewTemplate from '@coorpacademy/components/es/template/app-review';
|
|
5
|
+
import {TemplateContext} from '@coorpacademy/components/es/template/app-review/template-context';
|
|
5
6
|
|
|
6
|
-
import configureStore
|
|
7
|
+
import configureStore from './configure-store';
|
|
7
8
|
import {congratsProps, correctionPopinProps} from './fixtures/temp-fixture';
|
|
8
9
|
|
|
9
10
|
import type {AppOptions} from './types/common';
|
|
11
|
+
import type {StoreState} from './reducers';
|
|
10
12
|
import {SkillsProps} from './types/views/skills';
|
|
11
13
|
import type {SlidesViewStaticProps} from './types/views/slides';
|
|
12
14
|
|
|
13
15
|
import {Dispatchers} from './actions';
|
|
14
16
|
import {updateSlidesOnNext, updateSlidesOnValidation, validateSlide} from './actions/data/slides';
|
|
15
|
-
import {navigateTo, navigateBack,
|
|
17
|
+
import {navigateTo, navigateBack, ViewPath} from './actions/ui/navigation';
|
|
18
|
+
import {storeToken} from './actions/data/token';
|
|
16
19
|
import {updateFinishedSlides} from './actions/ui/finished-slides';
|
|
17
20
|
import {updateReviewStatus} from './actions/ui/review-status';
|
|
18
21
|
import {updateStepItemsOnValidation, updateStepItemsOnNext} from './actions/ui/step-items';
|
|
22
|
+
import {fetchSkills} from './actions/api/fetch-skills';
|
|
23
|
+
import {postProgression} from './actions/api/post-progression';
|
|
24
|
+
import {VIEWS} from './common';
|
|
19
25
|
|
|
20
26
|
// -----------------------------------------------------------------------------
|
|
21
27
|
|
|
22
28
|
type StaticProps = {
|
|
23
29
|
viewName: 'skills' | 'onboarding' | 'slides';
|
|
24
|
-
slides: SlidesViewStaticProps;
|
|
25
|
-
skills: SkillsProps;
|
|
30
|
+
slides: SlidesViewStaticProps | null;
|
|
31
|
+
skills: SkillsProps | null;
|
|
26
32
|
};
|
|
27
33
|
|
|
28
34
|
// -----------------------------------------------------------------------------
|
|
@@ -42,30 +48,43 @@ const mapDispatchToProps: Dispatchers = {
|
|
|
42
48
|
const getCurrentViewName = (storeState: StoreState): ViewPath =>
|
|
43
49
|
storeState.ui.navigation[storeState.ui.navigation.length - 1];
|
|
44
50
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
51
|
+
// -----------------------------------------------------------------------------
|
|
52
|
+
|
|
53
|
+
const mapStateToSkillsProps = (state: StoreState): SkillsProps | null => {
|
|
54
|
+
if (!state.data.skills) {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return {
|
|
59
|
+
title: '@todo title',
|
|
60
|
+
titleNoSkills: '@todo titleNoSkills',
|
|
61
|
+
textNoSkills: '@todo textNoSkills',
|
|
62
|
+
iconSkillAriaLabel: '@todo iconSkillAriaLabel',
|
|
63
|
+
isLoading: false,
|
|
64
|
+
isLoadingAriaLabel: '@todo loading',
|
|
65
|
+
listSkills: state.data.skills.map(skill => ({
|
|
66
|
+
'aria-label': '',
|
|
67
|
+
isCustom: skill.custom,
|
|
68
|
+
skillTitle: skill.name,
|
|
69
|
+
skillAriaLabel: '@todo skill aria label',
|
|
70
|
+
buttonLabel: '@todo button',
|
|
71
|
+
buttonAriaLabel: '@todo button aria label',
|
|
72
|
+
reviseLabel: '@todo revise',
|
|
73
|
+
reviseAriaLabel: '@todo revise aria label',
|
|
74
|
+
// eslint-disable-next-line no-console
|
|
75
|
+
onClick: () => console.log('@todo plug dispatcher select skill')
|
|
76
|
+
}))
|
|
77
|
+
};
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
// -----------------------------------------------------------------------------
|
|
81
|
+
|
|
82
|
+
const mapStateToSlidesProps = (state: StoreState): SlidesViewStaticProps | null => {
|
|
83
|
+
if (!state.data.slides) {
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return {
|
|
69
88
|
headerProps: {
|
|
70
89
|
mode: '__revision_mode',
|
|
71
90
|
skillName: '__agility',
|
|
@@ -86,9 +105,18 @@ const mapStateToProps = (state: StoreState): StaticProps => ({
|
|
|
86
105
|
correctionPopinProps,
|
|
87
106
|
congratsProps,
|
|
88
107
|
progression: state.data.progression
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
|
|
108
|
+
};
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
// -----------------------------------------------------------------------------
|
|
112
|
+
|
|
113
|
+
const mapStateToProps = (state: StoreState): StaticProps => {
|
|
114
|
+
return {
|
|
115
|
+
viewName: getCurrentViewName(state),
|
|
116
|
+
slides: mapStateToSlidesProps(state),
|
|
117
|
+
skills: mapStateToSkillsProps(state)
|
|
118
|
+
};
|
|
119
|
+
};
|
|
92
120
|
|
|
93
121
|
// Props = StaticProps && Dispatchers
|
|
94
122
|
|
|
@@ -96,28 +124,49 @@ const App = connect(mapStateToProps, mapDispatchToProps)(AppReviewTemplate);
|
|
|
96
124
|
|
|
97
125
|
// -----------------------------------------------------------------------------
|
|
98
126
|
|
|
99
|
-
const AppReview = ({options}: {options: AppOptions}): JSX.Element => {
|
|
127
|
+
const AppReview = ({options}: {options: AppOptions}): JSX.Element | null => {
|
|
100
128
|
const [store, setStore] = useState<Store<StoreState, AnyAction> | null>(null);
|
|
101
|
-
const [appStarted, setAppStarted] = useState<boolean>(false);
|
|
102
129
|
|
|
103
130
|
useEffect(() => {
|
|
104
|
-
if (store)
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
}
|
|
131
|
+
if (store) return;
|
|
132
|
+
|
|
133
|
+
const newStore = configureStore(options);
|
|
134
|
+
setStore(newStore);
|
|
135
|
+
}, [options, store]);
|
|
136
|
+
|
|
137
|
+
useEffect(() => {
|
|
138
|
+
if (store === null) return;
|
|
139
|
+
|
|
140
|
+
const {skillRef} = options;
|
|
141
|
+
const initialView: ViewPath = skillRef ? VIEWS.slides : VIEWS.skills;
|
|
142
|
+
store.dispatch(navigateTo(initialView));
|
|
143
|
+
}, [options, store]);
|
|
144
|
+
|
|
145
|
+
useEffect(() => {
|
|
146
|
+
if (store === null) return;
|
|
147
|
+
|
|
148
|
+
const {token} = options;
|
|
149
|
+
store.dispatch(storeToken(token));
|
|
114
150
|
}, [options, store]);
|
|
115
151
|
|
|
116
|
-
|
|
152
|
+
useEffect(() => {
|
|
153
|
+
if (store === null) return;
|
|
154
|
+
|
|
155
|
+
const {skillRef, token} = options;
|
|
156
|
+
skillRef
|
|
157
|
+
? store.dispatch(postProgression(skillRef, token))
|
|
158
|
+
: store.dispatch(fetchSkills(token));
|
|
159
|
+
}, [options, store]);
|
|
160
|
+
|
|
161
|
+
if (!store) return null;
|
|
162
|
+
|
|
163
|
+
const {templateContext: values} = options;
|
|
117
164
|
|
|
118
165
|
return (
|
|
119
166
|
<Provider store={store}>
|
|
120
|
-
<
|
|
167
|
+
<TemplateContext values={values}>
|
|
168
|
+
<App />
|
|
169
|
+
</TemplateContext>
|
|
121
170
|
</Provider>
|
|
122
171
|
);
|
|
123
172
|
};
|
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
import {combineReducers} from 'redux';
|
|
2
2
|
|
|
3
|
-
import progression from './progression';
|
|
4
|
-
import skills from './skills';
|
|
5
|
-
import slides from './slides';
|
|
6
|
-
import token from './token';
|
|
3
|
+
import progression, {ProgressionState} from './progression';
|
|
4
|
+
import skills, {SkillsState} from './skills';
|
|
5
|
+
import slides, {SlidesState} from './slides';
|
|
6
|
+
import token, {TokenState} from './token';
|
|
7
|
+
|
|
8
|
+
export type DataState = {
|
|
9
|
+
isFetching?: boolean;
|
|
10
|
+
progression?: ProgressionState;
|
|
11
|
+
skills: SkillsState;
|
|
12
|
+
slides: SlidesState;
|
|
13
|
+
token?: TokenState;
|
|
14
|
+
};
|
|
7
15
|
|
|
8
16
|
export default combineReducers({
|
|
9
17
|
progression,
|
|
@@ -1,101 +1,56 @@
|
|
|
1
|
-
import {getOr
|
|
1
|
+
import {getOr} from 'lodash/fp';
|
|
2
2
|
import {ValidateSlide, VALIDATE_SLIDE} from '../../actions/data/slides';
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
// -----------------------------------------------------------------------------
|
|
3
|
+
import {POST_PROGRESSION_SUCCESS, ReceiveProgression} from '../../actions/api/post-progression';
|
|
6
4
|
|
|
7
5
|
export type ProgressionState = {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
questionText?: string;
|
|
20
|
-
answerUI?: AnswerUI;
|
|
6
|
+
_id?: string;
|
|
7
|
+
state: {
|
|
8
|
+
isCorrect: boolean;
|
|
9
|
+
nextContent: {
|
|
10
|
+
ref: 'successExitNode' | string;
|
|
11
|
+
type: 'success' | 'slide';
|
|
12
|
+
};
|
|
13
|
+
pendingSlides: string[];
|
|
14
|
+
step: {
|
|
15
|
+
current: number;
|
|
16
|
+
};
|
|
21
17
|
};
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
export const initialState: ProgressionState = null;
|
|
27
|
-
|
|
28
|
-
// -----------------------------------------------------------------------------
|
|
18
|
+
// TO refactor: (slideNumber)
|
|
19
|
+
// virtual field
|
|
20
|
+
slideNumber?: number;
|
|
21
|
+
} | null; // TODO: ça ressemble beaucoup à ProgressionFromAPI et ça devrait l'être
|
|
29
22
|
|
|
30
23
|
const reducer = (
|
|
31
24
|
// eslint-disable-next-line default-param-last
|
|
32
|
-
state: ProgressionState =
|
|
33
|
-
action: ValidateSlide
|
|
25
|
+
state: ProgressionState = null,
|
|
26
|
+
action: ValidateSlide | ReceiveProgression
|
|
34
27
|
): ProgressionState => {
|
|
35
28
|
switch (action.type) {
|
|
36
29
|
case VALIDATE_SLIDE: {
|
|
37
30
|
const previousSlideNumber: number = getOr(-1, 'slideNumber', state);
|
|
38
31
|
// hard coded for now
|
|
32
|
+
// TODO: fix on VALIDATE ticket
|
|
39
33
|
return {
|
|
34
|
+
_id: '1234',
|
|
40
35
|
// virtual field
|
|
41
36
|
slideNumber: previousSlideNumber + 1,
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
questionText: 'Test',
|
|
52
|
-
answerUI: {
|
|
53
|
-
model: {
|
|
54
|
-
answers: [
|
|
55
|
-
{
|
|
56
|
-
title: 'There is no need for a password',
|
|
57
|
-
// TODO: onClick of each answer should use a dispatcher to
|
|
58
|
-
// update selected answers (in order to use them on validation)
|
|
59
|
-
// in each retrieval, the answers of answerUI need to be augmented
|
|
60
|
-
// for the onClick prop to achieve this.
|
|
61
|
-
onClick: noop,
|
|
62
|
-
selected: false,
|
|
63
|
-
help: 'help'
|
|
64
|
-
},
|
|
65
|
-
{
|
|
66
|
-
title: 'Lorem ipsum',
|
|
67
|
-
onClick: noop,
|
|
68
|
-
selected: false,
|
|
69
|
-
help: 'help'
|
|
70
|
-
},
|
|
71
|
-
{
|
|
72
|
-
title: 'Lorem',
|
|
73
|
-
onClick: noop,
|
|
74
|
-
selected: true,
|
|
75
|
-
order: 1,
|
|
76
|
-
help: 'help'
|
|
77
|
-
},
|
|
78
|
-
{
|
|
79
|
-
title: 'You need to have a password',
|
|
80
|
-
onClick: noop,
|
|
81
|
-
selected: false,
|
|
82
|
-
help: 'help'
|
|
83
|
-
},
|
|
84
|
-
{
|
|
85
|
-
title: 'Pouet',
|
|
86
|
-
onClick: noop,
|
|
87
|
-
selected: true,
|
|
88
|
-
order: 0,
|
|
89
|
-
help: 'help'
|
|
90
|
-
}
|
|
91
|
-
],
|
|
92
|
-
type: 'qcmDrag'
|
|
93
|
-
},
|
|
94
|
-
help: 'Help text will appear here'
|
|
37
|
+
state: {
|
|
38
|
+
pendingSlides: [],
|
|
39
|
+
step: {
|
|
40
|
+
current: Number.NaN
|
|
41
|
+
},
|
|
42
|
+
isCorrect: true,
|
|
43
|
+
nextContent: {
|
|
44
|
+
ref: 'sli_V1gKpYYZ2',
|
|
45
|
+
type: 'slide'
|
|
95
46
|
}
|
|
96
47
|
}
|
|
97
48
|
};
|
|
98
49
|
}
|
|
50
|
+
case POST_PROGRESSION_SUCCESS: {
|
|
51
|
+
const progression = action.payload;
|
|
52
|
+
return progression;
|
|
53
|
+
}
|
|
99
54
|
default:
|
|
100
55
|
return state;
|
|
101
56
|
}
|
|
@@ -1,21 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import {Skill} from '../../types/common';
|
|
2
|
+
import {ReceivedSkills, SKILLS_FETCH_SUCCESS} from '../../actions/api/fetch-skills';
|
|
3
3
|
|
|
4
|
-
export type SkillsState =
|
|
5
|
-
export const initialState: SkillsState = [];
|
|
6
|
-
|
|
7
|
-
// -----------------------------------------------------------------------------
|
|
4
|
+
export type SkillsState = Skill[];
|
|
8
5
|
|
|
9
6
|
// eslint-disable-next-line default-param-last
|
|
10
|
-
const reducer = (state: SkillsState =
|
|
7
|
+
const reducer = (state: SkillsState = [], action: ReceivedSkills): SkillsState => {
|
|
11
8
|
switch (action.type) {
|
|
12
|
-
case
|
|
9
|
+
case SKILLS_FETCH_SUCCESS:
|
|
13
10
|
return action.payload;
|
|
14
11
|
default:
|
|
15
12
|
return state;
|
|
16
13
|
}
|
|
17
14
|
};
|
|
18
15
|
|
|
19
|
-
// -----------------------------------------------------------------------------
|
|
20
|
-
|
|
21
16
|
export default reducer;
|
|
@@ -1,25 +1,22 @@
|
|
|
1
1
|
import map from 'lodash/fp/map';
|
|
2
2
|
import {
|
|
3
3
|
OnNextPayload,
|
|
4
|
-
Slide,
|
|
5
4
|
SlidesAction,
|
|
6
|
-
STORE_FIRST_SLIDE,
|
|
7
5
|
UPDATE_SLIDES_ON_NEXT,
|
|
8
6
|
UPDATE_SLIDES_ON_VALIDATION,
|
|
9
7
|
ValidationPayload
|
|
10
8
|
} from '../../actions/data/slides';
|
|
11
|
-
import {
|
|
9
|
+
import {UISlide} from '../../types/slides';
|
|
12
10
|
import {HIGHEST_INDEX, slideNumbers, TOTAL_SLIDES_STACK} from '../../common';
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
import {slide as qcmSlide} from '../../fixtures/qcm-slide';
|
|
12
|
+
import {SLIDE_FETCH_SUCCESS} from '../../actions/api/fetch-slide';
|
|
13
|
+
import {Slide} from '../../types/common';
|
|
15
14
|
|
|
16
15
|
export type SlidesState = {
|
|
17
16
|
slideNumbers: number[];
|
|
18
17
|
[key: number]: Slide;
|
|
19
18
|
};
|
|
20
19
|
|
|
21
|
-
// -----------------------------------------------------------------------------
|
|
22
|
-
|
|
23
20
|
const getInitialState = (): SlidesState => {
|
|
24
21
|
const state: SlidesState = {
|
|
25
22
|
slideNumbers
|
|
@@ -35,7 +32,7 @@ export const initialState: SlidesState = getInitialState();
|
|
|
35
32
|
|
|
36
33
|
// -----------------------------------------------------------------------------
|
|
37
34
|
|
|
38
|
-
const setFirstSlide = (state: SlidesState, slide:
|
|
35
|
+
const setFirstSlide = (state: SlidesState, slide: UISlide): SlidesState => {
|
|
39
36
|
const _state: SlidesState = {
|
|
40
37
|
slideNumbers
|
|
41
38
|
};
|
|
@@ -53,7 +50,7 @@ const setFirstSlide = (state: SlidesState, slide: SlideFromAPI): SlidesState =>
|
|
|
53
50
|
// ||-------> Handles the updates of a given slide on validation,
|
|
54
51
|
// & then updates de remaining slides if this given change should impact their content
|
|
55
52
|
const stateUpdateOnValidation = (state: SlidesState, payload: ValidationPayload): SlidesState => {
|
|
56
|
-
const {slideNumber, newSlideContent, numberOfFinishedSlides,
|
|
53
|
+
const {slideNumber, newSlideContent, numberOfFinishedSlides, nextContent} = payload;
|
|
57
54
|
const _state: SlidesState = {
|
|
58
55
|
slideNumbers
|
|
59
56
|
};
|
|
@@ -67,7 +64,7 @@ const stateUpdateOnValidation = (state: SlidesState, payload: ValidationPayload)
|
|
|
67
64
|
if (numberOfFinishedSlides === HIGHEST_INDEX) {
|
|
68
65
|
_state[index] = {
|
|
69
66
|
...previousValue,
|
|
70
|
-
|
|
67
|
+
nextContent,
|
|
71
68
|
position: newSlideContent.position,
|
|
72
69
|
isCorrect: newSlideContent.isCorrect
|
|
73
70
|
};
|
|
@@ -75,7 +72,7 @@ const stateUpdateOnValidation = (state: SlidesState, payload: ValidationPayload)
|
|
|
75
72
|
} else {
|
|
76
73
|
// updates the rest of the slides here
|
|
77
74
|
const {hidden, position} = previousValue;
|
|
78
|
-
_state[index] = {...
|
|
75
|
+
_state[index] = {...nextContent, endReview: newSlideContent.endReview, hidden, position};
|
|
79
76
|
}
|
|
80
77
|
}, state.slideNumbers);
|
|
81
78
|
|
|
@@ -96,8 +93,8 @@ const stateUpdateOnNext = (state: SlidesState, payload: OnNextPayload): SlidesSt
|
|
|
96
93
|
// the current slide
|
|
97
94
|
if (index === slideNumber) {
|
|
98
95
|
// when there is only one slide remaining, updates the slide value
|
|
99
|
-
if (numberOfFinishedSlides === HIGHEST_INDEX && previousValue.
|
|
100
|
-
_state[index] = {...previousValue.
|
|
96
|
+
if (numberOfFinishedSlides === HIGHEST_INDEX && previousValue.nextContent) {
|
|
97
|
+
_state[index] = {...previousValue.nextContent, position: previousValue.position};
|
|
101
98
|
} else _state[slideNumber] = newSlideContent;
|
|
102
99
|
} else {
|
|
103
100
|
// updates the rest of the slides here
|
|
@@ -120,8 +117,12 @@ const stateUpdateOnNext = (state: SlidesState, payload: OnNextPayload): SlidesSt
|
|
|
120
117
|
// eslint-disable-next-line default-param-last
|
|
121
118
|
const reducer = (state: SlidesState = initialState, action: SlidesAction): SlidesState => {
|
|
122
119
|
switch (action.type) {
|
|
123
|
-
case
|
|
124
|
-
|
|
120
|
+
case SLIDE_FETCH_SUCCESS: {
|
|
121
|
+
// TODO: An intermediate slide transform is needed here (or in fetchSlide)
|
|
122
|
+
// const apiSlide = action.payload;
|
|
123
|
+
// apiSlide adapt to uiSlide
|
|
124
|
+
const uiSlide = qcmSlide;
|
|
125
|
+
return setFirstSlide(state, uiSlide);
|
|
125
126
|
}
|
|
126
127
|
case UPDATE_SLIDES_ON_VALIDATION: {
|
|
127
128
|
return stateUpdateOnValidation(state, action.payload);
|
|
@@ -1,17 +1,9 @@
|
|
|
1
1
|
import {StoreToken, STORE_TOKEN} from '../../actions/data/token';
|
|
2
2
|
|
|
3
|
-
// -----------------------------------------------------------------------------
|
|
4
|
-
|
|
5
3
|
export type TokenState = string | null;
|
|
6
4
|
|
|
7
|
-
// -----------------------------------------------------------------------------
|
|
8
|
-
|
|
9
|
-
export const initialState: TokenState = null;
|
|
10
|
-
|
|
11
|
-
// -----------------------------------------------------------------------------
|
|
12
|
-
|
|
13
5
|
// eslint-disable-next-line default-param-last
|
|
14
|
-
const reducer = (state: TokenState =
|
|
6
|
+
const reducer = (state: TokenState = null, action: StoreToken): TokenState => {
|
|
15
7
|
switch (action.type) {
|
|
16
8
|
case STORE_TOKEN:
|
|
17
9
|
return action.payload;
|
|
@@ -20,6 +12,4 @@ const reducer = (state: TokenState = initialState, action: StoreToken): TokenSta
|
|
|
20
12
|
}
|
|
21
13
|
};
|
|
22
14
|
|
|
23
|
-
// -----------------------------------------------------------------------------
|
|
24
|
-
|
|
25
15
|
export default reducer;
|
package/src/reducers/index.ts
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import {combineReducers} from 'redux';
|
|
2
2
|
|
|
3
|
-
import data from './data';
|
|
4
|
-
import ui from './ui';
|
|
3
|
+
import data, {DataState} from './data';
|
|
4
|
+
import ui, {UIState} from './ui';
|
|
5
|
+
|
|
6
|
+
export type StoreState = {
|
|
7
|
+
ui: UIState;
|
|
8
|
+
data: DataState;
|
|
9
|
+
};
|
|
5
10
|
|
|
6
11
|
export default combineReducers({
|
|
7
12
|
data,
|
|
@@ -2,21 +2,15 @@ import forEach from 'lodash/fp/forEach';
|
|
|
2
2
|
import {UpdateFinishedSlides, UPDATE_FINISHED_SLIDES} from '../../actions/ui/finished-slides';
|
|
3
3
|
import {slideNumbers} from '../../common';
|
|
4
4
|
|
|
5
|
-
// -----------------------------------------------------------------------------
|
|
6
|
-
// Stores only successful slides
|
|
7
5
|
export type FinishedSlidesState = {
|
|
8
6
|
slideNumbers: number[];
|
|
9
7
|
[key: number]: true;
|
|
10
8
|
};
|
|
11
9
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
export const initialState: FinishedSlidesState = {
|
|
10
|
+
const initialState: FinishedSlidesState = {
|
|
15
11
|
slideNumbers
|
|
16
12
|
};
|
|
17
13
|
|
|
18
|
-
// -----------------------------------------------------------------------------
|
|
19
|
-
|
|
20
14
|
const _forEach: <T>(
|
|
21
15
|
iteratee: (value: T[keyof T], index: number) => void,
|
|
22
16
|
collection: T
|
package/src/reducers/ui/index.ts
CHANGED
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
import {combineReducers} from 'redux';
|
|
2
2
|
|
|
3
|
-
import finishedSlides from './finished-slides';
|
|
4
|
-
import navigation from './navigation';
|
|
5
|
-
import reviewStatus from './review-status';
|
|
6
|
-
import stepItems from './step-items';
|
|
3
|
+
import finishedSlides, {FinishedSlidesState} from './finished-slides';
|
|
4
|
+
import navigation, {NavigationState} from './navigation';
|
|
5
|
+
import reviewStatus, {ReviewStatusState} from './review-status';
|
|
6
|
+
import stepItems, {StepItemsState} from './step-items';
|
|
7
|
+
|
|
8
|
+
export type UIState = {
|
|
9
|
+
navigation: NavigationState;
|
|
10
|
+
stepItems: StepItemsState;
|
|
11
|
+
finishedSlides: FinishedSlidesState;
|
|
12
|
+
reviewStatus: ReviewStatusState;
|
|
13
|
+
};
|
|
7
14
|
|
|
8
15
|
export default combineReducers({
|
|
9
16
|
finishedSlides,
|