fcad-core-dragon 2.0.0-beta.3 → 2.0.0-beta.5
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 +33 -33
- package/.eslintignore +29 -29
- package/.eslintrc.cjs +81 -81
- package/CHANGELOG +13 -0
- package/README.md +71 -71
- package/bk.scss +117 -117
- package/package.json +8 -8
- package/src/$locales/en.json +145 -143
- package/src/$locales/fr.json +107 -105
- package/src/assets/data/onboardingMessages.json +47 -47
- package/src/components/AppBase.vue +1150 -1054
- package/src/components/AppBaseButton.test.js +22 -0
- package/src/components/AppBaseButton.vue +93 -87
- package/src/components/AppBaseErrorDisplay.vue +438 -438
- package/src/components/AppBaseFlipCard.vue +84 -84
- package/src/components/AppBaseModule.vue +1657 -1673
- package/src/components/AppBasePage.vue +742 -779
- package/src/components/AppBasePopover.vue +41 -41
- package/src/components/AppCompAudio.vue +265 -234
- package/src/components/AppCompBranchButtons.vue +556 -552
- package/src/components/AppCompButtonProgress.vue +121 -126
- package/src/components/AppCompCarousel.vue +328 -298
- package/src/components/AppCompInputCheckBoxNext.vue +200 -195
- package/src/components/AppCompInputDropdownNext.vue +201 -159
- package/src/components/AppCompInputRadioNext.vue +152 -152
- package/src/components/AppCompInputTextNext.vue +125 -106
- package/src/components/AppCompInputTextTableNext.vue +142 -141
- package/src/components/AppCompInputTextToFillDropdownNext.vue +238 -230
- package/src/components/AppCompInputTextToFillNext.vue +171 -171
- package/src/components/AppCompJauge.vue +74 -74
- package/src/components/AppCompMenu.vue +25 -10
- package/src/components/AppCompMenuItem.vue +228 -228
- package/src/components/AppCompNavigation.vue +972 -960
- package/src/components/AppCompNoteCall.vue +159 -133
- package/src/components/AppCompNoteCredit.vue +490 -292
- package/src/components/AppCompPlayBar.vue +1217 -1218
- package/src/components/AppCompPlayBarNext.vue +2060 -2052
- package/src/components/AppCompPlayBarProgress.vue +82 -82
- package/src/components/AppCompPopUpNext.vue +500 -503
- package/src/components/AppCompQuizNext.vue +2908 -2904
- package/src/components/AppCompQuizRecall.vue +298 -276
- package/src/components/AppCompSVGNext.vue +347 -347
- package/src/components/AppCompSettingsMenu.vue +172 -172
- package/src/components/AppCompTableOfContent.vue +386 -387
- package/src/components/AppCompTranscript.vue +24 -24
- package/src/components/AppCompVideoPlayer.vue +368 -368
- package/src/components/BaseModule.vue +55 -72
- package/src/components/tests__/AppBaseButton.spec.js +53 -0
- package/src/composables/useQuiz.js +206 -206
- package/src/externalComps/ModuleView.vue +22 -22
- package/src/externalComps/SummaryView.vue +91 -91
- package/src/main.js +272 -272
- package/src/mixins/$mediaMixins.js +819 -819
- package/src/mixins/timerMixin.js +155 -155
- package/src/module/stores/appStore.js +954 -893
- package/src/module/xapi/ADL.js +380 -376
- 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/Statement/agent.js +55 -55
- package/src/module/xapi/Statement/index.js +259 -259
- package/src/module/xapi/Statement/statement.js +253 -253
- 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 +1963 -1963
- package/src/module/xapi/xapiStatement.js +444 -444
- package/src/plugins/bus.js +8 -8
- package/src/plugins/gsap.js +14 -14
- package/src/plugins/helper.js +355 -308
- package/src/plugins/i18n.js +44 -44
- package/src/plugins/idb.js +227 -219
- 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 +48 -43
- package/src/router/routes.js +312 -312
- package/src/shared/generalfuncs.js +210 -210
- package/src/shared/validators.js +926 -1069
- package/vitest.config.js +19 -0
- package/vite.config.js +0 -27
package/src/main.js
CHANGED
|
@@ -1,272 +1,272 @@
|
|
|
1
|
-
import AppBase from './components/AppBase.vue'
|
|
2
|
-
import AppBaseButton from './components/AppBaseButton.vue'
|
|
3
|
-
import AppBaseModule from './components/AppBaseModule.vue'
|
|
4
|
-
import AppBasePage from './components/AppBasePage.vue'
|
|
5
|
-
import AppBaseFlipCard from './components/AppBaseFlipCard.vue'
|
|
6
|
-
import AppBasePopover from './components/AppBasePopover.vue'
|
|
7
|
-
import AppCompJauge from './components/AppCompJauge.vue'
|
|
8
|
-
import AppBaseErrorDisplay from './components/AppBaseErrorDisplay.vue'
|
|
9
|
-
//import AppCompBif from './components/AppCompBif.vue'
|
|
10
|
-
import AppCompAudio from './components/AppCompAudio.vue'
|
|
11
|
-
import AppCompBranchButtons from './components/AppCompBranchButtons.vue'
|
|
12
|
-
import AppCompCarousel from './components/AppCompCarousel.vue'
|
|
13
|
-
import AppCompViewDisplay from './components/AppCompViewDisplay.vue'
|
|
14
|
-
import AppCompTableOfContent from './components/AppCompTableOfContent.vue'
|
|
15
|
-
import AppCompMenu from './components/AppCompMenu.vue'
|
|
16
|
-
import AppCompMenuItem from './components/AppCompMenuItem.vue'
|
|
17
|
-
import AppCompPopUpNext from './components/AppCompPopUpNext.vue'
|
|
18
|
-
import AppCompNavigation from './components/AppCompNavigation.vue'
|
|
19
|
-
import AppCompNoteCall from './components/AppCompNoteCall.vue'
|
|
20
|
-
import AppCompNoteCredit from './components/AppCompNoteCredit.vue'
|
|
21
|
-
import AppCompVideoPlayer from './components/AppCompVideoPlayer.vue'
|
|
22
|
-
import AppCompPlayBarNext from './components/AppCompPlayBarNext.vue'
|
|
23
|
-
import AppCompQuizNext from './components/AppCompQuizNext.vue'
|
|
24
|
-
import AppCompQuizRecall from './components/AppCompQuizRecall.vue'
|
|
25
|
-
|
|
26
|
-
import GsapPlugin from './plugins/gsap'
|
|
27
|
-
import eventBus from './plugins/bus'
|
|
28
|
-
import helper from './plugins/helper'
|
|
29
|
-
import mergeLocales from './plugins/i18n'
|
|
30
|
-
import { scormPlugin } from './plugins/scorm'
|
|
31
|
-
import { xapiPlugin } from './plugins/xapi'
|
|
32
|
-
import { $idb } from './plugins/idb'
|
|
33
|
-
import { validatefileContent } from './shared/validators.js'
|
|
34
|
-
import { createPinia } from 'pinia'
|
|
35
|
-
import { useAppStore } from './module/stores/appStore.js'
|
|
36
|
-
import axios from 'axios'
|
|
37
|
-
import AppCompSVGNext from './components/AppCompSVGNext.vue'
|
|
38
|
-
import VueSafeTeleport from 'vue-safe-teleport'
|
|
39
|
-
import { FocusTrap } from 'focus-trap-vue'
|
|
40
|
-
|
|
41
|
-
const pinia = createPinia()
|
|
42
|
-
|
|
43
|
-
export default {
|
|
44
|
-
install(app, options) {
|
|
45
|
-
app.use(pinia)
|
|
46
|
-
app.use(scormPlugin, '$scorm')
|
|
47
|
-
app.use(GsapPlugin, '$gsap')
|
|
48
|
-
app.use(xapiPlugin, '$xapi')
|
|
49
|
-
app.use(VueSafeTeleport)
|
|
50
|
-
app.component('FocusTrap', FocusTrap)
|
|
51
|
-
|
|
52
|
-
app.config.globalProperties.$bus = eventBus
|
|
53
|
-
app.use($idb)
|
|
54
|
-
|
|
55
|
-
app.component('AppBase', AppBase)
|
|
56
|
-
app.component('AppBaseButton', AppBaseButton)
|
|
57
|
-
app.component('AppBaseModule', AppBaseModule)
|
|
58
|
-
app.component('AppBasePage', AppBasePage)
|
|
59
|
-
app.component('AppBaseFlipCard', AppBaseFlipCard)
|
|
60
|
-
app.component('AppBaseErrorDisplay', AppBaseErrorDisplay)
|
|
61
|
-
app.component('AppCompMenu', AppCompMenu)
|
|
62
|
-
//app.component('app-comp-bif', AppCompBif)
|
|
63
|
-
app.component('AppCompAudioPlayer', AppCompAudio)
|
|
64
|
-
app.component('AppCompBranchButtons', AppCompBranchButtons)
|
|
65
|
-
app.component('AppCompCarousel', AppCompCarousel)
|
|
66
|
-
app.component('AppCompMenuItem', AppCompMenuItem)
|
|
67
|
-
app.component('AppCompJauge', AppCompJauge)
|
|
68
|
-
app.component('AppCompTableOfContent', AppCompTableOfContent)
|
|
69
|
-
app.component('AppCompPopUpNext', AppCompPopUpNext)
|
|
70
|
-
app.component('AppCompNavigation', AppCompNavigation)
|
|
71
|
-
app.component('AppCompNoteCredit', AppCompNoteCredit)
|
|
72
|
-
app.component('AppCompNoteCall', AppCompNoteCall)
|
|
73
|
-
app.component('AppBasePopover', AppBasePopover)
|
|
74
|
-
app.component('AppCompVideoPlayer', AppCompVideoPlayer)
|
|
75
|
-
app.component('AppCompPlayBarNext', AppCompPlayBarNext)
|
|
76
|
-
app.component('AppCompQuizNext', AppCompQuizNext)
|
|
77
|
-
app.component('AppIconsNext', AppCompSVGNext)
|
|
78
|
-
app.component('AppCompQuizRecall', AppCompQuizRecall)
|
|
79
|
-
app.component(AppCompViewDisplay)
|
|
80
|
-
|
|
81
|
-
if (!options)
|
|
82
|
-
throw new Error(
|
|
83
|
-
'💥You did not provide i18n and vuex store. Please install and provide them.'
|
|
84
|
-
)
|
|
85
|
-
|
|
86
|
-
const requiredOptions = ['i18n', 'menuSettings']
|
|
87
|
-
const errorMissing = {
|
|
88
|
-
i18n: { a: 'Internationalisation', b: 'vue-I18n' },
|
|
89
|
-
menuSettings: { a: 'Menu Settings file', b: 'menuSettings' }
|
|
90
|
-
/// nom de composante avec l'error avec la string comme en haut
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/*Watch for appBase data received in the store
|
|
94
|
-
*To set connection Info
|
|
95
|
-
*To set the connection with indexDB
|
|
96
|
-
*To set document lang
|
|
97
|
-
*/
|
|
98
|
-
const appStore = useAppStore()
|
|
99
|
-
|
|
100
|
-
const unsubscribeToSetConfig = appStore.$onAction(
|
|
101
|
-
({
|
|
102
|
-
name, // name of the action
|
|
103
|
-
store, // store instance, same as `someStore`
|
|
104
|
-
args, // array of parameters passed to the action
|
|
105
|
-
after // hook after the action returns or resolves
|
|
106
|
-
}) => {
|
|
107
|
-
after((result) => {
|
|
108
|
-
if (name !== 'setAppConfigs') return
|
|
109
|
-
let { appConfigs } = appStore.$state
|
|
110
|
-
|
|
111
|
-
//Configure connection with the Data from appBase
|
|
112
|
-
configConnection(appConfigs).then((c) => {
|
|
113
|
-
//Save LRS CONFIGURATION TO STORE
|
|
114
|
-
appStore.lrsConfig = c
|
|
115
|
-
// Subscribe to changes in the state to save progress in localStorage when application is not in remote mode
|
|
116
|
-
if (!c.remote)
|
|
117
|
-
app.config.globalProperties.$idb
|
|
118
|
-
.openDB()
|
|
119
|
-
.then(() =>
|
|
120
|
-
app.config.globalProperties.$idb.saveState(
|
|
121
|
-
appStore,
|
|
122
|
-
appConfigs.idb_id
|
|
123
|
-
)
|
|
124
|
-
)
|
|
125
|
-
})
|
|
126
|
-
//Set document lang attribute (wcag request)
|
|
127
|
-
document.documentElement.setAttribute('lang', appConfigs.lang)
|
|
128
|
-
})
|
|
129
|
-
}
|
|
130
|
-
)
|
|
131
|
-
|
|
132
|
-
app.provide('unsubscribeToSetConfig', unsubscribeToSetConfig)
|
|
133
|
-
|
|
134
|
-
/* Check that required options are provided */
|
|
135
|
-
requiredOptions.forEach((key) => {
|
|
136
|
-
// required key is missing in $data that was passed for the page
|
|
137
|
-
if (!Object.keys(options).includes(key)) {
|
|
138
|
-
throw new Error(
|
|
139
|
-
`👉${errorMissing[key].a}👈 is not provided. Please install and provide 👉${errorMissing[key].b}👈.`
|
|
140
|
-
)
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
if (key === 'menuSettings') {
|
|
144
|
-
const mapAct = appStore.$state.thisModule.activities
|
|
145
|
-
if (!mapAct) return
|
|
146
|
-
const keys4Lesson = ['lessonTitle', ...mapAct.keys()]
|
|
147
|
-
const keys4ActivityOpt = ['title', 'subTitle']
|
|
148
|
-
const
|
|
149
|
-
const keys4Anchors = ['anchorName', 'pageRef', 'page']
|
|
150
|
-
|
|
151
|
-
const errChecked = validatefileContent(
|
|
152
|
-
'menuSettings',
|
|
153
|
-
options.menuSettings,
|
|
154
|
-
{
|
|
155
|
-
keys4Lesson,
|
|
156
|
-
|
|
157
|
-
keys4ActivityOpt,
|
|
158
|
-
keys4Anchors
|
|
159
|
-
}
|
|
160
|
-
)
|
|
161
|
-
if (errChecked) {
|
|
162
|
-
appStore.errMenuSetting = errChecked
|
|
163
|
-
} else {
|
|
164
|
-
appStore.errMenuSetting = false
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
})
|
|
168
|
-
|
|
169
|
-
window.App_DEBUGMODE = false
|
|
170
|
-
|
|
171
|
-
/* Local Method to configurate the connection info */
|
|
172
|
-
const configConnection = async (data) => {
|
|
173
|
-
if (data && data.specification !== 'xapi') return
|
|
174
|
-
|
|
175
|
-
switch (true) {
|
|
176
|
-
case window.location.origin.includes('cegepadistance.ca'): {
|
|
177
|
-
try {
|
|
178
|
-
let connectionInfo
|
|
179
|
-
|
|
180
|
-
// Accessing User && Activity Info from Url parametters
|
|
181
|
-
const queryString = window.location.search
|
|
182
|
-
const urlParams = new URLSearchParams(queryString)
|
|
183
|
-
|
|
184
|
-
//Get User && Activity info
|
|
185
|
-
if (urlParams.get('actor') && urlParams.get('activity_id')) {
|
|
186
|
-
connectionInfo = {
|
|
187
|
-
actor: JSON.parse(urlParams.get('actor')),
|
|
188
|
-
activity_id: urlParams.get('activity_id'),
|
|
189
|
-
endpoint: urlParams.get('endpoint'),
|
|
190
|
-
registration: urlParams.get('registration'),
|
|
191
|
-
remote: true
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
// Get LRS autorisation info from serveur
|
|
195
|
-
const request = await axios.get('../../configs-xapi/xapi.json')
|
|
196
|
-
|
|
197
|
-
const { basicauth } = request.data
|
|
198
|
-
|
|
199
|
-
connectionInfo.auth = basicauth
|
|
200
|
-
|
|
201
|
-
return connectionInfo
|
|
202
|
-
} catch (err) {
|
|
203
|
-
console.error('DOWNLOAD ERROR: 💥', err)
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
break
|
|
207
|
-
}
|
|
208
|
-
case window.location.origin.includes('localhost'): {
|
|
209
|
-
if (!data) return
|
|
210
|
-
let {
|
|
211
|
-
id,
|
|
212
|
-
crs_id = null,
|
|
213
|
-
actor = {
|
|
214
|
-
mbox: 'mailto:totoescargot@email.com',
|
|
215
|
-
name: 'Toto Escargot',
|
|
216
|
-
objectType: 'Agent'
|
|
217
|
-
},
|
|
218
|
-
endpointConfig = null,
|
|
219
|
-
remote = null
|
|
220
|
-
} = data
|
|
221
|
-
|
|
222
|
-
const origin = window.location.origin
|
|
223
|
-
const activity_id = crs_id
|
|
224
|
-
? `${origin}/${crs_id}/${id}`
|
|
225
|
-
: `${origin}/${id}`
|
|
226
|
-
|
|
227
|
-
if (remote == null) remote = false
|
|
228
|
-
|
|
229
|
-
if (endpointConfig == null)
|
|
230
|
-
endpointConfig = {
|
|
231
|
-
endpoint: 'https://learninglocker.cegepadistance.ca/data/xAPI/',
|
|
232
|
-
auth: 'Basic MmU4ZGQ3NTY1NDRiZWUxNmUxZWYzZDZiOThjNWVjY2YxNjVhZjIyNzpkY2Q5Zjk4OWZlYjU3MmZlZjBhNDkxZDIxNmYyNmQyY2M1YTQ4Nzlh'
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
let connectionInfo = {
|
|
236
|
-
actor,
|
|
237
|
-
activity_id,
|
|
238
|
-
remote,
|
|
239
|
-
...endpointConfig
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
return connectionInfo
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
//=================================END SET LRS INFO ====================================
|
|
248
|
-
window.setDebugMode = (mode) => {
|
|
249
|
-
appStore.appDebugMode = mode
|
|
250
|
-
const msg = mode ? 'DEBUG MODE ON' : 'DEBUG MODE OFF'
|
|
251
|
-
console.log(`🚩 ${msg}`)
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
appStore.menuSetting = options.menuSettings
|
|
255
|
-
|
|
256
|
-
//=================================SETTING PREFERENCES ====================================
|
|
257
|
-
|
|
258
|
-
//define the settings option for user preference according to the mode of App
|
|
259
|
-
let settingsOptions = {
|
|
260
|
-
autoplay: null
|
|
261
|
-
// onboarding: null,// Uncomment when ready to add onboarding in settings
|
|
262
|
-
// subtitles: null,// Uncomment when ready to add subtitle in settings
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
appStore.applicationSettings = settingsOptions
|
|
266
|
-
//=================================END SETTING PREFERENCES ====================================//
|
|
267
|
-
|
|
268
|
-
//mergeLocales
|
|
269
|
-
mergeLocales(options.i18n.global)
|
|
270
|
-
app.use(helper, '$helper')
|
|
271
|
-
}
|
|
272
|
-
}
|
|
1
|
+
import AppBase from './components/AppBase.vue'
|
|
2
|
+
import AppBaseButton from './components/AppBaseButton.vue'
|
|
3
|
+
import AppBaseModule from './components/AppBaseModule.vue'
|
|
4
|
+
import AppBasePage from './components/AppBasePage.vue'
|
|
5
|
+
import AppBaseFlipCard from './components/AppBaseFlipCard.vue'
|
|
6
|
+
import AppBasePopover from './components/AppBasePopover.vue'
|
|
7
|
+
import AppCompJauge from './components/AppCompJauge.vue'
|
|
8
|
+
import AppBaseErrorDisplay from './components/AppBaseErrorDisplay.vue'
|
|
9
|
+
//import AppCompBif from './components/AppCompBif.vue'
|
|
10
|
+
import AppCompAudio from './components/AppCompAudio.vue'
|
|
11
|
+
import AppCompBranchButtons from './components/AppCompBranchButtons.vue'
|
|
12
|
+
import AppCompCarousel from './components/AppCompCarousel.vue'
|
|
13
|
+
import AppCompViewDisplay from './components/AppCompViewDisplay.vue'
|
|
14
|
+
import AppCompTableOfContent from './components/AppCompTableOfContent.vue'
|
|
15
|
+
import AppCompMenu from './components/AppCompMenu.vue'
|
|
16
|
+
import AppCompMenuItem from './components/AppCompMenuItem.vue'
|
|
17
|
+
import AppCompPopUpNext from './components/AppCompPopUpNext.vue'
|
|
18
|
+
import AppCompNavigation from './components/AppCompNavigation.vue'
|
|
19
|
+
import AppCompNoteCall from './components/AppCompNoteCall.vue'
|
|
20
|
+
import AppCompNoteCredit from './components/AppCompNoteCredit.vue'
|
|
21
|
+
import AppCompVideoPlayer from './components/AppCompVideoPlayer.vue'
|
|
22
|
+
import AppCompPlayBarNext from './components/AppCompPlayBarNext.vue'
|
|
23
|
+
import AppCompQuizNext from './components/AppCompQuizNext.vue'
|
|
24
|
+
import AppCompQuizRecall from './components/AppCompQuizRecall.vue'
|
|
25
|
+
|
|
26
|
+
import GsapPlugin from './plugins/gsap'
|
|
27
|
+
import eventBus from './plugins/bus'
|
|
28
|
+
import helper from './plugins/helper'
|
|
29
|
+
import mergeLocales from './plugins/i18n'
|
|
30
|
+
import { scormPlugin } from './plugins/scorm'
|
|
31
|
+
import { xapiPlugin } from './plugins/xapi'
|
|
32
|
+
import { $idb } from './plugins/idb'
|
|
33
|
+
import { validatefileContent } from './shared/validators.js'
|
|
34
|
+
import { createPinia } from 'pinia'
|
|
35
|
+
import { useAppStore } from './module/stores/appStore.js'
|
|
36
|
+
import axios from 'axios'
|
|
37
|
+
import AppCompSVGNext from './components/AppCompSVGNext.vue'
|
|
38
|
+
import VueSafeTeleport from 'vue-safe-teleport'
|
|
39
|
+
import { FocusTrap } from 'focus-trap-vue'
|
|
40
|
+
|
|
41
|
+
const pinia = createPinia()
|
|
42
|
+
|
|
43
|
+
export default {
|
|
44
|
+
install(app, options) {
|
|
45
|
+
app.use(pinia)
|
|
46
|
+
app.use(scormPlugin, '$scorm')
|
|
47
|
+
app.use(GsapPlugin, '$gsap')
|
|
48
|
+
app.use(xapiPlugin, '$xapi')
|
|
49
|
+
app.use(VueSafeTeleport)
|
|
50
|
+
app.component('FocusTrap', FocusTrap)
|
|
51
|
+
|
|
52
|
+
app.config.globalProperties.$bus = eventBus
|
|
53
|
+
app.use($idb)
|
|
54
|
+
|
|
55
|
+
app.component('AppBase', AppBase)
|
|
56
|
+
app.component('AppBaseButton', AppBaseButton)
|
|
57
|
+
app.component('AppBaseModule', AppBaseModule)
|
|
58
|
+
app.component('AppBasePage', AppBasePage)
|
|
59
|
+
app.component('AppBaseFlipCard', AppBaseFlipCard)
|
|
60
|
+
app.component('AppBaseErrorDisplay', AppBaseErrorDisplay)
|
|
61
|
+
app.component('AppCompMenu', AppCompMenu)
|
|
62
|
+
//app.component('app-comp-bif', AppCompBif)
|
|
63
|
+
app.component('AppCompAudioPlayer', AppCompAudio)
|
|
64
|
+
app.component('AppCompBranchButtons', AppCompBranchButtons)
|
|
65
|
+
app.component('AppCompCarousel', AppCompCarousel)
|
|
66
|
+
app.component('AppCompMenuItem', AppCompMenuItem)
|
|
67
|
+
app.component('AppCompJauge', AppCompJauge)
|
|
68
|
+
app.component('AppCompTableOfContent', AppCompTableOfContent)
|
|
69
|
+
app.component('AppCompPopUpNext', AppCompPopUpNext)
|
|
70
|
+
app.component('AppCompNavigation', AppCompNavigation)
|
|
71
|
+
app.component('AppCompNoteCredit', AppCompNoteCredit)
|
|
72
|
+
app.component('AppCompNoteCall', AppCompNoteCall)
|
|
73
|
+
app.component('AppBasePopover', AppBasePopover)
|
|
74
|
+
app.component('AppCompVideoPlayer', AppCompVideoPlayer)
|
|
75
|
+
app.component('AppCompPlayBarNext', AppCompPlayBarNext)
|
|
76
|
+
app.component('AppCompQuizNext', AppCompQuizNext)
|
|
77
|
+
app.component('AppIconsNext', AppCompSVGNext)
|
|
78
|
+
app.component('AppCompQuizRecall', AppCompQuizRecall)
|
|
79
|
+
app.component(AppCompViewDisplay)
|
|
80
|
+
|
|
81
|
+
if (!options)
|
|
82
|
+
throw new Error(
|
|
83
|
+
'💥You did not provide i18n and vuex store. Please install and provide them.'
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
const requiredOptions = ['i18n', 'menuSettings']
|
|
87
|
+
const errorMissing = {
|
|
88
|
+
i18n: { a: 'Internationalisation', b: 'vue-I18n' },
|
|
89
|
+
menuSettings: { a: 'Menu Settings file', b: 'menuSettings' }
|
|
90
|
+
/// nom de composante avec l'error avec la string comme en haut
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/*Watch for appBase data received in the store
|
|
94
|
+
*To set connection Info
|
|
95
|
+
*To set the connection with indexDB
|
|
96
|
+
*To set document lang
|
|
97
|
+
*/
|
|
98
|
+
const appStore = useAppStore()
|
|
99
|
+
|
|
100
|
+
const unsubscribeToSetConfig = appStore.$onAction(
|
|
101
|
+
({
|
|
102
|
+
name, // name of the action
|
|
103
|
+
store, // store instance, same as `someStore`
|
|
104
|
+
args, // array of parameters passed to the action
|
|
105
|
+
after // hook after the action returns or resolves
|
|
106
|
+
}) => {
|
|
107
|
+
after((result) => {
|
|
108
|
+
if (name !== 'setAppConfigs') return
|
|
109
|
+
let { appConfigs } = appStore.$state
|
|
110
|
+
|
|
111
|
+
//Configure connection with the Data from appBase
|
|
112
|
+
configConnection(appConfigs).then((c) => {
|
|
113
|
+
//Save LRS CONFIGURATION TO STORE
|
|
114
|
+
appStore.lrsConfig = c
|
|
115
|
+
// Subscribe to changes in the state to save progress in localStorage when application is not in remote mode
|
|
116
|
+
if (!c.remote)
|
|
117
|
+
app.config.globalProperties.$idb
|
|
118
|
+
.openDB()
|
|
119
|
+
.then(() =>
|
|
120
|
+
app.config.globalProperties.$idb.saveState(
|
|
121
|
+
appStore,
|
|
122
|
+
appConfigs.idb_id
|
|
123
|
+
)
|
|
124
|
+
)
|
|
125
|
+
})
|
|
126
|
+
//Set document lang attribute (wcag request)
|
|
127
|
+
document.documentElement.setAttribute('lang', appConfigs.lang)
|
|
128
|
+
})
|
|
129
|
+
}
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
app.provide('unsubscribeToSetConfig', unsubscribeToSetConfig)
|
|
133
|
+
|
|
134
|
+
/* Check that required options are provided */
|
|
135
|
+
requiredOptions.forEach((key) => {
|
|
136
|
+
// required key is missing in $data that was passed for the page
|
|
137
|
+
if (!Object.keys(options).includes(key)) {
|
|
138
|
+
throw new Error(
|
|
139
|
+
`👉${errorMissing[key].a}👈 is not provided. Please install and provide 👉${errorMissing[key].b}👈.`
|
|
140
|
+
)
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (key === 'menuSettings') {
|
|
144
|
+
const mapAct = appStore.$state.thisModule.activities
|
|
145
|
+
if (!mapAct) return
|
|
146
|
+
const keys4Lesson = ['lessonTitle', 'lessonNumber', ...mapAct.keys()]
|
|
147
|
+
const keys4ActivityOpt = ['title', 'subTitle']
|
|
148
|
+
const keys4ActivityMandatory = ['time', 'anchors']
|
|
149
|
+
const keys4Anchors = ['anchorName', 'pageRef', 'page']
|
|
150
|
+
|
|
151
|
+
const errChecked = validatefileContent(
|
|
152
|
+
'menuSettings',
|
|
153
|
+
options.menuSettings,
|
|
154
|
+
{
|
|
155
|
+
keys4Lesson,
|
|
156
|
+
keys4ActivityMandatory,
|
|
157
|
+
keys4ActivityOpt,
|
|
158
|
+
keys4Anchors
|
|
159
|
+
}
|
|
160
|
+
)
|
|
161
|
+
if (errChecked) {
|
|
162
|
+
appStore.errMenuSetting = errChecked
|
|
163
|
+
} else {
|
|
164
|
+
appStore.errMenuSetting = false
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
})
|
|
168
|
+
|
|
169
|
+
window.App_DEBUGMODE = false
|
|
170
|
+
|
|
171
|
+
/* Local Method to configurate the connection info */
|
|
172
|
+
const configConnection = async (data) => {
|
|
173
|
+
if (data && data.specification !== 'xapi') return
|
|
174
|
+
|
|
175
|
+
switch (true) {
|
|
176
|
+
case window.location.origin.includes('cegepadistance.ca'): {
|
|
177
|
+
try {
|
|
178
|
+
let connectionInfo
|
|
179
|
+
|
|
180
|
+
// Accessing User && Activity Info from Url parametters
|
|
181
|
+
const queryString = window.location.search
|
|
182
|
+
const urlParams = new URLSearchParams(queryString)
|
|
183
|
+
|
|
184
|
+
//Get User && Activity info
|
|
185
|
+
if (urlParams.get('actor') && urlParams.get('activity_id')) {
|
|
186
|
+
connectionInfo = {
|
|
187
|
+
actor: JSON.parse(urlParams.get('actor')),
|
|
188
|
+
activity_id: urlParams.get('activity_id'),
|
|
189
|
+
endpoint: urlParams.get('endpoint'),
|
|
190
|
+
registration: urlParams.get('registration'),
|
|
191
|
+
remote: true
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
// Get LRS autorisation info from serveur
|
|
195
|
+
const request = await axios.get('../../configs-xapi/xapi.json')
|
|
196
|
+
|
|
197
|
+
const { basicauth } = request.data
|
|
198
|
+
|
|
199
|
+
connectionInfo.auth = basicauth
|
|
200
|
+
|
|
201
|
+
return connectionInfo
|
|
202
|
+
} catch (err) {
|
|
203
|
+
console.error('DOWNLOAD ERROR: 💥', err)
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
break
|
|
207
|
+
}
|
|
208
|
+
case window.location.origin.includes('localhost'): {
|
|
209
|
+
if (!data) return
|
|
210
|
+
let {
|
|
211
|
+
id,
|
|
212
|
+
crs_id = null,
|
|
213
|
+
actor = {
|
|
214
|
+
mbox: 'mailto:totoescargot@email.com',
|
|
215
|
+
name: 'Toto Escargot',
|
|
216
|
+
objectType: 'Agent'
|
|
217
|
+
},
|
|
218
|
+
endpointConfig = null,
|
|
219
|
+
remote = null
|
|
220
|
+
} = data
|
|
221
|
+
|
|
222
|
+
const origin = window.location.origin
|
|
223
|
+
const activity_id = crs_id
|
|
224
|
+
? `${origin}/${crs_id}/${id}`
|
|
225
|
+
: `${origin}/${id}`
|
|
226
|
+
|
|
227
|
+
if (remote == null) remote = false
|
|
228
|
+
|
|
229
|
+
if (endpointConfig == null)
|
|
230
|
+
endpointConfig = {
|
|
231
|
+
endpoint: 'https://learninglocker.cegepadistance.ca/data/xAPI/',
|
|
232
|
+
auth: 'Basic MmU4ZGQ3NTY1NDRiZWUxNmUxZWYzZDZiOThjNWVjY2YxNjVhZjIyNzpkY2Q5Zjk4OWZlYjU3MmZlZjBhNDkxZDIxNmYyNmQyY2M1YTQ4Nzlh'
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
let connectionInfo = {
|
|
236
|
+
actor,
|
|
237
|
+
activity_id,
|
|
238
|
+
remote,
|
|
239
|
+
...endpointConfig
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
return connectionInfo
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
//=================================END SET LRS INFO ====================================
|
|
248
|
+
window.setDebugMode = (mode) => {
|
|
249
|
+
appStore.appDebugMode = mode
|
|
250
|
+
const msg = mode ? 'DEBUG MODE ON' : 'DEBUG MODE OFF'
|
|
251
|
+
console.log(`🚩 ${msg}`)
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
appStore.menuSetting = options.menuSettings
|
|
255
|
+
|
|
256
|
+
//=================================SETTING PREFERENCES ====================================
|
|
257
|
+
|
|
258
|
+
//define the settings option for user preference according to the mode of App
|
|
259
|
+
let settingsOptions = {
|
|
260
|
+
autoplay: null
|
|
261
|
+
// onboarding: null,// Uncomment when ready to add onboarding in settings
|
|
262
|
+
// subtitles: null,// Uncomment when ready to add subtitle in settings
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
appStore.applicationSettings = settingsOptions
|
|
266
|
+
//=================================END SETTING PREFERENCES ====================================//
|
|
267
|
+
|
|
268
|
+
//mergeLocales
|
|
269
|
+
mergeLocales(options.i18n.global)
|
|
270
|
+
app.use(helper, '$helper')
|
|
271
|
+
}
|
|
272
|
+
}
|