fcad-core-dragon 2.0.1 → 2.0.2-beta.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 (90) hide show
  1. package/.editorconfig +33 -33
  2. package/.eslintignore +29 -29
  3. package/.eslintrc.cjs +81 -81
  4. package/CHANGELOG +17 -1
  5. package/bk.scss +117 -117
  6. package/package.json +1 -1
  7. package/src/$locales/en.json +18 -4
  8. package/src/$locales/fr.json +17 -3
  9. package/src/assets/data/onboardingMessages.json +47 -47
  10. package/src/components/AppBase.vue +36 -341
  11. package/src/components/AppBaseErrorDisplay.vue +438 -438
  12. package/src/components/AppBaseFlipCard.vue +84 -84
  13. package/src/components/AppBaseModule.vue +16 -21
  14. package/src/components/AppBasePage.vue +45 -14
  15. package/src/components/AppBasePopover.vue +41 -41
  16. package/src/components/AppBaseSkeleton.vue +45 -0
  17. package/src/components/AppCompAudio.vue +12 -3
  18. package/src/components/AppCompButtonProgress.vue +13 -2
  19. package/src/components/AppCompCarousel.vue +12 -4
  20. package/src/components/AppCompInputCheckBoxNx.vue +324 -0
  21. package/src/components/AppCompInputDropdownNx.vue +295 -0
  22. package/src/components/AppCompInputRadioNx.vue +264 -0
  23. package/src/components/AppCompInputTextNx.vue +148 -0
  24. package/src/components/AppCompInputTextTableNx.vue +198 -0
  25. package/src/components/AppCompInputTextToFillDropdownNx.vue +291 -0
  26. package/src/components/AppCompInputTextToFillNx.vue +277 -0
  27. package/src/components/AppCompJauge.vue +11 -4
  28. package/src/components/AppCompMenu.vue +7 -14
  29. package/src/components/AppCompMenuItem.vue +7 -5
  30. package/src/components/AppCompNavigation.vue +21 -21
  31. package/src/components/AppCompNoteCall.vue +1 -0
  32. package/src/components/AppCompNoteCredit.vue +2 -1
  33. package/src/components/AppCompPlayBarNext.vue +94 -41
  34. package/src/components/AppCompPlayBarProgress.vue +82 -82
  35. package/src/components/AppCompPopUpNext.vue +6 -6
  36. package/src/components/AppCompQuiz.vue +500 -0
  37. package/src/components/AppCompQuizRecall.vue +113 -66
  38. package/src/components/AppCompSettingsMenu.vue +172 -172
  39. package/src/components/AppCompTableOfContent.vue +39 -10
  40. package/src/components/AppCompVideoPlayer.vue +1 -1
  41. package/src/components/AppCompViewDisplay.vue +6 -6
  42. package/src/composables/useQuiz.js +62 -179
  43. package/src/directives/nvdaFix.js +53 -0
  44. package/src/externalComps/ModuleView.vue +22 -22
  45. package/src/externalComps/SummaryView.vue +91 -91
  46. package/src/main.js +227 -30
  47. package/src/mixins/$mediaMixins.js +1 -11
  48. package/src/module/stores/appStore.js +29 -11
  49. package/src/module/xapi/Crypto/Hasher.js +241 -241
  50. package/src/module/xapi/Crypto/WordArray.js +278 -278
  51. package/src/module/xapi/Crypto/algorithms/BufferedBlockAlgorithm.js +103 -103
  52. package/src/module/xapi/Crypto/algorithms/C_algo.js +315 -315
  53. package/src/module/xapi/Crypto/algorithms/HMAC.js +9 -9
  54. package/src/module/xapi/Crypto/algorithms/SHA1.js +9 -9
  55. package/src/module/xapi/Crypto/encoders/Base.js +105 -105
  56. package/src/module/xapi/Crypto/encoders/Base64.js +99 -99
  57. package/src/module/xapi/Crypto/encoders/Hex.js +61 -61
  58. package/src/module/xapi/Crypto/encoders/Latin1.js +61 -61
  59. package/src/module/xapi/Crypto/encoders/Utf8.js +45 -45
  60. package/src/module/xapi/Crypto/index.js +53 -53
  61. package/src/module/xapi/Statement/activity.js +47 -47
  62. package/src/module/xapi/Statement/agent.js +55 -55
  63. package/src/module/xapi/Statement/group.js +26 -26
  64. package/src/module/xapi/Statement/index.js +259 -259
  65. package/src/module/xapi/Statement/statement.js +253 -253
  66. package/src/module/xapi/Statement/statementRef.js +23 -23
  67. package/src/module/xapi/Statement/substatement.js +22 -22
  68. package/src/module/xapi/Statement/verb.js +36 -36
  69. package/src/module/xapi/activitytypes.js +17 -17
  70. package/src/module/xapi/utils.js +167 -167
  71. package/src/module/xapi/verbs.js +294 -294
  72. package/src/module/xapi/xapiStatement.js +444 -444
  73. package/src/plugins/bus.js +8 -8
  74. package/src/plugins/gsap.js +14 -14
  75. package/src/plugins/i18n.js +44 -44
  76. package/src/plugins/idb.js +1 -1
  77. package/src/plugins/save.js +37 -37
  78. package/src/plugins/scorm.js +287 -287
  79. package/src/plugins/xapi.js +11 -11
  80. package/src/public/index.html +33 -33
  81. package/src/shared/generalfuncs.js +134 -0
  82. package/src/shared/validators.js +308 -234
  83. package/src/components/AppCompInputCheckBoxNext.vue +0 -205
  84. package/src/components/AppCompInputDropdownNext.vue +0 -201
  85. package/src/components/AppCompInputRadioNext.vue +0 -158
  86. package/src/components/AppCompInputTextNext.vue +0 -124
  87. package/src/components/AppCompInputTextTableNext.vue +0 -142
  88. package/src/components/AppCompInputTextToFillDropdownNext.vue +0 -238
  89. package/src/components/AppCompInputTextToFillNext.vue +0 -171
  90. package/src/components/AppCompQuizNext.vue +0 -2908
@@ -204,6 +204,140 @@ const fileAssets = {
204
204
  let formatted = string.replaceAll('_', ' ').toLowerCase()
205
205
  formatted = `${formatted.substring(0, 1).toUpperCase()}${formatted.slice(1).toLowerCase()}`
206
206
  return formatted
207
+ },
208
+
209
+ /**
210
+ * @description compares 2 array
211
+ * @param {Array} array1
212
+ * @param {Array} array2
213
+ * @returns {Boolean}
214
+ */
215
+ isEqual: (array1, array2) => {
216
+ // if length is not equal
217
+ if (array1.length != array2.length) {
218
+ return false
219
+ } else {
220
+ // comapring each element of array
221
+ for (let i = 0; i < array1.length; i++) {
222
+ if (array1[i] != array2[i]) {
223
+ return false
224
+ }
225
+ }
226
+ return true
227
+ }
228
+ },
229
+ /**
230
+ * @description used by the dropdown quiz
231
+ * @param {Array} answers what the user has answered
232
+ * @param {Array} solution the correct choices
233
+ * @returns {Boolean}
234
+ */
235
+ compareSelectedAnswers: (answers, solution) => {
236
+ for (let index = 0; index < answers.length; index++) {
237
+ const elementAnswers = answers[index]
238
+ const elementSolution = solution[index]
239
+ if (elementAnswers.reponse_id !== elementSolution) {
240
+ return false
241
+ }
242
+ }
243
+ return true
244
+ },
245
+
246
+ /**
247
+ * @description used by the texte_troue_select quiz
248
+ * @param {Array} answers what the user has answered
249
+ * @param {Array} solution the correct choices
250
+ * @returns {Boolean}
251
+ */
252
+ compareSelectedTextToFillAnswers: (answers, solution) => {
253
+ for (let index = 0; index < answers.length; index++) {
254
+ const elementAnswers = answers[index]
255
+ const elementSolution = Object.values(solution[index])[0]
256
+ if (elementAnswers.reponse_id !== elementSolution) {
257
+ return false
258
+ }
259
+ }
260
+ return true
261
+ },
262
+
263
+ /**
264
+ * @description used by the texte_tableau quiz and texte_troue quiz
265
+ * @param {Array} answers what the user has answered
266
+ * @param {Array} solution the correct choices
267
+ * @returns {Boolean}
268
+ */
269
+ compareTextAnswers: (answers, solution) => {
270
+ for (let index = 0; index < answers.length; index++) {
271
+ const elementAnswers = answers[index]
272
+ const elementSolution = solution[index]
273
+ if (
274
+ !this.$helper.containsValue(
275
+ elementSolution.reponse_value,
276
+ elementAnswers.reponse
277
+ )
278
+ ) {
279
+ return false
280
+ }
281
+ }
282
+ return true
283
+ },
284
+
285
+ /**
286
+ * @description used by the texte_tableau quiz and texte_troue quiz
287
+ * @param {Array} answers what the user has answered
288
+ * @param {Array} solution the correct choices
289
+ * @returns {Boolean}
290
+ */
291
+ compareTextAnswers2: (answers, solution) => {
292
+ for (let index = 0; index < answers.length; index++) {
293
+ const elementAnswers = answers[index]
294
+ const elementSolution = solution[index]
295
+ if (
296
+ !this.$helper.containsValue(
297
+ Object.values(elementSolution)[0],
298
+ elementAnswers.reponse
299
+ )
300
+ ) {
301
+ return false
302
+ }
303
+ }
304
+ return true
305
+ },
306
+
307
+ /**
308
+ * @description used by the association quiz
309
+ * @param {Object} answers what the user has answered
310
+ * @param {Object} solution the correct choices
311
+ * @returns {Boolean}
312
+ */
313
+ compareObjectAnswers: (answers, solution) => {
314
+ let answersKey = Object.keys(answers)
315
+ for (let index = 0; index < answersKey.length; index++) {
316
+ const elementAnswers = answers[answersKey[index]]
317
+ const elementSolution = solution[answersKey[index]]
318
+ if (elementAnswers !== elementSolution) {
319
+ return false
320
+ }
321
+ }
322
+ return true
323
+ },
324
+
325
+ /**
326
+ * @description used by the dragdrop quiz
327
+ * @param {Object} answers what the user has answered
328
+ * @param {Object} solution the correct choices
329
+ * @returns {Boolean}
330
+ */
331
+ compareObjectAnswers2: (answers, solution) => {
332
+ let answersKey = Object.keys(answers)
333
+ for (let index = 0; index < answersKey.length; index++) {
334
+ const elementAnswers = answers[answersKey[index]]
335
+ const elementSolution = solution[answersKey[index]]
336
+ if (!this.isEqual(elementAnswers, elementSolution)) {
337
+ return false
338
+ }
339
+ }
340
+ return true
207
341
  }
208
342
  }
209
343
 
@@ -1,3 +1,248 @@
1
+ // Errors message to display in the console
2
+ const ERR_TYPE = {
3
+ err0: `\n 💥 Missing \x1B[1m$attr$ \x1B[0mfor $comp$. \x1B[1m$attr$ \x1B[0m should be provided with following attributes: \x1B[1m{$data$}`,
4
+ err1: `\n 💥 Invalid declaration for \x1B[1m$wrd$ \x1B[0m object`,
5
+ err2: `\n 💥 Invalid type declaration for 👉\x1B[1m$attr$ \x1B[0m👈 in \x1B[1m$el$\x1B[0m. Expected is \x1B[3m$type$ \x1B[0mtype with some value`,
6
+ err3: `\n 💥 Missing required argument 👉\x1B[1m$key$\x1B[0m👈 in \x1B[1m$el$\x1B[0m. Required arguments are: \x1B[1m$args$`,
7
+ err4: `\n 💥 Missing required argument 👉\x1B[1m$key$\x1B[0m👈 in \x1B[1m$el$\x1B[0m. Required arguments are: \x1B[1m$args$`
8
+ }
9
+
10
+ // Errors message to display in Appplication UI
11
+ const ERR_TYPE_MSG = {
12
+ err0: `\n Données manquantes pour <span style='text-transform: uppercase;'>$comp$</span>. Assurez-vous que le composant reçoit l'attribut <b>$attr$</b> avec des données pour: <b>$data$</b>`,
13
+ err1: `\n Déclaration invalide pour <b>$wrd$</b>. Assurez-vous que l'application a du data.`,
14
+ err2: `\n Vous avez une declaration invalide dans <b>$attr$</b>. 👉<b>$el$</b>👈 n'accepte que le type <i>$type$</i> et ne peut pas être vide`,
15
+ err3: `\n L'attribut 👉<b>$key$</b>👈 est manquant dans <b>$el$</b>. Les attributs requis sont: <b>$args$</b>`
16
+ }
17
+
18
+ //Get all the invalids properties from the object
19
+ /*Add element from target array that are NOT in arr to the wrongArray*/
20
+ const checkerWrong = (arr, target) => {
21
+ let wrongArray = []
22
+ target.every((v) => {
23
+ if (arr.includes(v)) {
24
+ return true
25
+ } else {
26
+ wrongArray.push(v)
27
+ return true
28
+ }
29
+ })
30
+ return wrongArray
31
+ }
32
+ //Get all the required properties that are missing from the object
33
+ /*Add element from the arr that are NOT in target arr to the missingArray*/
34
+ const checkerMissing = (arr, target) => {
35
+ let missingArray = []
36
+ arr.every((v) => {
37
+ if (target.includes(v)) {
38
+ return true
39
+ } else {
40
+ missingArray.push(v)
41
+ return true
42
+ }
43
+ })
44
+ return missingArray
45
+ }
46
+
47
+ /**
48
+ * @description - Method to validate that given object attributes hold expected types
49
+ * @param {Object} Obj - object to validate
50
+ * @param {Object} Args - List of expected type groups - each type group must be an array of attributes with the same type
51
+ * @param {Array} notRequiredArgs - list of field that should be considered as optional in the object. Will not give error if not * provided but will be validated if they are present with wrong type or empty
52
+ * @param {Array} compName - Name of the component- will be display in error message
53
+ * @param {Array} err - list off errors to be added to
54
+ * @return {Object} list of errors - {errorInConsole, errorList} : errorlist can be used to display messages on template and
55
+ * errorInConsole to display messages in browser console
56
+ * @exemple - Given $user= {name:'toto', username:'totoEscargot', id:'id001', age:23, books:['one', 'two', 'three'] }
57
+ * Use validator on $user: validateObjType($user, {stringType:['name', 'username' , 'id'], numbType:['age'], arrayType:['books']})
58
+ * Will fail if any listed attribute not in $user or have wrong value. Error messages will be in console
59
+ *
60
+ */
61
+
62
+ const validateObjType = (
63
+ Obj,
64
+ Args = {
65
+ boolType: null,
66
+ arrayType: null,
67
+ stringType: null,
68
+ objectType: null,
69
+ numbType: null
70
+ },
71
+ notRequiredArgs = null,
72
+ compName = 'component',
73
+ err = null
74
+ ) => {
75
+ let errorInConsole = err && err.errorInConsole ? err.errorInConsole : []
76
+ let errorList = err && err.errorList ? err.errorLIst : []
77
+ let optionalArgs =
78
+ notRequiredArgs && notRequiredArgs.length ? notRequiredArgs : []
79
+ //=====Expected Arguments validation =================//
80
+ //Should have an object argument
81
+ if (!Obj) throw new Error(`No valid arguments provided`)
82
+
83
+ //List required attributes
84
+ const required = []
85
+
86
+ for (const _type in Args) {
87
+ // Should be a required type
88
+ if (
89
+ ![
90
+ 'boolType',
91
+ 'arrayType',
92
+ 'stringType',
93
+ 'objectType',
94
+ 'numberType'
95
+ ].includes(_type)
96
+ )
97
+ throw new Error(`Unknown types declaration : ${_type}`)
98
+
99
+ if (Args[_type] && Args[_type].length) {
100
+ for (let el of Args[_type]) {
101
+ //Check that each given element is a string
102
+ if (el.constructor !== String)
103
+ throw new Error(
104
+ `Invalid type detected in ${JSON.stringify(
105
+ Args[_type]
106
+ )}. Item ${Args[_type].indexOf(el) + 1} should be a String`
107
+ )
108
+
109
+ if (!optionalArgs.includes(el)) required.push(el)
110
+ }
111
+ }
112
+ }
113
+
114
+ //validate Args Keys type
115
+ for (const _type in Args) {
116
+ for (let el of Args[_type]) {
117
+ let reg = /(\$el\$)|(\$type\$)|(\$attr\$)/g
118
+
119
+ switch (true) {
120
+ // Check That each given element exist in data if not optional
121
+ case Obj[el] === undefined && required.includes(el): {
122
+ reg = /(\$key\$)|(\$el\$)|(\$args\$)/g
123
+ const reg2 = /\[|\]|/g
124
+
125
+ errorInConsole.push(
126
+ ERR_TYPE.err3.replace(reg, (e) => {
127
+ if (e == '$key$') return el
128
+ if (e == '$el$') return compName
129
+ if (e == '$args$') return JSON.stringify(required)
130
+ })
131
+ )
132
+
133
+ errorList.push(
134
+ ERR_TYPE_MSG.err3.replace(reg, (e) => {
135
+ if (e == '$key$') return el
136
+ if (e == '$el$') return compName || 'Composant'
137
+ if (e == '$args$')
138
+ return JSON.stringify(required).replaceAll(reg2, '')
139
+ })
140
+ )
141
+ break
142
+ }
143
+ //Should have Correct Types $attr$ $el$ $type$
144
+ case _type == 'boolType' &&
145
+ Obj[el] !== undefined &&
146
+ Obj[el].constructor !== Boolean:
147
+ errorInConsole.push(
148
+ ERR_TYPE.err2.replace(reg, (e) => {
149
+ if (e == '$attr$') return compName || 'Composant'
150
+ if (e == '$el$') return el
151
+ if (e == '$type$') return 'Boolean'
152
+ })
153
+ )
154
+ errorList.push(
155
+ ERR_TYPE_MSG.err2.replace(reg, (e) => {
156
+ if (e == '$attr$') return compName || 'Composant'
157
+ if (e == '$el$') return el
158
+ if (e == '$type$') return 'Boolean'
159
+ })
160
+ )
161
+ break
162
+
163
+ case _type == 'stringType' &&
164
+ Obj[el] !== undefined &&
165
+ (Obj[el].constructor !== String || !Obj[el].trim().length):
166
+ errorInConsole.push(
167
+ ERR_TYPE.err2.replace(reg, (e) => {
168
+ if (e == '$attr$') return compName || 'Composant'
169
+ if (e == '$el$') return el
170
+ if (e == '$type$') return 'String'
171
+ })
172
+ )
173
+ errorList.push(
174
+ ERR_TYPE_MSG.err2.replace(reg, (e) => {
175
+ if (e == '$attr$') return compName || 'Composant'
176
+ if (e == '$el$') return el
177
+ if (e == '$type$') return 'String'
178
+ })
179
+ )
180
+ break
181
+
182
+ case _type == 'arrayType' &&
183
+ Obj[el] !== null &&
184
+ Obj[el] !== undefined &&
185
+ (Obj[el].constructor !== Array || !Obj[el].length):
186
+ errorInConsole.push(
187
+ ERR_TYPE.err2.replace(reg, (e) => {
188
+ if (e == '$attr$') return compName || 'Composant'
189
+ if (e == '$el$') return el
190
+ if (e == '$type$') return 'Array'
191
+ })
192
+ )
193
+ errorList.push(
194
+ ERR_TYPE_MSG.err2.replace(reg, (e) => {
195
+ if (e == '$attr$') return compName || 'Composant'
196
+ if (e == '$el$') return el
197
+ if (e == '$type$') return 'Array'
198
+ })
199
+ )
200
+ break
201
+
202
+ case _type == 'numberType' &&
203
+ Obj[el] !== undefined &&
204
+ Obj[el].constructor !== Number:
205
+ errorInConsole.push(
206
+ ERR_TYPE.err2.replace(reg, (e) => {
207
+ if (e == '$attr$') return compName || 'Composant'
208
+ if (e == '$el$') return el
209
+ if (e == '$type$') return 'Number'
210
+ })
211
+ )
212
+ errorList.push(
213
+ ERR_TYPE_MSG.err2.replace(reg, (e) => {
214
+ if (e == '$attr$') return compName || 'Composant'
215
+ if (e == '$el$') return el
216
+ if (e == '$type$') return 'Number'
217
+ })
218
+ )
219
+ break
220
+
221
+ case _type == 'objectType' &&
222
+ Obj[el] !== undefined &&
223
+ Obj[el].constructor !== Object:
224
+ errorInConsole.push(
225
+ ERR_TYPE.err2.replace(reg, (e) => {
226
+ if (e == '$attr$') return compName || 'Composant'
227
+ if (e == '$el$') return el
228
+ if (e == '$type$') return 'Object'
229
+ })
230
+ )
231
+ errorList.push(
232
+ ERR_TYPE_MSG.err2.replace(reg, (e) => {
233
+ if (e == '$attr$') return compName || 'Composant'
234
+ if (e == '$el$') return el
235
+ if (e == '$type$') return 'Object'
236
+ })
237
+ )
238
+ break
239
+ }
240
+ }
241
+ }
242
+
243
+ return { errorInConsole, errorList }
244
+ }
245
+
1
246
  /**
2
247
  * @description Validator for the content of menu setting file
3
248
  * @param {String} fName- name of the file for use case
@@ -475,49 +720,6 @@ const validateAudioData = (data) => {
475
720
  }
476
721
  return errorList
477
722
  }
478
- //Get all the invalids properties from the object
479
- /*Add element from target array that are NOT in arr to the wrongArray*/
480
- const checkerWrong = (arr, target) => {
481
- let wrongArray = []
482
- target.every((v) => {
483
- if (arr.includes(v)) {
484
- return true
485
- } else {
486
- wrongArray.push(v)
487
- return true
488
- }
489
- })
490
- return wrongArray
491
- }
492
- //Get all the required properties that are missing from the object
493
- /*Add element from the arr that are NOT in target arr to the missingArray*/
494
- const checkerMissing = (arr, target) => {
495
- let missingArray = []
496
- arr.every((v) => {
497
- if (target.includes(v)) {
498
- return true
499
- } else {
500
- missingArray.push(v)
501
- return true
502
- }
503
- })
504
- return missingArray
505
- }
506
-
507
- const ERR_TYPE = {
508
- err0: `\n 💥 Missing \x1B[1m$attr$ \x1B[0mfor $comp$. \x1B[1m$attr$ \x1B[0m should be provided with following attributes: \x1B[1m{$data$}`,
509
- err1: `\n 💥 Invalid declaration for \x1B[1m$wrd$ \x1B[0m object`,
510
- err2: `\n 💥 Invalid type declaration for 👉\x1B[1m$attr$ \x1B[0m👈 in \x1B[1m$el$\x1B[0m. Expected is \x1B[3m$type$ \x1B[0mtype with some value`,
511
- err3: `\n 💥 Missing required argument 👉\x1B[1m$key$\x1B[0m👈 in \x1B[1m$el$\x1B[0m. Required arguments are: \x1B[1m$args$`,
512
- err4: `\n 💥 Missing required argument 👉\x1B[1m$key$\x1B[0m👈 in \x1B[1m$el$\x1B[0m. Required arguments are: \x1B[1m$args$`
513
- }
514
-
515
- const ERR_TYPE_MSG = {
516
- err0: `\n Données manquantes pour <span style='text-transform: uppercase;'>$comp$</span>. Assurez-vous que le composant reçoit l'attribut <b>$attr$</b> avec des données pour: <b>$data$</b>`,
517
- err1: `\n Déclaration invalide pour <b>$wrd$</b>. Assurez-vous que l'application a du data.`,
518
- err2: `\n Vous avez une declaration invalide dans <b>$attr$</b>. 👉<b>$el$</b>👈 n'accepte que le type <i>$type$</i> et ne peut pas être vide`,
519
- err3: `\n L'attribut 👉<b>$key$</b>👈 est manquant dans <b>$el$</b>. Les attributs requis sont: <b>$args$</b>`
520
- }
521
723
 
522
724
  /**
523
725
  * @description Validator for the content of app data.
@@ -643,196 +845,6 @@ const validateAppContent = (data, silent = false) => {
643
845
  return errorList
644
846
  }
645
847
 
646
- /**
647
- * @description - Method to validate that given object attributes hold expected types
648
- * @param {Object} Obj - object to validate
649
- * @param {Object} Args - List of expected type groups - each type group must be an array of attributes with the same type
650
- * @param {Array} notRequiredArgs - list of field that should be considered as optional in the object. Will not give error if not * provided but will be validated if they are present with wrong type or empty
651
- * @param {Array} compName - Name of the component- will be display in error message
652
- * @param {Array} err - list off errors to be added to
653
- * @return {Object} list of errors - {errorInConsole, errorList} : errorlist can be used to display messages on template and
654
- * errorInConsole to display messages in browser console
655
- * @exemple - Given $user= {name:'toto', username:'totoEscargot', id:'id001', age:23, books:['one', 'two', 'three'] }
656
- * Use validator on $user: validateObjType($user, {stringType:['name', 'username' , 'id'], numbType:['age'], arrayType:['books']})
657
- * Will fail if any listed attribute not in $user or have wrong value. Error messages will be in console
658
- *
659
- */
660
-
661
- const validateObjType = (
662
- Obj,
663
- Args = {
664
- boolType: null,
665
- arrayType: null,
666
- stringType: null,
667
- objectType: null,
668
- numbType: null
669
- },
670
- notRequiredArgs = null,
671
- compName = 'component',
672
- err = null
673
- ) => {
674
- let errorInConsole = err && err.errorInConsole ? err.errorInConsole : []
675
- let errorList = err && err.errorList ? err.errorLIst : []
676
- let optionalArgs =
677
- notRequiredArgs && notRequiredArgs.length ? notRequiredArgs : []
678
- //=====Expected Arguments validation =================//
679
- //Should have an object argument
680
- if (!Obj) throw new Error(`No valid arguments provided`)
681
-
682
- //validate Args Keys type
683
- for (const _type in Args) {
684
- // Should be a required type
685
- if (
686
- ![
687
- 'boolType',
688
- 'arrayType',
689
- 'stringType',
690
- 'objectType',
691
- 'numbType'
692
- ].includes(_type)
693
- )
694
- throw new Error(`Unknown types declaration : ${_type}`)
695
-
696
- if (Args[_type] && Args[_type].length) {
697
- for (let el of Args[_type]) {
698
- //Check that each given element is a string
699
- if (el.constructor !== String)
700
- throw new Error(
701
- `Invalid type detected in ${JSON.stringify(
702
- Args[_type]
703
- )}. Item ${Args[_type].indexOf(el) + 1} should be a String`
704
- )
705
-
706
- let reg = /(\$el\$)|(\$type\$)|(\$attr\$)/g
707
-
708
- let isOptionalArg = optionalArgs.includes(el) ? true : false
709
-
710
- switch (true) {
711
- // Check That each given element exist in data if not optional
712
- case Obj[el] === undefined && !isOptionalArg: {
713
- reg = /(\$key\$)|(\$el\$)|(\$args\$)/g
714
- const reg2 = /\[|\]|/g
715
-
716
- errorInConsole.push(
717
- ERR_TYPE.err3.replace(reg, (e) => {
718
- if (e == '$key$') return el
719
- if (e == '$el$') return compName
720
- if (e == '$args$') return JSON.stringify(Args[_type])
721
- })
722
- )
723
-
724
- errorList.push(
725
- ERR_TYPE_MSG.err3.replace(reg, (e) => {
726
- if (e == '$key$') return el
727
- if (e == '$el$') return compName || 'Composant'
728
- if (e == '$args$')
729
- return JSON.stringify(Args[_type]).replaceAll(reg2, '')
730
- })
731
- )
732
- break
733
- }
734
- //Should have Correct Types $attr$ $el$ $type$
735
- case _type == 'boolType' &&
736
- Obj[el] !== undefined &&
737
- Obj[el].constructor !== Boolean:
738
- errorInConsole.push(
739
- ERR_TYPE.err2.replace(reg, (e) => {
740
- if (e == '$attr$') return compName || 'Composant'
741
- if (e == '$el$') return el
742
- if (e == '$type$') return 'Boolean'
743
- })
744
- )
745
- errorList.push(
746
- ERR_TYPE_MSG.err2.replace(reg, (e) => {
747
- if (e == '$attr$') return compName || 'Composant'
748
- if (e == '$el$') return el
749
- if (e == '$type$') return 'Boolean'
750
- })
751
- )
752
- break
753
-
754
- case _type == 'stringType' &&
755
- Obj[el] !== undefined &&
756
- (Obj[el].constructor !== String || !Obj[el].trim().length):
757
- errorInConsole.push(
758
- ERR_TYPE.err2.replace(reg, (e) => {
759
- if (e == '$attr$') return compName || 'Composant'
760
- if (e == '$el$') return el
761
- if (e == '$type$') return 'String'
762
- })
763
- )
764
- errorList.push(
765
- ERR_TYPE_MSG.err2.replace(reg, (e) => {
766
- if (e == '$attr$') return compName || 'Composant'
767
- if (e == '$el$') return el
768
- if (e == '$type$') return 'String'
769
- })
770
- )
771
- break
772
-
773
- case _type == 'arrayType' &&
774
- Obj[el] !== undefined &&
775
- (Obj[el].constructor !== Array || !Obj[el].length):
776
- errorInConsole.push(
777
- ERR_TYPE.err2.replace(reg, (e) => {
778
- if (e == '$attr$') return compName || 'Composant'
779
- if (e == '$el$') return el
780
- if (e == '$type$') return 'Array'
781
- })
782
- )
783
- errorList.push(
784
- ERR_TYPE_MSG.err2.replace(reg, (e) => {
785
- if (e == '$attr$') return compName || 'Composant'
786
- if (e == '$el$') return el
787
- if (e == '$type$') return 'Array'
788
- })
789
- )
790
- break
791
-
792
- case _type == 'numberType' &&
793
- Obj[el] !== undefined &&
794
- Obj[el].constructor !== Number:
795
- errorInConsole.push(
796
- ERR_TYPE.err2.replace(reg, (e) => {
797
- if (e == '$attr$') return compName || 'Composant'
798
- if (e == '$el$') return el
799
- if (e == '$type$') return 'Number'
800
- })
801
- )
802
- errorList.push(
803
- ERR_TYPE_MSG.err2.replace(reg, (e) => {
804
- if (e == '$attr$') return compName || 'Composant'
805
- if (e == '$el$') return el
806
- if (e == '$type$') return 'Number'
807
- })
808
- )
809
- break
810
-
811
- case _type == 'objectType' &&
812
- Obj[el] !== undefined &&
813
- Obj[el].constructor !== Object:
814
- errorInConsole.push(
815
- ERR_TYPE.err2.replace(reg, (e) => {
816
- if (e == '$attr$') return compName || 'Composant'
817
- if (e == '$el$') return el
818
- if (e == '$type$') return 'Object'
819
- })
820
- )
821
- errorList.push(
822
- ERR_TYPE_MSG.err2.replace(reg, (e) => {
823
- if (e == '$attr$') return compName || 'Composant'
824
- if (e == '$el$') return el
825
- if (e == '$type$') return 'Object'
826
- })
827
- )
828
- break
829
- }
830
- }
831
- }
832
- }
833
-
834
- return { errorInConsole, errorList }
835
- }
836
848
  /**
837
849
  * @description - Method validate the definition of SVG data.
838
850
  * @param {Array || Object } SVGData - the data defining the SVG to render
@@ -918,11 +930,73 @@ const validateSvgDefinition = (SVGData) => {
918
930
  return true
919
931
  }
920
932
 
933
+ /**
934
+ * @description - Method validate the definition data forthe quiz.
935
+ * @param {Object} data - the data defining the SVG to render
936
+ * @return true - if valid
937
+ * */
938
+ const validateQuizData = (data) => {
939
+ let errors
940
+ let stringType = ['ennonce', 'id', 'type_question', 'texte_base']
941
+ let arrayType = ['choix_reponse', 'solution']
942
+ let objectType = ['retroaction']
943
+ let numberType = ['valeur_point', 'max_tentative']
944
+ let optionalArgs = ['valeur_point', 'max_tentative', 'texte_base']
945
+
946
+ errors = validateObjType(
947
+ data,
948
+ { stringType, arrayType, objectType, numberType },
949
+ optionalArgs,
950
+ 'quizData'
951
+ )
952
+
953
+ let hasError = errors.errorInConsole.length || errors.errorList.length
954
+
955
+ if (hasError) return errors
956
+
957
+ //validate Containt for retroaction
958
+
959
+ switch (true) {
960
+ case data.retroaction != null:
961
+ objectType = ['retro_positive', 'retro_negative', 'retro_neutre']
962
+
963
+ errors = validateObjType(
964
+ data.retroaction,
965
+ { objectType },
966
+ null,
967
+ 'quizData retraoction'
968
+ )
969
+ hasError = errors.errorInConsole.length || errors.errorList.length
970
+
971
+ if (hasError) return errors
972
+
973
+ // Validate containt of retroaction attributes
974
+ stringType = ['title', 'hypertext']
975
+
976
+ for (const key of Object.keys(data.retroaction)) {
977
+ errors = validateObjType(
978
+ data.retroaction[key],
979
+ { stringType },
980
+ null,
981
+ key
982
+ )
983
+
984
+ hasError = errors.errorInConsole.length || errors.errorList.length
985
+
986
+ if (hasError) return errors
987
+ }
988
+
989
+ break
990
+ }
991
+ return errors
992
+ }
993
+
921
994
  export {
922
995
  validateObjType,
923
996
  validateVideoData,
924
997
  validateAudioData,
925
998
  validatefileContent,
926
999
  validateAppContent,
927
- validateSvgDefinition
1000
+ validateSvgDefinition,
1001
+ validateQuizData
928
1002
  }