@coorpacademy/app-review 0.1.9 → 0.1.11

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 (70) hide show
  1. package/es/actions/ui/navigation.d.ts +1 -1
  2. package/es/fixtures/qcm-slide.js +1 -1
  3. package/es/helpers/map-api-slide-to-ui.d.ts +8 -0
  4. package/es/helpers/map-api-slide-to-ui.js +175 -0
  5. package/es/helpers/test/fixtures/free-text.d.ts +4 -0
  6. package/es/helpers/test/fixtures/free-text.js +24 -0
  7. package/es/helpers/test/fixtures/qcm-drag.d.ts +4 -0
  8. package/es/helpers/test/fixtures/qcm-drag.js +106 -0
  9. package/es/helpers/test/fixtures/qcm-graphic.d.ts +4 -0
  10. package/es/helpers/test/fixtures/qcm-graphic.js +70 -0
  11. package/es/helpers/test/fixtures/qcm.d.ts +4 -0
  12. package/es/helpers/test/fixtures/qcm.js +99 -0
  13. package/es/helpers/test/fixtures/select-template.d.ts +4 -0
  14. package/es/helpers/test/fixtures/select-template.js +88 -0
  15. package/es/helpers/test/fixtures/slider.d.ts +4 -0
  16. package/es/helpers/test/fixtures/slider.js +27 -0
  17. package/es/helpers/test/fixtures/text-template.d.ts +4 -0
  18. package/es/helpers/test/fixtures/text-template.js +48 -0
  19. package/es/helpers/test/map-api-slide-to-ui.test.d.ts +1 -0
  20. package/es/helpers/test/map-api-slide-to-ui.test.js +32 -0
  21. package/es/index.js +29 -9
  22. package/es/reducers/ui/navigation.d.ts +1 -1
  23. package/es/test/index.test.js +18 -15
  24. package/es/test/util/services.mock.js +2 -32
  25. package/es/types/common.d.ts +62 -5
  26. package/es/types/slides.d.ts +27 -16
  27. package/lib/actions/ui/navigation.d.ts +1 -1
  28. package/lib/fixtures/qcm-slide.js +1 -1
  29. package/lib/helpers/map-api-slide-to-ui.d.ts +8 -0
  30. package/lib/helpers/map-api-slide-to-ui.js +181 -0
  31. package/lib/helpers/test/fixtures/free-text.d.ts +4 -0
  32. package/lib/helpers/test/fixtures/free-text.js +24 -0
  33. package/lib/helpers/test/fixtures/qcm-drag.d.ts +4 -0
  34. package/lib/helpers/test/fixtures/qcm-drag.js +106 -0
  35. package/lib/helpers/test/fixtures/qcm-graphic.d.ts +4 -0
  36. package/lib/helpers/test/fixtures/qcm-graphic.js +70 -0
  37. package/lib/helpers/test/fixtures/qcm.d.ts +4 -0
  38. package/lib/helpers/test/fixtures/qcm.js +99 -0
  39. package/lib/helpers/test/fixtures/select-template.d.ts +4 -0
  40. package/lib/helpers/test/fixtures/select-template.js +88 -0
  41. package/lib/helpers/test/fixtures/slider.d.ts +4 -0
  42. package/lib/helpers/test/fixtures/slider.js +27 -0
  43. package/lib/helpers/test/fixtures/text-template.d.ts +4 -0
  44. package/lib/helpers/test/fixtures/text-template.js +48 -0
  45. package/lib/helpers/test/map-api-slide-to-ui.test.d.ts +1 -0
  46. package/lib/helpers/test/map-api-slide-to-ui.test.js +43 -0
  47. package/lib/index.js +29 -9
  48. package/lib/reducers/ui/navigation.d.ts +1 -1
  49. package/lib/test/index.test.js +19 -16
  50. package/lib/test/util/services.mock.js +13 -32
  51. package/lib/types/common.d.ts +62 -5
  52. package/lib/types/slides.d.ts +27 -16
  53. package/package.json +4 -3
  54. package/src/actions/ui/navigation.ts +1 -1
  55. package/src/fixtures/qcm-slide.ts +1 -1
  56. package/src/helpers/map-api-slide-to-ui.ts +253 -0
  57. package/src/helpers/test/fixtures/free-text.ts +28 -0
  58. package/src/helpers/test/fixtures/qcm-drag.ts +110 -0
  59. package/src/helpers/test/fixtures/qcm-graphic.ts +74 -0
  60. package/src/helpers/test/fixtures/qcm.ts +108 -0
  61. package/src/helpers/test/fixtures/select-template.ts +92 -0
  62. package/src/helpers/test/fixtures/slider.ts +31 -0
  63. package/src/helpers/test/fixtures/text-template.ts +52 -0
  64. package/src/helpers/test/map-api-slide-to-ui.test.ts +55 -0
  65. package/src/index.tsx +35 -11
  66. package/src/reducers/ui/navigation.ts +1 -1
  67. package/src/test/index.test.tsx +23 -12
  68. package/src/test/util/services.mock.ts +2 -32
  69. package/src/types/common.ts +74 -5
  70. package/src/types/slides.ts +29 -12
@@ -0,0 +1,48 @@
1
+ import noop from 'lodash/fp/noop';
2
+ export const textTemplateSlide = {
3
+ question: {
4
+ content: {
5
+ media: {
6
+ src: [],
7
+ posters: [],
8
+ subtitles: []
9
+ },
10
+ template: 'Un {{inp58402}} model.',
11
+ choices: [
12
+ {
13
+ media: {
14
+ src: [],
15
+ posters: [],
16
+ subtitles: []
17
+ },
18
+ items: [],
19
+ _id: '62433c2c58920f02c4950de0',
20
+ type: 'text',
21
+ name: 'inp58402',
22
+ id: '62433c2c58920f02c4950de0'
23
+ }
24
+ ]
25
+ },
26
+ type: 'template',
27
+ header: 'Comment le protégé doit-il percevoir son mentor ?',
28
+ explanation: 'Saisissez votre réponse (en anglais).'
29
+ },
30
+ 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é.",
31
+ tips: "L'origine de l'expression <i>role model</i> est attribué au sociologue Robert K. Merton.",
32
+ universalRef: 'sli_VJKQonm2g',
33
+ hasClue: true,
34
+ id: 'sli_VJKQonm2g'
35
+ };
36
+ export const textTemplateUISlide = {
37
+ type: 'template',
38
+ template: 'Un {{inp58402}} model.',
39
+ answers: [
40
+ {
41
+ type: 'text',
42
+ name: 'inp58402',
43
+ placeholder: 'Type here',
44
+ value: undefined,
45
+ onChange: noop
46
+ }
47
+ ]
48
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,32 @@
1
+ import test from 'ava';
2
+ import { mapApiSlideToUi } from '../map-api-slide-to-ui';
3
+ import { qcmUISlide, qcmSlide } from './fixtures/qcm';
4
+ import { qcmDragUISlide, qcmDragSlide } from './fixtures/qcm-drag';
5
+ import { freeTextSlide, freeTextUISlide } from './fixtures/free-text';
6
+ import { qcmGraphicUISlide, qcmGraphicSlide } from './fixtures/qcm-graphic';
7
+ import { textTemplateSlide, textTemplateUISlide } from './fixtures/text-template';
8
+ import { selectTemplateSlide, selectTemplateUISlide } from './fixtures/select-template';
9
+ import { sliderSlide, sliderUISlide } from './fixtures/slider';
10
+ const _mapApiSlideToUi = mapApiSlideToUi({ translate: (text) => text });
11
+ const macro = test.macro({
12
+ title(providedTitle) {
13
+ return `should handle ${providedTitle} conversion`.trim();
14
+ },
15
+ exec(t, arg) {
16
+ t.deepEqual(JSON.parse(JSON.stringify(_mapApiSlideToUi(arg.slide))), JSON.parse(JSON.stringify(arg.expectedUiSlide)));
17
+ }
18
+ });
19
+ test('qcm', macro, { slide: qcmSlide, expectedUiSlide: qcmUISlide });
20
+ test('qcm drag', macro, { slide: qcmDragSlide, expectedUiSlide: qcmDragUISlide });
21
+ test('qcm graphic', macro, { slide: qcmGraphicSlide, expectedUiSlide: qcmGraphicUISlide });
22
+ test('text template', macro, { slide: textTemplateSlide, expectedUiSlide: textTemplateUISlide });
23
+ test('select template', macro, {
24
+ slide: selectTemplateSlide,
25
+ expectedUiSlide: selectTemplateUISlide
26
+ });
27
+ test('free text', macro, { slide: freeTextSlide, expectedUiSlide: freeTextUISlide });
28
+ test('slider', macro, { slide: sliderSlide, expectedUiSlide: sliderUISlide });
29
+ test('should throw an error if the question type can not be handled', t => {
30
+ const faultySlide = { ...qcmSlide, question: { type: 'lol' } };
31
+ t.throws(() => _mapApiSlideToUi(faultySlide));
32
+ });
package/es/index.js CHANGED
@@ -2,6 +2,8 @@ import React, { useEffect, useState } from 'react';
2
2
  import { connect, Provider } from 'react-redux';
3
3
  import AppReviewTemplate from '@coorpacademy/components/es/template/app-review';
4
4
  import { TemplateContext } from '@coorpacademy/components/es/template/app-review/template-context';
5
+ import isEmpty from 'lodash/fp/isEmpty';
6
+ import get from 'lodash/fp/get';
5
7
  import configureStore from './configure-store';
6
8
  import { congratsProps, correctionPopinProps } from './fixtures/temp-fixture';
7
9
  import { updateSlidesOnNext, updateSlidesOnValidation, validateSlide } from './actions/data/slides';
@@ -87,6 +89,7 @@ const mapStateToProps = (state) => {
87
89
  const App = connect(mapStateToProps, mapDispatchToProps)(AppReviewTemplate);
88
90
  const AppReview = ({ options }) => {
89
91
  const [store, setStore] = useState(null);
92
+ const [isSlideFetched, setIsSlideFetched] = useState(false);
90
93
  useEffect(() => {
91
94
  if (store)
92
95
  return;
@@ -94,28 +97,45 @@ const AppReview = ({ options }) => {
94
97
  setStore(newStore);
95
98
  }, [options, store]);
96
99
  useEffect(() => {
97
- if (store === null)
100
+ if (!store || isSlideFetched)
98
101
  return;
99
- const { skillRef } = options;
100
- const initialView = skillRef ? VIEWS.slides : VIEWS.skills;
101
- store.dispatch(navigateTo(initialView));
102
- }, [options, store]);
102
+ return store.subscribe(() => {
103
+ const isSlidePresent = !isEmpty(store.getState().data.slides[0].questionText);
104
+ return isSlidePresent && setIsSlideFetched(isSlidePresent);
105
+ }); // using the first slide questionText for now, should only check for a slide's presence
106
+ // when the refactor is done (slides will be feed one by one on api's side)
107
+ }, [isSlideFetched, options, store]);
103
108
  useEffect(() => {
104
- if (store === null)
109
+ const token = get('token', options);
110
+ if (store === null || isEmpty(token))
105
111
  return;
106
- const { token } = options;
107
112
  store.dispatch(storeToken(token));
108
113
  }, [options, store]);
109
114
  useEffect(() => {
110
- if (store === null)
115
+ const token = get('token', options);
116
+ if (store === null || isEmpty(token))
111
117
  return;
112
- const { skillRef, token } = options;
118
+ const skillRef = get('skillRef', options);
113
119
  // ThunkAction is not assignable to parameter of type 'AnyAction'
114
120
  // ts problem describre here = https://github.com/reduxjs/redux-thunk/issues/333
115
121
  skillRef
116
122
  ? store.dispatch(postProgression(skillRef, token))
117
123
  : store.dispatch(fetchSkills(token));
118
124
  }, [options, store]);
125
+ useEffect(() => {
126
+ if (store === null)
127
+ return;
128
+ const { skillRef } = options;
129
+ if (skillRef && !isSlideFetched) {
130
+ store.dispatch(navigateTo('loader')); // use loader while posting progression
131
+ return;
132
+ }
133
+ // TODO: when slides state is refactored (data + mapping),
134
+ // use loader in case a skillRef is found && no slides from the API
135
+ // are found
136
+ const initialView = skillRef ? VIEWS.slides : VIEWS.skills;
137
+ store.dispatch(navigateTo(initialView));
138
+ }, [isSlideFetched, options, store]);
119
139
  if (!store)
120
140
  return null;
121
141
  const { templateContext: values } = options;
@@ -1,4 +1,4 @@
1
1
  import { type NavigateTo, type NavigateBack } from '../../actions/ui/navigation';
2
- export declare type NavigationState = Array<'skills' | 'onboarding' | 'slides'>;
2
+ export declare type NavigationState = Array<'skills' | 'onboarding' | 'slides' | 'loader'>;
3
3
  declare const reducer: (state: NavigationState | undefined, action: NavigateTo | NavigateBack) => NavigationState;
4
4
  export default reducer;
@@ -42,22 +42,25 @@ const appOptions = {
42
42
  skillRef: 'skill_NJC0jFKoH',
43
43
  services
44
44
  };
45
- test('should validate all the slides (all correct scenario)', async (t) => {
46
- // t.plan(13);
45
+ test('should show the loader while the app is fetching the data', async (t) => {
47
46
  t.plan(2);
48
- const { container } = render(React.createElement(AppReview, { options: appOptions, key: 0 }));
47
+ const { container } = render(React.createElement(AppReview, { options: appOptions }));
49
48
  await waitForChanges(1000);
50
- const wrapper = container.querySelector('[data-name="loader"]');
51
- t.truthy(wrapper);
52
- /*
53
- const wrapper = container.querySelector('[data-name="slides-revision-container"]');
54
- t.truthy(wrapper);
55
-
56
- const stackedSlidesContainer = wrapper?.querySelector('[data-name="stacked-slides-container"]');
57
-
58
- t.truthy(stackedSlidesContainer);
59
-
60
- await clickAllSlides(t, container);
61
- */
49
+ const loader = container.querySelector('[data-name="loader"]');
50
+ t.truthy(loader);
51
+ // await waitFor(async () => {
52
+ // // await sleep(500);
53
+ // const result = await t.try(tt => {
54
+ // // rerender(<AppReview options={appOptions} />);
55
+ // const slidesContainer = container.querySelector('[data-name="slides-revision-container"]');
56
+ // tt.truthy(slidesContainer);
57
+ // });
58
+ // if (result.passed) return result.commit();
59
+ // result.discard();
60
+ // throw result.errors;
61
+ // });
62
+ // const stackedSlidesContainer = container.querySelector('[data-name="stacked-slides-container"]');
63
+ // t.truthy(stackedSlidesContainer);
64
+ // await clickAllSlides(t, container);
62
65
  t.pass();
63
66
  });
@@ -1,3 +1,4 @@
1
+ import { qcmSlide } from '../../helpers/test/fixtures/qcm';
1
2
  export const services = {
2
3
  fetchSkills: () => {
3
4
  return Promise.resolve([
@@ -16,38 +17,7 @@ export const services = {
16
17
  ]);
17
18
  },
18
19
  fetchSlide: ref => {
19
- // return Promise.resolve(qcm); // why qcm does not look like a slide returned from mooc ?
20
- return Promise.resolve({
21
- question: {
22
- content: {
23
- choices: [
24
- {
25
- selected: false,
26
- title: 'choix1',
27
- help: '(help choix1)',
28
- ariaLabel: '__ariaLabel1',
29
- onClick: () => undefined
30
- },
31
- {
32
- selected: false,
33
- title: 'choix2',
34
- help: '(help choix2)',
35
- ariaLabel: '__ariaLabel2',
36
- onClick: () => undefined
37
- },
38
- {
39
- selected: false,
40
- title: 'choix3',
41
- help: '(help choix3)',
42
- ariaLabel: '__ariaLabel3',
43
- onClick: () => undefined
44
- }
45
- ]
46
- }
47
- },
48
- klf: '___klf',
49
- universalRef: ref
50
- });
20
+ return Promise.resolve({ ...qcmSlide, universalRef: ref, id: ref });
51
21
  },
52
22
  postProgression: () => {
53
23
  return Promise.resolve({
@@ -4,14 +4,71 @@ declare type TemplateContextValues = {
4
4
  theme?: unknown;
5
5
  translations?: unknown;
6
6
  };
7
- export declare type SlideFromAPI = {
8
- question: {
9
- content: {
10
- choices: Record<string, unknown>[];
11
- };
7
+ export declare type ChoiceFromAPI = {
8
+ _id: string;
9
+ id?: string;
10
+ value?: string;
11
+ name?: string;
12
+ type?: 'text' | 'select';
13
+ label?: string;
14
+ items: {
15
+ text: string;
16
+ value: string;
17
+ _id: string;
18
+ }[];
19
+ media?: unknown;
20
+ };
21
+ declare type BaseContent = {
22
+ media?: unknown;
23
+ choices: ChoiceFromAPI[];
24
+ };
25
+ declare type Question = {
26
+ header?: string;
27
+ content: BaseContent;
28
+ explanation?: string;
29
+ };
30
+ export declare type QcmQuestion = Question & {
31
+ type: 'qcm';
32
+ };
33
+ export declare type QcmGraphicQuestion = Question & {
34
+ type: 'qcmGraphic';
35
+ };
36
+ export declare type QcmDragQuestion = Question & {
37
+ type: 'qcmDrag';
38
+ };
39
+ export declare type BasicQuestion = Omit<Question, 'content'> & {
40
+ type: 'basic';
41
+ content: {
42
+ media?: unknown;
43
+ label?: string;
44
+ placeholder?: string;
45
+ id: string;
46
+ };
47
+ };
48
+ export declare type SliderQuestion = Omit<Question, 'content'> & {
49
+ content: {
50
+ media?: unknown;
51
+ unitLabel: string;
52
+ min: number;
53
+ max: number;
54
+ step?: number;
12
55
  };
56
+ type: 'slider';
57
+ };
58
+ export declare type TemplateQuestion = Omit<Question, 'content'> & {
59
+ content: BaseContent & {
60
+ template: string;
61
+ };
62
+ type: 'template';
63
+ };
64
+ export declare type SlideFromAPI = {
65
+ question: QcmQuestion | QcmGraphicQuestion | QcmDragQuestion | BasicQuestion | SliderQuestion | TemplateQuestion;
13
66
  klf: string;
14
67
  universalRef: string;
68
+ tips?: string;
69
+ clue?: string;
70
+ hasClue?: boolean;
71
+ id?: string;
15
72
  };
16
73
  export declare type ProgressionFromAPI = {
17
74
  _id: string;
@@ -1,9 +1,10 @@
1
1
  export declare type Choice = {
2
2
  order?: number;
3
3
  selected: boolean;
4
- title: string;
5
- help: string;
4
+ title?: string;
5
+ help?: string;
6
6
  onClick: Function;
7
+ ariaLabel?: string;
7
8
  };
8
9
  export declare type QcmDrag = {
9
10
  type: 'qcmDrag';
@@ -12,22 +13,20 @@ export declare type QcmDrag = {
12
13
  };
13
14
  export declare type Qcm = {
14
15
  type: 'qcm';
15
- choices: (Choice & {
16
- ariaLabel: string;
17
- })[];
16
+ answers: Choice[];
18
17
  };
19
18
  export declare type QcmGraphic = {
20
19
  type: 'qcmGraphic';
21
- choices: (Choice & {
20
+ answers: (Choice & {
22
21
  image: string;
23
22
  })[];
24
23
  };
25
24
  export declare type FreeText = {
26
25
  type: 'freeText';
27
26
  placeholder: string;
28
- value: string;
27
+ value?: string;
29
28
  onChange: Function;
30
- ariaLabel: string;
29
+ ariaLabel?: string;
31
30
  };
32
31
  export declare type DropDownOption = {
33
32
  name: string;
@@ -37,26 +36,38 @@ export declare type DropDownOption = {
37
36
  };
38
37
  export declare type DropDown = {
39
38
  type: 'dropDown';
40
- onChange: Function;
39
+ onChange?: Function;
41
40
  options: DropDownOption[];
42
- theme: 'filter' | 'invalid' | 'header' | 'mooc' | 'question' | 'sort' | 'thematiques' | 'player' | 'template' | 'coorpmanager';
41
+ theme?: 'filter' | 'invalid' | 'header' | 'mooc' | 'question' | 'sort' | 'thematiques' | 'player' | 'template' | 'coorpmanager';
43
42
  };
44
43
  export declare type QuestionRange = {
45
44
  type: 'slider';
46
- onChange: Function;
47
- onChangeEnd: Function;
48
- multi: boolean;
45
+ placeholder?: string;
46
+ onChange?: Function;
47
+ onChangeEnd?: Function;
48
+ multi?: boolean;
49
49
  value: number | number[];
50
50
  title: string;
51
51
  minLabel: string;
52
52
  maxLabel: string;
53
53
  };
54
+ export declare type TextTemplate = {
55
+ type: 'text';
56
+ name: string;
57
+ placeholder: string;
58
+ value?: string;
59
+ onChange: Function;
60
+ };
61
+ export declare type SelectionTemplate = {
62
+ type: 'select';
63
+ name: string;
64
+ onChange?: Function;
65
+ options?: DropDownOption[];
66
+ };
54
67
  export declare type Template = {
55
68
  type: 'template';
56
69
  template: string;
57
- choices: (DropDown & {
58
- type?: string;
59
- })[];
70
+ answers: (TextTemplate | SelectionTemplate)[];
60
71
  };
61
72
  export declare type AnswerUI = {
62
73
  model: QcmDrag | Qcm | QcmGraphic | FreeText | DropDown | QuestionRange | Template;
@@ -2,7 +2,7 @@ import { AppOptions } from '../../types/common';
2
2
  export declare const NAVIGATE_TO = "@@navigation/NAVIGATE_TO";
3
3
  export declare const NAVIGATE_BACK = "@@navigation/NAVIGATE_BACK";
4
4
  export declare const START_APP = "@@navigation/START_APP";
5
- export declare type ViewPath = 'skills' | 'onboarding' | 'slides';
5
+ export declare type ViewPath = 'skills' | 'onboarding' | 'slides' | 'loader';
6
6
  export declare type NavigateTo = {
7
7
  type: '@@navigation/NAVIGATE_TO';
8
8
  payload: ViewPath;
@@ -5,7 +5,7 @@ export var slide = {
5
5
  help: '__help',
6
6
  model: {
7
7
  type: 'qcm',
8
- choices: [
8
+ answers: [
9
9
  {
10
10
  selected: false,
11
11
  title: 'choix1',
@@ -0,0 +1,8 @@
1
+ import { AnswerUI } from '../types/slides';
2
+ import { SlideFromAPI } from '../types/common';
3
+ declare type UiUtils = {
4
+ translate: (text: string) => string;
5
+ };
6
+ export declare const getQuestionType: (slide: SlideFromAPI) => SlideFromAPI['question']['type'];
7
+ export declare const mapApiSlideToUi: (uiUtils: UiUtils) => (slide: SlideFromAPI) => AnswerUI['model'] | void;
8
+ export {};
@@ -0,0 +1,181 @@
1
+ import { concat, divide, get, getOr, head, includes, indexOf, isEmpty, map, noop, pipe, rangeStep, size, toInteger } from 'lodash/fp';
2
+ var qcmProps = function (question) {
3
+ // TODO: EDIT_CHOICES -> getAnswerValues
4
+ var answers = [];
5
+ return {
6
+ type: 'qcm',
7
+ answers: map(function (choice) { return ({
8
+ title: choice.label,
9
+ selected: includes(choice.label, answers),
10
+ // TODO: EDIT_CHOICES
11
+ onClick: noop,
12
+ ariaLabel: choice.label
13
+ }); },
14
+ // TODO: EDIT_CHOICES -> getChoices
15
+ question.content.choices)
16
+ };
17
+ };
18
+ var qcmDragProps = function (question) {
19
+ // mock the answers
20
+ // TODO: EDIT_CHOICES -> getAnswerValues
21
+ var answers = [];
22
+ return {
23
+ type: 'qcmDrag',
24
+ answers: map(function (choice) {
25
+ var indexInAnswer = indexOf(choice.label, answers);
26
+ return {
27
+ title: choice.label,
28
+ selected: indexInAnswer !== -1,
29
+ order: indexInAnswer,
30
+ // TODO: EDIT_CHOICES
31
+ onClick: noop
32
+ };
33
+ // TODO: EDIT_CHOICES -> getChoices
34
+ }, question.content.choices)
35
+ };
36
+ };
37
+ var qcmGraphicProps = function (question) {
38
+ // mock the answers
39
+ // TODO: EDIT_CHOICES -> getAnswerValues
40
+ var answers = [];
41
+ return {
42
+ type: 'qcmGraphic',
43
+ answers: map(function (choice) { return ({
44
+ title: choice.label,
45
+ image: get('media.src.0.url', choice),
46
+ selected: includes(choice.label, answers),
47
+ // TODO: EDIT_CHOICES
48
+ onClick: noop
49
+ }); },
50
+ // TODO: EDIT_CHOICES -> getChoices
51
+ question.content.choices)
52
+ };
53
+ };
54
+ var templateTextProps = function (uiUtils) {
55
+ return function (choice, index) {
56
+ var translate = uiUtils.translate;
57
+ // TODO: EDIT_CHOICES -> getAnswerValues
58
+ var answers = [];
59
+ return {
60
+ type: 'text',
61
+ name: getOr('', 'name', choice),
62
+ placeholder: translate('Type here'),
63
+ value: get(index, answers),
64
+ // TODO: EDIT_CHOICES
65
+ onChange: noop
66
+ };
67
+ };
68
+ };
69
+ // const getItemText = (item: ChoiceFromAPI['items'][0]): item['text'] is string =>
70
+ var templateSelectProps = function (uiUtils) {
71
+ return function (choice, index) {
72
+ var translate = uiUtils.translate;
73
+ // TODO: EDIT_CHOICES -> getAnswerValues
74
+ var answers = [];
75
+ var answer = get(index, answers);
76
+ var temporaryOption = {
77
+ name: translate('Select an answer'),
78
+ value: '',
79
+ validOption: false,
80
+ selected: true
81
+ };
82
+ var selectOptions = choice.items.map(function (item) {
83
+ var itemText = getOr('', 'text', item);
84
+ return {
85
+ name: itemText,
86
+ value: itemText,
87
+ validOption: true,
88
+ selected: itemText === answer
89
+ };
90
+ });
91
+ return {
92
+ type: 'select',
93
+ name: getOr('', 'name', choice),
94
+ // TODO: EDIT_CHOICES
95
+ onChange: noop,
96
+ options: isEmpty(answer) ? concat([temporaryOption], selectOptions) : selectOptions
97
+ };
98
+ };
99
+ };
100
+ var templateProps = function (uiUtils) {
101
+ var templateTextProps_ = templateTextProps(uiUtils);
102
+ var templateSelectProps_ = templateSelectProps(uiUtils);
103
+ return function (question) {
104
+ // TODO: EDIT_CHOICES -> getChoices
105
+ var choices = question.content.choices;
106
+ return {
107
+ type: 'template',
108
+ template: get('content.template', question),
109
+ answers: choices.map(function (choice, index) {
110
+ return choice.type === 'text'
111
+ ? templateTextProps_(choice, index)
112
+ : templateSelectProps_(choice, index);
113
+ })
114
+ };
115
+ };
116
+ };
117
+ var basicProps = function (uiUtils) {
118
+ var translate = uiUtils.translate;
119
+ // TODO: EDIT_CHOICES -> getAnswerValues
120
+ var answers = [];
121
+ return function () {
122
+ return {
123
+ type: 'freeText',
124
+ placeholder: translate('Type here'),
125
+ value: head(answers),
126
+ // TODO: EDIT_CHOICES
127
+ onChange: noop
128
+ };
129
+ };
130
+ };
131
+ var sliderProps = function (question) {
132
+ var values = rangeStep(getOr(1, 'content.step', question), getOr(Number.NaN, 'content.min', question), getOr(Number.NaN, 'content.max', question) + 1
133
+ // Lodash doesn't infere the type very well here
134
+ );
135
+ // TODO: EDIT_CHOICES -> getAnswerValues
136
+ var answers = [];
137
+ var stateValue = head(answers);
138
+ var currentValue = toInteger(stateValue);
139
+ var indexValue = indexOf(currentValue, values);
140
+ var sliderPosition = divide(indexValue, size(values) - 1);
141
+ var unitLabel = get('question.content.unitLabel', question);
142
+ return {
143
+ type: 'slider',
144
+ placeholder: question.explanation,
145
+ minLabel: "".concat(question.content.min, " ").concat(unitLabel),
146
+ maxLabel: "".concat(question.content.max, " ").concat(unitLabel),
147
+ title: "".concat(currentValue, " ").concat(question.content.unitLabel),
148
+ value: sliderPosition,
149
+ // TODO: EDIT_CHOICES
150
+ onChange: noop
151
+ };
152
+ };
153
+ export var getQuestionType = function (slide) {
154
+ return slide.question.type;
155
+ };
156
+ export var mapApiSlideToUi = function (uiUtils) {
157
+ var basicProps_ = basicProps(uiUtils);
158
+ var templateProps_ = templateProps(uiUtils);
159
+ return function (slide) {
160
+ if (!slide) {
161
+ return;
162
+ }
163
+ var type = getQuestionType(slide);
164
+ switch (type) {
165
+ case 'qcm':
166
+ return pipe(get('question'), qcmProps)(slide);
167
+ case 'qcmGraphic':
168
+ return pipe(get('question'), qcmGraphicProps)(slide);
169
+ case 'qcmDrag':
170
+ return pipe(get('question'), qcmDragProps)(slide);
171
+ case 'basic':
172
+ return basicProps_();
173
+ case 'template':
174
+ return pipe(get('question'), templateProps_)(slide);
175
+ case 'slider':
176
+ return pipe(get('question'), sliderProps)(slide);
177
+ default:
178
+ throw new Error("".concat(type, " is not an handled question.type"));
179
+ }
180
+ };
181
+ };
@@ -0,0 +1,4 @@
1
+ import { FreeText } from '../../../types/slides';
2
+ import { SlideFromAPI } from '../../../types/common';
3
+ export declare const freeTextSlide: SlideFromAPI;
4
+ export declare const freeTextUISlide: FreeText;
@@ -0,0 +1,24 @@
1
+ import noop from 'lodash/fp/noop';
2
+ export var freeTextSlide = {
3
+ id: 'sli_E1Pcl-XAYbi',
4
+ universalRef: 'sli_E1Pcl-XAYbi',
5
+ question: {
6
+ type: 'basic',
7
+ header: 'sli_E1Pcl-XAYbi.header',
8
+ explanation: 'sli_E1Pcl-XAYbi.explanation',
9
+ content: {
10
+ label: 'sli_E1Pcl-XAYbi.label',
11
+ placeholder: 'sli_E1Pcl-XAYbi.placeholder',
12
+ id: 'sli_E1Pcl-XAYbi.choice_1'
13
+ }
14
+ },
15
+ clue: 'sli_E1Pcl-XAYbi.clue',
16
+ klf: 'sli_E1Pcl-XAYbi.klf',
17
+ tips: 'sli_E1Pcl-XAYbi.tips'
18
+ };
19
+ export var freeTextUISlide = {
20
+ type: 'freeText',
21
+ placeholder: 'Type here',
22
+ value: undefined,
23
+ onChange: noop
24
+ };
@@ -0,0 +1,4 @@
1
+ import { QcmDrag } from '../../../types/slides';
2
+ import { SlideFromAPI } from '../../../types/common';
3
+ export declare const qcmDragSlide: SlideFromAPI;
4
+ export declare const qcmDragUISlide: QcmDrag;