@coorpacademy/app-review 0.1.8 → 0.1.10
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 +8 -5
- package/es/actions/api/fetch-slide.d.ts +8 -5
- package/es/actions/api/post-progression.d.ts +8 -5
- package/es/actions/ui/navigation.d.ts +1 -1
- package/es/fixtures/qcm-slide.js +1 -1
- package/es/helpers/map-api-slide-to-ui.d.ts +8 -0
- package/es/helpers/map-api-slide-to-ui.js +175 -0
- package/es/helpers/test/fixtures/free-text.d.ts +4 -0
- package/es/helpers/test/fixtures/free-text.js +24 -0
- package/es/helpers/test/fixtures/qcm-drag.d.ts +4 -0
- package/es/helpers/test/fixtures/qcm-drag.js +106 -0
- package/es/helpers/test/fixtures/qcm-graphic.d.ts +4 -0
- package/es/helpers/test/fixtures/qcm-graphic.js +70 -0
- package/es/helpers/test/fixtures/qcm.d.ts +4 -0
- package/es/helpers/test/fixtures/qcm.js +99 -0
- package/es/helpers/test/fixtures/select-template.d.ts +4 -0
- package/es/helpers/test/fixtures/select-template.js +88 -0
- package/es/helpers/test/fixtures/slider.d.ts +4 -0
- package/es/helpers/test/fixtures/slider.js +27 -0
- package/es/helpers/test/fixtures/text-template.d.ts +4 -0
- package/es/helpers/test/fixtures/text-template.js +48 -0
- package/es/helpers/test/map-api-slide-to-ui.test.d.ts +1 -0
- package/es/helpers/test/map-api-slide-to-ui.test.js +32 -0
- package/es/index.d.ts +1 -1
- package/es/index.js +31 -16
- package/es/reducers/ui/navigation.d.ts +1 -1
- package/es/test/index.test.js +18 -15
- package/es/test/util/services.mock.js +2 -32
- package/es/types/common.d.ts +62 -5
- package/es/types/slides.d.ts +27 -16
- package/lib/actions/api/fetch-skills.d.ts +8 -5
- package/lib/actions/api/fetch-slide.d.ts +8 -5
- package/lib/actions/api/post-progression.d.ts +8 -5
- package/lib/actions/ui/navigation.d.ts +1 -1
- package/lib/fixtures/qcm-slide.js +1 -1
- package/lib/helpers/map-api-slide-to-ui.d.ts +8 -0
- package/lib/helpers/map-api-slide-to-ui.js +181 -0
- package/lib/helpers/test/fixtures/free-text.d.ts +4 -0
- package/lib/helpers/test/fixtures/free-text.js +24 -0
- package/lib/helpers/test/fixtures/qcm-drag.d.ts +4 -0
- package/lib/helpers/test/fixtures/qcm-drag.js +106 -0
- package/lib/helpers/test/fixtures/qcm-graphic.d.ts +4 -0
- package/lib/helpers/test/fixtures/qcm-graphic.js +70 -0
- package/lib/helpers/test/fixtures/qcm.d.ts +4 -0
- package/lib/helpers/test/fixtures/qcm.js +99 -0
- package/lib/helpers/test/fixtures/select-template.d.ts +4 -0
- package/lib/helpers/test/fixtures/select-template.js +88 -0
- package/lib/helpers/test/fixtures/slider.d.ts +4 -0
- package/lib/helpers/test/fixtures/slider.js +27 -0
- package/lib/helpers/test/fixtures/text-template.d.ts +4 -0
- package/lib/helpers/test/fixtures/text-template.js +48 -0
- package/lib/helpers/test/map-api-slide-to-ui.test.d.ts +1 -0
- package/lib/helpers/test/map-api-slide-to-ui.test.js +43 -0
- package/lib/index.d.ts +1 -1
- package/lib/index.js +31 -16
- package/lib/reducers/ui/navigation.d.ts +1 -1
- package/lib/test/index.test.js +19 -16
- package/lib/test/util/services.mock.js +13 -32
- package/lib/types/common.d.ts +62 -5
- package/lib/types/slides.d.ts +27 -16
- package/package.json +3 -3
- package/src/actions/api/fetch-skills.ts +8 -4
- package/src/actions/api/fetch-slide.ts +8 -4
- package/src/actions/api/post-progression.ts +14 -4
- package/src/actions/ui/navigation.ts +1 -1
- package/src/fixtures/qcm-slide.ts +1 -1
- package/src/helpers/map-api-slide-to-ui.ts +253 -0
- package/src/helpers/test/fixtures/free-text.ts +28 -0
- package/src/helpers/test/fixtures/qcm-drag.ts +110 -0
- package/src/helpers/test/fixtures/qcm-graphic.ts +74 -0
- package/src/helpers/test/fixtures/qcm.ts +108 -0
- package/src/helpers/test/fixtures/select-template.ts +92 -0
- package/src/helpers/test/fixtures/slider.ts +31 -0
- package/src/helpers/test/fixtures/text-template.ts +52 -0
- package/src/helpers/test/map-api-slide-to-ui.test.ts +55 -0
- package/src/index.tsx +39 -30
- package/src/reducers/ui/navigation.ts +1 -1
- package/src/test/index.test.tsx +23 -12
- package/src/test/util/services.mock.ts +2 -32
- package/src/types/common.ts +74 -5
- package/src/types/globals.d.ts +0 -5
- package/src/types/slides.ts +29 -12
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import noop from 'lodash/fp/noop';
|
|
2
|
+
import {Template} from '../../../types/slides';
|
|
3
|
+
import {SlideFromAPI} from '../../../types/common';
|
|
4
|
+
|
|
5
|
+
export const textTemplateSlide: SlideFromAPI = {
|
|
6
|
+
question: {
|
|
7
|
+
content: {
|
|
8
|
+
media: {
|
|
9
|
+
src: [],
|
|
10
|
+
posters: [],
|
|
11
|
+
subtitles: []
|
|
12
|
+
},
|
|
13
|
+
template: 'Un {{inp58402}} model.',
|
|
14
|
+
choices: [
|
|
15
|
+
{
|
|
16
|
+
media: {
|
|
17
|
+
src: [],
|
|
18
|
+
posters: [],
|
|
19
|
+
subtitles: []
|
|
20
|
+
},
|
|
21
|
+
items: [],
|
|
22
|
+
_id: '62433c2c58920f02c4950de0',
|
|
23
|
+
type: 'text',
|
|
24
|
+
name: 'inp58402',
|
|
25
|
+
id: '62433c2c58920f02c4950de0'
|
|
26
|
+
}
|
|
27
|
+
]
|
|
28
|
+
},
|
|
29
|
+
type: 'template',
|
|
30
|
+
header: 'Comment le protégé doit-il percevoir son mentor ?',
|
|
31
|
+
explanation: 'Saisissez votre réponse (en anglais).'
|
|
32
|
+
},
|
|
33
|
+
klf: "Le mentoré voit dans son mentor un <i>role model</i>, c'est-à-dire un exemple inspirant qui lui permet de se projeter dans un poste à responsabilité.",
|
|
34
|
+
tips: "L'origine de l'expression <i>role model</i> est attribué au sociologue Robert K. Merton.",
|
|
35
|
+
universalRef: 'sli_VJKQonm2g',
|
|
36
|
+
hasClue: true,
|
|
37
|
+
id: 'sli_VJKQonm2g'
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export const textTemplateUISlide: Template = {
|
|
41
|
+
type: 'template',
|
|
42
|
+
template: 'Un {{inp58402}} model.',
|
|
43
|
+
answers: [
|
|
44
|
+
{
|
|
45
|
+
type: 'text',
|
|
46
|
+
name: 'inp58402',
|
|
47
|
+
placeholder: 'Type here',
|
|
48
|
+
value: undefined,
|
|
49
|
+
onChange: noop
|
|
50
|
+
}
|
|
51
|
+
]
|
|
52
|
+
};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import test from 'ava';
|
|
2
|
+
import {SlideFromAPI} from '../../types/common';
|
|
3
|
+
import {mapApiSlideToUi} from '../map-api-slide-to-ui';
|
|
4
|
+
import {
|
|
5
|
+
QcmDrag,
|
|
6
|
+
Qcm,
|
|
7
|
+
QcmGraphic,
|
|
8
|
+
FreeText,
|
|
9
|
+
DropDown,
|
|
10
|
+
QuestionRange,
|
|
11
|
+
Template
|
|
12
|
+
} from '../../types/slides';
|
|
13
|
+
import {qcmUISlide, qcmSlide} from './fixtures/qcm';
|
|
14
|
+
import {qcmDragUISlide, qcmDragSlide} from './fixtures/qcm-drag';
|
|
15
|
+
import {freeTextSlide, freeTextUISlide} from './fixtures/free-text';
|
|
16
|
+
import {qcmGraphicUISlide, qcmGraphicSlide} from './fixtures/qcm-graphic';
|
|
17
|
+
import {textTemplateSlide, textTemplateUISlide} from './fixtures/text-template';
|
|
18
|
+
import {selectTemplateSlide, selectTemplateUISlide} from './fixtures/select-template';
|
|
19
|
+
import {sliderSlide, sliderUISlide} from './fixtures/slider';
|
|
20
|
+
|
|
21
|
+
const _mapApiSlideToUi = mapApiSlideToUi({translate: (text: string) => text});
|
|
22
|
+
|
|
23
|
+
const macro = test.macro({
|
|
24
|
+
title(providedTitle) {
|
|
25
|
+
return `should handle ${providedTitle} conversion`.trim();
|
|
26
|
+
},
|
|
27
|
+
exec(
|
|
28
|
+
t,
|
|
29
|
+
arg: {
|
|
30
|
+
slide: SlideFromAPI;
|
|
31
|
+
expectedUiSlide: QcmDrag | Qcm | QcmGraphic | FreeText | DropDown | QuestionRange | Template;
|
|
32
|
+
}
|
|
33
|
+
) {
|
|
34
|
+
t.deepEqual(
|
|
35
|
+
JSON.parse(JSON.stringify(_mapApiSlideToUi(arg.slide))),
|
|
36
|
+
JSON.parse(JSON.stringify(arg.expectedUiSlide))
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
test('qcm', macro, {slide: qcmSlide, expectedUiSlide: qcmUISlide});
|
|
42
|
+
test('qcm drag', macro, {slide: qcmDragSlide, expectedUiSlide: qcmDragUISlide});
|
|
43
|
+
test('qcm graphic', macro, {slide: qcmGraphicSlide, expectedUiSlide: qcmGraphicUISlide});
|
|
44
|
+
test('text template', macro, {slide: textTemplateSlide, expectedUiSlide: textTemplateUISlide});
|
|
45
|
+
test('select template', macro, {
|
|
46
|
+
slide: selectTemplateSlide,
|
|
47
|
+
expectedUiSlide: selectTemplateUISlide
|
|
48
|
+
});
|
|
49
|
+
test('free text', macro, {slide: freeTextSlide, expectedUiSlide: freeTextUISlide});
|
|
50
|
+
test('slider', macro, {slide: sliderSlide, expectedUiSlide: sliderUISlide});
|
|
51
|
+
|
|
52
|
+
test('should throw an error if the question type can not be handled', t => {
|
|
53
|
+
const faultySlide = {...qcmSlide, question: {type: 'lol'}};
|
|
54
|
+
t.throws(() => _mapApiSlideToUi(faultySlide as SlideFromAPI));
|
|
55
|
+
});
|
package/src/index.tsx
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import React, {useEffect, useState} from 'react';
|
|
2
|
+
import type {} from 'redux-thunk/extend-redux'; // https://github.com/reduxjs/redux-thunk/issues/333
|
|
2
3
|
import {AnyAction, Store} from 'redux';
|
|
3
4
|
import {connect, Provider} from 'react-redux';
|
|
4
5
|
import AppReviewTemplate from '@coorpacademy/components/es/template/app-review';
|
|
5
6
|
import {TemplateContext} from '@coorpacademy/components/es/template/app-review/template-context';
|
|
6
7
|
|
|
8
|
+
import isEmpty from 'lodash/fp/isEmpty';
|
|
9
|
+
import get from 'lodash/fp/get';
|
|
7
10
|
import configureStore from './configure-store';
|
|
8
11
|
import {congratsProps, correctionPopinProps} from './fixtures/temp-fixture';
|
|
9
12
|
|
|
@@ -23,16 +26,12 @@ import {fetchSkills} from './actions/api/fetch-skills';
|
|
|
23
26
|
import {postProgression} from './actions/api/post-progression';
|
|
24
27
|
import {VIEWS} from './common';
|
|
25
28
|
|
|
26
|
-
// -----------------------------------------------------------------------------
|
|
27
|
-
|
|
28
29
|
type StaticProps = {
|
|
29
|
-
viewName: 'skills' | 'onboarding' | 'slides';
|
|
30
|
+
viewName: 'skills' | 'onboarding' | 'slides' | 'loader';
|
|
30
31
|
slides: SlidesViewStaticProps | null;
|
|
31
32
|
skills: SkillsProps | null;
|
|
32
33
|
};
|
|
33
34
|
|
|
34
|
-
// -----------------------------------------------------------------------------
|
|
35
|
-
|
|
36
35
|
const mapDispatchToProps: Dispatchers = {
|
|
37
36
|
navigateTo,
|
|
38
37
|
navigateBack,
|
|
@@ -48,8 +47,6 @@ const mapDispatchToProps: Dispatchers = {
|
|
|
48
47
|
const getCurrentViewName = (storeState: StoreState): ViewPath =>
|
|
49
48
|
storeState.ui.navigation[storeState.ui.navigation.length - 1];
|
|
50
49
|
|
|
51
|
-
// -----------------------------------------------------------------------------
|
|
52
|
-
|
|
53
50
|
const mapStateToSkillsProps = (state: StoreState): SkillsProps | null => {
|
|
54
51
|
if (!state.data.skills) {
|
|
55
52
|
return null;
|
|
@@ -77,8 +74,6 @@ const mapStateToSkillsProps = (state: StoreState): SkillsProps | null => {
|
|
|
77
74
|
};
|
|
78
75
|
};
|
|
79
76
|
|
|
80
|
-
// -----------------------------------------------------------------------------
|
|
81
|
-
|
|
82
77
|
const mapStateToSlidesProps = (state: StoreState): SlidesViewStaticProps | null => {
|
|
83
78
|
if (!state.data.slides) {
|
|
84
79
|
return null;
|
|
@@ -108,8 +103,6 @@ const mapStateToSlidesProps = (state: StoreState): SlidesViewStaticProps | null
|
|
|
108
103
|
};
|
|
109
104
|
};
|
|
110
105
|
|
|
111
|
-
// -----------------------------------------------------------------------------
|
|
112
|
-
|
|
113
106
|
const mapStateToProps = (state: StoreState): StaticProps => {
|
|
114
107
|
return {
|
|
115
108
|
viewName: getCurrentViewName(state),
|
|
@@ -118,14 +111,11 @@ const mapStateToProps = (state: StoreState): StaticProps => {
|
|
|
118
111
|
};
|
|
119
112
|
};
|
|
120
113
|
|
|
121
|
-
// Props = StaticProps && Dispatchers
|
|
122
|
-
|
|
123
114
|
const App = connect(mapStateToProps, mapDispatchToProps)(AppReviewTemplate);
|
|
124
115
|
|
|
125
|
-
// -----------------------------------------------------------------------------
|
|
126
|
-
|
|
127
116
|
const AppReview = ({options}: {options: AppOptions}): JSX.Element | null => {
|
|
128
117
|
const [store, setStore] = useState<Store<StoreState, AnyAction> | null>(null);
|
|
118
|
+
const [isSlideFetched, setIsSlideFetched] = useState(false);
|
|
129
119
|
|
|
130
120
|
useEffect(() => {
|
|
131
121
|
if (store) return;
|
|
@@ -135,29 +125,52 @@ const AppReview = ({options}: {options: AppOptions}): JSX.Element | null => {
|
|
|
135
125
|
}, [options, store]);
|
|
136
126
|
|
|
137
127
|
useEffect(() => {
|
|
138
|
-
if (store
|
|
128
|
+
if (!store || isSlideFetched) return;
|
|
139
129
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
130
|
+
return store.subscribe(() => {
|
|
131
|
+
const isSlidePresent = !isEmpty(store.getState().data.slides[0].questionText);
|
|
132
|
+
return isSlidePresent && setIsSlideFetched(isSlidePresent);
|
|
133
|
+
}); // using the first slide questionText for now, should only check for a slide's presence
|
|
134
|
+
// when the refactor is done (slides will be feed one by one on api's side)
|
|
135
|
+
}, [isSlideFetched, options, store]);
|
|
144
136
|
|
|
145
137
|
useEffect(() => {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
const {token} = options;
|
|
138
|
+
const token = get('token', options);
|
|
139
|
+
if (store === null || isEmpty(token)) return;
|
|
149
140
|
store.dispatch(storeToken(token));
|
|
150
141
|
}, [options, store]);
|
|
151
142
|
|
|
152
143
|
useEffect(() => {
|
|
153
|
-
|
|
144
|
+
const token = get('token', options);
|
|
145
|
+
if (store === null || isEmpty(token)) return;
|
|
146
|
+
|
|
147
|
+
const skillRef = get('skillRef', options);
|
|
154
148
|
|
|
155
|
-
|
|
149
|
+
// ThunkAction is not assignable to parameter of type 'AnyAction'
|
|
150
|
+
// ts problem describre here = https://github.com/reduxjs/redux-thunk/issues/333
|
|
156
151
|
skillRef
|
|
157
152
|
? store.dispatch(postProgression(skillRef, token))
|
|
158
153
|
: store.dispatch(fetchSkills(token));
|
|
159
154
|
}, [options, store]);
|
|
160
155
|
|
|
156
|
+
useEffect(() => {
|
|
157
|
+
if (store === null) return;
|
|
158
|
+
|
|
159
|
+
const {skillRef} = options;
|
|
160
|
+
|
|
161
|
+
if (skillRef && !isSlideFetched) {
|
|
162
|
+
store.dispatch(navigateTo('loader')); // use loader while posting progression
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// TODO: when slides state is refactored (data + mapping),
|
|
167
|
+
// use loader in case a skillRef is found && no slides from the API
|
|
168
|
+
// are found
|
|
169
|
+
|
|
170
|
+
const initialView: ViewPath = skillRef ? VIEWS.slides : VIEWS.skills;
|
|
171
|
+
store.dispatch(navigateTo(initialView));
|
|
172
|
+
}, [isSlideFetched, options, store]);
|
|
173
|
+
|
|
161
174
|
if (!store) return null;
|
|
162
175
|
|
|
163
176
|
const {templateContext: values} = options;
|
|
@@ -171,15 +184,11 @@ const AppReview = ({options}: {options: AppOptions}): JSX.Element | null => {
|
|
|
171
184
|
);
|
|
172
185
|
};
|
|
173
186
|
|
|
174
|
-
// -----------------------------------------------------------------------------
|
|
175
|
-
|
|
176
187
|
declare global {
|
|
177
188
|
// eslint-disable-next-line no-shadow
|
|
178
189
|
interface Window {
|
|
179
|
-
|
|
190
|
+
__REDUX_DEVTOOLS_EXTENSION_COMPOSE__?: Function;
|
|
180
191
|
}
|
|
181
192
|
}
|
|
182
193
|
|
|
183
|
-
// -----------------------------------------------------------------------------
|
|
184
|
-
|
|
185
194
|
export default AppReview;
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
NAVIGATE_TO
|
|
6
6
|
} from '../../actions/ui/navigation';
|
|
7
7
|
|
|
8
|
-
export type NavigationState = Array<'skills' | 'onboarding' | 'slides'>;
|
|
8
|
+
export type NavigationState = Array<'skills' | 'onboarding' | 'slides' | 'loader'>;
|
|
9
9
|
|
|
10
10
|
const reducer = (
|
|
11
11
|
// eslint-disable-next-line default-param-last
|
package/src/test/index.test.tsx
CHANGED
|
@@ -65,24 +65,35 @@ const appOptions: AppOptions = {
|
|
|
65
65
|
services
|
|
66
66
|
};
|
|
67
67
|
|
|
68
|
-
test('should
|
|
69
|
-
// t.plan(13);
|
|
68
|
+
test('should show the loader while the app is fetching the data', async t => {
|
|
70
69
|
t.plan(2);
|
|
71
|
-
const {container} = render(<AppReview options={appOptions}
|
|
70
|
+
const {container} = render(<AppReview options={appOptions} />);
|
|
71
|
+
|
|
72
72
|
await waitForChanges(1000);
|
|
73
73
|
|
|
74
|
-
const
|
|
75
|
-
t.truthy(
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
74
|
+
const loader = container.querySelector('[data-name="loader"]');
|
|
75
|
+
t.truthy(loader);
|
|
76
|
+
|
|
77
|
+
// await waitFor(async () => {
|
|
78
|
+
// // await sleep(500);
|
|
79
|
+
// const result = await t.try(tt => {
|
|
80
|
+
// // rerender(<AppReview options={appOptions} />);
|
|
81
|
+
|
|
82
|
+
// const slidesContainer = container.querySelector('[data-name="slides-revision-container"]');
|
|
83
|
+
|
|
84
|
+
// tt.truthy(slidesContainer);
|
|
85
|
+
// });
|
|
86
|
+
|
|
87
|
+
// if (result.passed) return result.commit();
|
|
88
|
+
// result.discard();
|
|
89
|
+
// throw result.errors;
|
|
90
|
+
// });
|
|
79
91
|
|
|
80
|
-
const stackedSlidesContainer =
|
|
92
|
+
// const stackedSlidesContainer = container.querySelector('[data-name="stacked-slides-container"]');
|
|
81
93
|
|
|
82
|
-
t.truthy(stackedSlidesContainer);
|
|
94
|
+
// t.truthy(stackedSlidesContainer);
|
|
83
95
|
|
|
84
|
-
await clickAllSlides(t, container);
|
|
85
|
-
*/
|
|
96
|
+
// await clickAllSlides(t, container);
|
|
86
97
|
|
|
87
98
|
t.pass();
|
|
88
99
|
});
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import {qcmSlide} from '../../helpers/test/fixtures/qcm';
|
|
1
2
|
import {Services} from '../../types/common';
|
|
2
3
|
|
|
3
4
|
export const services: Services = {
|
|
@@ -18,38 +19,7 @@ export const services: Services = {
|
|
|
18
19
|
]);
|
|
19
20
|
},
|
|
20
21
|
fetchSlide: ref => {
|
|
21
|
-
|
|
22
|
-
return Promise.resolve({
|
|
23
|
-
question: {
|
|
24
|
-
content: {
|
|
25
|
-
choices: [
|
|
26
|
-
{
|
|
27
|
-
selected: false,
|
|
28
|
-
title: 'choix1',
|
|
29
|
-
help: '(help choix1)',
|
|
30
|
-
ariaLabel: '__ariaLabel1',
|
|
31
|
-
onClick: (): void => undefined
|
|
32
|
-
},
|
|
33
|
-
{
|
|
34
|
-
selected: false,
|
|
35
|
-
title: 'choix2',
|
|
36
|
-
help: '(help choix2)',
|
|
37
|
-
ariaLabel: '__ariaLabel2',
|
|
38
|
-
onClick: (): void => undefined
|
|
39
|
-
},
|
|
40
|
-
{
|
|
41
|
-
selected: false,
|
|
42
|
-
title: 'choix3',
|
|
43
|
-
help: '(help choix3)',
|
|
44
|
-
ariaLabel: '__ariaLabel3',
|
|
45
|
-
onClick: (): void => undefined
|
|
46
|
-
}
|
|
47
|
-
]
|
|
48
|
-
}
|
|
49
|
-
},
|
|
50
|
-
klf: '___klf',
|
|
51
|
-
universalRef: ref
|
|
52
|
-
});
|
|
22
|
+
return Promise.resolve({...qcmSlide, universalRef: ref, id: ref});
|
|
53
23
|
},
|
|
54
24
|
postProgression: () => {
|
|
55
25
|
return Promise.resolve({
|
package/src/types/common.ts
CHANGED
|
@@ -7,14 +7,83 @@ type TemplateContextValues = {
|
|
|
7
7
|
translations?: unknown; // TODO type Translations
|
|
8
8
|
};
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
// TODO: EDIT_CHOICES -> specify typing
|
|
11
|
+
export type ChoiceFromAPI = {
|
|
12
|
+
_id: string;
|
|
13
|
+
id?: string;
|
|
14
|
+
value?: string;
|
|
15
|
+
name?: string;
|
|
16
|
+
type?: 'text' | 'select';
|
|
17
|
+
label?: string;
|
|
18
|
+
items: {text: string; value: string; _id: string}[];
|
|
19
|
+
media?: unknown;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
type BaseContent = {
|
|
23
|
+
media?: unknown;
|
|
24
|
+
choices: ChoiceFromAPI[];
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
type Question = {
|
|
28
|
+
header?: string;
|
|
29
|
+
content: BaseContent;
|
|
30
|
+
explanation?: string;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export type QcmQuestion = Question & {
|
|
34
|
+
type: 'qcm';
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export type QcmGraphicQuestion = Question & {
|
|
38
|
+
type: 'qcmGraphic';
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export type QcmDragQuestion = Question & {
|
|
42
|
+
type: 'qcmDrag';
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export type BasicQuestion = Omit<Question, 'content'> & {
|
|
46
|
+
type: 'basic';
|
|
47
|
+
content: {
|
|
48
|
+
media?: unknown;
|
|
49
|
+
label?: string;
|
|
50
|
+
placeholder?: string;
|
|
51
|
+
id: string;
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export type SliderQuestion = Omit<Question, 'content'> & {
|
|
56
|
+
content: {
|
|
57
|
+
media?: unknown;
|
|
58
|
+
unitLabel: string;
|
|
59
|
+
min: number;
|
|
60
|
+
max: number;
|
|
61
|
+
step?: number;
|
|
15
62
|
};
|
|
63
|
+
type: 'slider';
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
export type TemplateQuestion = Omit<Question, 'content'> & {
|
|
67
|
+
content: BaseContent & {
|
|
68
|
+
template: string;
|
|
69
|
+
};
|
|
70
|
+
type: 'template';
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export type SlideFromAPI = {
|
|
74
|
+
question:
|
|
75
|
+
| QcmQuestion
|
|
76
|
+
| QcmGraphicQuestion
|
|
77
|
+
| QcmDragQuestion
|
|
78
|
+
| BasicQuestion
|
|
79
|
+
| SliderQuestion
|
|
80
|
+
| TemplateQuestion;
|
|
16
81
|
klf: string;
|
|
17
82
|
universalRef: string;
|
|
83
|
+
tips?: string;
|
|
84
|
+
clue?: string;
|
|
85
|
+
hasClue?: boolean;
|
|
86
|
+
id?: string;
|
|
18
87
|
};
|
|
19
88
|
|
|
20
89
|
export type ProgressionFromAPI = {
|
package/src/types/globals.d.ts
CHANGED
|
@@ -3,8 +3,3 @@ declare module 'browser-env';
|
|
|
3
3
|
declare module '@coorpacademy/components/es/template/app-review';
|
|
4
4
|
declare module '@coorpacademy/components/es/template/app-review/template-context';
|
|
5
5
|
declare module '@coorpacademy/redux-task';
|
|
6
|
-
|
|
7
|
-
// eslint-disable-next-line no-shadow
|
|
8
|
-
declare interface Window {
|
|
9
|
-
__REDUX_DEVTOOLS_EXTENSION_COMPOSE__?: Function;
|
|
10
|
-
}
|
package/src/types/slides.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
export type Choice = {
|
|
2
2
|
order?: number;
|
|
3
3
|
selected: boolean;
|
|
4
|
-
title
|
|
5
|
-
help
|
|
4
|
+
title?: string;
|
|
5
|
+
help?: string;
|
|
6
6
|
onClick: Function;
|
|
7
|
+
ariaLabel?: string;
|
|
7
8
|
};
|
|
8
9
|
|
|
9
10
|
export type QcmDrag = {
|
|
@@ -14,20 +15,20 @@ export type QcmDrag = {
|
|
|
14
15
|
|
|
15
16
|
export type Qcm = {
|
|
16
17
|
type: 'qcm';
|
|
17
|
-
|
|
18
|
+
answers: Choice[];
|
|
18
19
|
};
|
|
19
20
|
|
|
20
21
|
export type QcmGraphic = {
|
|
21
22
|
type: 'qcmGraphic';
|
|
22
|
-
|
|
23
|
+
answers: (Choice & {image: string})[];
|
|
23
24
|
};
|
|
24
25
|
|
|
25
26
|
export type FreeText = {
|
|
26
27
|
type: 'freeText';
|
|
27
28
|
placeholder: string;
|
|
28
|
-
value
|
|
29
|
+
value?: string;
|
|
29
30
|
onChange: Function;
|
|
30
|
-
ariaLabel
|
|
31
|
+
ariaLabel?: string;
|
|
31
32
|
};
|
|
32
33
|
|
|
33
34
|
export type DropDownOption = {
|
|
@@ -39,9 +40,9 @@ export type DropDownOption = {
|
|
|
39
40
|
|
|
40
41
|
export type DropDown = {
|
|
41
42
|
type: 'dropDown';
|
|
42
|
-
onChange
|
|
43
|
+
onChange?: Function;
|
|
43
44
|
options: DropDownOption[];
|
|
44
|
-
theme
|
|
45
|
+
theme?:
|
|
45
46
|
| 'filter'
|
|
46
47
|
| 'invalid'
|
|
47
48
|
| 'header'
|
|
@@ -56,19 +57,35 @@ export type DropDown = {
|
|
|
56
57
|
|
|
57
58
|
export type QuestionRange = {
|
|
58
59
|
type: 'slider';
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
60
|
+
placeholder?: string;
|
|
61
|
+
onChange?: Function;
|
|
62
|
+
onChangeEnd?: Function;
|
|
63
|
+
multi?: boolean;
|
|
62
64
|
value: number | number[];
|
|
63
65
|
title: string;
|
|
64
66
|
minLabel: string;
|
|
65
67
|
maxLabel: string;
|
|
66
68
|
};
|
|
67
69
|
|
|
70
|
+
export type TextTemplate = {
|
|
71
|
+
type: 'text';
|
|
72
|
+
name: string;
|
|
73
|
+
placeholder: string;
|
|
74
|
+
value?: string;
|
|
75
|
+
onChange: Function;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
export type SelectionTemplate = {
|
|
79
|
+
type: 'select';
|
|
80
|
+
name: string;
|
|
81
|
+
onChange?: Function;
|
|
82
|
+
options?: DropDownOption[];
|
|
83
|
+
};
|
|
84
|
+
|
|
68
85
|
export type Template = {
|
|
69
86
|
type: 'template';
|
|
70
87
|
template: string;
|
|
71
|
-
|
|
88
|
+
answers: (TextTemplate | SelectionTemplate)[];
|
|
72
89
|
};
|
|
73
90
|
|
|
74
91
|
export type AnswerUI = {
|