fcad-core-dragon 2.1.0 → 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.
- package/.editorconfig +7 -7
- package/.gitlab-ci.yml +124 -0
- package/.prettierrc +11 -11
- package/.vscode/extensions.json +8 -8
- package/.vscode/settings.json +46 -16
- package/CHANGELOG +520 -520
- package/README.md +57 -57
- package/documentation/.vitepress/config.js +114 -114
- package/documentation/api-examples.md +49 -49
- package/documentation/composants/app-base-button.md +58 -58
- package/documentation/composants/app-base-error-display.md +59 -59
- package/documentation/composants/app-base-popover.md +68 -68
- package/documentation/composants/app-comp-audio.md +75 -75
- package/documentation/composants/app-comp-branch-buttons.md +111 -111
- package/documentation/composants/app-comp-button-progress.md +53 -53
- package/documentation/composants/app-comp-carousel.md +53 -53
- package/documentation/composants/app-comp-container.md +53 -53
- package/documentation/composants/app-comp-input-checkbox-next.md +42 -42
- package/documentation/composants/app-comp-input-dropdown-next.md +34 -34
- package/documentation/composants/app-comp-input-radio-next.md +39 -39
- package/documentation/composants/app-comp-input-text-next.md +35 -35
- package/documentation/composants/app-comp-input-text-table-next.md +34 -34
- package/documentation/composants/app-comp-input-text-to-fill-dropdown-next.md +53 -53
- package/documentation/composants/app-comp-input-text-to-fill-next.md +31 -31
- package/documentation/composants/app-comp-jauge.md +31 -31
- package/documentation/composants/app-comp-menu-item.md +55 -55
- package/documentation/composants/app-comp-menu.md +29 -29
- package/documentation/composants/app-comp-navigation.md +41 -41
- package/documentation/composants/app-comp-note-call.md +53 -53
- package/documentation/composants/app-comp-note-credit.md +53 -53
- package/documentation/composants/app-comp-play-bar-next.md +53 -53
- package/documentation/composants/app-comp-pop-up-next.md +93 -93
- package/documentation/composants/app-comp-quiz-next.md +235 -235
- package/documentation/composants/app-comp-quiz-recall.md +53 -53
- package/documentation/composants/app-comp-svg-next.md +53 -53
- package/documentation/composants/app-comp-table-of-content.md +50 -50
- package/documentation/composants/app-comp-video-player.md +82 -82
- package/documentation/composants.md +46 -46
- package/documentation/composants_critiques/ModelPageComposant.md +53 -53
- package/documentation/composants_critiques/app-base-module.md +43 -43
- package/documentation/composants_critiques/app-base-page.md +48 -48
- package/documentation/composants_critiques/app-base.md +311 -311
- package/documentation/composants_critiques/main.md +15 -15
- package/documentation/demarrage.md +50 -50
- package/documentation/deploiement.md +57 -57
- package/documentation/index.md +33 -33
- package/documentation/markdown-examples.md +85 -85
- package/documentation/public/vite.svg +14 -14
- package/documentation/public/vuejs.svg +1 -1
- package/documentation/public/vuetify.svg +5 -5
- package/eslint.config.js +60 -60
- package/junit-report.xml +182 -0
- package/package.json +66 -59
- package/playwright/index.html +12 -0
- package/playwright/index.js +21 -0
- package/playwright-ct.config.js +95 -0
- package/src/$locales/en.json +157 -157
- package/src/$locales/fr.json +120 -120
- package/src/assets/data/onboardingMessages.json +47 -47
- package/src/components/AppBase.vue +1171 -1169
- package/src/components/AppBaseButton.vue +90 -95
- package/src/components/AppBaseErrorDisplay.vue +438 -438
- package/src/components/AppBaseFlipCard.vue +84 -84
- package/src/components/AppBaseModule.vue +1639 -1634
- package/src/components/AppBasePage.vue +3 -2
- package/src/components/AppBasePopover.vue +41 -41
- package/src/components/AppBaseSkeleton.vue +66 -66
- package/src/components/AppCompAudio.vue +261 -256
- package/src/components/AppCompBranchButtons.vue +508 -508
- package/src/components/AppCompButtonProgress.vue +137 -132
- package/src/components/AppCompCarousel.vue +342 -336
- package/src/components/AppCompContainer.vue +29 -29
- package/src/components/AppCompInputCheckBoxNx.vue +325 -323
- package/src/components/AppCompInputDropdownNx.vue +302 -299
- package/src/components/AppCompInputRadioNx.vue +287 -284
- package/src/components/AppCompInputTextNx.vue +156 -153
- package/src/components/AppCompInputTextTableNx.vue +205 -202
- package/src/components/AppCompInputTextToFillDropdownNx.vue +343 -340
- package/src/components/AppCompInputTextToFillNx.vue +316 -313
- package/src/components/AppCompJauge.vue +81 -81
- package/src/components/AppCompMenu.vue +6 -2
- package/src/components/AppCompMenuItem.vue +246 -240
- package/src/components/AppCompNavigation.vue +977 -972
- package/src/components/AppCompNoteCall.vue +167 -161
- package/src/components/AppCompNoteCredit.vue +496 -491
- package/src/components/AppCompPlayBarNext.vue +2290 -2288
- package/src/components/AppCompPopUpNext.vue +508 -504
- package/src/components/AppCompQuizNext.vue +515 -510
- package/src/components/AppCompQuizRecall.vue +355 -350
- package/src/components/AppCompSVGNext.vue +346 -346
- package/src/components/AppCompSettingsMenu.vue +177 -172
- package/src/components/AppCompTableOfContent.vue +433 -427
- package/src/components/AppCompVideoPlayer.vue +377 -377
- package/src/components/AppCompViewDisplay.vue +6 -6
- package/src/components/BaseModule.vue +55 -55
- package/src/composables/useIdleDetector.js +56 -56
- package/src/composables/useQuiz.js +89 -89
- package/src/composables/useTimer.js +172 -172
- package/src/directives/nvdaFix.js +53 -53
- package/src/externalComps/ModuleView.vue +22 -22
- package/src/externalComps/SummaryView.vue +91 -91
- package/src/main.js +493 -476
- package/src/module/stores/appStore.js +960 -947
- package/src/module/xapi/ADL.js +520 -520
- package/src/module/xapi/Crypto/Hasher.js +241 -241
- package/src/module/xapi/Crypto/WordArray.js +278 -278
- package/src/module/xapi/Crypto/algorithms/BufferedBlockAlgorithm.js +103 -103
- package/src/module/xapi/Crypto/algorithms/C_algo.js +315 -315
- package/src/module/xapi/Crypto/algorithms/HMAC.js +9 -9
- package/src/module/xapi/Crypto/algorithms/SHA1.js +9 -9
- package/src/module/xapi/Crypto/encoders/Base.js +105 -105
- package/src/module/xapi/Crypto/encoders/Base64.js +99 -99
- package/src/module/xapi/Crypto/encoders/Hex.js +61 -61
- package/src/module/xapi/Crypto/encoders/Latin1.js +61 -61
- package/src/module/xapi/Crypto/encoders/Utf8.js +45 -45
- package/src/module/xapi/Crypto/index.js +53 -53
- package/src/module/xapi/Statement/activity.js +47 -47
- package/src/module/xapi/Statement/agent.js +55 -55
- package/src/module/xapi/Statement/group.js +26 -26
- package/src/module/xapi/Statement/index.js +259 -259
- package/src/module/xapi/Statement/statement.js +253 -253
- package/src/module/xapi/Statement/statementRef.js +23 -23
- package/src/module/xapi/Statement/substatement.js +22 -22
- package/src/module/xapi/Statement/verb.js +36 -36
- package/src/module/xapi/activitytypes.js +17 -17
- package/src/module/xapi/launch.js +157 -157
- package/src/module/xapi/utils.js +167 -167
- package/src/module/xapi/verbs.js +294 -294
- package/src/module/xapi/wrapper.js +1895 -1895
- package/src/module/xapi/xapiStatement.js +444 -444
- package/src/plugins/analytics.js +34 -34
- package/src/plugins/bus.js +12 -8
- package/src/plugins/gsap.js +17 -15
- package/src/plugins/helper.js +355 -358
- package/src/plugins/i18n.js +27 -26
- package/src/plugins/idb.js +227 -227
- package/src/plugins/save.js +37 -37
- package/src/plugins/scorm.js +287 -287
- package/src/plugins/xapi.js +11 -11
- package/src/public/index.html +33 -33
- package/src/router/index.js +57 -57
- package/src/router/routes.js +312 -312
- package/src/shared/generalfuncs.js +344 -344
- package/src/shared/validators.js +1018 -1018
- package/tests/component/AppBaseButton.spec.js +53 -0
- package/tests/component/pinia.spec.js +24 -0
- package/{src/components/tests__ → tests/unit}/AppBaseButton.spec.js +53 -53
- package/tests/unit/AppCompInputCheckBoxNx.spec.js +59 -0
- package/tests/unit/AppCompInputDropdownNx.spec.js +51 -0
- package/tests/unit/AppCompInputRadioNx.spec.js +59 -0
- package/tests/unit/AppCompInputTextNx.spec.js +44 -0
- package/tests/unit/AppCompInputTextTableNx.spec.js +77 -0
- package/tests/unit/AppCompInputTextToFillDropdownNx.spec.js +60 -0
- package/tests/unit/AppCompInputTextToFillNx.spec.js +45 -0
- package/tests/unit/AppCompQuizNext.spec.js +114 -0
- package/tests/unit/AppCompVideoPlayer.spec.js +177 -0
- package/{src/components/tests__ → tests/unit}/useTimer.spec.js +91 -91
- package/vitest.config.js +28 -19
- package/vitest.setup.js +28 -0
- package/src/components/AppBaseButton.test.js +0 -21
package/src/plugins/helper.js
CHANGED
|
@@ -1,358 +1,355 @@
|
|
|
1
|
-
import routes from '../router/routes'
|
|
2
|
-
import { useAppStore } from '../module/stores/appStore'
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
import
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
/***
|
|
14
|
-
* @description: helper to get the collection of routes of activies from vue-Router.
|
|
15
|
-
* @note If need more info from the router , use directly the vue-router
|
|
16
|
-
* @param {String} ID [optional] - ID of an activity (ex: A01).
|
|
17
|
-
* @return {Array} - return all routes for an activity Or all the routes of the module
|
|
18
|
-
*
|
|
19
|
-
*/
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
return `${fcadVersion}`
|
|
60
|
-
},
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* @description: helper to get App setting information from the store.
|
|
64
|
-
* @param {String} sName - a key of specific value from the settings
|
|
65
|
-
* ex: 'specification' to return the specification of the app: xapi |scorm
|
|
66
|
-
* @return {Object|null} -
|
|
67
|
-
*/
|
|
68
|
-
getSettingsFromStore(sName = null) {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
*
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
* @
|
|
91
|
-
* @
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
* @
|
|
170
|
-
* @
|
|
171
|
-
*
|
|
172
|
-
*
|
|
173
|
-
*
|
|
174
|
-
*
|
|
175
|
-
*
|
|
176
|
-
* - case
|
|
177
|
-
*
|
|
178
|
-
*
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
alink.
|
|
194
|
-
|
|
195
|
-
alink.
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
* @
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
const
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
//
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
* @
|
|
261
|
-
*
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
courseId
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
courseLocation
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
linkedResource
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
let
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
* @
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
}
|
|
357
|
-
})
|
|
358
|
-
}
|
|
1
|
+
import routes from '../router/routes'
|
|
2
|
+
import { useAppStore } from '../module/stores/appStore'
|
|
3
|
+
|
|
4
|
+
import axios from 'axios'
|
|
5
|
+
|
|
6
|
+
import locale_en from '../$locales/en.json'
|
|
7
|
+
import locale_fr from '../$locales/fr.json'
|
|
8
|
+
|
|
9
|
+
export default {
|
|
10
|
+
install: (app) => {
|
|
11
|
+
const store = useAppStore()
|
|
12
|
+
app.config.globalProperties.$helper = {
|
|
13
|
+
/***
|
|
14
|
+
* @description: helper to get the collection of routes of activies from vue-Router.
|
|
15
|
+
* @note If need more info from the router , use directly the vue-router
|
|
16
|
+
* @param {String} ID [optional] - ID of an activity (ex: A01).
|
|
17
|
+
* @return {Array} - return all routes for an activity Or all the routes of the module
|
|
18
|
+
*
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
getRoutesFromVueRouter: (ID) => {
|
|
22
|
+
let { children: all_routes, meta } = routes[1].children[0]
|
|
23
|
+
|
|
24
|
+
if (ID) {
|
|
25
|
+
let f = all_routes.find((route) => route.meta.id === ID)
|
|
26
|
+
if (f) {
|
|
27
|
+
all_routes = f.children
|
|
28
|
+
meta = f.meta
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return { all_routes, meta }
|
|
32
|
+
},
|
|
33
|
+
/** @description: helper to get the build timestamp. Useful for QA
|
|
34
|
+
*
|
|
35
|
+
*/
|
|
36
|
+
getBuildTime() {
|
|
37
|
+
return document.documentElement.dataset.buildTime
|
|
38
|
+
},
|
|
39
|
+
/** @description: helper to get the template version used by projgen to create this project. Useful for QA
|
|
40
|
+
*
|
|
41
|
+
*/
|
|
42
|
+
getTemplateVersion() {
|
|
43
|
+
return document.documentElement.dataset.templateVersion
|
|
44
|
+
},
|
|
45
|
+
/**
|
|
46
|
+
* @description: helper to get the FCAD version full string. Useful for QA
|
|
47
|
+
*
|
|
48
|
+
*/
|
|
49
|
+
getFcadVersionString() {
|
|
50
|
+
const fcadVersion = store.getAppPackageInfo('packageVersion')
|
|
51
|
+
const fcadName = store.getAppPackageInfo('packageName')
|
|
52
|
+
return `[${fcadName} ${fcadVersion}] [fcad-template v${this.getTemplateVersion()}] [build ${this.getBuildTime()}]`
|
|
53
|
+
},
|
|
54
|
+
/** @description: helper to get the FCAD version number. Useful for QA
|
|
55
|
+
*
|
|
56
|
+
*/
|
|
57
|
+
getFcadVersion() {
|
|
58
|
+
const fcadVersion = store.getAppPackageInfo('packageVersion')
|
|
59
|
+
return `${fcadVersion}`
|
|
60
|
+
},
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* @description: helper to get App setting information from the store.
|
|
64
|
+
* @param {String} sName - a key of specific value from the settings
|
|
65
|
+
* ex: 'specification' to return the specification of the app: xapi |scorm
|
|
66
|
+
* @return {Object|null} -
|
|
67
|
+
*/
|
|
68
|
+
getSettingsFromStore(sName = null) {
|
|
69
|
+
if (
|
|
70
|
+
!store.$state.appConfigs ||
|
|
71
|
+
store.$state.appConfigs[sName] == undefined
|
|
72
|
+
)
|
|
73
|
+
return null
|
|
74
|
+
|
|
75
|
+
if (sName) return store.$state.appConfigs[sName]
|
|
76
|
+
else return store.$state.appConfigs
|
|
77
|
+
},
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* @description: helper to get the menu information from the store.
|
|
81
|
+
*
|
|
82
|
+
*/
|
|
83
|
+
getMenuInfoFromStore() {
|
|
84
|
+
if (store.$state.menuSetting) return store.$state.menuSetting
|
|
85
|
+
else return null
|
|
86
|
+
},
|
|
87
|
+
/***
|
|
88
|
+
* @description Method to return a myme time of a document
|
|
89
|
+
* @param {String} aType extension of the document exemple: doc , pdf ect...
|
|
90
|
+
* @return {String} mime
|
|
91
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/MIME_types/Common_types
|
|
92
|
+
*/
|
|
93
|
+
mimeTypeFor(aType) {
|
|
94
|
+
let mimeType = false
|
|
95
|
+
|
|
96
|
+
switch (true) {
|
|
97
|
+
case aType.endsWith('.doc'):
|
|
98
|
+
// Microsoft Word
|
|
99
|
+
mimeType = 'application/msword'
|
|
100
|
+
break
|
|
101
|
+
|
|
102
|
+
case aType.endsWith('.docx'):
|
|
103
|
+
// Microsoft Word (OpenXML)
|
|
104
|
+
mimeType =
|
|
105
|
+
'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
|
|
106
|
+
break
|
|
107
|
+
|
|
108
|
+
case aType.endsWith('.pdf'):
|
|
109
|
+
//Adobe Portable Document Format (PDF)
|
|
110
|
+
mimeType = 'application/pdf'
|
|
111
|
+
break
|
|
112
|
+
case aType.endsWith('.odt'):
|
|
113
|
+
// OpenDocument text document
|
|
114
|
+
mimeType = 'application/vnd.oasis.opendocument.text'
|
|
115
|
+
break
|
|
116
|
+
|
|
117
|
+
case aType.endsWith('.txt'):
|
|
118
|
+
// Text, (generally ASCII or ISO 8859-n)
|
|
119
|
+
mimeType = 'text/plain'
|
|
120
|
+
break
|
|
121
|
+
|
|
122
|
+
case aType.endsWith('.jpeg') || aType.endsWith('.jpg'):
|
|
123
|
+
// JPEG images
|
|
124
|
+
mimeType = 'image/jpeg'
|
|
125
|
+
break
|
|
126
|
+
|
|
127
|
+
case aType.endsWith('.png'):
|
|
128
|
+
// Portable Network Graphics
|
|
129
|
+
mimeType = 'image/png'
|
|
130
|
+
break
|
|
131
|
+
case aType.endsWith('.csv'):
|
|
132
|
+
// Comma-separated values (CSV)
|
|
133
|
+
mimeType = 'text/csv'
|
|
134
|
+
break
|
|
135
|
+
|
|
136
|
+
case aType.endsWith('.xls'):
|
|
137
|
+
// Microsoft Excel
|
|
138
|
+
mimeType = 'application/vnd.ms-excel'
|
|
139
|
+
break
|
|
140
|
+
case aType.endsWith('.xlsx'):
|
|
141
|
+
// Microsoft Excel (OpenXML)
|
|
142
|
+
mimeType =
|
|
143
|
+
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
|
|
144
|
+
break
|
|
145
|
+
case aType.endsWith('.ppt'):
|
|
146
|
+
//Microsoft PowerPoint
|
|
147
|
+
mimeType = 'application/vnd.ms-powerpoint'
|
|
148
|
+
break
|
|
149
|
+
case aType.endsWith('.pptx'):
|
|
150
|
+
//Microsoft PowerPoint (OpenXML)
|
|
151
|
+
mimeType =
|
|
152
|
+
'tapplication/vnd.openxmlformats-officedocument.presentationml.presentation'
|
|
153
|
+
break
|
|
154
|
+
case aType.endsWith('.htm') || aType.endsWith('.html'):
|
|
155
|
+
// HyperText Markup Language (HTML)
|
|
156
|
+
mimeType = 'text/html'
|
|
157
|
+
break
|
|
158
|
+
case aType.endsWith('.ggb') || aType.endsWith('.ggb'):
|
|
159
|
+
// HyperText Markup Language (HTML)
|
|
160
|
+
mimeType = 'text/xml'
|
|
161
|
+
break
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return mimeType
|
|
165
|
+
},
|
|
166
|
+
/***
|
|
167
|
+
* @description method to download a file.
|
|
168
|
+
* @param {String} filePath url of the file to download
|
|
169
|
+
* @param {String} outputName 'the default name for the download file'
|
|
170
|
+
* @summary Use axios to simulate a file request from server.
|
|
171
|
+
* Create <a> tag with downloadable link and download the element to user PC.
|
|
172
|
+
* Remove a element after download
|
|
173
|
+
* @usage:
|
|
174
|
+
* - case 1: the file is in the public folder of your project. Use full path ex: downloadFile('./public/
|
|
175
|
+
* myfile')
|
|
176
|
+
* - case 2: file is in another folder in a src of your project. Use relative path. import the file and provide it to the * downloader fonction ex: downloadFile(require('@/accets/another_folder
|
|
177
|
+
* )
|
|
178
|
+
*
|
|
179
|
+
*/
|
|
180
|
+
async downloadFile(filepath, outputName) {
|
|
181
|
+
try {
|
|
182
|
+
if (filepath && filepath.constructor === String) {
|
|
183
|
+
const res = await axios.get(filepath, { responseType: 'blob' }) // use http request
|
|
184
|
+
const blob = new Blob([res.data], {
|
|
185
|
+
// type: res.data.type
|
|
186
|
+
type: this.mimeTypeFor(filepath)
|
|
187
|
+
}) // create a blob element
|
|
188
|
+
|
|
189
|
+
const alink = document.createElement('a') //create a element
|
|
190
|
+
|
|
191
|
+
alink.href = URL.createObjectURL(blob) //create url reference for the object
|
|
192
|
+
alink.download = outputName || `myFile` // set download name
|
|
193
|
+
alink.click() //symulate click event to download the object
|
|
194
|
+
|
|
195
|
+
URL.revokeObjectURL(alink.href) //release the url referrence of the object
|
|
196
|
+
} else throw new Error('No URL provided for download')
|
|
197
|
+
} catch (err) {
|
|
198
|
+
// plugin has access to $bus through the Vue.proptotype
|
|
199
|
+
const msg = this.getKeyFromLocal('message.err_download_file')
|
|
200
|
+
|
|
201
|
+
app.config.globalProperties.$bus.$emit('open-popup', {
|
|
202
|
+
type: 'popup-info',
|
|
203
|
+
value: { text_1: `⚠️ ${msg}` }
|
|
204
|
+
})
|
|
205
|
+
console.error('DOWNLOAD ERROR: 💥', err)
|
|
206
|
+
}
|
|
207
|
+
},
|
|
208
|
+
/***
|
|
209
|
+
* @description - helper methode to retrive a word from a local file.
|
|
210
|
+
* @param {String} key - key of the word to retrive ex: 'a.b.c'
|
|
211
|
+
* @return {String } - return the value of the key ex: 'hello world' if exist or the key ('a.b.c')
|
|
212
|
+
*/
|
|
213
|
+
getKeyFromLocal(key) {
|
|
214
|
+
if (!key) throw new Error('Missing Key for search')
|
|
215
|
+
const lang = store.$state.appConfigs.lang // get lang from the store
|
|
216
|
+
const dic = { en: locale_en, fr: locale_fr } //contents of the json locales
|
|
217
|
+
const keys = key.split('.')
|
|
218
|
+
|
|
219
|
+
let value
|
|
220
|
+
for (let i = 0; i < keys.length; i++) {
|
|
221
|
+
let n = keys[i]
|
|
222
|
+
if (i === 0 && dic[lang][n]) value = dic[lang][n]
|
|
223
|
+
else if (value[n]) value = value[n]
|
|
224
|
+
else return (value = key)
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
return value
|
|
228
|
+
},
|
|
229
|
+
|
|
230
|
+
/***
|
|
231
|
+
* @description: Insert line break opportunities into a URL
|
|
232
|
+
* @param {String} url - original url string to formate
|
|
233
|
+
* @credit - https://css-tricks.com/better-line-breaks-for-long-urls/
|
|
234
|
+
*/
|
|
235
|
+
breakUrlString(url) {
|
|
236
|
+
// Split the URL into an array to distinguish double slashes from single slashes
|
|
237
|
+
const doubleSlash = url.split('//')
|
|
238
|
+
|
|
239
|
+
// Format the strings on either side of double slashes separately
|
|
240
|
+
let formatted = doubleSlash
|
|
241
|
+
.map(
|
|
242
|
+
(str) =>
|
|
243
|
+
// Insert a word break opportunity after a colon
|
|
244
|
+
str
|
|
245
|
+
.replace(/(?<after>:)/giu, '$1<wbr>')
|
|
246
|
+
// Before a single slash, tilde, period, comma, hyphen, underline, question mark, number sign, or percent symbol
|
|
247
|
+
.replace(/(?<before>[/~.,\-_?#%])/giu, '<wbr>$1')
|
|
248
|
+
// Before and after an equals sign or ampersand
|
|
249
|
+
.replace(/(?<beforeAndAfter>[=&])/giu, '<wbr>$1<wbr>')
|
|
250
|
+
// Reconnect the strings with word break opportunities after double slashes
|
|
251
|
+
)
|
|
252
|
+
.join('//<wbr>')
|
|
253
|
+
|
|
254
|
+
return formatted
|
|
255
|
+
},
|
|
256
|
+
/***
|
|
257
|
+
* @description: Creates the right url and id for the next lesson, depending on the environment (projets/campus)
|
|
258
|
+
* Works with full url (ex: https://projets...) or a partial url (ex: 109-101-MQ-60-TP/M1Intro/index.php) set in app.
|
|
259
|
+
* When working locally, uses the projets.cegepadistance.ca environment
|
|
260
|
+
* @param {Object} linkedResource - Setting from app.settings.js
|
|
261
|
+
* @return {Object} - linkedResource object with the right url and id values according to current environment
|
|
262
|
+
*/
|
|
263
|
+
getNextLessonEnv(linkedResource) {
|
|
264
|
+
let courseLocation, host, courseId
|
|
265
|
+
/**ID*/
|
|
266
|
+
if (linkedResource.id.startsWith('http')) {
|
|
267
|
+
courseId = linkedResource.id.split('lrs-xapi/')[1]
|
|
268
|
+
} else {
|
|
269
|
+
courseId = linkedResource.id
|
|
270
|
+
if (courseId.startsWith('/')) {
|
|
271
|
+
courseId = courseId.substring(1)
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/**URL*/
|
|
276
|
+
//If the value is a complete url, split and keep the end only ex: 109-101-MQ-60-TP/M1Intro/index.php
|
|
277
|
+
if (linkedResource.url.startsWith('http')) {
|
|
278
|
+
courseLocation = linkedResource.url.split('lrs-xapi/')[1]
|
|
279
|
+
} else {
|
|
280
|
+
courseLocation = linkedResource.url
|
|
281
|
+
if (courseLocation.startsWith('/')) {
|
|
282
|
+
courseLocation = courseLocation.substring(1)
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
host = import.meta.env.PROD
|
|
287
|
+
? window.location.host
|
|
288
|
+
: 'projets.cegepadistance.ca'
|
|
289
|
+
|
|
290
|
+
linkedResource.id = `https://${host}/lrs-xapi/${courseId}`
|
|
291
|
+
linkedResource.url = `https://${host}/lrs-xapi/${courseLocation}`
|
|
292
|
+
|
|
293
|
+
return linkedResource
|
|
294
|
+
},
|
|
295
|
+
|
|
296
|
+
//Method to get let last activity
|
|
297
|
+
getlastItemInMap(map) {
|
|
298
|
+
return [...map][map.size - 1]
|
|
299
|
+
},
|
|
300
|
+
|
|
301
|
+
/***
|
|
302
|
+
* Method to format Time to ISOS String
|
|
303
|
+
* @param {String} T - time Iso Time
|
|
304
|
+
* @return {String} - time PT Format
|
|
305
|
+
*/
|
|
306
|
+
|
|
307
|
+
formatToISOSTime(t) {
|
|
308
|
+
if (!t) return
|
|
309
|
+
let regex = new RegExp(':', 'gm')
|
|
310
|
+
let T = !regex.test(t) ? this.formatTime(t) : t
|
|
311
|
+
|
|
312
|
+
// let timeStr = `PT${t}S`
|
|
313
|
+
|
|
314
|
+
let timeStr =
|
|
315
|
+
T.match(regex).length > 1
|
|
316
|
+
? `PT${T.split(':')[0]}H${T.split(':')[1]}M${T.split(':')[2]}S`
|
|
317
|
+
: `PT00H${T.split(':')[0]}M${T.split(':')[1]}S`
|
|
318
|
+
|
|
319
|
+
return timeStr
|
|
320
|
+
},
|
|
321
|
+
/***
|
|
322
|
+
* Method to format Time to ISOS String
|
|
323
|
+
* @param {String} T - time Iso Time
|
|
324
|
+
* @return {String} - time PT Format
|
|
325
|
+
*/
|
|
326
|
+
formatTime(time) {
|
|
327
|
+
let returnStr = ``
|
|
328
|
+
// format a time from second to 00:00:00
|
|
329
|
+
const option = { minimumIntegerDigits: 2, useGrouping: false }
|
|
330
|
+
const minutes = Math.floor(time / 60).toLocaleString('en-US', option)
|
|
331
|
+
const seconds = Math.floor(time - minutes * 60).toLocaleString(
|
|
332
|
+
'en-US',
|
|
333
|
+
option
|
|
334
|
+
)
|
|
335
|
+
const hours = Math.floor(time / 3600).toLocaleString('en-US', option)
|
|
336
|
+
if (hours == '00') {
|
|
337
|
+
returnStr = `${minutes}:${seconds}`
|
|
338
|
+
} else {
|
|
339
|
+
returnStr = `${hours}:${minutes}:${seconds}`
|
|
340
|
+
}
|
|
341
|
+
return returnStr
|
|
342
|
+
}, // END formatTime
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* @description check if a values exists in a array
|
|
346
|
+
* @param {Array} array
|
|
347
|
+
* @param value
|
|
348
|
+
* @returns {Boolean}
|
|
349
|
+
*/
|
|
350
|
+
containsValue(array, value) {
|
|
351
|
+
return array.includes(value)
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|