@coorpacademy/app-review 0.1.5 → 0.1.7
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/data/progression.d.ts +30 -0
- package/es/actions/data/progression.js +12 -0
- package/es/actions/data/slides.d.ts +19 -15
- package/es/actions/data/slides.js +5 -0
- package/es/actions/data/token.d.ts +2 -2
- package/es/actions/data/token.js +1 -1
- package/es/actions/index.d.ts +2 -1
- package/es/configure-store.d.ts +2 -10
- package/es/configure-store.js +2 -1
- package/es/index.d.ts +1 -1
- package/es/index.js +43 -26
- package/es/index.test.js +5 -5
- package/es/middlewares/on-receive-progression.d.ts +6 -0
- package/es/middlewares/on-receive-progression.js +22 -0
- package/es/middlewares/on-receive-progression.test.d.ts +1 -0
- package/es/middlewares/on-receive-progression.test.js +43 -0
- package/es/middlewares/on-start-app.js +13 -5
- package/es/middlewares/on-start-app.test.d.ts +1 -0
- package/es/middlewares/on-start-app.test.js +53 -0
- package/es/reducers/data/index.d.ts +1 -1
- package/es/reducers/data/progression.d.ts +14 -8
- package/es/reducers/data/progression.js +17 -54
- package/es/reducers/data/slides.js +11 -6
- package/es/reducers/index.d.ts +1 -1
- package/es/services/fetch-skills.js +1 -2
- package/es/services/fetch-slide.d.ts +8 -0
- package/es/services/fetch-slide.js +26 -0
- package/es/services/post-progression.d.ts +8 -0
- package/es/services/post-progression.js +33 -0
- package/es/services/post-progression.mock.d.ts +5 -0
- package/es/services/post-progression.mock.js +31 -0
- package/es/services/post-progression.test.d.ts +1 -0
- package/es/services/post-progression.test.js +30 -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/types/common.d.ts +8 -2
- package/es/types/ui-progression.d.ts +10 -0
- package/es/types/ui-progression.js +1 -0
- package/lib/actions/data/progression.d.ts +30 -0
- package/lib/actions/data/progression.js +12 -0
- package/lib/actions/data/slides.d.ts +19 -15
- package/lib/actions/data/slides.js +5 -0
- package/lib/actions/data/token.d.ts +2 -2
- package/lib/actions/data/token.js +1 -1
- package/lib/actions/index.d.ts +2 -1
- package/lib/configure-store.d.ts +2 -10
- package/lib/configure-store.js +2 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.js +43 -26
- package/lib/index.test.js +5 -7
- package/lib/middlewares/on-receive-progression.d.ts +6 -0
- package/lib/middlewares/on-receive-progression.js +27 -0
- package/lib/middlewares/on-receive-progression.test.d.ts +1 -0
- package/lib/middlewares/on-receive-progression.test.js +88 -0
- package/lib/middlewares/on-start-app.js +15 -7
- package/lib/middlewares/on-start-app.test.d.ts +1 -0
- package/lib/middlewares/on-start-app.test.js +98 -0
- package/lib/reducers/data/index.d.ts +1 -1
- package/lib/reducers/data/progression.d.ts +14 -8
- package/lib/reducers/data/progression.js +17 -54
- package/lib/reducers/data/slides.js +11 -6
- package/lib/reducers/index.d.ts +1 -1
- package/lib/services/fetch-skills.js +2 -5
- package/lib/services/fetch-slide.d.ts +8 -0
- package/lib/services/fetch-slide.js +64 -0
- package/lib/services/post-progression.d.ts +8 -0
- package/lib/services/post-progression.js +77 -0
- package/lib/services/post-progression.mock.d.ts +5 -0
- package/lib/services/post-progression.mock.js +31 -0
- package/lib/services/post-progression.test.d.ts +1 -0
- package/lib/services/post-progression.test.js +84 -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/types/common.d.ts +8 -2
- package/lib/types/ui-progression.d.ts +10 -0
- package/lib/types/ui-progression.js +1 -0
- package/package.json +4 -5
- package/readme.md +4 -5
- package/src/actions/data/progression.ts +50 -0
- package/src/actions/data/slides.ts +25 -17
- package/src/actions/data/token.ts +2 -2
- package/src/actions/index.ts +4 -1
- package/src/configure-store.ts +5 -13
- package/src/index.test.tsx +5 -7
- package/src/index.tsx +54 -29
- package/src/middlewares/on-receive-progression.test.ts +60 -0
- package/src/middlewares/on-receive-progression.ts +42 -0
- package/src/middlewares/on-start-app.test.ts +68 -0
- package/src/middlewares/on-start-app.ts +13 -5
- package/src/reducers/data/progression.ts +34 -69
- package/src/reducers/data/slides.ts +13 -8
- package/src/services/fetch-skills.ts +1 -2
- package/src/services/fetch-slide.ts +43 -0
- package/src/services/post-progression.mock.ts +35 -0
- package/src/services/post-progression.test.ts +41 -0
- package/src/services/post-progression.ts +50 -0
- package/src/services/tools/fetch-responses.ts +1 -1
- package/src/services/tools/sleep.ts +4 -0
- package/src/types/common.ts +8 -2
- package/src/types/globals.d.ts +1 -0
- package/src/types/ui-progression.ts +25 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import map from 'lodash/fp/map';
|
|
2
2
|
import { STORE_FIRST_SLIDE, UPDATE_SLIDES_ON_NEXT, UPDATE_SLIDES_ON_VALIDATION } from '../../actions/data/slides';
|
|
3
3
|
import { HIGHEST_INDEX, slideNumbers, TOTAL_SLIDES_STACK } from '../../common';
|
|
4
|
+
import { slide as qcmSlide } from '../../fixtures/qcm-slide';
|
|
4
5
|
// -----------------------------------------------------------------------------
|
|
5
6
|
const getInitialState = () => {
|
|
6
7
|
const state = {
|
|
@@ -30,7 +31,7 @@ const setFirstSlide = (state, slide) => {
|
|
|
30
31
|
// ||-------> Handles the updates of a given slide on validation,
|
|
31
32
|
// & then updates de remaining slides if this given change should impact their content
|
|
32
33
|
const stateUpdateOnValidation = (state, payload) => {
|
|
33
|
-
const { slideNumber, newSlideContent, numberOfFinishedSlides,
|
|
34
|
+
const { slideNumber, newSlideContent, numberOfFinishedSlides, nextContent } = payload;
|
|
34
35
|
const _state = {
|
|
35
36
|
slideNumbers
|
|
36
37
|
};
|
|
@@ -43,7 +44,7 @@ const stateUpdateOnValidation = (state, payload) => {
|
|
|
43
44
|
if (numberOfFinishedSlides === HIGHEST_INDEX) {
|
|
44
45
|
_state[index] = {
|
|
45
46
|
...previousValue,
|
|
46
|
-
|
|
47
|
+
nextContent,
|
|
47
48
|
position: newSlideContent.position,
|
|
48
49
|
isCorrect: newSlideContent.isCorrect
|
|
49
50
|
};
|
|
@@ -54,7 +55,7 @@ const stateUpdateOnValidation = (state, payload) => {
|
|
|
54
55
|
else {
|
|
55
56
|
// updates the rest of the slides here
|
|
56
57
|
const { hidden, position } = previousValue;
|
|
57
|
-
_state[index] = { ...
|
|
58
|
+
_state[index] = { ...nextContent, endReview: newSlideContent.endReview, hidden, position };
|
|
58
59
|
}
|
|
59
60
|
}, state.slideNumbers);
|
|
60
61
|
return _state;
|
|
@@ -72,8 +73,8 @@ const stateUpdateOnNext = (state, payload) => {
|
|
|
72
73
|
// the current slide
|
|
73
74
|
if (index === slideNumber) {
|
|
74
75
|
// when there is only one slide remaining, updates the slide value
|
|
75
|
-
if (numberOfFinishedSlides === HIGHEST_INDEX && previousValue.
|
|
76
|
-
_state[index] = { ...previousValue.
|
|
76
|
+
if (numberOfFinishedSlides === HIGHEST_INDEX && previousValue.nextContent) {
|
|
77
|
+
_state[index] = { ...previousValue.nextContent, position: previousValue.position };
|
|
77
78
|
}
|
|
78
79
|
else
|
|
79
80
|
_state[slideNumber] = newSlideContent;
|
|
@@ -97,7 +98,11 @@ const stateUpdateOnNext = (state, payload) => {
|
|
|
97
98
|
const reducer = (state = initialState, action) => {
|
|
98
99
|
switch (action.type) {
|
|
99
100
|
case STORE_FIRST_SLIDE: {
|
|
100
|
-
|
|
101
|
+
// TODO: An intermediate slide transform is needed here (or in fetchSlide)
|
|
102
|
+
// const apiSlide = action.payload;
|
|
103
|
+
// apiSlide adapt to uiSlide
|
|
104
|
+
const uiSlide = qcmSlide;
|
|
105
|
+
return setFirstSlide(state, uiSlide);
|
|
101
106
|
}
|
|
102
107
|
case UPDATE_SLIDES_ON_VALIDATION: {
|
|
103
108
|
return stateUpdateOnValidation(state, action.payload);
|
package/es/reducers/index.d.ts
CHANGED
|
@@ -11,5 +11,5 @@ declare const _default: import("redux").Reducer<import("redux").CombinedState<{
|
|
|
11
11
|
reviewStatus: import("./ui/review-status").ReviewStatusState;
|
|
12
12
|
stepItems: import("./ui/step-items").StepItems;
|
|
13
13
|
}>;
|
|
14
|
-
}>, import("../actions/data/slides").ValidateSlide | import("../actions/data/slides").SlidesAction | import("../actions/data/skills").ReceivedSkills | import("../actions/data/token").StoreToken | import("../actions/ui/finished-slides").UpdateFinishedSlides | import("../actions/ui/navigation").NavigateTo | import("../actions/ui/navigation").NavigateBack | import("../actions/ui/review-status").UpdateReviewStatus | import("../actions/ui/step-items").StepItemsAction>;
|
|
14
|
+
}>, import("../actions/data/progression").ReceiveProgression | import("../actions/data/slides").ValidateSlide | import("../actions/data/slides").SlidesAction | import("../actions/data/skills").ReceivedSkills | import("../actions/data/token").StoreToken | import("../actions/ui/finished-slides").UpdateFinishedSlides | import("../actions/ui/navigation").NavigateTo | import("../actions/ui/navigation").NavigateBack | import("../actions/ui/review-status").UpdateReviewStatus | import("../actions/ui/step-items").StepItemsAction>;
|
|
15
15
|
export default _default;
|
|
@@ -8,8 +8,7 @@ const fetchSkills = fetch => async (token) => {
|
|
|
8
8
|
const response = await fetch(`${host}/api/v2/skills/review/user/${userId}`, {
|
|
9
9
|
headers: { authorization: token }
|
|
10
10
|
});
|
|
11
|
-
|
|
12
|
-
return skills;
|
|
11
|
+
return toJSON(response);
|
|
13
12
|
};
|
|
14
13
|
// -----------------------------------------------------------------------------
|
|
15
14
|
const createFetchSkills = () => {
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import crossFetch from 'cross-fetch';
|
|
2
|
+
import { SlideFromAPI } from '../actions/data/slides';
|
|
3
|
+
declare type FetchSlide = (slideRef: string, token: string) => Promise<SlideFromAPI>;
|
|
4
|
+
declare type FetchSlideBuilder = (fetch: typeof crossFetch) => FetchSlide;
|
|
5
|
+
declare const fetchSlide: FetchSlideBuilder;
|
|
6
|
+
export { fetchSlide };
|
|
7
|
+
declare const _default: FetchSlide;
|
|
8
|
+
export default _default;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import crossFetch from 'cross-fetch';
|
|
2
|
+
// import {JWT} from '../types/common';
|
|
3
|
+
// import {toJSON} from './tools/fetch-responses';
|
|
4
|
+
import { okJSONResponse } from './tools/fetch.mocks';
|
|
5
|
+
// -----------------------------------------------------------------------------
|
|
6
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars, unicorn/consistent-function-scoping, require-await
|
|
7
|
+
const fetchSlide = fetch => async (slideRef, token) => {
|
|
8
|
+
// const {host}: JWT = decode(token);
|
|
9
|
+
// const response = await fetch(`${host}/api/v2/slide/${slideRef}`, {
|
|
10
|
+
// headers: {authorization: token}
|
|
11
|
+
// });
|
|
12
|
+
// const slide = (await toJSON(response)) as SlideFromAPI;
|
|
13
|
+
// return slide;
|
|
14
|
+
return {};
|
|
15
|
+
};
|
|
16
|
+
// -----------------------------------------------------------------------------
|
|
17
|
+
const createFetchSlide = () => {
|
|
18
|
+
if (process.env.SERVICES !== 'mocks') {
|
|
19
|
+
return fetchSlide(crossFetch);
|
|
20
|
+
}
|
|
21
|
+
// TODO: use an appropriate mock
|
|
22
|
+
return fetchSlide(okJSONResponse({}));
|
|
23
|
+
};
|
|
24
|
+
// -----------------------------------------------------------------------------
|
|
25
|
+
export { fetchSlide };
|
|
26
|
+
export default createFetchSlide();
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import crossFetch from 'cross-fetch';
|
|
2
|
+
import { ProgressionFromAPI } from '../actions/data/progression';
|
|
3
|
+
declare type PostProgression = (skillRef: string, token: string) => Promise<ProgressionFromAPI>;
|
|
4
|
+
declare type CreatePostProgression = (fetch: typeof crossFetch) => PostProgression;
|
|
5
|
+
declare const postProgression: CreatePostProgression;
|
|
6
|
+
export { postProgression };
|
|
7
|
+
declare const _default: PostProgression;
|
|
8
|
+
export default _default;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import crossFetch from 'cross-fetch';
|
|
2
|
+
import decode from 'jwt-decode';
|
|
3
|
+
import { toJSON } from './tools/fetch-responses';
|
|
4
|
+
import mockPostProgression from './post-progression.mock';
|
|
5
|
+
// -----------------------------------------------------------------------------
|
|
6
|
+
const postProgression = fetch => async (skillRef, token) => {
|
|
7
|
+
const { host } = decode(token);
|
|
8
|
+
const response = await fetch(`${host}/api/v2/progressions`, {
|
|
9
|
+
method: 'post',
|
|
10
|
+
headers: { authorization: token },
|
|
11
|
+
body: JSON.stringify({
|
|
12
|
+
content: {
|
|
13
|
+
ref: skillRef,
|
|
14
|
+
type: 'slide'
|
|
15
|
+
},
|
|
16
|
+
engine: {
|
|
17
|
+
ref: 'review',
|
|
18
|
+
version: '1'
|
|
19
|
+
}
|
|
20
|
+
})
|
|
21
|
+
});
|
|
22
|
+
return toJSON(response);
|
|
23
|
+
};
|
|
24
|
+
// -----------------------------------------------------------------------------
|
|
25
|
+
const createPostProgression = () => {
|
|
26
|
+
if (process.env.SERVICES !== 'mocks') {
|
|
27
|
+
return postProgression(crossFetch);
|
|
28
|
+
}
|
|
29
|
+
return postProgression(mockPostProgression);
|
|
30
|
+
};
|
|
31
|
+
// -----------------------------------------------------------------------------
|
|
32
|
+
export { postProgression };
|
|
33
|
+
export default createPostProgression();
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { okJSONResponse } from './tools/fetch.mocks';
|
|
2
|
+
export const mockedProgression = {
|
|
3
|
+
_id: '62b1d1087aa12f00253f40ee',
|
|
4
|
+
state: {
|
|
5
|
+
// ------------------------------------------------------
|
|
6
|
+
// unused for now / to decide whether to use it when the
|
|
7
|
+
// validation-progression is plugged in
|
|
8
|
+
pendingSlides: [],
|
|
9
|
+
step: {
|
|
10
|
+
current: Number.NaN
|
|
11
|
+
},
|
|
12
|
+
// ------------------------------------------------------
|
|
13
|
+
isCorrect: true,
|
|
14
|
+
nextContent: {
|
|
15
|
+
ref: 'sli_N1XACJobn',
|
|
16
|
+
type: 'slide'
|
|
17
|
+
}
|
|
18
|
+
// slides: [
|
|
19
|
+
// 'sli_NJ3m5KtWh',
|
|
20
|
+
// 'sli_V1gKpYYZ2',
|
|
21
|
+
// 'sli_VJzOgotbh',
|
|
22
|
+
// 'sli_V1ug-dtZn',
|
|
23
|
+
// 'sli_VyZU-ejW3',
|
|
24
|
+
// 'sli_Vy8ChgjZh',
|
|
25
|
+
// 'sli_V1ijS1oWh',
|
|
26
|
+
// 'sli_N1XACJobn'
|
|
27
|
+
// ],
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
const mockCreateProgression = okJSONResponse(mockedProgression);
|
|
31
|
+
export default mockCreateProgression;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import test from 'ava';
|
|
2
|
+
import { postProgression } from './post-progression';
|
|
3
|
+
import { okJSONResponse, token } from './tools/fetch.mocks';
|
|
4
|
+
const skillRef = '_skill-ref';
|
|
5
|
+
test('should create progression with success', async (t) => {
|
|
6
|
+
const result = {
|
|
7
|
+
_id: '123456123456',
|
|
8
|
+
state: {
|
|
9
|
+
// is "isCorrect" always true for a 1st progression?
|
|
10
|
+
isCorrect: true,
|
|
11
|
+
step: {
|
|
12
|
+
current: 1
|
|
13
|
+
},
|
|
14
|
+
nextContent: {
|
|
15
|
+
type: 'slide',
|
|
16
|
+
ref: 'sli_NJ3m5KtWh'
|
|
17
|
+
},
|
|
18
|
+
pendingSlides: []
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
const mockedPostProgression = postProgression(okJSONResponse(result));
|
|
22
|
+
const progression = await mockedPostProgression(skillRef, token);
|
|
23
|
+
t.deepEqual(result, progression);
|
|
24
|
+
});
|
|
25
|
+
test('should reject bad token', async (t) => {
|
|
26
|
+
const badToken = 'token is not a jwt';
|
|
27
|
+
const mockedPostProgression = postProgression(okJSONResponse(null));
|
|
28
|
+
const error = await t.throwsAsync(() => mockedPostProgression(skillRef, badToken));
|
|
29
|
+
t.is(error?.message, "Invalid token specified: Cannot read properties of undefined (reading 'replace')");
|
|
30
|
+
});
|
|
@@ -2,6 +2,6 @@ export declare class ResponseError extends Error {
|
|
|
2
2
|
statusCode: number;
|
|
3
3
|
constructor(statusCode: number, statusText: string, body?: string);
|
|
4
4
|
}
|
|
5
|
-
export declare const toJSON: (response: Response) => Promise<
|
|
5
|
+
export declare const toJSON: <T = unknown>(response: Response) => Promise<T>;
|
|
6
6
|
export declare const toText: (response: Response) => Promise<string>;
|
|
7
7
|
export declare const toVoid: (response: Response) => Promise<void>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const sleep: (msToSleep: number) => Promise<void>;
|
package/es/types/common.d.ts
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
declare type TemplateContextValues = {
|
|
2
|
+
brandTheme?: unknown;
|
|
3
|
+
theme?: unknown;
|
|
4
|
+
translations?: unknown;
|
|
5
|
+
};
|
|
2
6
|
export declare type AppOptions = {
|
|
3
7
|
token: string;
|
|
4
8
|
theme?: unknown;
|
|
5
9
|
translations?: unknown;
|
|
6
|
-
|
|
10
|
+
templateContext?: TemplateContextValues;
|
|
11
|
+
skillRef?: string;
|
|
7
12
|
};
|
|
8
13
|
export declare type JWT = {
|
|
9
14
|
exp: number;
|
|
@@ -17,3 +22,4 @@ export declare type JWT = {
|
|
|
17
22
|
export declare type WithRequired<T, K extends keyof T> = T & {
|
|
18
23
|
[P in K]-?: T[P];
|
|
19
24
|
};
|
|
25
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export declare type ProgressionFromAPI = {
|
|
2
|
+
_id: string;
|
|
3
|
+
state: {
|
|
4
|
+
isCorrect: boolean;
|
|
5
|
+
step: {
|
|
6
|
+
current: number;
|
|
7
|
+
};
|
|
8
|
+
nextContent: {
|
|
9
|
+
type: 'success' | 'slide';
|
|
10
|
+
ref: 'successExitNode' | string;
|
|
11
|
+
};
|
|
12
|
+
pendingSlides: [];
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
export declare const RECEIVE_PROGRESSION = "@@data/progression/RECEIVE_PROGRESSION";
|
|
16
|
+
export declare const ERROR_CREATING_PROGRESSION = "@@data/progression/ERROR_CREATING_PROGRESSION";
|
|
17
|
+
export declare type ReceiveProgressionPayload = {
|
|
18
|
+
progression: ProgressionFromAPI;
|
|
19
|
+
token: string;
|
|
20
|
+
};
|
|
21
|
+
export declare type ReceiveProgression = {
|
|
22
|
+
type: typeof RECEIVE_PROGRESSION;
|
|
23
|
+
payload: ReceiveProgressionPayload;
|
|
24
|
+
};
|
|
25
|
+
export declare type ErrorCreatingProgression = {
|
|
26
|
+
type: typeof ERROR_CREATING_PROGRESSION;
|
|
27
|
+
payload: Error;
|
|
28
|
+
};
|
|
29
|
+
export declare const receiveProgression: (payload: ReceiveProgressionPayload) => ReceiveProgression;
|
|
30
|
+
export declare const errorCreatingProgression: (error: Error) => ErrorCreatingProgression;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// -----------------------------------------------------------------------------
|
|
2
|
+
export var RECEIVE_PROGRESSION = '@@data/progression/RECEIVE_PROGRESSION';
|
|
3
|
+
export var ERROR_CREATING_PROGRESSION = '@@data/progression/ERROR_CREATING_PROGRESSION';
|
|
4
|
+
// -----------------------------------------------------------------------------
|
|
5
|
+
export var receiveProgression = function (payload) { return ({
|
|
6
|
+
type: RECEIVE_PROGRESSION,
|
|
7
|
+
payload: payload
|
|
8
|
+
}); };
|
|
9
|
+
export var errorCreatingProgression = function (error) { return ({
|
|
10
|
+
type: ERROR_CREATING_PROGRESSION,
|
|
11
|
+
payload: error
|
|
12
|
+
}); };
|
|
@@ -1,32 +1,35 @@
|
|
|
1
|
-
import { Slide as
|
|
1
|
+
import { Slide as UISlide } from '../../types/slides';
|
|
2
2
|
export declare const STORE_FIRST_SLIDE = "@@slide/STORE_FIRST_SLIDE";
|
|
3
3
|
export declare const UPDATE_SLIDES_ON_VALIDATION = "@@slide/UPDATE_SLIDES_ON_VALIDATION";
|
|
4
4
|
export declare const UPDATE_SLIDES_ON_NEXT = "@@slide/UPDATE_SLIDES_ON_NEXT";
|
|
5
5
|
export declare const VALIDATE_SLIDE = "@@slide/VALIDATE";
|
|
6
6
|
export declare const FETCH_NEXT_CONTENT = "@@slide/FETCH_NEXT_CONTENT";
|
|
7
|
+
export declare const ERROR_FETCHING_SLIDE = "@@data/slide/ERROR_FETCHING_SLIDE";
|
|
7
8
|
declare type SlideUIAnimations = 'unstack' | 'restack';
|
|
8
|
-
export declare type Slide =
|
|
9
|
+
export declare type Slide = UISlide & {
|
|
9
10
|
hidden?: boolean;
|
|
10
11
|
position: number;
|
|
11
12
|
animationType?: SlideUIAnimations;
|
|
12
13
|
isCorrect?: boolean;
|
|
13
14
|
endReview?: boolean;
|
|
14
|
-
|
|
15
|
+
nextContent?: Omit<Slide, 'endReview' | 'hidden' | 'position' | 'nextContent'>;
|
|
16
|
+
};
|
|
17
|
+
export declare type SlideFromAPI = {
|
|
18
|
+
question: {
|
|
19
|
+
content: {
|
|
20
|
+
choices: Record<string, unknown>[];
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
klf: string;
|
|
24
|
+
universalRef: string;
|
|
15
25
|
};
|
|
16
26
|
export declare type ValidationPayload = {
|
|
17
27
|
slideNumber: number;
|
|
18
28
|
newSlideContent: Slide;
|
|
19
29
|
numberOfFinishedSlides: number;
|
|
20
|
-
|
|
21
|
-
};
|
|
22
|
-
export declare type OnNextPayload = Omit<ValidationPayload, 'nextSlide'>;
|
|
23
|
-
export declare type FetchNextPayload = {
|
|
24
|
-
answer: string[];
|
|
25
|
-
content: {
|
|
26
|
-
ref: string;
|
|
27
|
-
type: string;
|
|
28
|
-
};
|
|
30
|
+
nextContent: Slide;
|
|
29
31
|
};
|
|
32
|
+
export declare type OnNextPayload = Omit<ValidationPayload, 'nextContent'>;
|
|
30
33
|
export declare type StoreFirstSlide = {
|
|
31
34
|
type: typeof STORE_FIRST_SLIDE;
|
|
32
35
|
payload: SlideFromAPI;
|
|
@@ -42,13 +45,14 @@ export declare type UpdateSlidesOnNext = {
|
|
|
42
45
|
export declare type ValidateSlide = {
|
|
43
46
|
type: typeof VALIDATE_SLIDE;
|
|
44
47
|
};
|
|
45
|
-
export declare type
|
|
46
|
-
type: typeof
|
|
47
|
-
payload:
|
|
48
|
+
export declare type ErrorFetchingSlide = {
|
|
49
|
+
type: typeof ERROR_FETCHING_SLIDE;
|
|
50
|
+
payload: Error;
|
|
48
51
|
};
|
|
49
52
|
export declare type SlidesAction = StoreFirstSlide | UpdateSlidesOnValidation | UpdateSlidesOnNext;
|
|
50
53
|
export declare const storeFirstSlide: (slide: SlideFromAPI) => StoreFirstSlide;
|
|
51
54
|
export declare const updateSlidesOnValidation: (payload: ValidationPayload) => UpdateSlidesOnValidation;
|
|
52
55
|
export declare const updateSlidesOnNext: (payload: OnNextPayload) => UpdateSlidesOnNext;
|
|
53
56
|
export declare const validateSlide: () => ValidateSlide;
|
|
57
|
+
export declare const errorFetchingSlide: (error: Error) => ErrorFetchingSlide;
|
|
54
58
|
export {};
|
|
@@ -4,6 +4,7 @@ export var UPDATE_SLIDES_ON_VALIDATION = '@@slide/UPDATE_SLIDES_ON_VALIDATION';
|
|
|
4
4
|
export var UPDATE_SLIDES_ON_NEXT = '@@slide/UPDATE_SLIDES_ON_NEXT';
|
|
5
5
|
export var VALIDATE_SLIDE = '@@slide/VALIDATE';
|
|
6
6
|
export var FETCH_NEXT_CONTENT = '@@slide/FETCH_NEXT_CONTENT';
|
|
7
|
+
export var ERROR_FETCHING_SLIDE = '@@data/slide/ERROR_FETCHING_SLIDE';
|
|
7
8
|
// -----------------------------------------------------------------------------
|
|
8
9
|
export var storeFirstSlide = function (slide) { return ({
|
|
9
10
|
type: STORE_FIRST_SLIDE,
|
|
@@ -20,3 +21,7 @@ export var updateSlidesOnNext = function (payload) { return ({
|
|
|
20
21
|
export var validateSlide = function () { return ({
|
|
21
22
|
type: VALIDATE_SLIDE
|
|
22
23
|
}); };
|
|
24
|
+
export var errorFetchingSlide = function (error) { return ({
|
|
25
|
+
type: ERROR_FETCHING_SLIDE,
|
|
26
|
+
payload: error
|
|
27
|
+
}); };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export declare const STORE_TOKEN = "@@token/STORE_TOKEN";
|
|
1
|
+
export declare const STORE_TOKEN = "@@data/token/STORE_TOKEN";
|
|
2
2
|
export declare type StoreToken = {
|
|
3
|
-
type:
|
|
3
|
+
type: typeof STORE_TOKEN;
|
|
4
4
|
payload: string;
|
|
5
5
|
};
|
|
6
6
|
export declare const storeToken: (token: string) => StoreToken;
|
package/lib/actions/index.d.ts
CHANGED
|
@@ -5,7 +5,8 @@ import { updateFinishedSlides } from './ui/finished-slides';
|
|
|
5
5
|
import { navigateBack, navigateTo, NavigateBack, NavigateTo, StartApp } from './ui/navigation';
|
|
6
6
|
import { updateReviewStatus } from './ui/review-status';
|
|
7
7
|
import { updateStepItemsOnValidation, updateStepItemsOnNext } from './ui/step-items';
|
|
8
|
-
|
|
8
|
+
import { ErrorCreatingProgression, ReceiveProgression } from './data/progression';
|
|
9
|
+
export declare type Action = NavigateBack | NavigateTo | ReceivedSkills | ErrorFetchingSkills | StartApp | StoreFirstSlide | StoreToken | ErrorCreatingProgression | ReceiveProgression;
|
|
9
10
|
export declare type Dispatchers = {
|
|
10
11
|
navigateTo: typeof navigateTo;
|
|
11
12
|
navigateBack: typeof navigateBack;
|
package/lib/configure-store.d.ts
CHANGED
|
@@ -6,18 +6,10 @@ import { NavigationState } from './reducers/ui/navigation';
|
|
|
6
6
|
import { ReviewStatusState } from './reducers/ui/review-status';
|
|
7
7
|
import { StepItemsState } from './reducers/ui/step-items';
|
|
8
8
|
import { FinishedSlidesState } from './reducers/ui/finished-slides';
|
|
9
|
-
import {
|
|
9
|
+
import { ProgressionState } from './reducers/data/progression';
|
|
10
10
|
declare type DataState = {
|
|
11
11
|
isFetching?: boolean;
|
|
12
|
-
progression?:
|
|
13
|
-
slideNumber: number;
|
|
14
|
-
isCorrect?: boolean;
|
|
15
|
-
exitNode?: 'successExitNode' | 'failExitNode';
|
|
16
|
-
nextSlide?: {
|
|
17
|
-
questionText?: string;
|
|
18
|
-
answerUI?: AnswerUI;
|
|
19
|
-
};
|
|
20
|
-
} | null;
|
|
12
|
+
progression?: ProgressionState;
|
|
21
13
|
skills: SkillsState;
|
|
22
14
|
slides: SlidesState;
|
|
23
15
|
token?: TokenState;
|
package/lib/configure-store.js
CHANGED
|
@@ -2,6 +2,7 @@ import { applyMiddleware, compose, createStore } from 'redux';
|
|
|
2
2
|
import thunk from 'redux-thunk';
|
|
3
3
|
import rootReducer from './reducers';
|
|
4
4
|
import onStartApp from './middlewares/on-start-app';
|
|
5
|
+
import onReceiveProgression from './middlewares/on-receive-progression';
|
|
5
6
|
// -----------------------------------------------------------------------------
|
|
6
7
|
export default function configureStore() {
|
|
7
8
|
var _compose = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
|
|
@@ -11,7 +12,7 @@ export default function configureStore() {
|
|
|
11
12
|
traceLimit: 25
|
|
12
13
|
})
|
|
13
14
|
: compose;
|
|
14
|
-
var enhancer = _compose(applyMiddleware(thunk, onStartApp));
|
|
15
|
+
var enhancer = _compose(applyMiddleware(thunk, onStartApp, onReceiveProgression));
|
|
15
16
|
var store = createStore(rootReducer, undefined, enhancer);
|
|
16
17
|
return store;
|
|
17
18
|
}
|
package/lib/index.d.ts
CHANGED
package/lib/index.js
CHANGED
|
@@ -37,6 +37,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
37
37
|
import React, { useEffect, useState } from 'react';
|
|
38
38
|
import { connect, Provider } from 'react-redux';
|
|
39
39
|
import AppReviewTemplate from '@coorpacademy/components/es/template/app-review';
|
|
40
|
+
import { TemplateContext } from '@coorpacademy/components/es/template/app-review/template-context';
|
|
40
41
|
import configureStore from './configure-store';
|
|
41
42
|
import { congratsProps, correctionPopinProps } from './fixtures/temp-fixture';
|
|
42
43
|
import { updateSlidesOnNext, updateSlidesOnValidation, validateSlide } from './actions/data/slides';
|
|
@@ -59,29 +60,38 @@ var mapDispatchToProps = {
|
|
|
59
60
|
var getCurrentViewName = function (storeState) {
|
|
60
61
|
return storeState.ui.navigation[storeState.ui.navigation.length - 1];
|
|
61
62
|
};
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
63
|
+
// -----------------------------------------------------------------------------
|
|
64
|
+
var mapStateToSkillsProps = function (state) {
|
|
65
|
+
if (!state.data.skills) {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
return {
|
|
69
|
+
title: '@todo title',
|
|
70
|
+
titleNoSkills: '@todo titleNoSkills',
|
|
71
|
+
textNoSkills: '@todo textNoSkills',
|
|
72
|
+
iconSkillAriaLabel: '@todo iconSkillAriaLabel',
|
|
73
|
+
isLoading: false,
|
|
74
|
+
isLoadingAriaLabel: '@todo loading',
|
|
75
|
+
listSkills: state.data.skills.map(function (skill) { return ({
|
|
76
|
+
'aria-label': '',
|
|
77
|
+
isCustom: skill.custom,
|
|
78
|
+
skillTitle: skill.name,
|
|
79
|
+
skillAriaLabel: '@todo skill aria label',
|
|
80
|
+
buttonLabel: '@todo button',
|
|
81
|
+
buttonAriaLabel: '@todo button aria label',
|
|
82
|
+
reviseLabel: '@todo revise',
|
|
83
|
+
reviseAriaLabel: '@todo revise aria label',
|
|
84
|
+
// eslint-disable-next-line no-console
|
|
85
|
+
onClick: function () { return console.log('@todo plug dispatcher select skill'); }
|
|
86
|
+
}); })
|
|
87
|
+
};
|
|
88
|
+
};
|
|
89
|
+
// -----------------------------------------------------------------------------
|
|
90
|
+
var mapStateToSlidesProps = function (state) {
|
|
91
|
+
if (!state.data.slides) {
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
return {
|
|
85
95
|
headerProps: {
|
|
86
96
|
mode: '__revision_mode',
|
|
87
97
|
skillName: '__agility',
|
|
@@ -102,7 +112,12 @@ var mapStateToProps = function (state) { return ({
|
|
|
102
112
|
correctionPopinProps: correctionPopinProps,
|
|
103
113
|
congratsProps: congratsProps,
|
|
104
114
|
progression: state.data.progression
|
|
105
|
-
}
|
|
115
|
+
};
|
|
116
|
+
};
|
|
117
|
+
// -----------------------------------------------------------------------------
|
|
118
|
+
var mapStateToProps = function (state) { return ({
|
|
119
|
+
viewName: getCurrentViewName(state),
|
|
120
|
+
slides: mapStateToSlidesProps(state),
|
|
106
121
|
skills: mapStateToSkillsProps(state)
|
|
107
122
|
}); };
|
|
108
123
|
// Props = StaticProps && Dispatchers
|
|
@@ -134,9 +149,11 @@ var AppReview = function (_a) {
|
|
|
134
149
|
}
|
|
135
150
|
}, [options, store]);
|
|
136
151
|
if (!store || !appStarted)
|
|
137
|
-
return
|
|
152
|
+
return null;
|
|
153
|
+
var values = options.templateContext;
|
|
138
154
|
return (React.createElement(Provider, { store: store },
|
|
139
|
-
React.createElement(
|
|
155
|
+
React.createElement(TemplateContext, { values: values },
|
|
156
|
+
React.createElement(App, null))));
|
|
140
157
|
};
|
|
141
158
|
// -----------------------------------------------------------------------------
|
|
142
159
|
export default AppReview;
|
package/lib/index.test.js
CHANGED
|
@@ -38,17 +38,12 @@ import browserEnv from 'browser-env';
|
|
|
38
38
|
import test from 'ava';
|
|
39
39
|
import React from 'react';
|
|
40
40
|
import { render, fireEvent, act } from '@testing-library/react';
|
|
41
|
-
import {
|
|
41
|
+
import { sleep } from './services/tools/sleep';
|
|
42
42
|
import AppReview from '.';
|
|
43
43
|
browserEnv({ pretendToBeVisual: true });
|
|
44
44
|
var elementExists = function (foundElements) {
|
|
45
45
|
return foundElements && foundElements[0];
|
|
46
46
|
};
|
|
47
|
-
var sleep = function (msToSleep) {
|
|
48
|
-
return new Promise(function (resolve) {
|
|
49
|
-
setTimeout(resolve, msToSleep);
|
|
50
|
-
});
|
|
51
|
-
};
|
|
52
47
|
var waitForChanges = function (msToWait) {
|
|
53
48
|
if (msToWait === void 0) { msToWait = 3000; }
|
|
54
49
|
return __awaiter(void 0, void 0, void 0, function () {
|
|
@@ -134,7 +129,10 @@ var clickAllSlides = function (t, container, accumulator) {
|
|
|
134
129
|
};
|
|
135
130
|
var appOptions = {
|
|
136
131
|
token: process.env.API_TEST_TOKEN || '',
|
|
137
|
-
|
|
132
|
+
templateContext: {
|
|
133
|
+
theme: { color: { primary: '#123' } }
|
|
134
|
+
},
|
|
135
|
+
skillRef: 'skill_NJC0jFKoH'
|
|
138
136
|
};
|
|
139
137
|
test('should validate all the slides (all correct scenario)', function (t) { return __awaiter(void 0, void 0, void 0, function () {
|
|
140
138
|
var container, wrapper, stackedSlidesContainer;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Middleware, Store } from 'redux';
|
|
2
|
+
import { Dispatch } from 'redux';
|
|
3
|
+
import { ErrorFetchingSlide, StoreFirstSlide } from '../actions/data/slides';
|
|
4
|
+
import { ReceiveProgression } from '../actions/data/progression';
|
|
5
|
+
declare const onReceiveProgression: Middleware<{}, Store, Dispatch<ReceiveProgression | StoreFirstSlide | ErrorFetchingSlide>>;
|
|
6
|
+
export default onReceiveProgression;
|