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,344 +1,344 @@
1
- // const allfile = require.context('@/', true, /\.vue$/) //get all .vue file at the root of the project where lib will be installed
2
- const allfile = import.meta.glob(['@/**/*.vue', '!@/**/_*'], {
3
- eager: true
4
- }) //get all .vue file at the root of the project where lib will be installed
5
-
6
- const allfileKeys = Object.keys(allfile)
7
-
8
- //console.log('ALL PATHS', fileArray)
9
- allfileKeys.forEach(function (key, index, array) {
10
- array[index] = {
11
- name: key.replace('/src', '.').replace('.vue', ''),
12
- fullPath: allfile[key].default.__file,
13
- content: allfile[key].default
14
- }
15
- })
16
-
17
- const fileAssets = {
18
- // return the collection of all the files in the project directory
19
- allFiles: () => allfileKeys,
20
-
21
- // Return all the file in './views' with the Name Module
22
- getViews: () => {
23
- return fileAssets
24
- .allFiles()
25
- .filter(
26
- (file) =>
27
- file.name.startsWith('./views') &&
28
- !file.name.split('/')[2].includes('copy')
29
- )
30
- },
31
- // return all files that are in the folder './src/module' of the project with name respecting following condition:
32
- // must start with a capital P followed by a digit (P0, P1, P2...) and not contain keyword "copy"
33
- getActivities: () => {
34
- return fileAssets.allFiles().filter((file) => {
35
- if (
36
- file.name.startsWith('./module/A') &&
37
- /^P[0-9]{2,3}/.test(file.name.split('/')[3]) &&
38
- !file.name.split('/')[3].includes('copy')
39
- )
40
- return true
41
- else return false
42
- })
43
- },
44
-
45
- // search a specific file and return its content
46
- fetchFileContent: (file) => allfile[file].default,
47
-
48
- /**
49
- * @description Validator for the content of menu setting file
50
- * @param {String} fName- name of the file for use case
51
- * @param {Object} fData: file's data to validate
52
- * @param {Object} [requiredArgs] list of arguments to include consider in validation ()
53
- */
54
- validatefileContent: (fName, fData, requiredArgs = {}) => {
55
- let err = null
56
- if (import.meta.env.DEV) {
57
- switch (fName) {
58
- case 'menuSettings': {
59
- const { keys4Activity, keys4Anchors } = requiredArgs
60
-
61
- //*validate that data is an {Object}. if Not send error message
62
- if (fData.constructor !== Object)
63
- err = '💥Invalid file provided for menu settings'
64
-
65
- if (Object.entries(fData).length > 0) {
66
- const content = Object.entries(fData)
67
-
68
- for (let el of content) {
69
- // validate that the content of each entry is an object
70
- if (el[1].constructor !== Object || !Object.keys(el[1]).length) {
71
- err = `💥 invalid data provided for key 👉 ${el[0]} 👈 in ➡ menu.setting.js \n 🚩Must be of type {Object}`
72
- break
73
- }
74
- }
75
- // Validate that each entry has the required key
76
- if (!err) {
77
- for (let el of content) {
78
- const entry = el[1]
79
- for (let k of keys4Activity) {
80
- if (!entry[k]) {
81
- err = `💥 Missing 👉 ${k} 👈 in ${el[0]} in ➡ menu.setting.js \n 🚩Allowed indexes are: 👉 ${keys4Activity}`
82
- break
83
- } else {
84
- //validate that each entry as correct value type
85
- switch (k) {
86
- case 'anchors':
87
- if (entry[k].constructor !== Array)
88
- err = `💥 Invalid anchors declaration for 👉 ${el[0]} 👈 in ➡ menu.setting.j \n 🚩Must be of type {Array}`
89
- else {
90
- const anchors = entry.anchors
91
-
92
- for (let a of anchors) {
93
- //trow error if numbers of keys are not the same as required
94
- const a_numb = anchors.indexOf(a) + 1
95
- if (Object.keys(a).length !== keys4Anchors.length) {
96
- err = `💥 Invalid declaration in 👉anchor ${a_numb}👈 for ➡ ${el[0]} in ➡ menu.setting.js \n 🚩 Allowed indexes are: 👉 ${keys4Anchors}`
97
- break
98
- }
99
- // Validated that required keys condition and type is met
100
- for (let k of keys4Anchors) {
101
- if (!a[k]) {
102
- err = `💥 Missing 👉 ${k} 👈 for anchor ${a_numb} ➡ ${el[0]} ➡ menu.setting.js \n 🚩 Allowed indexes are: 👉 ${keys4Anchors}`
103
- } else if (a[k].constructor !== String) {
104
- err = `💥 Invalid 👉 ${k} 👈 declaration for anchor ${a_numb} ➡ ${el[0]} ➡ menu.setting.js \n 🚩 Must be of type {String}`
105
- }
106
- if (err) break
107
- }
108
- if (err) break
109
- }
110
- }
111
-
112
- break
113
- default:
114
- if (entry[k].constructor !== String)
115
- err = `Invalid 👉 ${k} 👈 declaration for ➡ ${el[0]} in ➡ menu.setting.js \n 🚩 Must be of type {String}`
116
- break
117
- }
118
- }
119
- }
120
-
121
- if (err) break
122
- }
123
- }
124
- }
125
- break
126
- }
127
- }
128
- }
129
- return err
130
- },
131
-
132
- /**
133
- * @description Validator for the content of menu setting file
134
- * @param {String} a- array of file for use case
135
- * @param {Object} [requiredArgs] list of arguments to include consider in validation ()
136
- */
137
- buildMapTree: (a) => {
138
- // Load files in module folder
139
-
140
- if (a.length < 0) return
141
-
142
- const mapTree = new Map()
143
- // There is a file in the module folder
144
-
145
- a.forEach((e) => {
146
- const fileRef = e.name.replace(/(\.\/)/g, '')
147
- const splitted = fileRef.split('/')
148
- const activityName = splitted[1]
149
- const fileName = splitted[splitted.length - 1].replace(/(\.vue)/g, '')
150
- const fileContent = e.content
151
- if (!Object.keys(fileContent).includes('data')) return
152
- // Handling single page type
153
- // adding the page in a map for the Pages
154
-
155
- // Add the key in the map for the routes if it is not in the map, with its data as new Map;
156
- if (!mapTree.get(activityName)) {
157
- mapTree.set(activityName, new Map())
158
- }
159
-
160
- if (fileName.length === 3) {
161
- mapTree.get(activityName).set(fileName, {
162
- ref: fileRef,
163
- content: fileContent.data(),
164
- fullPath: e.fullPath
165
- }) // add entry for the page
166
- }
167
- // Handleling Groupe page type
168
- else if (fileName.length > 3 && fileName.includes('_')) {
169
- const keyToFind = fileName.split('_', 1)[0] // Pxx
170
- const KeyToAdd = fileName.split('_')[1] // Exx
171
-
172
- // // search for the page key in the map
173
- if (!mapTree.get(activityName).has(keyToFind)) return
174
-
175
- // save a reference for the value of the key
176
- const tempSave = mapTree.get(activityName).get(keyToFind)
177
-
178
- // transform value of found key to a new map
179
- if (!mapTree.get(activityName).get(keyToFind).size) {
180
- mapTree.get(activityName).set(keyToFind, new Map())
181
- // Update reference of key's
182
- mapTree.get(activityName).get(keyToFind).set(keyToFind, tempSave)
183
- }
184
-
185
- // Add page EXX in Map if it is not already added
186
- if (!mapTree.get(activityName).get(keyToFind).get(KeyToAdd))
187
- mapTree.get(activityName).get(keyToFind).set(fileName, {
188
- ref: fileRef,
189
- content: fileContent.data(),
190
- fullPath: e.fullPath
191
- })
192
- }
193
- })
194
-
195
- return mapTree
196
- },
197
-
198
- /**
199
- * @description Capitalize word in string
200
- * @param {String} a- array of file for use case
201
- * @param {Object} [requiredArgs] list of arguments to include consider in validation ()
202
- */
203
- capitalize: (string) => {
204
- let formatted = string.replaceAll('_', ' ').toLowerCase()
205
- formatted = `${formatted.substring(0, 1).toUpperCase()}${formatted.slice(1).toLowerCase()}`
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
341
- }
342
- }
343
-
344
- export { fileAssets }
1
+ // const allfile = require.context('@/', true, /\.vue$/) //get all .vue file at the root of the project where lib will be installed
2
+ const allfile = import.meta.glob(['@/**/*.vue', '!@/**/_*'], {
3
+ eager: true
4
+ }) //get all .vue file at the root of the project where lib will be installed
5
+
6
+ const allfileKeys = Object.keys(allfile)
7
+
8
+ //console.log('ALL PATHS', fileArray)
9
+ allfileKeys.forEach(function (key, index, array) {
10
+ array[index] = {
11
+ name: key.replace('/src', '.').replace('.vue', ''),
12
+ fullPath: allfile[key].default.__file,
13
+ content: allfile[key].default
14
+ }
15
+ })
16
+
17
+ const fileAssets = {
18
+ // return the collection of all the files in the project directory
19
+ allFiles: () => allfileKeys,
20
+
21
+ // Return all the file in './views' with the Name Module
22
+ getViews: () => {
23
+ return fileAssets
24
+ .allFiles()
25
+ .filter(
26
+ (file) =>
27
+ file.name.startsWith('./views') &&
28
+ !file.name.split('/')[2].includes('copy')
29
+ )
30
+ },
31
+ // return all files that are in the folder './src/module' of the project with name respecting following condition:
32
+ // must start with a capital P followed by a digit (P0, P1, P2...) and not contain keyword "copy"
33
+ getActivities: () => {
34
+ return fileAssets.allFiles().filter((file) => {
35
+ if (
36
+ file.name.startsWith('./module/A') &&
37
+ /^P[0-9]{2,3}/.test(file.name.split('/')[3]) &&
38
+ !file.name.split('/')[3].includes('copy')
39
+ )
40
+ return true
41
+ else return false
42
+ })
43
+ },
44
+
45
+ // search a specific file and return its content
46
+ fetchFileContent: (file) => allfile[file].default,
47
+
48
+ /**
49
+ * @description Validator for the content of menu setting file
50
+ * @param {String} fName- name of the file for use case
51
+ * @param {Object} fData: file's data to validate
52
+ * @param {Object} [requiredArgs] list of arguments to include consider in validation ()
53
+ */
54
+ validatefileContent: (fName, fData, requiredArgs = {}) => {
55
+ let err = null
56
+ if (import.meta.env.DEV) {
57
+ switch (fName) {
58
+ case 'menuSettings': {
59
+ const { keys4Activity, keys4Anchors } = requiredArgs
60
+
61
+ //*validate that data is an {Object}. if Not send error message
62
+ if (fData.constructor !== Object)
63
+ err = '💥Invalid file provided for menu settings'
64
+
65
+ if (Object.entries(fData).length > 0) {
66
+ const content = Object.entries(fData)
67
+
68
+ for (let el of content) {
69
+ // validate that the content of each entry is an object
70
+ if (el[1].constructor !== Object || !Object.keys(el[1]).length) {
71
+ err = `💥 invalid data provided for key 👉 ${el[0]} 👈 in ➡ menu.setting.js \n 🚩Must be of type {Object}`
72
+ break
73
+ }
74
+ }
75
+ // Validate that each entry has the required key
76
+ if (!err) {
77
+ for (let el of content) {
78
+ const entry = el[1]
79
+ for (let k of keys4Activity) {
80
+ if (!entry[k]) {
81
+ err = `💥 Missing 👉 ${k} 👈 in ${el[0]} in ➡ menu.setting.js \n 🚩Allowed indexes are: 👉 ${keys4Activity}`
82
+ break
83
+ } else {
84
+ //validate that each entry as correct value type
85
+ switch (k) {
86
+ case 'anchors':
87
+ if (entry[k].constructor !== Array)
88
+ err = `💥 Invalid anchors declaration for 👉 ${el[0]} 👈 in ➡ menu.setting.j \n 🚩Must be of type {Array}`
89
+ else {
90
+ const anchors = entry.anchors
91
+
92
+ for (let a of anchors) {
93
+ //trow error if numbers of keys are not the same as required
94
+ const a_numb = anchors.indexOf(a) + 1
95
+ if (Object.keys(a).length !== keys4Anchors.length) {
96
+ err = `💥 Invalid declaration in 👉anchor ${a_numb}👈 for ➡ ${el[0]} in ➡ menu.setting.js \n 🚩 Allowed indexes are: 👉 ${keys4Anchors}`
97
+ break
98
+ }
99
+ // Validated that required keys condition and type is met
100
+ for (let k of keys4Anchors) {
101
+ if (!a[k]) {
102
+ err = `💥 Missing 👉 ${k} 👈 for anchor ${a_numb} ➡ ${el[0]} ➡ menu.setting.js \n 🚩 Allowed indexes are: 👉 ${keys4Anchors}`
103
+ } else if (a[k].constructor !== String) {
104
+ err = `💥 Invalid 👉 ${k} 👈 declaration for anchor ${a_numb} ➡ ${el[0]} ➡ menu.setting.js \n 🚩 Must be of type {String}`
105
+ }
106
+ if (err) break
107
+ }
108
+ if (err) break
109
+ }
110
+ }
111
+
112
+ break
113
+ default:
114
+ if (entry[k].constructor !== String)
115
+ err = `Invalid 👉 ${k} 👈 declaration for ➡ ${el[0]} in ➡ menu.setting.js \n 🚩 Must be of type {String}`
116
+ break
117
+ }
118
+ }
119
+ }
120
+
121
+ if (err) break
122
+ }
123
+ }
124
+ }
125
+ break
126
+ }
127
+ }
128
+ }
129
+ return err
130
+ },
131
+
132
+ /**
133
+ * @description Validator for the content of menu setting file
134
+ * @param {String} a- array of file for use case
135
+ * @param {Object} [requiredArgs] list of arguments to include consider in validation ()
136
+ */
137
+ buildMapTree: (a) => {
138
+ // Load files in module folder
139
+
140
+ if (a.length < 0) return
141
+
142
+ const mapTree = new Map()
143
+ // There is a file in the module folder
144
+
145
+ a.forEach((e) => {
146
+ const fileRef = e.name.replace(/(\.\/)/g, '')
147
+ const splitted = fileRef.split('/')
148
+ const activityName = splitted[1]
149
+ const fileName = splitted[splitted.length - 1].replace(/(\.vue)/g, '')
150
+ const fileContent = e.content
151
+ if (!Object.keys(fileContent).includes('data')) return
152
+ // Handling single page type
153
+ // adding the page in a map for the Pages
154
+
155
+ // Add the key in the map for the routes if it is not in the map, with its data as new Map;
156
+ if (!mapTree.get(activityName)) {
157
+ mapTree.set(activityName, new Map())
158
+ }
159
+
160
+ if (fileName.length === 3) {
161
+ mapTree.get(activityName).set(fileName, {
162
+ ref: fileRef,
163
+ content: fileContent.data(),
164
+ fullPath: e.fullPath
165
+ }) // add entry for the page
166
+ }
167
+ // Handleling Groupe page type
168
+ else if (fileName.length > 3 && fileName.includes('_')) {
169
+ const keyToFind = fileName.split('_', 1)[0] // Pxx
170
+ const KeyToAdd = fileName.split('_')[1] // Exx
171
+
172
+ // // search for the page key in the map
173
+ if (!mapTree.get(activityName).has(keyToFind)) return
174
+
175
+ // save a reference for the value of the key
176
+ const tempSave = mapTree.get(activityName).get(keyToFind)
177
+
178
+ // transform value of found key to a new map
179
+ if (!mapTree.get(activityName).get(keyToFind).size) {
180
+ mapTree.get(activityName).set(keyToFind, new Map())
181
+ // Update reference of key's
182
+ mapTree.get(activityName).get(keyToFind).set(keyToFind, tempSave)
183
+ }
184
+
185
+ // Add page EXX in Map if it is not already added
186
+ if (!mapTree.get(activityName).get(keyToFind).get(KeyToAdd))
187
+ mapTree.get(activityName).get(keyToFind).set(fileName, {
188
+ ref: fileRef,
189
+ content: fileContent.data(),
190
+ fullPath: e.fullPath
191
+ })
192
+ }
193
+ })
194
+
195
+ return mapTree
196
+ },
197
+
198
+ /**
199
+ * @description Capitalize word in string
200
+ * @param {String} a- array of file for use case
201
+ * @param {Object} [requiredArgs] list of arguments to include consider in validation ()
202
+ */
203
+ capitalize: (string) => {
204
+ let formatted = string.replaceAll('_', ' ').toLowerCase()
205
+ formatted = `${formatted.substring(0, 1).toUpperCase()}${formatted.slice(1).toLowerCase()}`
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
341
+ }
342
+ }
343
+
344
+ export { fileAssets }