fcad-core-dragon 2.1.1 → 2.1.2

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 (160) hide show
  1. package/.editorconfig +7 -7
  2. package/.gitlab-ci.yml +124 -0
  3. package/.prettierrc +11 -11
  4. package/.vscode/extensions.json +8 -8
  5. package/.vscode/settings.json +46 -16
  6. package/CHANGELOG +520 -520
  7. package/README.md +57 -57
  8. package/documentation/.vitepress/config.js +114 -114
  9. package/documentation/api-examples.md +49 -49
  10. package/documentation/composants/app-base-button.md +58 -58
  11. package/documentation/composants/app-base-error-display.md +59 -59
  12. package/documentation/composants/app-base-popover.md +68 -68
  13. package/documentation/composants/app-comp-audio.md +75 -75
  14. package/documentation/composants/app-comp-branch-buttons.md +111 -111
  15. package/documentation/composants/app-comp-button-progress.md +53 -53
  16. package/documentation/composants/app-comp-carousel.md +53 -53
  17. package/documentation/composants/app-comp-container.md +53 -53
  18. package/documentation/composants/app-comp-input-checkbox-next.md +42 -42
  19. package/documentation/composants/app-comp-input-dropdown-next.md +34 -34
  20. package/documentation/composants/app-comp-input-radio-next.md +39 -39
  21. package/documentation/composants/app-comp-input-text-next.md +35 -35
  22. package/documentation/composants/app-comp-input-text-table-next.md +34 -34
  23. package/documentation/composants/app-comp-input-text-to-fill-dropdown-next.md +53 -53
  24. package/documentation/composants/app-comp-input-text-to-fill-next.md +31 -31
  25. package/documentation/composants/app-comp-jauge.md +31 -31
  26. package/documentation/composants/app-comp-menu-item.md +55 -55
  27. package/documentation/composants/app-comp-menu.md +29 -29
  28. package/documentation/composants/app-comp-navigation.md +41 -41
  29. package/documentation/composants/app-comp-note-call.md +53 -53
  30. package/documentation/composants/app-comp-note-credit.md +53 -53
  31. package/documentation/composants/app-comp-play-bar-next.md +53 -53
  32. package/documentation/composants/app-comp-pop-up-next.md +93 -93
  33. package/documentation/composants/app-comp-quiz-next.md +235 -235
  34. package/documentation/composants/app-comp-quiz-recall.md +53 -53
  35. package/documentation/composants/app-comp-svg-next.md +53 -53
  36. package/documentation/composants/app-comp-table-of-content.md +50 -50
  37. package/documentation/composants/app-comp-video-player.md +82 -82
  38. package/documentation/composants.md +46 -46
  39. package/documentation/composants_critiques/ModelPageComposant.md +53 -53
  40. package/documentation/composants_critiques/app-base-module.md +43 -43
  41. package/documentation/composants_critiques/app-base-page.md +48 -48
  42. package/documentation/composants_critiques/app-base.md +311 -311
  43. package/documentation/composants_critiques/main.md +15 -15
  44. package/documentation/demarrage.md +50 -50
  45. package/documentation/deploiement.md +57 -57
  46. package/documentation/index.md +33 -33
  47. package/documentation/markdown-examples.md +85 -85
  48. package/documentation/public/vite.svg +14 -14
  49. package/documentation/public/vuejs.svg +1 -1
  50. package/documentation/public/vuetify.svg +5 -5
  51. package/eslint.config.js +60 -60
  52. package/junit-report.xml +182 -0
  53. package/package.json +66 -59
  54. package/playwright/index.html +12 -0
  55. package/playwright/index.js +21 -0
  56. package/playwright-ct.config.js +95 -0
  57. package/src/$locales/en.json +157 -157
  58. package/src/$locales/fr.json +120 -120
  59. package/src/assets/data/onboardingMessages.json +47 -47
  60. package/src/components/AppBase.vue +1171 -1169
  61. package/src/components/AppBaseButton.vue +90 -95
  62. package/src/components/AppBaseErrorDisplay.vue +438 -438
  63. package/src/components/AppBaseFlipCard.vue +84 -84
  64. package/src/components/AppBaseModule.vue +1639 -1634
  65. package/src/components/AppBasePage.vue +867 -866
  66. package/src/components/AppBasePopover.vue +41 -41
  67. package/src/components/AppBaseSkeleton.vue +66 -66
  68. package/src/components/AppCompAudio.vue +261 -256
  69. package/src/components/AppCompBranchButtons.vue +508 -508
  70. package/src/components/AppCompButtonProgress.vue +137 -132
  71. package/src/components/AppCompCarousel.vue +342 -336
  72. package/src/components/AppCompContainer.vue +29 -29
  73. package/src/components/AppCompInputCheckBoxNx.vue +325 -323
  74. package/src/components/AppCompInputDropdownNx.vue +302 -299
  75. package/src/components/AppCompInputRadioNx.vue +287 -284
  76. package/src/components/AppCompInputTextNx.vue +156 -153
  77. package/src/components/AppCompInputTextTableNx.vue +205 -202
  78. package/src/components/AppCompInputTextToFillDropdownNx.vue +343 -340
  79. package/src/components/AppCompInputTextToFillNx.vue +316 -313
  80. package/src/components/AppCompJauge.vue +81 -81
  81. package/src/components/AppCompMenu.vue +6 -1
  82. package/src/components/AppCompMenuItem.vue +246 -240
  83. package/src/components/AppCompNavigation.vue +977 -972
  84. package/src/components/AppCompNoteCall.vue +167 -161
  85. package/src/components/AppCompNoteCredit.vue +496 -491
  86. package/src/components/AppCompPlayBarNext.vue +2290 -2288
  87. package/src/components/AppCompPopUpNext.vue +508 -504
  88. package/src/components/AppCompQuizNext.vue +515 -510
  89. package/src/components/AppCompQuizRecall.vue +355 -350
  90. package/src/components/AppCompSVGNext.vue +346 -346
  91. package/src/components/AppCompSettingsMenu.vue +177 -172
  92. package/src/components/AppCompTableOfContent.vue +433 -427
  93. package/src/components/AppCompVideoPlayer.vue +377 -377
  94. package/src/components/AppCompViewDisplay.vue +6 -6
  95. package/src/components/BaseModule.vue +55 -55
  96. package/src/composables/useIdleDetector.js +56 -56
  97. package/src/composables/useQuiz.js +89 -89
  98. package/src/composables/useTimer.js +172 -172
  99. package/src/directives/nvdaFix.js +53 -53
  100. package/src/externalComps/ModuleView.vue +22 -22
  101. package/src/externalComps/SummaryView.vue +91 -91
  102. package/src/main.js +493 -476
  103. package/src/module/stores/appStore.js +960 -947
  104. package/src/module/xapi/ADL.js +520 -520
  105. package/src/module/xapi/Crypto/Hasher.js +241 -241
  106. package/src/module/xapi/Crypto/WordArray.js +278 -278
  107. package/src/module/xapi/Crypto/algorithms/BufferedBlockAlgorithm.js +103 -103
  108. package/src/module/xapi/Crypto/algorithms/C_algo.js +315 -315
  109. package/src/module/xapi/Crypto/algorithms/HMAC.js +9 -9
  110. package/src/module/xapi/Crypto/algorithms/SHA1.js +9 -9
  111. package/src/module/xapi/Crypto/encoders/Base.js +105 -105
  112. package/src/module/xapi/Crypto/encoders/Base64.js +99 -99
  113. package/src/module/xapi/Crypto/encoders/Hex.js +61 -61
  114. package/src/module/xapi/Crypto/encoders/Latin1.js +61 -61
  115. package/src/module/xapi/Crypto/encoders/Utf8.js +45 -45
  116. package/src/module/xapi/Crypto/index.js +53 -53
  117. package/src/module/xapi/Statement/activity.js +47 -47
  118. package/src/module/xapi/Statement/agent.js +55 -55
  119. package/src/module/xapi/Statement/group.js +26 -26
  120. package/src/module/xapi/Statement/index.js +259 -259
  121. package/src/module/xapi/Statement/statement.js +253 -253
  122. package/src/module/xapi/Statement/statementRef.js +23 -23
  123. package/src/module/xapi/Statement/substatement.js +22 -22
  124. package/src/module/xapi/Statement/verb.js +36 -36
  125. package/src/module/xapi/activitytypes.js +17 -17
  126. package/src/module/xapi/launch.js +157 -157
  127. package/src/module/xapi/utils.js +167 -167
  128. package/src/module/xapi/verbs.js +294 -294
  129. package/src/module/xapi/wrapper.js +1895 -1895
  130. package/src/module/xapi/xapiStatement.js +444 -444
  131. package/src/plugins/analytics.js +34 -34
  132. package/src/plugins/bus.js +12 -8
  133. package/src/plugins/gsap.js +17 -17
  134. package/src/plugins/helper.js +355 -358
  135. package/src/plugins/i18n.js +27 -26
  136. package/src/plugins/idb.js +227 -227
  137. package/src/plugins/save.js +37 -37
  138. package/src/plugins/scorm.js +287 -287
  139. package/src/plugins/xapi.js +11 -11
  140. package/src/public/index.html +33 -33
  141. package/src/router/index.js +57 -57
  142. package/src/router/routes.js +312 -312
  143. package/src/shared/generalfuncs.js +344 -344
  144. package/src/shared/validators.js +1018 -1018
  145. package/tests/component/AppBaseButton.spec.js +53 -0
  146. package/tests/component/pinia.spec.js +24 -0
  147. package/{src/components/tests__ → tests/unit}/AppBaseButton.spec.js +53 -53
  148. package/tests/unit/AppCompInputCheckBoxNx.spec.js +59 -0
  149. package/tests/unit/AppCompInputDropdownNx.spec.js +51 -0
  150. package/tests/unit/AppCompInputRadioNx.spec.js +59 -0
  151. package/tests/unit/AppCompInputTextNx.spec.js +44 -0
  152. package/tests/unit/AppCompInputTextTableNx.spec.js +77 -0
  153. package/tests/unit/AppCompInputTextToFillDropdownNx.spec.js +60 -0
  154. package/tests/unit/AppCompInputTextToFillNx.spec.js +45 -0
  155. package/tests/unit/AppCompQuizNext.spec.js +114 -0
  156. package/tests/unit/AppCompVideoPlayer.spec.js +177 -0
  157. package/{src/components/tests__ → tests/unit}/useTimer.spec.js +91 -91
  158. package/vitest.config.js +28 -19
  159. package/vitest.setup.js +28 -0
  160. package/src/components/AppBaseButton.test.js +0 -21
@@ -1,284 +1,287 @@
1
- <!-- About this Component--
2
- * Renders a RADIO BUTTON input to display choices of response for the Quiz component
3
- * Related Quiz to question: REPONSE_UNIQUE
4
- * Receives the a data object defined by user
5
- * Used by AppCompQuiz
6
- * Uses useQuiz composable
7
- -->
8
-
9
- <template>
10
- <div v-if="inputData.length > 0" :id="id" class="input-box">
11
- <fieldset :aria-label="fieldsetLabel">
12
- <template
13
- v-for="(choixReponse, index) in quizInputDataValue"
14
- :Key="`div_chx_${id}-${choixReponse.id}`"
15
- >
16
- <div class="box-radio">
17
- <label
18
- :key="`lbl_chx_${id}_${choixReponse.id}`"
19
- :for="`chx_${id}_${choixReponse.id}`"
20
- class="radio-label"
21
- :class="[
22
- { answerSlct: selected == choixReponse.value },
23
- `${retro[index] || ''}`
24
- ]"
25
- >
26
- <input
27
- :id="`chx_${id}_${choixReponse.id}`"
28
- :key="`chx_${id}_${choixReponse.id}`"
29
- v-model="selected"
30
- type="radio"
31
- :name="`btn-radios-${id}`"
32
- class="radio-input"
33
- :aria-labelledby="`span_${id}_${choixReponse.id}`"
34
- :aria-describedby="`${id}_${choixReponse.id}-msg-erreur`"
35
- :value="choixReponse.value"
36
- />
37
-
38
- <span
39
- :id="`span_${id}_${choixReponse.id}`"
40
- class="radio-contenu"
41
- v-html="choixReponse.value"
42
- />
43
- <span
44
- :id="`${id}_${choixReponse.id}-msg-erreur`"
45
- :key="`msg_chx_${id}_${choixReponse.id}`"
46
- class="sr-only"
47
- >
48
- {{ messageAccessibility[index] }}
49
- </span>
50
- </label>
51
- </div>
52
- </template>
53
- </fieldset>
54
- </div>
55
- </template>
56
- <script>
57
- import { useQuiz } from '../composables/useQuiz'
58
- import { validateObjType } from '../shared/validators'
59
- export default {
60
- name: 'AppCompInputRadioNx',
61
- /* PROPS USED FOR PARENT TO COMMUNICATE DATA TO CHILD */
62
- props: {
63
- modelValue: {
64
- type: Array,
65
- default: () => []
66
- },
67
- inputData: {
68
- type: Array,
69
- default: () => []
70
- },
71
-
72
- solution: {
73
- type: Array,
74
- default: () => []
75
- },
76
-
77
- id: {
78
- type: String,
79
- default: ''
80
- }
81
- },
82
- /* EVENT EMITTED WHEN MODELVALUE CHANGES|UPDATE */
83
- emits: ['update:modelValue', 'enable-submit'],
84
-
85
- setup(props) {
86
- const { retroType, addRetroStyle, resetRetroStyle } = useQuiz()
87
-
88
- return { retroType, addRetroStyle, resetRetroStyle }
89
- },
90
- data() {
91
- return {
92
- quizInputDataValue: [],
93
- result: null,
94
- retro: [],
95
- messageAccessibility: []
96
- }
97
- },
98
- computed: {
99
- fieldsetLabel() {
100
- return `${this.$t('quizState.radioFieldset')} ${this.inputData.length} ${this.$t('quizState.options')}`
101
- },
102
- /* INTERNAL REACTIVE VALUE THAT BIND WITH MODELVALUE PROPS */
103
- inputValue: {
104
- get() {
105
- return this.modelValue
106
- },
107
-
108
- set(newValue) {
109
- this.$emit('update:modelValue', [...newValue])
110
- }
111
- },
112
- /**
113
- * internal reactive value that map the options to add SELECTED attribute on each option
114
- * this attribute value can be changed when user select the option
115
- */
116
- mappedOptions() {
117
- const options = this.inputData.map(
118
- (op) => (op = { ...op, selected: false })
119
- )
120
-
121
- return options
122
- },
123
- selected: {
124
- /**
125
- * Return the value of the selected element in the modelValue
126
- */
127
- get() {
128
- // return this.modelValue
129
- const selectedItem = this.modelValue.find((item) => {
130
- return item.selected
131
- })
132
-
133
- return selectedItem ? selectedItem.value : ''
134
- },
135
- /**
136
- * Modify the value of a item in the array model and return the array
137
- */
138
- set(newValue) {
139
- this.resetRetroStyle([this.retro, this.messageAccessibility])
140
-
141
- // create change THE SELECTED attribute OF THE selected option
142
- const updatedModelValue = this.mappedOptions
143
- .map((option) => ({
144
- ...option,
145
- selected: option.value === newValue
146
- }))
147
- .filter((e) => e.selected)
148
-
149
- this.inputValue = updatedModelValue // trigger the reactivity of the inputVAlue
150
- }
151
- }
152
- },
153
- watch: {
154
- inputValue: {
155
- handler(newValue, oldValue) {
156
- if (this.$el && this.$el.id !== this.id) return
157
-
158
- const selectedItem = this.modelValue.some((e) => e.selected)
159
- this.$emit('enable-submit', selectedItem)
160
- },
161
- immediate: true,
162
- deep: true
163
- }
164
- },
165
-
166
- created() {
167
- if (import.meta.env.DEV) {
168
- let errors = this.validateInputData()
169
-
170
- if (errors && errors.errorList.length)
171
- return this.$bus.$emit('input-error', { e: this.id, errors })
172
- }
173
-
174
- this.quizInputDataValue = this.inputData
175
- },
176
- mounted() {},
177
-
178
- methods: {
179
- /**
180
- * @description validate the raw data received by the component to render is view
181
- * @returns {Object} errors - errorList: to display in view and errorConsole, to be displayed in console
182
- */
183
- validateInputData() {
184
- let errors = null //array for errors dectected
185
- let stringType = ['id', 'value']
186
-
187
- if (!this.inputData.length) return errors
188
- for (let i = 0; i < this.inputData.length; i++) {
189
- errors = validateObjType(
190
- this.inputData[i],
191
- { stringType },
192
- null,
193
- `choix_reponse #${i + 1}`
194
- )
195
- const { errorList, errorInConsole } = errors
196
-
197
- if (errorList.length || errorInConsole.length) return errors
198
- }
199
-
200
- return errors
201
- },
202
- /**
203
- * @description Component validation method to validate the user input against the solution
204
- * can handle logic of Css style to apply (correct/wrong Answer)
205
- */
206
- validateAnswer() {
207
- //Validate the user answer
208
- let validatedResults
209
- if (this.solution != null) {
210
- validatedResults = this.inputValue.map(
211
- (a) =>
212
- (a = {
213
- ...a,
214
- correct: this.solution.includes(a.id)
215
- })
216
- )
217
- } else {
218
- validatedResults = this.inputValue.map(
219
- (a) =>
220
- (a = {
221
- ...a,
222
- correct: null
223
- })
224
- )
225
- }
226
-
227
- const mappedResults = this.mappedOptions.map((a) => {
228
- if (this.solution != null) {
229
- if (a.id == validatedResults[0].id) a = validatedResults[0]
230
- a.correct = this.solution.includes(a.id)
231
- return a
232
- } else {
233
- if (a.id == validatedResults[0].id) a = validatedResults[0]
234
- a.correct = null
235
- return a
236
- }
237
- })
238
-
239
- //Set the valition style
240
- let { classRetro, mesA11y } = this.addRetroStyle(
241
- this.solution,
242
- mappedResults,
243
- this.inputData.length
244
- )
245
- this.retro = classRetro
246
- this.messageAccessibility = mesA11y
247
-
248
- //Retrive the user response from validation
249
- this.result = mappedResults.filter((a) => a.selected)
250
-
251
- let retro = this.retroType(this.solution, this.result)
252
-
253
- const { correct, ...answer } = this.result[0]
254
-
255
- return {
256
- userAnswer: answer,
257
- correctAnswer: correct,
258
- retroType: retro
259
- }
260
- }
261
- }
262
- }
263
- </script>
264
- <style lang="scss">
265
- .custom-control-input:focus ~ .custom-control-label::before {
266
- border: inherit;
267
- }
268
-
269
- .custom-control-input:focus ~ .custom-control-label::before {
270
- box-shadow: inherit;
271
- -webkit-box-shadow: inherit;
272
- }
273
-
274
- fieldset {
275
- border: inherit;
276
- }
277
-
278
- .radio-label {
279
- //position: relative;
280
- span {
281
- width: 90%;
282
- }
283
- }
284
- </style>
1
+ <!-- About this Component--
2
+ * Renders a RADIO BUTTON input to display choices of response for the Quiz component
3
+ * Related Quiz to question: REPONSE_UNIQUE
4
+ * Receives the a data object defined by user
5
+ * Used by AppCompQuiz
6
+ * Uses useQuiz composable
7
+ -->
8
+
9
+ <template>
10
+ <div v-if="inputData.length > 0" :id="id" class="input-box">
11
+ <fieldset :aria-label="fieldsetLabel">
12
+ <template
13
+ v-for="(choixReponse, index) in quizInputDataValue"
14
+ :Key="`div_chx_${id}-${choixReponse.id}`"
15
+ >
16
+ <div class="box-radio">
17
+ <label
18
+ :key="`lbl_chx_${id}_${choixReponse.id}`"
19
+ :for="`chx_${id}_${choixReponse.id}`"
20
+ class="radio-label"
21
+ :class="[
22
+ { answerSlct: selected == choixReponse.value },
23
+ `${retro[index] || ''}`
24
+ ]"
25
+ >
26
+ <input
27
+ :id="`chx_${id}_${choixReponse.id}`"
28
+ :key="`chx_${id}_${choixReponse.id}`"
29
+ v-model="selected"
30
+ type="radio"
31
+ :name="`btn-radios-${id}`"
32
+ class="radio-input"
33
+ :aria-labelledby="`span_${id}_${choixReponse.id}`"
34
+ :aria-describedby="`${id}_${choixReponse.id}-msg-erreur`"
35
+ :value="choixReponse.value"
36
+ />
37
+
38
+ <span
39
+ :id="`span_${id}_${choixReponse.id}`"
40
+ class="radio-contenu"
41
+ v-html="choixReponse.value"
42
+ />
43
+ <span
44
+ :id="`${id}_${choixReponse.id}-msg-erreur`"
45
+ :key="`msg_chx_${id}_${choixReponse.id}`"
46
+ class="sr-only"
47
+ >
48
+ {{ messageAccessibility[index] }}
49
+ </span>
50
+ </label>
51
+ </div>
52
+ </template>
53
+ </fieldset>
54
+ </div>
55
+ </template>
56
+ <script>
57
+ import { useQuiz } from '../composables/useQuiz'
58
+ import { validateObjType } from '../shared/validators'
59
+ import { useI18n } from 'vue-i18n'
60
+
61
+ export default {
62
+ name: 'AppCompInputRadioNx',
63
+ /* PROPS USED FOR PARENT TO COMMUNICATE DATA TO CHILD */
64
+ props: {
65
+ modelValue: {
66
+ type: Array,
67
+ default: () => []
68
+ },
69
+ inputData: {
70
+ type: Array,
71
+ default: () => []
72
+ },
73
+
74
+ solution: {
75
+ type: Array,
76
+ default: () => []
77
+ },
78
+
79
+ id: {
80
+ type: String,
81
+ default: ''
82
+ }
83
+ },
84
+ /* EVENT EMITTED WHEN MODELVALUE CHANGES|UPDATE */
85
+ emits: ['update:modelValue', 'enable-submit'],
86
+
87
+ setup(props) {
88
+ const { t } = useI18n()
89
+ const { retroType, addRetroStyle, resetRetroStyle } = useQuiz()
90
+
91
+ return { retroType, addRetroStyle, resetRetroStyle, t }
92
+ },
93
+ data() {
94
+ return {
95
+ quizInputDataValue: [],
96
+ result: null,
97
+ retro: [],
98
+ messageAccessibility: []
99
+ }
100
+ },
101
+ computed: {
102
+ fieldsetLabel() {
103
+ return `${this.$t('quizState.radioFieldset')} ${this.inputData.length} ${this.$t('quizState.options')}`
104
+ },
105
+ /* INTERNAL REACTIVE VALUE THAT BIND WITH MODELVALUE PROPS */
106
+ inputValue: {
107
+ get() {
108
+ return this.modelValue
109
+ },
110
+
111
+ set(newValue) {
112
+ this.$emit('update:modelValue', [...newValue])
113
+ }
114
+ },
115
+ /**
116
+ * internal reactive value that map the options to add SELECTED attribute on each option
117
+ * this attribute value can be changed when user select the option
118
+ */
119
+ mappedOptions() {
120
+ const options = this.inputData.map(
121
+ (op) => (op = { ...op, selected: false })
122
+ )
123
+
124
+ return options
125
+ },
126
+ selected: {
127
+ /**
128
+ * Return the value of the selected element in the modelValue
129
+ */
130
+ get() {
131
+ // return this.modelValue
132
+ const selectedItem = this.modelValue.find((item) => {
133
+ return item.selected
134
+ })
135
+
136
+ return selectedItem ? selectedItem.value : ''
137
+ },
138
+ /**
139
+ * Modify the value of a item in the array model and return the array
140
+ */
141
+ set(newValue) {
142
+ this.resetRetroStyle([this.retro, this.messageAccessibility])
143
+
144
+ // create change THE SELECTED attribute OF THE selected option
145
+ const updatedModelValue = this.mappedOptions
146
+ .map((option) => ({
147
+ ...option,
148
+ selected: option.value === newValue
149
+ }))
150
+ .filter((e) => e.selected)
151
+
152
+ this.inputValue = updatedModelValue // trigger the reactivity of the inputVAlue
153
+ }
154
+ }
155
+ },
156
+ watch: {
157
+ inputValue: {
158
+ handler(newValue, oldValue) {
159
+ if (this.$el && this.$el.id !== this.id) return
160
+
161
+ const selectedItem = this.modelValue.some((e) => e.selected)
162
+ this.$emit('enable-submit', selectedItem)
163
+ },
164
+ immediate: true,
165
+ deep: true
166
+ }
167
+ },
168
+
169
+ created() {
170
+ if (import.meta.env.DEV) {
171
+ let errors = this.validateInputData()
172
+
173
+ if (errors && errors.errorList.length)
174
+ return this.$bus.$emit('input-error', { e: this.id, errors })
175
+ }
176
+
177
+ this.quizInputDataValue = this.inputData
178
+ },
179
+ mounted() {},
180
+
181
+ methods: {
182
+ /**
183
+ * @description validate the raw data received by the component to render is view
184
+ * @returns {Object} errors - errorList: to display in view and errorConsole, to be displayed in console
185
+ */
186
+ validateInputData() {
187
+ let errors = null //array for errors dectected
188
+ let stringType = ['id', 'value']
189
+
190
+ if (!this.inputData.length) return errors
191
+ for (let i = 0; i < this.inputData.length; i++) {
192
+ errors = validateObjType(
193
+ this.inputData[i],
194
+ { stringType },
195
+ null,
196
+ `choix_reponse #${i + 1}`
197
+ )
198
+ const { errorList, errorInConsole } = errors
199
+
200
+ if (errorList.length || errorInConsole.length) return errors
201
+ }
202
+
203
+ return errors
204
+ },
205
+ /**
206
+ * @description Component validation method to validate the user input against the solution
207
+ * can handle logic of Css style to apply (correct/wrong Answer)
208
+ */
209
+ validateAnswer() {
210
+ //Validate the user answer
211
+ let validatedResults
212
+ if (this.solution != null) {
213
+ validatedResults = this.inputValue.map(
214
+ (a) =>
215
+ (a = {
216
+ ...a,
217
+ correct: this.solution.includes(a.id)
218
+ })
219
+ )
220
+ } else {
221
+ validatedResults = this.inputValue.map(
222
+ (a) =>
223
+ (a = {
224
+ ...a,
225
+ correct: null
226
+ })
227
+ )
228
+ }
229
+
230
+ const mappedResults = this.mappedOptions.map((a) => {
231
+ if (this.solution != null) {
232
+ if (a.id == validatedResults[0].id) a = validatedResults[0]
233
+ a.correct = this.solution.includes(a.id)
234
+ return a
235
+ } else {
236
+ if (a.id == validatedResults[0].id) a = validatedResults[0]
237
+ a.correct = null
238
+ return a
239
+ }
240
+ })
241
+
242
+ //Set the valition style
243
+ let { classRetro, mesA11y } = this.addRetroStyle(
244
+ this.solution,
245
+ mappedResults,
246
+ this.inputData.length
247
+ )
248
+ this.retro = classRetro
249
+ this.messageAccessibility = mesA11y
250
+
251
+ //Retrive the user response from validation
252
+ this.result = mappedResults.filter((a) => a.selected)
253
+
254
+ let retro = this.retroType(this.solution, this.result)
255
+
256
+ const { correct, ...answer } = this.result[0]
257
+
258
+ return {
259
+ userAnswer: answer,
260
+ correctAnswer: correct,
261
+ retroType: retro
262
+ }
263
+ }
264
+ }
265
+ }
266
+ </script>
267
+ <style lang="scss">
268
+ .custom-control-input:focus ~ .custom-control-label::before {
269
+ border: inherit;
270
+ }
271
+
272
+ .custom-control-input:focus ~ .custom-control-label::before {
273
+ box-shadow: inherit;
274
+ -webkit-box-shadow: inherit;
275
+ }
276
+
277
+ fieldset {
278
+ border: inherit;
279
+ }
280
+
281
+ .radio-label {
282
+ //position: relative;
283
+ span {
284
+ width: 90%;
285
+ }
286
+ }
287
+ </style>