fcad-core-dragon 2.1.2 → 2.2.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.gitlab-ci.yml +24 -42
- package/.vscode/settings.json +0 -30
- package/CHANGELOG +16 -0
- package/artifacts/playwright-report/index.html +85 -0
- package/package.json +29 -26
- package/src/components/AppBasePage.vue +3 -8
- package/src/components/AppCompAudio.vue +3 -3
- package/src/components/AppCompBranchButtons.vue +6 -3
- package/src/components/AppCompInputCheckBoxNx.vue +2 -1
- package/src/components/AppCompInputDropdownNx.vue +5 -5
- package/src/components/AppCompInputRadioNx.vue +2 -1
- package/src/components/AppCompInputTextNx.vue +0 -2
- package/src/components/AppCompInputTextTableNx.vue +4 -4
- package/src/components/AppCompInputTextToFillDropdownNx.vue +4 -6
- package/src/components/AppCompInputTextToFillNx.vue +1 -24
- package/src/components/AppCompNoteCredit.vue +9 -7
- package/src/components/AppCompPlayBarNext.vue +17 -11
- package/src/components/AppCompQuizRecall.vue +10 -6
- package/src/components/AppCompVideoPlayer.vue +2 -1
- package/src/main.js +20 -6
- package/src/plugins/i18n.js +8 -7
- package/tests/mocks/routes.mock.js +2 -0
- package/tests/unit/AppCompAudio.spec.js +139 -0
- package/tests/unit/AppCompBranchButtons.spec.js +172 -0
- package/tests/unit/AppCompCarousel.spec.js +62 -0
- package/tests/unit/AppCompNoteCredit.spec.js +49 -0
- package/tests/unit/AppCompVideoPlayer.spec.js +97 -102
- package/tests/unit/useQuiz.spec.js +72 -0
- package/tests/utility/colors.js +10 -0
- package/vitest.config.js +49 -23
- package/vitest.setup.js +70 -1
- package/junit-report.xml +0 -182
- package/tests/unit/AppCompQuizNext.spec.js +0 -114
package/package.json
CHANGED
|
@@ -1,33 +1,12 @@
|
|
|
1
1
|
{
|
|
2
|
-
"name": "fcad-core-dragon",
|
|
3
|
-
"version": "2.1.2",
|
|
4
|
-
"private": false,
|
|
5
|
-
"type": "module",
|
|
6
|
-
"main": "./src/main.js",
|
|
7
|
-
"scripts": {
|
|
8
|
-
"build": "vite build",
|
|
9
|
-
"dev": "vite",
|
|
10
|
-
"docs:build": "vitepress build documentation",
|
|
11
|
-
"docs:dev": "vitepress dev documentation",
|
|
12
|
-
"docs:preview": "vitepress preview documentation",
|
|
13
|
-
"lintfix": "eslint --fix src",
|
|
14
|
-
"lintreport": "eslint ./src",
|
|
15
|
-
"preview": "vite preview",
|
|
16
|
-
"reset": "rm -rf ./node_modules package-lock.json .cache dist && npm i && npm run watch",
|
|
17
|
-
"test:unit": "vitest",
|
|
18
|
-
"vue": "vue",
|
|
19
|
-
"watch": "nodemon -e js,vue,html,json -x yalc publish --push",
|
|
20
|
-
"format": "prettier --write src/",
|
|
21
|
-
"test-ct": "playwright test -c playwright-ct.config.js"
|
|
22
|
-
},
|
|
23
|
-
"config": {
|
|
24
|
-
"projname": ""
|
|
25
|
-
},
|
|
26
2
|
"browserslist": [
|
|
27
3
|
"> 1%",
|
|
28
4
|
"last 2 versions",
|
|
29
5
|
"not dead"
|
|
30
6
|
],
|
|
7
|
+
"config": {
|
|
8
|
+
"projname": ""
|
|
9
|
+
},
|
|
31
10
|
"dependencies": {
|
|
32
11
|
"axios": "^1.6.8",
|
|
33
12
|
"gsap": "^3.12.5",
|
|
@@ -44,23 +23,47 @@
|
|
|
44
23
|
"@playwright/test": "^1.56.1",
|
|
45
24
|
"@types/node": "^24.10.0",
|
|
46
25
|
"@vitejs/plugin-vue": "^6.0.1",
|
|
26
|
+
"@vitest/coverage-v8": "^4.0.15",
|
|
47
27
|
"@vue/eslint-config-prettier": "^10.2.0",
|
|
48
28
|
"@vue/test-utils": "^2.4.6",
|
|
49
29
|
"eslint": "^9.38.0",
|
|
50
30
|
"eslint-plugin-cypress": "^5.1.0",
|
|
51
31
|
"eslint-plugin-vue": "~10.3.0",
|
|
52
32
|
"globals": "^16.4.0",
|
|
33
|
+
"happy-dom": "^20.0.10",
|
|
53
34
|
"jsdom": "^25.0.1",
|
|
54
35
|
"nodemon": "^3.1.0",
|
|
55
36
|
"prettier": "^3.6.2",
|
|
56
37
|
"sass-embedded": "^1.91.0",
|
|
57
38
|
"vitepress": "^1.6.3",
|
|
58
|
-
"vitest": "^
|
|
39
|
+
"vitest": "^4.0.15",
|
|
59
40
|
"vue-i18n": "^11.1.12",
|
|
60
41
|
"vue-router": "^4.4.5",
|
|
61
42
|
"vuetify": "^3.10.10"
|
|
62
43
|
},
|
|
63
44
|
"engines": {
|
|
64
45
|
"node": ">0.11.9"
|
|
65
|
-
}
|
|
46
|
+
},
|
|
47
|
+
"main": "./src/main.js",
|
|
48
|
+
"name": "fcad-core-dragon",
|
|
49
|
+
"private": false,
|
|
50
|
+
"scripts": {
|
|
51
|
+
"build": "vite build",
|
|
52
|
+
"dev": "vite",
|
|
53
|
+
"docs:build": "vitepress build documentation",
|
|
54
|
+
"docs:dev": "vitepress dev documentation",
|
|
55
|
+
"docs:preview": "vitepress preview documentation",
|
|
56
|
+
"format": "prettier --write src/",
|
|
57
|
+
"lintfix": "eslint --fix src",
|
|
58
|
+
"lintreport": "eslint ./src",
|
|
59
|
+
"preview": "vite preview",
|
|
60
|
+
"reset": "rm -rf ./node_modules package-lock.json .cache dist && npm i && npm run watch",
|
|
61
|
+
"test-ct": "playwright test -c playwright-ct.config.js",
|
|
62
|
+
"test:unit": "vitest",
|
|
63
|
+
"test:unit:coverage": "vitest --coverage",
|
|
64
|
+
"vue": "vue",
|
|
65
|
+
"watch": "nodemon -e js,vue,html,json -x yalc publish --push"
|
|
66
|
+
},
|
|
67
|
+
"type": "module",
|
|
68
|
+
"version": "2.2.0-beta.2"
|
|
66
69
|
}
|
|
@@ -11,7 +11,6 @@
|
|
|
11
11
|
<div class="ctn">
|
|
12
12
|
Activity info: Route : {{ $route.path }}
|
|
13
13
|
<br />
|
|
14
|
-
|
|
15
14
|
Activity id : {{ getDebugModeInfo.id }}
|
|
16
15
|
<br />
|
|
17
16
|
Nombre de page : {{ getDebugModeInfo.size }}
|
|
@@ -96,6 +95,7 @@ export default {
|
|
|
96
95
|
}
|
|
97
96
|
},
|
|
98
97
|
setup(props) {
|
|
98
|
+
//console.log('dans setup')
|
|
99
99
|
const store = useAppStore()
|
|
100
100
|
const { activityRef, id: pageID, type: pageType } = props.pageData
|
|
101
101
|
const { t } = useI18n()
|
|
@@ -167,35 +167,29 @@ export default {
|
|
|
167
167
|
getModuleInfo() {
|
|
168
168
|
return this.store.getModuleInfo
|
|
169
169
|
},
|
|
170
|
-
|
|
171
170
|
getAllActivities() {
|
|
172
171
|
return this.store.getAllActivities()
|
|
173
172
|
},
|
|
174
173
|
getConnectionInfo() {
|
|
175
174
|
return this.store.getConnectionInfo
|
|
176
175
|
},
|
|
177
|
-
|
|
178
176
|
getAnchorsForActivity() {
|
|
179
177
|
return this.store.getAnchorsForActivity()
|
|
180
178
|
},
|
|
181
179
|
getBifChoice() {
|
|
182
180
|
return this.store.getBifChoice
|
|
183
181
|
},
|
|
184
|
-
|
|
185
182
|
isBranchingPage() {
|
|
186
183
|
return this.$route.meta.type === 'branching' && this.type !== 'pg_branch'
|
|
187
184
|
},
|
|
188
|
-
|
|
189
185
|
//================================================
|
|
190
186
|
settingsOptions() {
|
|
191
187
|
return this.settingsOptionsELPlus
|
|
192
188
|
},
|
|
193
|
-
|
|
194
189
|
settingsSelected() {
|
|
195
190
|
const setting = this.getApplicationSettings
|
|
196
191
|
return setting
|
|
197
192
|
},
|
|
198
|
-
|
|
199
193
|
errorPage() {
|
|
200
194
|
let err = false
|
|
201
195
|
if (import.meta.env.DEV) {
|
|
@@ -380,7 +374,8 @@ export default {
|
|
|
380
374
|
/**
|
|
381
375
|
* Observe changes in the number of poperties to dispatch updates in the userdata in the Store
|
|
382
376
|
*/
|
|
383
|
-
|
|
377
|
+
// console.log('ici')
|
|
378
|
+
//console.log(this.userInteraction)
|
|
384
379
|
if (newValue && Object.entries(this.userInteraction).length) {
|
|
385
380
|
await this.store.updateUserMetaData({
|
|
386
381
|
activityRef: this.pageData.activityRef,
|
|
@@ -107,11 +107,11 @@ export default {
|
|
|
107
107
|
...mapState(useAppStore, ['getCurrentBrowser', 'getCurrentPage']),
|
|
108
108
|
$audElement() {
|
|
109
109
|
if (!this.isSet) return null
|
|
110
|
+
const { id, mTranscript } = this.audData
|
|
110
111
|
return {
|
|
111
|
-
id
|
|
112
|
-
mTranscript
|
|
112
|
+
id,
|
|
113
|
+
mTranscript,
|
|
113
114
|
mType: 'audio',
|
|
114
|
-
mSubtitles: null,
|
|
115
115
|
mElement: this.$refs['m-audio']
|
|
116
116
|
}
|
|
117
117
|
},
|
|
@@ -250,6 +250,7 @@ export default {
|
|
|
250
250
|
this.isCard = this.cards && Object.keys(this.cards).length != 0
|
|
251
251
|
this.idActivity = this.$router.currentRoute.value.meta.activity_ref
|
|
252
252
|
this.branchs = this.$router.currentRoute.value.meta.children
|
|
253
|
+
|
|
253
254
|
this.getbranchsData()
|
|
254
255
|
},
|
|
255
256
|
methods: {
|
|
@@ -271,7 +272,7 @@ export default {
|
|
|
271
272
|
branchData.progression = progression
|
|
272
273
|
if (isNaN(branchData.progression)) branchData.progression = 0
|
|
273
274
|
|
|
274
|
-
if (this.isCard) {
|
|
275
|
+
if (this.isCard && this.getMatchingElement(branchData.id)) {
|
|
275
276
|
const { title, text, imgFile, imgAlt, btnTitle } =
|
|
276
277
|
this.getMatchingElement(branchData.id)
|
|
277
278
|
|
|
@@ -476,12 +477,14 @@ export default {
|
|
|
476
477
|
* @return {Object} Matching element from
|
|
477
478
|
*/
|
|
478
479
|
getMatchingElement(id) {
|
|
480
|
+
let matchingBranch = null
|
|
479
481
|
if (this.isCustomButton) {
|
|
480
|
-
|
|
482
|
+
matchingBranch = this.customButtons.find((c) => c.brchName === id)
|
|
481
483
|
}
|
|
482
484
|
if (this.isCard) {
|
|
483
|
-
|
|
485
|
+
matchingBranch = this.cards.find((c) => c.brchName === id)
|
|
484
486
|
}
|
|
487
|
+
return matchingBranch ? matchingBranch : null
|
|
485
488
|
}
|
|
486
489
|
}
|
|
487
490
|
}
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
:items="getItemOptions(index)"
|
|
30
30
|
:open-text="`${$t('message.dropdown_list')}_${singleDropdown.ennonce}`"
|
|
31
31
|
:aria-describedby="`${id}_${singleDropdown.id}-msg-erreur`"
|
|
32
|
+
menu-icon="mdi-chevron-down"
|
|
32
33
|
@update:model-value="onSelectUpdate($event, index)"
|
|
33
34
|
></v-select>
|
|
34
35
|
|
|
@@ -169,11 +170,10 @@ export default {
|
|
|
169
170
|
null,
|
|
170
171
|
`liste déroulante #${i + 1}`
|
|
171
172
|
)
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
}
|
|
173
|
+
if (!e || !e.errorList || !e.errorInConsole) return null
|
|
174
|
+
const { errorList, errorInConsole } = e
|
|
175
|
+
if (errorInConsole.length) errors.errorInConsole.push(errorInConsole[0])
|
|
176
|
+
if (errorList.length) errors.errorList.push(errorList[0])
|
|
177
177
|
}
|
|
178
178
|
|
|
179
179
|
return errors
|
|
@@ -129,10 +129,10 @@ export default {
|
|
|
129
129
|
`texte tableau #${i + 1}`
|
|
130
130
|
)
|
|
131
131
|
|
|
132
|
-
if (e
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
132
|
+
if (!e || !e.errorList || !e.errorInConsole) return null
|
|
133
|
+
const { errorList, errorInConsole } = e
|
|
134
|
+
if (errorInConsole.length) errors.errorInConsole.push(errorInConsole[0])
|
|
135
|
+
if (errorList.length) errors.errorList.push(errorList[0])
|
|
136
136
|
}
|
|
137
137
|
|
|
138
138
|
return errors
|
|
@@ -34,6 +34,7 @@
|
|
|
34
34
|
:items="getItemOptions(textInput.index)"
|
|
35
35
|
:aria-describedby="`${id}_${textInput.id}-msg-erreur`"
|
|
36
36
|
:aria-labelledby="`${id}_${textInput.id}-label`"
|
|
37
|
+
menu-icon="mdi-chevron-down"
|
|
37
38
|
@update:model-value="onSelectUpdate($event, textInput.index)"
|
|
38
39
|
/>
|
|
39
40
|
<span
|
|
@@ -173,7 +174,7 @@ export default {
|
|
|
173
174
|
let splittedText = str.split(regex)
|
|
174
175
|
let listInput = []
|
|
175
176
|
|
|
176
|
-
for (let i = 0; i < splittedText.length
|
|
177
|
+
for (let i = 0; i < splittedText.length; i++) {
|
|
177
178
|
listInput.push({
|
|
178
179
|
id: `text-${i}`,
|
|
179
180
|
type: 'text',
|
|
@@ -183,9 +184,10 @@ export default {
|
|
|
183
184
|
if (i < splittedText.length - 1)
|
|
184
185
|
listInput.push({ id: `select-${i}`, type: 'select', index: i })
|
|
185
186
|
}
|
|
187
|
+
|
|
186
188
|
let lI = listInput.findLast((element) => element.type == 'select')
|
|
187
|
-
this.inputCount = lI.index + 1
|
|
188
189
|
|
|
190
|
+
this.inputCount = lI.index + 1
|
|
189
191
|
this.inputElements = listInput
|
|
190
192
|
},
|
|
191
193
|
/**
|
|
@@ -299,14 +301,11 @@ fieldset {
|
|
|
299
301
|
div.texteatrou {
|
|
300
302
|
display: inline !important;
|
|
301
303
|
|
|
302
|
-
|
|
303
304
|
.cnt-input {
|
|
304
305
|
display: inline;
|
|
305
306
|
.v-input {
|
|
306
307
|
display: inline-block !important;
|
|
307
308
|
|
|
308
|
-
|
|
309
|
-
|
|
310
309
|
:deep(.v-input__control),
|
|
311
310
|
:deep(.v-field) {
|
|
312
311
|
width: 240px !important;
|
|
@@ -339,5 +338,4 @@ div.texteatrou {
|
|
|
339
338
|
}
|
|
340
339
|
}
|
|
341
340
|
}
|
|
342
|
-
|
|
343
341
|
</style>
|
|
@@ -132,29 +132,6 @@ export default {
|
|
|
132
132
|
mounted() {},
|
|
133
133
|
|
|
134
134
|
methods: {
|
|
135
|
-
/**
|
|
136
|
-
* @description validate the raw data received by the component to render is view
|
|
137
|
-
* @returns {Object} errors - errorList: to display in view and errorConsole, to be displayed in console
|
|
138
|
-
*/
|
|
139
|
-
validateInputData() {
|
|
140
|
-
let errors = null //array for errors dectected
|
|
141
|
-
let stringType = ['id', 'value']
|
|
142
|
-
|
|
143
|
-
if (!this.inputData.length) return errors
|
|
144
|
-
for (let i = 0; i < this.inputData.length; i++) {
|
|
145
|
-
errors = validateObjType(
|
|
146
|
-
this.inputData[i],
|
|
147
|
-
{ stringType },
|
|
148
|
-
null,
|
|
149
|
-
`choix_reponse #${i + 1}`
|
|
150
|
-
)
|
|
151
|
-
const { errorList, errorInConsole } = errors
|
|
152
|
-
|
|
153
|
-
if (errorList.length || errorInConsole.length) return errors
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
return errors
|
|
157
|
-
},
|
|
158
135
|
/**
|
|
159
136
|
* @description create the object to genate the text and inputs
|
|
160
137
|
* @param {String} str the text with holes to fill
|
|
@@ -165,7 +142,7 @@ export default {
|
|
|
165
142
|
let splittedText = str.split(regex)
|
|
166
143
|
let listInput = []
|
|
167
144
|
|
|
168
|
-
for (let i = 0; i < splittedText.length
|
|
145
|
+
for (let i = 0; i < splittedText.length; i++) {
|
|
169
146
|
listInput.push({
|
|
170
147
|
id: `text-${i}`,
|
|
171
148
|
type: 'text',
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
:error-text="`Vous avez une/des erreur(s) dans la création des notes/crédits.`"
|
|
27
27
|
></app-base-error-display>
|
|
28
28
|
<template v-else>
|
|
29
|
-
<div v-if="
|
|
29
|
+
<div v-if="hasNotes" class="ctn-note">
|
|
30
30
|
<p class="t-note">{{ $t('text.title_note') }}</p>
|
|
31
31
|
<div id="notes-list">
|
|
32
32
|
<template
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
</template>
|
|
63
63
|
</div>
|
|
64
64
|
</div>
|
|
65
|
-
<div v-if="
|
|
65
|
+
<div v-if="hasCredits" class="ctn-credit">
|
|
66
66
|
<p class="t-crdt">{{ $t('text.title_credit') }}</p>
|
|
67
67
|
|
|
68
68
|
<ul id="credits-list">
|
|
@@ -109,7 +109,13 @@ export default {
|
|
|
109
109
|
'getCurrentPage',
|
|
110
110
|
'getNotes',
|
|
111
111
|
'getCredits'
|
|
112
|
-
])
|
|
112
|
+
]),
|
|
113
|
+
hasNotes() {
|
|
114
|
+
return this.notes && this.notes.length
|
|
115
|
+
},
|
|
116
|
+
hasCredits() {
|
|
117
|
+
return this.credits && this.credits.length
|
|
118
|
+
}
|
|
113
119
|
},
|
|
114
120
|
created() {},
|
|
115
121
|
beforeUnmount() {
|
|
@@ -414,10 +420,6 @@ export default {
|
|
|
414
420
|
}
|
|
415
421
|
}
|
|
416
422
|
|
|
417
|
-
// .note-txt {
|
|
418
|
-
// pointer-events: none;
|
|
419
|
-
// }
|
|
420
|
-
|
|
421
423
|
.box-nc {
|
|
422
424
|
margin-top: 54px;
|
|
423
425
|
overflow-y: auto;
|
|
@@ -460,6 +460,7 @@ export default {
|
|
|
460
460
|
const timer = reactive(new Timer(id)) // Making Timer instance reactive to be able to track changes
|
|
461
461
|
const { t } = useI18n()
|
|
462
462
|
return { id, store, timer, t }
|
|
463
|
+
//return { id, store, timer }
|
|
463
464
|
},
|
|
464
465
|
data() {
|
|
465
466
|
return {
|
|
@@ -913,7 +914,7 @@ export default {
|
|
|
913
914
|
* @description - handle all the listeners for medias
|
|
914
915
|
*/
|
|
915
916
|
setMediaHandlers() {
|
|
916
|
-
if (this.mediaElement) {
|
|
917
|
+
if (this.mediaElement && this.mediaElement.addEventListener) {
|
|
917
918
|
//Prevent default on keys used for navigation in the player (prevent scrollbar to be trigger when changing volume)
|
|
918
919
|
this.pbContainer.addEventListener('keydown', this.keysPreventDefault)
|
|
919
920
|
//progressBar events
|
|
@@ -921,7 +922,7 @@ export default {
|
|
|
921
922
|
//window handlers for playbar progress
|
|
922
923
|
window.addEventListener('mousemove', this.progressWindowMove)
|
|
923
924
|
window.addEventListener('mouseup', this.progressWindowUp)
|
|
924
|
-
|
|
925
|
+
// console.log('⚠️--- TEST AppCompPlayBarNext---', this.mediaElement)
|
|
925
926
|
//Update data when media as a timeupdate/ended
|
|
926
927
|
this.mediaElement.addEventListener(
|
|
927
928
|
'timeupdate',
|
|
@@ -1580,7 +1581,10 @@ export default {
|
|
|
1580
1581
|
*/
|
|
1581
1582
|
setVideoHandlers() {
|
|
1582
1583
|
//Tooltip
|
|
1584
|
+
if (!this.progressArea || !this.progressArea.addEventListener) return
|
|
1583
1585
|
this.progressArea.addEventListener('mousemove', this.updateSeekTooltip)
|
|
1586
|
+
|
|
1587
|
+
if (!this.mediaContainer || !this.mediaContainer.addEventListener) return
|
|
1584
1588
|
//Fullscreen
|
|
1585
1589
|
this.mediaContainer.addEventListener(
|
|
1586
1590
|
'fullscreenchange',
|
|
@@ -1594,7 +1598,10 @@ export default {
|
|
|
1594
1598
|
*/
|
|
1595
1599
|
removeVideoHandlers() {
|
|
1596
1600
|
//Tooltip
|
|
1601
|
+
if (!this.progressArea || !this.progressArea.addEventListener) return
|
|
1597
1602
|
this.progressArea.removeEventListener('mousemove', this.updateSeekTooltip)
|
|
1603
|
+
if (!this.mediaContainer || !this.mediaContainer.removeEventListener)
|
|
1604
|
+
return
|
|
1598
1605
|
//Fullscreen
|
|
1599
1606
|
this.mediaContainer.removeEventListener(
|
|
1600
1607
|
'fullscreenchange',
|
|
@@ -1628,7 +1635,7 @@ export default {
|
|
|
1628
1635
|
*/
|
|
1629
1636
|
toggleFullScreen() {
|
|
1630
1637
|
const fullscreenElement = this.mediaContainer
|
|
1631
|
-
console.log(fullscreenElement)
|
|
1638
|
+
//console.log(fullscreenElement)
|
|
1632
1639
|
|
|
1633
1640
|
if (document.fullscreenElement) {
|
|
1634
1641
|
// exitFullscreen is only available on the Document object.
|
|
@@ -1777,7 +1784,8 @@ export default {
|
|
|
1777
1784
|
*/
|
|
1778
1785
|
|
|
1779
1786
|
hideControls() {
|
|
1780
|
-
|
|
1787
|
+
//Always show playbar when paused or not in fullscreen mode
|
|
1788
|
+
if (this.mediaElement.paused || !document.fullscreenElement) return
|
|
1781
1789
|
|
|
1782
1790
|
this.hideTimer = setTimeout(() => {
|
|
1783
1791
|
this.showControlsValue = false
|
|
@@ -1795,12 +1803,10 @@ export default {
|
|
|
1795
1803
|
</script>
|
|
1796
1804
|
<style lang="scss" scoped>
|
|
1797
1805
|
.pb-container.video {
|
|
1798
|
-
position: absolute;
|
|
1799
1806
|
height: 100%;
|
|
1800
1807
|
width: 100%;
|
|
1801
1808
|
justify-content: center;
|
|
1802
1809
|
display: flex;
|
|
1803
|
-
margin-bottom: 78px;
|
|
1804
1810
|
}
|
|
1805
1811
|
|
|
1806
1812
|
.playback-button {
|
|
@@ -1808,7 +1814,7 @@ export default {
|
|
|
1808
1814
|
bottom: 0;
|
|
1809
1815
|
left: 0;
|
|
1810
1816
|
width: 100%;
|
|
1811
|
-
height:
|
|
1817
|
+
height: 100%;
|
|
1812
1818
|
display: flex;
|
|
1813
1819
|
flex-flow: column wrap;
|
|
1814
1820
|
justify-content: center;
|
|
@@ -1837,8 +1843,6 @@ export default {
|
|
|
1837
1843
|
width: 100%;
|
|
1838
1844
|
display: flex;
|
|
1839
1845
|
flex-direction: column;
|
|
1840
|
-
position: absolute;
|
|
1841
|
-
bottom: -78px;
|
|
1842
1846
|
opacity: 0;
|
|
1843
1847
|
z-index: 2;
|
|
1844
1848
|
|
|
@@ -2260,8 +2264,10 @@ export default {
|
|
|
2260
2264
|
|
|
2261
2265
|
.FS {
|
|
2262
2266
|
&:fullscreen {
|
|
2263
|
-
.pb-
|
|
2264
|
-
|
|
2267
|
+
.pb-container {
|
|
2268
|
+
position: absolute;
|
|
2269
|
+
bottom: 0;
|
|
2270
|
+
height: 78px;
|
|
2265
2271
|
}
|
|
2266
2272
|
}
|
|
2267
2273
|
}
|
|
@@ -104,19 +104,14 @@ export default {
|
|
|
104
104
|
getUserInteraction: {
|
|
105
105
|
async handler(newValue) {
|
|
106
106
|
if (!this.getUserInteraction) return
|
|
107
|
-
|
|
108
107
|
const { activityId, pageId } = this.quizRecallData
|
|
109
108
|
const interaction = this.getPageInteraction(
|
|
110
109
|
activityId,
|
|
111
110
|
pageId
|
|
112
111
|
).userInteraction
|
|
113
|
-
|
|
114
|
-
if (!interaction) return
|
|
115
112
|
//Get quizRecall answer
|
|
116
113
|
if (this.quizRecallData && this.quizData) {
|
|
117
114
|
await this.getQuizRecallAnswer(interaction)
|
|
118
|
-
} else {
|
|
119
|
-
this.quizRecall.done == false
|
|
120
115
|
}
|
|
121
116
|
},
|
|
122
117
|
immediate: true,
|
|
@@ -209,6 +204,13 @@ export default {
|
|
|
209
204
|
//Get datas from quizRecallData and userData and add them to quizRecall object
|
|
210
205
|
async getQuizRecallAnswer(userData) {
|
|
211
206
|
await this.$nextTick() //wait for the DOM to update
|
|
207
|
+
//userData will be undefined if the page containing the target quiz was never visited
|
|
208
|
+
if (typeof userData === 'undefined') {
|
|
209
|
+
this.quizRecall.done = false //set quiz recall message (quiz not completed)
|
|
210
|
+
this.isReady = true //hide the skeleton
|
|
211
|
+
return
|
|
212
|
+
}
|
|
213
|
+
|
|
212
214
|
const { quizId, hypertext_done, hypertext_undone, title, titletag } =
|
|
213
215
|
this.quizRecallData
|
|
214
216
|
|
|
@@ -216,6 +218,7 @@ export default {
|
|
|
216
218
|
if (hypertext_done) {
|
|
217
219
|
this.quizRecall.hypertext_done = hypertext_done
|
|
218
220
|
}
|
|
221
|
+
|
|
219
222
|
if (hypertext_undone) {
|
|
220
223
|
this.quizRecall.hypertext_undone = hypertext_undone
|
|
221
224
|
}
|
|
@@ -231,6 +234,7 @@ export default {
|
|
|
231
234
|
}
|
|
232
235
|
}
|
|
233
236
|
//Get the quiz answers from userData
|
|
237
|
+
|
|
234
238
|
const answers = userData.quizAnswers || {}
|
|
235
239
|
let quizAnswer = answers[quizId] || null
|
|
236
240
|
|
|
@@ -243,7 +247,6 @@ export default {
|
|
|
243
247
|
this.quizRecall.answer = quizAnswer.value[0].filled || ''
|
|
244
248
|
this.quizRecall.ennonce = this.quizData.ennonce
|
|
245
249
|
}
|
|
246
|
-
this.quizRecall
|
|
247
250
|
this.isReady = true //Set isReady to true to display the component
|
|
248
251
|
},
|
|
249
252
|
|
|
@@ -301,6 +304,7 @@ export default {
|
|
|
301
304
|
)
|
|
302
305
|
this.hasError.push(msgErr)
|
|
303
306
|
}
|
|
307
|
+
|
|
304
308
|
//Validate if all required properties are present in quizRecallData
|
|
305
309
|
if (missingRequired.length > 0) {
|
|
306
310
|
let msgErr = `QuizRecallData missing required ${missingRequired} property`
|
|
@@ -282,6 +282,7 @@ export default {
|
|
|
282
282
|
resizeVideo(size, container) {
|
|
283
283
|
let defaultSize = 100
|
|
284
284
|
if (size == 'sm') defaultSize = 68
|
|
285
|
+
|
|
285
286
|
//const videoElement = document.querySelector('.__media-container')
|
|
286
287
|
const videoElement = this.$vidElement.mMediaContainer
|
|
287
288
|
setTimeout(() => {
|
|
@@ -304,7 +305,7 @@ $widthVideo: 100%;
|
|
|
304
305
|
|
|
305
306
|
.app-video-player {
|
|
306
307
|
display: flex;
|
|
307
|
-
flex-direction:
|
|
308
|
+
flex-direction: column;
|
|
308
309
|
flex-wrap: wrap;
|
|
309
310
|
position: relative;
|
|
310
311
|
align-items: center;
|
package/src/main.js
CHANGED
|
@@ -28,7 +28,7 @@ import GsapPlugin from './plugins/gsap'
|
|
|
28
28
|
import eventBus from './plugins/bus'
|
|
29
29
|
import helper from './plugins/helper'
|
|
30
30
|
import analytics from './plugins/analytics'
|
|
31
|
-
import
|
|
31
|
+
import initLocalisation from './plugins/i18n'
|
|
32
32
|
import { scormPlugin } from './plugins/scorm'
|
|
33
33
|
import { xapiPlugin } from './plugins/xapi'
|
|
34
34
|
import { $idb } from './plugins/idb'
|
|
@@ -41,19 +41,33 @@ import VueSafeTeleport from 'vue-safe-teleport'
|
|
|
41
41
|
import { FocusTrap } from 'focus-trap-vue'
|
|
42
42
|
import nvdaFix from './directives/nvdaFix.js'
|
|
43
43
|
import pckg from '../package.json'
|
|
44
|
+
import fcadRouter from './router/index.js'
|
|
45
|
+
import '@mdi/font/css/materialdesignicons.css'
|
|
46
|
+
import 'vuetify/styles'
|
|
47
|
+
import { createVuetify } from 'vuetify'
|
|
48
|
+
import { fr, en } from 'vuetify/locale'
|
|
49
|
+
|
|
44
50
|
const pinia = createPinia()
|
|
45
51
|
|
|
46
52
|
export default {
|
|
47
53
|
install(app, options) {
|
|
54
|
+
app.use(fcadRouter)
|
|
48
55
|
app.use(pinia)
|
|
49
56
|
app.use(scormPlugin)
|
|
50
57
|
app.use(GsapPlugin)
|
|
51
58
|
app.use(xapiPlugin)
|
|
52
59
|
app.use(VueSafeTeleport)
|
|
53
60
|
app.component('FocusTrap', FocusTrap)
|
|
54
|
-
|
|
55
61
|
app.use(eventBus)
|
|
56
62
|
app.use($idb)
|
|
63
|
+
const vuetify = createVuetify({
|
|
64
|
+
locale: {
|
|
65
|
+
locale: 'fr',
|
|
66
|
+
fallback: 'en',
|
|
67
|
+
messages: { fr, en }
|
|
68
|
+
}
|
|
69
|
+
})
|
|
70
|
+
app.use(vuetify)
|
|
57
71
|
|
|
58
72
|
app.component('AppBase', AppBase)
|
|
59
73
|
app.component('AppBaseButton', AppBaseButton)
|
|
@@ -332,7 +346,6 @@ export default {
|
|
|
332
346
|
|
|
333
347
|
let server = remote ? specification : 'local'
|
|
334
348
|
//falback to idb when scorm and origin is localhost
|
|
335
|
-
//falback to idb when scorm and origin is localhost
|
|
336
349
|
if (
|
|
337
350
|
(specification == 'scorm' && window.location.hostname == 'localhost') ||
|
|
338
351
|
!window.location.hostname.includes('cegepadistance.ca')
|
|
@@ -476,9 +489,10 @@ export default {
|
|
|
476
489
|
|
|
477
490
|
appStore.applicationSettings = settingsOptions
|
|
478
491
|
//=================================END SETTING PREFERENCES ====================================//
|
|
479
|
-
|
|
480
|
-
//
|
|
481
|
-
|
|
492
|
+
// const appi18b = options.i18n
|
|
493
|
+
// console.log('i18n options received in appBase plugin...', appi18b)
|
|
494
|
+
const i18n = initLocalisation(options.i18n)
|
|
495
|
+
app.use(i18n)
|
|
482
496
|
app.use(helper)
|
|
483
497
|
app.use(analytics)
|
|
484
498
|
|