fcad-core-dragon 2.0.1 → 2.0.2-beta.1
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/CHANGELOG +16 -1
- package/package.json +1 -1
- package/src/$locales/en.json +18 -4
- package/src/$locales/fr.json +17 -3
- package/src/components/AppBase.vue +36 -341
- package/src/components/AppBaseModule.vue +16 -21
- package/src/components/AppBasePage.vue +45 -14
- package/src/components/AppBaseSkeleton.vue +45 -0
- package/src/components/AppCompAudio.vue +12 -3
- package/src/components/AppCompButtonProgress.vue +13 -2
- package/src/components/AppCompCarousel.vue +12 -4
- package/src/components/AppCompInputCheckBoxNx.vue +324 -0
- package/src/components/AppCompInputDropdownNx.vue +295 -0
- package/src/components/AppCompInputRadioNx.vue +264 -0
- package/src/components/AppCompInputTextNx.vue +148 -0
- package/src/components/AppCompInputTextTableNx.vue +198 -0
- package/src/components/AppCompInputTextToFillDropdownNx.vue +291 -0
- package/src/components/AppCompInputTextToFillNx.vue +277 -0
- package/src/components/AppCompJauge.vue +11 -4
- package/src/components/AppCompMenu.vue +7 -14
- package/src/components/AppCompMenuItem.vue +7 -5
- package/src/components/AppCompNavigation.vue +21 -21
- package/src/components/AppCompNoteCall.vue +1 -0
- package/src/components/AppCompNoteCredit.vue +2 -1
- package/src/components/AppCompPlayBarNext.vue +94 -41
- package/src/components/AppCompPopUpNext.vue +6 -6
- package/src/components/AppCompQuizNx.vue +500 -0
- package/src/components/AppCompQuizRecall.vue +113 -66
- package/src/components/AppCompTableOfContent.vue +39 -10
- package/src/components/AppCompVideoPlayer.vue +1 -1
- package/src/composables/useQuiz.js +62 -179
- package/src/directives/nvdaFix.js +53 -0
- package/src/main.js +227 -30
- package/src/mixins/$mediaMixins.js +1 -11
- package/src/module/stores/appStore.js +29 -11
- package/src/plugins/idb.js +1 -1
- package/src/shared/generalfuncs.js +134 -0
- package/src/shared/validators.js +308 -234
- package/src/components/AppCompInputCheckBoxNext.vue +0 -205
- package/src/components/AppCompInputDropdownNext.vue +0 -201
- package/src/components/AppCompInputRadioNext.vue +0 -158
- package/src/components/AppCompInputTextNext.vue +0 -124
- package/src/components/AppCompInputTextTableNext.vue +0 -142
- package/src/components/AppCompInputTextToFillDropdownNext.vue +0 -238
- package/src/components/AppCompInputTextToFillNext.vue +0 -171
- package/src/components/AppCompQuizNext.vue +0 -2908
package/CHANGELOG
CHANGED
|
@@ -1,8 +1,23 @@
|
|
|
1
|
-
2.0.1(
|
|
1
|
+
2.0.2-beta.1(19 août 2025)
|
|
2
|
+
Exercices : Réécriture complète de la logique derrière les exercices
|
|
3
|
+
|
|
4
|
+
Rappel de réponse : Mise à jour automatique du contenu quand la réponse change.
|
|
5
|
+
|
|
6
|
+
Accessibilité : Balise fieldset qui annonce la marche \ suivre quand on arrive sur un exercice
|
|
7
|
+
|
|
8
|
+
Lecteur audio : meilleur responsive
|
|
9
|
+
|
|
10
|
+
Ajout de composants Skeleton Loader (Vuetify) au moment du chargement du contenu des exercices
|
|
11
|
+
|
|
12
|
+
Nouveau nom de classe dans les exercices texte tableau
|
|
13
|
+
|
|
14
|
+
2.0.1(12 août 2025)
|
|
2
15
|
carroussel : Changement du titre h3 pour une balise p avec une classe
|
|
3
16
|
|
|
4
17
|
TOC : Alignement vertical du libellé "terminé"
|
|
5
18
|
|
|
19
|
+
Nouveau fichier (vuetify.scss) pour overrider les variables SASS vuetify, La liste complète des variables SASS globales pouvant être modifiées se trouve ici : https://vuetifyjs.com/en/api/globals/#sass
|
|
20
|
+
|
|
6
21
|
2.0.1-beta.1(12 mai 2025)
|
|
7
22
|
Vitepress : La documentation du FCAD 2 est maintenant dans le dossier "documentation"
|
|
8
23
|
|
package/package.json
CHANGED
package/src/$locales/en.json
CHANGED
|
@@ -75,7 +75,9 @@
|
|
|
75
75
|
},
|
|
76
76
|
"label": {
|
|
77
77
|
"side_panel": "side panel",
|
|
78
|
-
"timer": "estimated time"
|
|
78
|
+
"timer": "estimated time",
|
|
79
|
+
"info_long": "Display notes and references",
|
|
80
|
+
"note_reference": "???"
|
|
79
81
|
},
|
|
80
82
|
"message": {
|
|
81
83
|
"err_download_file": "The file download has failed.",
|
|
@@ -83,7 +85,7 @@
|
|
|
83
85
|
"first_option_dropdown": "Choose an option",
|
|
84
86
|
"no_attempts": "You have no more attempts.",
|
|
85
87
|
"loading_state_msg": "Loading. Please wait...",
|
|
86
|
-
"progress_card": "
|
|
88
|
+
"progress_card": "Progress status:",
|
|
87
89
|
"recall_done": "You have answered the question :",
|
|
88
90
|
"recall_undone": "You have not answered the question.",
|
|
89
91
|
"skip_content": "Skip to the main content."
|
|
@@ -129,7 +131,19 @@
|
|
|
129
131
|
"goodAnswer": "Good answer",
|
|
130
132
|
"badAnswer": "Wrong answer",
|
|
131
133
|
"neutralAnswer": "Neutral answer",
|
|
132
|
-
"answers": "Answer choices"
|
|
134
|
+
"answers": "Answer choices",
|
|
135
|
+
"radioFieldset": "Select one answer from the following",
|
|
136
|
+
"checkboxFieldset": "Select one or more answers from the following",
|
|
137
|
+
"options": "options",
|
|
138
|
+
"textTableFieldset1": "Fill the",
|
|
139
|
+
"textTableFieldset2": "following text fields",
|
|
140
|
+
"dropdownFieldsetSingle": "Select an answer in the following dropdown list",
|
|
141
|
+
"dropdownFieldsetMulti1": "Select an answer in the",
|
|
142
|
+
"dropdownFieldsetMulti2": "following dropdown lists",
|
|
143
|
+
"textToFillFieldset1": "In the following text, fill the",
|
|
144
|
+
"textToFillFieldset2": "text fields",
|
|
145
|
+
"textToFillDropdownFieldset1": "In the following text, Select an answer in the",
|
|
146
|
+
"textToFillDropdownFieldset2": "text fields"
|
|
133
147
|
},
|
|
134
148
|
"a11y_sr": {
|
|
135
149
|
"time": {
|
|
@@ -140,4 +154,4 @@
|
|
|
140
154
|
"seek_slider": "Seek slider",
|
|
141
155
|
"range_expression": "at %x of %y."
|
|
142
156
|
}
|
|
143
|
-
}
|
|
157
|
+
}
|
package/src/$locales/fr.json
CHANGED
|
@@ -38,7 +38,9 @@
|
|
|
38
38
|
},
|
|
39
39
|
"label": {
|
|
40
40
|
"side_panel": "fenêtre latérale",
|
|
41
|
-
"timer": "temps estimé"
|
|
41
|
+
"timer": "temps estimé",
|
|
42
|
+
"info_long": "Afficher les notes et les mentions de sources",
|
|
43
|
+
"note_reference": "Note de reference"
|
|
42
44
|
},
|
|
43
45
|
"message": {
|
|
44
46
|
"err_download_file": "Le téléchargement de ce fichier a échoué.",
|
|
@@ -46,7 +48,7 @@
|
|
|
46
48
|
"first_option_dropdown": "Choisir une option",
|
|
47
49
|
"no_attempts": "Vous n'avez plus d'essai.",
|
|
48
50
|
"loading_state_msg": "Chargement. Veuillez patienter...",
|
|
49
|
-
"progress_card": "État d’avancement:",
|
|
51
|
+
"progress_card": "État d’avancement :",
|
|
50
52
|
"recall_done": "Vous avez répondu précédemment à la question :",
|
|
51
53
|
"recall_undone": "Vous n'avez pas répondu à la question concernée.",
|
|
52
54
|
"skip_content": "Passer au contenu principal"
|
|
@@ -92,7 +94,19 @@
|
|
|
92
94
|
"goodAnswer": "Bonne réponse",
|
|
93
95
|
"badAnswer": "Mauvaise réponse",
|
|
94
96
|
"neutralAnswer": "Réponse neutre",
|
|
95
|
-
"answers": "Choix de réponses"
|
|
97
|
+
"answers": "Choix de réponses",
|
|
98
|
+
"radioFieldset": "Sélectionnez une réponse parmi les",
|
|
99
|
+
"checkboxFieldset": "Sélectionnez une ou plusieurs réponses parmi les",
|
|
100
|
+
"options": "options suivantes",
|
|
101
|
+
"textTableFieldset1": "Remplissez les",
|
|
102
|
+
"textTableFieldset2": "champs de texte suivants",
|
|
103
|
+
"dropdownFieldsetSingle": "Sélectionnez une réponse dans la liste déroulante suivante",
|
|
104
|
+
"dropdownFieldsetMulti1": "Sélectionnez une réponse dans les",
|
|
105
|
+
"dropdownFieldsetMulti2": "listes déroulantes suivantes",
|
|
106
|
+
"textToFillFieldset1": "Dans le texte qui suit, remplissez les",
|
|
107
|
+
"textToFillFieldset2": "champs de texte",
|
|
108
|
+
"textToFillDropdownFieldset1": "Dans le texte qui suit, Sélectionnez une réponse dans les",
|
|
109
|
+
"textToFillDropdownFieldset2": "listes déroulantes"
|
|
96
110
|
},
|
|
97
111
|
"a11y_sr": {
|
|
98
112
|
"time": {
|
|
@@ -45,7 +45,8 @@
|
|
|
45
45
|
:model-value="!appReady && initialLoading"
|
|
46
46
|
class="align-center justify-center"
|
|
47
47
|
scrim="white"
|
|
48
|
-
opacity="0.
|
|
48
|
+
opacity="0.9"
|
|
49
|
+
:persistent="true"
|
|
49
50
|
>
|
|
50
51
|
<div class="text-center grp-spinners">
|
|
51
52
|
<v-icon id="icon_loading" icon="mdi-dots-circle" size="x-large" />
|
|
@@ -97,7 +98,8 @@ export default {
|
|
|
97
98
|
resizeiPad: false,
|
|
98
99
|
buildInfoClicked: false,
|
|
99
100
|
error: [],
|
|
100
|
-
initialLoading: true
|
|
101
|
+
initialLoading: true,
|
|
102
|
+
f5KeyPressed: false
|
|
101
103
|
}
|
|
102
104
|
},
|
|
103
105
|
computed: {
|
|
@@ -109,15 +111,13 @@ export default {
|
|
|
109
111
|
'getAppStatus',
|
|
110
112
|
'getUserInteraction',
|
|
111
113
|
'getConnectionInfo',
|
|
112
|
-
'getDataFromServer',
|
|
113
114
|
'getAllActivities',
|
|
114
115
|
'getMediaPlaybarValues',
|
|
115
116
|
'getAppConfigs',
|
|
116
117
|
'getErrorMenu',
|
|
117
118
|
'getRouteHistory',
|
|
118
119
|
'getBookmarkEnabled',
|
|
119
|
-
'getApplicationSettings'
|
|
120
|
-
'getCompStatusTracker'
|
|
120
|
+
'getApplicationSettings'
|
|
121
121
|
]),
|
|
122
122
|
getwidth() {
|
|
123
123
|
return window.innerWidth
|
|
@@ -162,87 +162,14 @@ export default {
|
|
|
162
162
|
}
|
|
163
163
|
},
|
|
164
164
|
watch: {
|
|
165
|
-
|
|
166
|
-
deep: true,
|
|
167
|
-
//in development environment (localhost), don't wait for the axios call
|
|
168
|
-
immediate: import.meta.env.DEV,
|
|
165
|
+
'store.$state.userDataLoaded': {
|
|
169
166
|
handler() {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
* Ref:https://developer.mozilla.org/en-US/docs/Web/API/Document/visibilitychange_event
|
|
176
|
-
* https://developer.mozilla.org/en-US/docs/Web/API/Navigator/sendBeacon
|
|
177
|
-
*/
|
|
178
|
-
|
|
179
|
-
if (!this.getConnectionInfo)
|
|
180
|
-
return setTimeout(() => {
|
|
181
|
-
this.setProgress()
|
|
182
|
-
}, 200)
|
|
183
|
-
|
|
184
|
-
if (this.getIsMobile) {
|
|
185
|
-
document.addEventListener(
|
|
186
|
-
'visibilitychange',
|
|
187
|
-
() => {
|
|
188
|
-
if (document.visibilityState === 'hidden') {
|
|
189
|
-
this.executeCloseEventTriggered()
|
|
190
|
-
}
|
|
191
|
-
},
|
|
192
|
-
false
|
|
193
|
-
)
|
|
194
|
-
}
|
|
195
|
-
// initialize scorm Commuinication with LMS || xAPI LRS
|
|
196
|
-
if (this.getModuleInfo.packageType === 'scorm') {
|
|
197
|
-
this.$scorm.Initialize()
|
|
198
|
-
setTimeout(() => {
|
|
199
|
-
this.setProgress()
|
|
200
|
-
}, 200)
|
|
201
|
-
} else if (
|
|
202
|
-
this.getModuleInfo.packageType === 'xapi' &&
|
|
203
|
-
this.getConnectionInfo &&
|
|
204
|
-
this.getConnectionInfo.actor &&
|
|
205
|
-
this.getConnectionInfo.remote
|
|
206
|
-
) {
|
|
207
|
-
const {
|
|
208
|
-
auth,
|
|
209
|
-
endpoint,
|
|
210
|
-
registration = this.$xapi.ruuid()
|
|
211
|
-
} = this.getConnectionInfo
|
|
212
|
-
|
|
213
|
-
const config = {
|
|
214
|
-
auth,
|
|
215
|
-
endpoint,
|
|
216
|
-
registration,
|
|
217
|
-
activity_platform: `SIPI_organizationId`
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
this.$xapi._configLRS(config) // configure and launch LRS
|
|
221
|
-
|
|
222
|
-
setTimeout(() => {
|
|
223
|
-
this.fetchDataFromServer().then(() => {
|
|
224
|
-
setTimeout(() => {
|
|
225
|
-
this.setProgress()
|
|
226
|
-
}, 200)
|
|
227
|
-
})
|
|
228
|
-
}, 200)
|
|
229
|
-
}
|
|
230
|
-
}
|
|
167
|
+
!this.store.$state.userDataLoaded
|
|
168
|
+
? this.updateTracker('appBase', 'loading')
|
|
169
|
+
: this.updateTracker('appBase', 'ready')
|
|
170
|
+
},
|
|
171
|
+
immediate: true
|
|
231
172
|
}
|
|
232
|
-
//===========FOR TESTING TIMER TIMEOUT====//
|
|
233
|
-
// elapsedIdleTime: {
|
|
234
|
-
// handler() {
|
|
235
|
-
// console.log(
|
|
236
|
-
// '⌛:',
|
|
237
|
-
// this.elapsedIdleTime,
|
|
238
|
-
// this.timerCurrentState,
|
|
239
|
-
// this.activityDuration
|
|
240
|
-
// )
|
|
241
|
-
|
|
242
|
-
// //max idle time allowed 300s (5 min)
|
|
243
|
-
// },
|
|
244
|
-
// immediate: true
|
|
245
|
-
// }
|
|
246
173
|
},
|
|
247
174
|
|
|
248
175
|
created() {
|
|
@@ -252,8 +179,8 @@ export default {
|
|
|
252
179
|
//Declare loading state if no error was detected
|
|
253
180
|
|
|
254
181
|
if (!this.error.length) {
|
|
255
|
-
this.updateTracker('appBase', 'loading')
|
|
256
|
-
this.
|
|
182
|
+
// this.updateTracker('appBase', 'loading')
|
|
183
|
+
this.initializeApp(this.appConfig)
|
|
257
184
|
}
|
|
258
185
|
|
|
259
186
|
window.versionFCAD = this.$helper.getFcadVersionString()
|
|
@@ -281,12 +208,19 @@ export default {
|
|
|
281
208
|
this.$bus.$on('stop-idle-detector', this.unsetIdleDetector)
|
|
282
209
|
},
|
|
283
210
|
beforeMount() {
|
|
211
|
+
window.addEventListener('keydown', this.handleF5KeyPressed)
|
|
284
212
|
window.addEventListener(
|
|
285
213
|
'beforeunload',
|
|
286
214
|
(e) => {
|
|
287
|
-
this.executeCloseEventTriggered()
|
|
288
215
|
// e.preventDefault()
|
|
289
216
|
// e.returnValue = true
|
|
217
|
+
|
|
218
|
+
//prevent app to send/Save data when F5 is pressed to reload app
|
|
219
|
+
if (this.f5KeyPressed) return
|
|
220
|
+
|
|
221
|
+
this.executeCloseEventTriggered()
|
|
222
|
+
|
|
223
|
+
//debugger
|
|
290
224
|
},
|
|
291
225
|
true
|
|
292
226
|
)
|
|
@@ -295,6 +229,7 @@ export default {
|
|
|
295
229
|
mounted() {
|
|
296
230
|
// set the language of the app
|
|
297
231
|
this.setLocale(this.getAppConfigs.lang)
|
|
232
|
+
window.addEventListener('keydown', this.handleF5KeyPressed)
|
|
298
233
|
},
|
|
299
234
|
beforeUnmount() {
|
|
300
235
|
this.$bus.$off('set-comp-status', this.updateTracker)
|
|
@@ -306,7 +241,9 @@ export default {
|
|
|
306
241
|
this.$bus.$off('start-idle-detector', this.setIdleDetector)
|
|
307
242
|
this.$bus.$off('stop-idle-detector', this.unsetIdleDetector)
|
|
308
243
|
this.$bus.$off('start-timer', this.startAppTimer)
|
|
309
|
-
|
|
244
|
+
window.removeEventListener('keydown', this.handleF5KeyPressed)
|
|
245
|
+
if (this.getAppConfigs.remote && this.unsubscribeToSetConfig)
|
|
246
|
+
this.unsubscribeToSetConfig() //stop watching changing in store to save to local storage
|
|
310
247
|
},
|
|
311
248
|
methods: {
|
|
312
249
|
...mapActions(useAppStore, [
|
|
@@ -317,7 +254,7 @@ export default {
|
|
|
317
254
|
'setApplicationSettings',
|
|
318
255
|
'setMediaPlaybarValues',
|
|
319
256
|
'updateCompStatusTracker',
|
|
320
|
-
'
|
|
257
|
+
'initializeApp',
|
|
321
258
|
'setMobileState',
|
|
322
259
|
'setCurrentBrowser'
|
|
323
260
|
]),
|
|
@@ -425,145 +362,6 @@ export default {
|
|
|
425
362
|
return device
|
|
426
363
|
},
|
|
427
364
|
|
|
428
|
-
async fetchDataFromServer() {
|
|
429
|
-
this.updateTracker('appBase_fetch', 'loading')
|
|
430
|
-
if (this.getModuleInfo.packageType !== 'xapi') return
|
|
431
|
-
if (!this.getConnectionInfo || !this.getConnectionInfo.remote) return
|
|
432
|
-
|
|
433
|
-
const actorMbox = this.getConnectionInfo.actor.mbox.replace('mailto:', '')
|
|
434
|
-
const activityId = this.getConnectionInfo.activity_id
|
|
435
|
-
const _url = new URL(activityId)
|
|
436
|
-
const parentID = `${_url.origin}/${this.getModuleInfo.courseID}` // redefining activity id for statement
|
|
437
|
-
|
|
438
|
-
const lessonProgressParam = { email: actorMbox, activityId }
|
|
439
|
-
const lessonStateParam = {
|
|
440
|
-
email: actorMbox,
|
|
441
|
-
activityId,
|
|
442
|
-
verb: 'completed'
|
|
443
|
-
}
|
|
444
|
-
const lessonPosionParam = {
|
|
445
|
-
email: actorMbox,
|
|
446
|
-
activityId
|
|
447
|
-
}
|
|
448
|
-
const playbarParam = {
|
|
449
|
-
email: actorMbox,
|
|
450
|
-
activityId,
|
|
451
|
-
verb: 'played'
|
|
452
|
-
}
|
|
453
|
-
const preferencesParam = {
|
|
454
|
-
email: actorMbox,
|
|
455
|
-
activityId: parentID,
|
|
456
|
-
verb: 'preferred'
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
const fetchParams = [
|
|
460
|
-
lessonProgressParam,
|
|
461
|
-
lessonStateParam,
|
|
462
|
-
lessonPosionParam,
|
|
463
|
-
playbarParam,
|
|
464
|
-
preferencesParam
|
|
465
|
-
]
|
|
466
|
-
|
|
467
|
-
const {
|
|
468
|
-
userData,
|
|
469
|
-
savedPoint,
|
|
470
|
-
preferredSettings,
|
|
471
|
-
playbarValues,
|
|
472
|
-
lessonStatus
|
|
473
|
-
} = await this.$xapi._getBulkData(fetchParams)
|
|
474
|
-
|
|
475
|
-
const { routeHistory = [], ...userProgress } = userData
|
|
476
|
-
|
|
477
|
-
const completedState = lessonStatus || {}
|
|
478
|
-
const lessonPosition = savedPoint || ''
|
|
479
|
-
const applicationSettings = preferredSettings || {}
|
|
480
|
-
//====FOR TESTING====//
|
|
481
|
-
// console.log('💾 RECORDS ', {
|
|
482
|
-
// userProgress,
|
|
483
|
-
// routeHistory,
|
|
484
|
-
// lessonPosition,
|
|
485
|
-
// completedState,
|
|
486
|
-
// playbarValues,
|
|
487
|
-
// applicationSettings
|
|
488
|
-
// })
|
|
489
|
-
//Update the App Store data
|
|
490
|
-
this.updateDataFetchFromServer({
|
|
491
|
-
userProgress,
|
|
492
|
-
routeHistory,
|
|
493
|
-
lessonPosition,
|
|
494
|
-
completedState,
|
|
495
|
-
playbarValues,
|
|
496
|
-
applicationSettings
|
|
497
|
-
}).then(() => {
|
|
498
|
-
this.updateTracker('appBase_fetch', 'ready')
|
|
499
|
-
})
|
|
500
|
-
},
|
|
501
|
-
|
|
502
|
-
async fetchDataFromServerOptimized() {
|
|
503
|
-
this.updateTracker('appBase_fetch', 'loading')
|
|
504
|
-
if (this.getModuleInfo.packageType !== 'xapi') return
|
|
505
|
-
if (!this.getConnectionInfo || !this.getConnectionInfo.remote) return
|
|
506
|
-
|
|
507
|
-
const actorMbox = this.getConnectionInfo.actor.mbox.replace('mailto:', '')
|
|
508
|
-
const activityId = this.getConnectionInfo.activity_id
|
|
509
|
-
const _url = new URL(activityId)
|
|
510
|
-
const parentID = `${_url.origin}/${this.getModuleInfo.courseID}` // redefining activity id for statement
|
|
511
|
-
|
|
512
|
-
const lessonProgressParam = { email: actorMbox, activityId }
|
|
513
|
-
const lessonStateParam = {
|
|
514
|
-
email: actorMbox,
|
|
515
|
-
activityId,
|
|
516
|
-
verb: 'completed'
|
|
517
|
-
}
|
|
518
|
-
const lessonPosionParam = {
|
|
519
|
-
email: actorMbox,
|
|
520
|
-
activityId
|
|
521
|
-
}
|
|
522
|
-
const playbarParam = {
|
|
523
|
-
email: actorMbox,
|
|
524
|
-
activityId,
|
|
525
|
-
verb: 'played'
|
|
526
|
-
}
|
|
527
|
-
const preferencesParam = {
|
|
528
|
-
email: actorMbox,
|
|
529
|
-
activityId: parentID,
|
|
530
|
-
verb: 'preferred'
|
|
531
|
-
}
|
|
532
|
-
|
|
533
|
-
const fetchParams = [
|
|
534
|
-
lessonProgressParam,
|
|
535
|
-
lessonStateParam,
|
|
536
|
-
lessonPosionParam,
|
|
537
|
-
playbarParam,
|
|
538
|
-
preferencesParam
|
|
539
|
-
]
|
|
540
|
-
|
|
541
|
-
const {
|
|
542
|
-
userData,
|
|
543
|
-
savedPoint,
|
|
544
|
-
preferredSettings,
|
|
545
|
-
playbarValues,
|
|
546
|
-
lessonStatus
|
|
547
|
-
} = await this.$xapi._getBulkData(fetchParams)
|
|
548
|
-
|
|
549
|
-
const { routeHistory = [], ...userProgress } = userData
|
|
550
|
-
|
|
551
|
-
const completedState = lessonStatus || {}
|
|
552
|
-
const lessonPosition = savedPoint || ''
|
|
553
|
-
const applicationSettings = preferredSettings || {}
|
|
554
|
-
//Update the App Store data
|
|
555
|
-
this.updateDataFetchFromServer({
|
|
556
|
-
userProgress,
|
|
557
|
-
routeHistory,
|
|
558
|
-
lessonPosition,
|
|
559
|
-
completedState,
|
|
560
|
-
playbarValues,
|
|
561
|
-
applicationSettings
|
|
562
|
-
}).then(() => {
|
|
563
|
-
this.updateTracker('appBase_fetch', 'ready')
|
|
564
|
-
})
|
|
565
|
-
},
|
|
566
|
-
|
|
567
365
|
executeCloseEventTriggered() {
|
|
568
366
|
if (
|
|
569
367
|
this.getModuleInfo.packageType === 'scorm' &&
|
|
@@ -582,113 +380,6 @@ export default {
|
|
|
582
380
|
}
|
|
583
381
|
},
|
|
584
382
|
|
|
585
|
-
async setProgress() {
|
|
586
|
-
const packageType = this.getModuleInfo.packageType
|
|
587
|
-
switch (packageType) {
|
|
588
|
-
case 'scorm':
|
|
589
|
-
{
|
|
590
|
-
// Get saved data from suspend_data or from localStorage to update the store:
|
|
591
|
-
// LMS is connected
|
|
592
|
-
if (this.$scorm.initialized) {
|
|
593
|
-
// launching the lesson (if the lesson is not already completed)
|
|
594
|
-
const lessonStatus = this.$scorm.GetValue(
|
|
595
|
-
'cmi.core.lesson_status',
|
|
596
|
-
true
|
|
597
|
-
)
|
|
598
|
-
if (lessonStatus === 'unknown') {
|
|
599
|
-
this.$scorm.setValue('cmi.core.lesson_status', 'incomplete') // set the lesson status to in complete
|
|
600
|
-
this.$scorm.Commit() // persist data
|
|
601
|
-
}
|
|
602
|
-
// chacked if there is a existing record in the LMS
|
|
603
|
-
if (this.$scorm.GetValue('cmi.suspend_data') !== '') {
|
|
604
|
-
const scormRecord = this.$scorm
|
|
605
|
-
.GetValue('cmi.suspend_data')
|
|
606
|
-
.replace(/\\/g, '')
|
|
607
|
-
const { userData, routeHistory, userSettings } =
|
|
608
|
-
JSON.parse(scormRecord)
|
|
609
|
-
|
|
610
|
-
this.setUserMetaData(userData)
|
|
611
|
-
this.setRouteHistory(routeHistory) // update store recored with existing record
|
|
612
|
-
this.setApplicationSettings(userSettings) // update store recored with existing record
|
|
613
|
-
}
|
|
614
|
-
// check for the bookmark existance in LMS
|
|
615
|
-
if (
|
|
616
|
-
this.$scorm.GetValue('cmi.core.lesson_location', false) !== ''
|
|
617
|
-
) {
|
|
618
|
-
let lessonPosition = this.$scorm.GetValue(
|
|
619
|
-
'cmi.core.lesson_location',
|
|
620
|
-
false
|
|
621
|
-
)
|
|
622
|
-
if (this.bookmarkActive && lessonPosition)
|
|
623
|
-
this.$router.push({ name: lessonPosition }) //Should Redirect to bookmark
|
|
624
|
-
}
|
|
625
|
-
|
|
626
|
-
// No LMS use LocalStorage record
|
|
627
|
-
} else {
|
|
628
|
-
this.$idb.openDB().then(() => {
|
|
629
|
-
this.$idb.getFromDB(this.getModuleInfo.idbID).then((res) => {
|
|
630
|
-
if (res && res.$record) {
|
|
631
|
-
const { routeHistory, userSettings, progress } = res.$record
|
|
632
|
-
this.setUserMetaData(progress) // update store record with existing record
|
|
633
|
-
this.setRouteHistory(routeHistory) // update store record with existing route info
|
|
634
|
-
if (userSettings) this.setApplicationSettings(userSettings) // update store record with existing user settings
|
|
635
|
-
}
|
|
636
|
-
})
|
|
637
|
-
})
|
|
638
|
-
}
|
|
639
|
-
}
|
|
640
|
-
break
|
|
641
|
-
|
|
642
|
-
case 'xapi':
|
|
643
|
-
{
|
|
644
|
-
if (
|
|
645
|
-
this.getConnectionInfo &&
|
|
646
|
-
this.getConnectionInfo.actor &&
|
|
647
|
-
this.getConnectionInfo.remote
|
|
648
|
-
) {
|
|
649
|
-
if (!this.getDataFromServer) return
|
|
650
|
-
//Try to get the user progress from LRS
|
|
651
|
-
const {
|
|
652
|
-
playbarValues,
|
|
653
|
-
routeHistory,
|
|
654
|
-
userProgress,
|
|
655
|
-
lessonPosition,
|
|
656
|
-
applicationSettings
|
|
657
|
-
} = this.getDataFromServer
|
|
658
|
-
|
|
659
|
-
this.setUserMetaData(userProgress) // update store record with existing record
|
|
660
|
-
this.setRouteHistory(routeHistory) // update store record with existing record
|
|
661
|
-
|
|
662
|
-
if (playbarValues) this.setMediaPlaybarValues(playbarValues) // update store record with existing record
|
|
663
|
-
|
|
664
|
-
if (applicationSettings)
|
|
665
|
-
this.setApplicationSettings(applicationSettings) // set the user preferred settings
|
|
666
|
-
|
|
667
|
-
//Handel bookmark navigation
|
|
668
|
-
if (this.bookmarkActive && lessonPosition)
|
|
669
|
-
this.$router.push({ name: lessonPosition }) //Should Redirect to bookmark
|
|
670
|
-
} else {
|
|
671
|
-
//Get existing records for user data in local store
|
|
672
|
-
this.$idb.openDB().then(() => {
|
|
673
|
-
this.$idb.getFromDB(this.getModuleInfo.idbID).then((res) => {
|
|
674
|
-
if (res && res.$record) {
|
|
675
|
-
const { routeHistory, userSettings, progress } = res.$record
|
|
676
|
-
this.setUserMetaData(progress) // update store record with existing record
|
|
677
|
-
this.setRouteHistory(routeHistory) // update store record with existing route info
|
|
678
|
-
|
|
679
|
-
if (userSettings) {
|
|
680
|
-
this.setApplicationSettings(userSettings) // update store record with existing user setting
|
|
681
|
-
}
|
|
682
|
-
}
|
|
683
|
-
})
|
|
684
|
-
})
|
|
685
|
-
}
|
|
686
|
-
}
|
|
687
|
-
|
|
688
|
-
break
|
|
689
|
-
}
|
|
690
|
-
this.updateTracker('appBase', 'ready')
|
|
691
|
-
},
|
|
692
383
|
updateTracker(name, status) {
|
|
693
384
|
this.updateCompStatusTracker({ name, status })
|
|
694
385
|
},
|
|
@@ -772,9 +463,9 @@ export default {
|
|
|
772
463
|
//ID is of activity (menu, conclusion, activite, intro )
|
|
773
464
|
const activityStr = activityId.split('/').toReversed()[0]
|
|
774
465
|
|
|
775
|
-
if (!this.
|
|
466
|
+
if (!this.getUserInteraction[activityId])
|
|
776
467
|
return this.$xapi.verbs.initialized
|
|
777
|
-
|
|
468
|
+
|
|
778
469
|
let activity_ref
|
|
779
470
|
//Define the activity reference
|
|
780
471
|
if (['menu', 'introduction', 'A00'].includes(activityStr))
|
|
@@ -786,7 +477,10 @@ export default {
|
|
|
786
477
|
activity_ref = aNum.length > 1 ? `A${aNum}` : `A0${aNum}`
|
|
787
478
|
} else activity_ref = activityStr // should be AXX
|
|
788
479
|
|
|
789
|
-
if (
|
|
480
|
+
if (
|
|
481
|
+
this.getUserInteraction &&
|
|
482
|
+
this.getUserInteraction[activity_ref]
|
|
483
|
+
)
|
|
790
484
|
return this.$xapi.verbs.resumed
|
|
791
485
|
else return this.$xapi.verbs.initialized
|
|
792
486
|
}
|
|
@@ -1262,7 +956,6 @@ export default {
|
|
|
1262
956
|
//error if There is more than one activity when is_single_activity
|
|
1263
957
|
switch (true) {
|
|
1264
958
|
case isSingleActivity && activitiesList.size > 1:
|
|
1265
|
-
console.log('ici')
|
|
1266
959
|
errMessage = `La configuration choisie ne permet pas d'avoir plus d'une activité dans l'application. \n Vous devez soit désactiver l'option 💲<b>is_single_activity</b> ou retirer TOUTES les autres activités`
|
|
1267
960
|
|
|
1268
961
|
consoleMsg = `Cannot have more than 1 activity with this settings configuration. Either disable 💲is_single_activity or DELETE ALL others activities`
|
|
@@ -1270,14 +963,12 @@ export default {
|
|
|
1270
963
|
break
|
|
1271
964
|
|
|
1272
965
|
case isSingleActivity && !noMenu:
|
|
1273
|
-
console.log('LA')
|
|
1274
966
|
errMessage = `Le MENU n'est pas disponible avec la configuration choisie.\n Vous devez soit désactiver l'option 💲<b>no_menu</b> ou l'option 💲<b>is_single_activity</b>`
|
|
1275
967
|
consoleMsg = `Cannot have MENU with current settings configuration. Either set 💲no_menu:false or 💲is_single_activity:false`
|
|
1276
968
|
this.error.push(errMessage)
|
|
1277
969
|
break
|
|
1278
970
|
|
|
1279
971
|
case err:
|
|
1280
|
-
console.log('LA LA')
|
|
1281
972
|
errMessage = `Il y une erreur dans votre fichier menu.setting.js. \n ouvrez votre console pour voir l'erreur et corriger la dans menu.setting.js `
|
|
1282
973
|
consoleMsg = this.getErrorMenu
|
|
1283
974
|
this.error.push(errMessage)
|
|
@@ -1289,6 +980,10 @@ export default {
|
|
|
1289
980
|
`%c WARNING!>>> ${consoleMsg}`,
|
|
1290
981
|
'background: orange; color: white; display: block; border-radius:5px; margin:5px;'
|
|
1291
982
|
)
|
|
983
|
+
},
|
|
984
|
+
|
|
985
|
+
handleF5KeyPressed(e) {
|
|
986
|
+
this.f5KeyPressed = e.code == 'F5'
|
|
1292
987
|
}
|
|
1293
988
|
}
|
|
1294
989
|
}
|