fcad-core-dragon 2.1.0-beta.4 → 2.1.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/.editorconfig +8 -33
- package/.prettierrc +11 -0
- package/.vscode/extensions.json +8 -0
- package/.vscode/settings.json +16 -0
- package/CHANGELOG +20 -0
- package/eslint.config.js +60 -0
- package/package.json +9 -9
- package/src/$locales/en.json +3 -3
- package/src/$locales/fr.json +3 -3
- package/src/assets/data/onboardingMessages.json +47 -47
- package/src/components/AppBase.vue +5 -6
- package/src/components/AppBaseErrorDisplay.vue +438 -438
- package/src/components/AppBaseFlipCard.vue +84 -84
- package/src/components/AppBaseModule.vue +15 -17
- package/src/components/AppBasePage.vue +91 -8
- package/src/components/AppBasePopover.vue +41 -41
- package/src/components/AppBaseSkeleton.vue +24 -3
- package/src/components/AppCompAudio.vue +12 -2
- package/src/components/AppCompInputCheckBoxNx.vue +1 -2
- package/src/components/AppCompInputRadioNx.vue +8 -2
- package/src/components/AppCompInputTextToFillDropdownNx.vue +45 -0
- package/src/components/AppCompMenu.vue +423 -423
- package/src/components/AppCompNavigation.vue +2 -2
- package/src/components/AppCompPlayBarNext.vue +123 -94
- package/src/components/AppCompPopUpNext.vue +2 -2
- package/src/components/AppCompQuizNext.vue +12 -2
- package/src/components/AppCompQuizRecall.vue +10 -4
- package/src/components/AppCompSettingsMenu.vue +172 -172
- package/src/components/AppCompTableOfContent.vue +1 -4
- package/src/components/AppCompVideoPlayer.vue +7 -0
- package/src/components/AppCompViewDisplay.vue +6 -6
- package/src/composables/useTimer.js +17 -20
- package/src/externalComps/ModuleView.vue +22 -22
- package/src/externalComps/SummaryView.vue +91 -91
- package/src/main.js +5 -5
- package/src/module/stores/appStore.js +0 -1
- 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/utils.js +167 -167
- package/src/module/xapi/verbs.js +294 -294
- package/src/module/xapi/xapiStatement.js +444 -444
- package/src/plugins/analytics.js +4 -4
- package/src/plugins/bus.js +8 -8
- package/src/plugins/gsap.js +4 -2
- package/src/plugins/helper.js +8 -4
- 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 +1 -1
- package/src/shared/validators.js +22 -6
- package/.eslintignore +0 -29
- package/.eslintrc.cjs +0 -81
- package/bk.scss +0 -117
|
@@ -1,84 +1,84 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<!--
|
|
3
|
-
inspire by : https://vuejsexamples.com/generic-flip-card-in-vue-that-allows-completely-arbitrary-content-on-each-side/
|
|
4
|
-
-->
|
|
5
|
-
<div class="flip-card" role="button" aria-pressed="false" @click="fnClick">
|
|
6
|
-
<div class="inside-card" :class="{ flip: isFlipped }">
|
|
7
|
-
<div class="front-card" name="front-card">
|
|
8
|
-
<slot name="front-card" />
|
|
9
|
-
</div>
|
|
10
|
-
<div class="back-card">
|
|
11
|
-
<slot name="back-card" />
|
|
12
|
-
</div>
|
|
13
|
-
</div>
|
|
14
|
-
</div>
|
|
15
|
-
</template>
|
|
16
|
-
<script>
|
|
17
|
-
export default {
|
|
18
|
-
props: {
|
|
19
|
-
isActive: {
|
|
20
|
-
type: Boolean,
|
|
21
|
-
default: false
|
|
22
|
-
}
|
|
23
|
-
},
|
|
24
|
-
emits: ['click'],
|
|
25
|
-
data() {
|
|
26
|
-
return {
|
|
27
|
-
isFlipped: false
|
|
28
|
-
}
|
|
29
|
-
},
|
|
30
|
-
methods: {
|
|
31
|
-
/**
|
|
32
|
-
* @fires click to parent componant or page
|
|
33
|
-
*/
|
|
34
|
-
fnClick() {
|
|
35
|
-
this.$emit('click', this.$el)
|
|
36
|
-
this.isFlipped = !this.isFlipped
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
</script>
|
|
41
|
-
<style lang="scss">
|
|
42
|
-
.flip-card {
|
|
43
|
-
height: auto;
|
|
44
|
-
cursor: pointer;
|
|
45
|
-
|
|
46
|
-
/***** Parameretre modifiable *****/
|
|
47
|
-
perspective: 100%;
|
|
48
|
-
width: 90%;
|
|
49
|
-
|
|
50
|
-
.inside-card {
|
|
51
|
-
position: relative;
|
|
52
|
-
width: 100%;
|
|
53
|
-
height: 100%;
|
|
54
|
-
|
|
55
|
-
/***** Parameretre modifiable *****/
|
|
56
|
-
transform-style: preserve-3d;
|
|
57
|
-
transition: transform 0.5s;
|
|
58
|
-
|
|
59
|
-
&.flip {
|
|
60
|
-
/***** Parameretre modifiable *****/
|
|
61
|
-
transform: rotateY(180deg);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
.front-card,
|
|
65
|
-
.back-card {
|
|
66
|
-
position: absolute;
|
|
67
|
-
width: 100%;
|
|
68
|
-
height: 100%;
|
|
69
|
-
-webkit-backface-visibility: hidden;
|
|
70
|
-
backface-visibility: hidden;
|
|
71
|
-
|
|
72
|
-
.img-flip-card {
|
|
73
|
-
width: 90%;
|
|
74
|
-
height: auto;
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
.back-card {
|
|
79
|
-
/***** Parameretre modifiable *****/
|
|
80
|
-
transform: rotateY(180deg);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
</style>
|
|
1
|
+
<template>
|
|
2
|
+
<!--
|
|
3
|
+
inspire by : https://vuejsexamples.com/generic-flip-card-in-vue-that-allows-completely-arbitrary-content-on-each-side/
|
|
4
|
+
-->
|
|
5
|
+
<div class="flip-card" role="button" aria-pressed="false" @click="fnClick">
|
|
6
|
+
<div class="inside-card" :class="{ flip: isFlipped }">
|
|
7
|
+
<div class="front-card" name="front-card">
|
|
8
|
+
<slot name="front-card" />
|
|
9
|
+
</div>
|
|
10
|
+
<div class="back-card">
|
|
11
|
+
<slot name="back-card" />
|
|
12
|
+
</div>
|
|
13
|
+
</div>
|
|
14
|
+
</div>
|
|
15
|
+
</template>
|
|
16
|
+
<script>
|
|
17
|
+
export default {
|
|
18
|
+
props: {
|
|
19
|
+
isActive: {
|
|
20
|
+
type: Boolean,
|
|
21
|
+
default: false
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
emits: ['click'],
|
|
25
|
+
data() {
|
|
26
|
+
return {
|
|
27
|
+
isFlipped: false
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
methods: {
|
|
31
|
+
/**
|
|
32
|
+
* @fires click to parent componant or page
|
|
33
|
+
*/
|
|
34
|
+
fnClick() {
|
|
35
|
+
this.$emit('click', this.$el)
|
|
36
|
+
this.isFlipped = !this.isFlipped
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
</script>
|
|
41
|
+
<style lang="scss">
|
|
42
|
+
.flip-card {
|
|
43
|
+
height: auto;
|
|
44
|
+
cursor: pointer;
|
|
45
|
+
|
|
46
|
+
/***** Parameretre modifiable *****/
|
|
47
|
+
perspective: 100%;
|
|
48
|
+
width: 90%;
|
|
49
|
+
|
|
50
|
+
.inside-card {
|
|
51
|
+
position: relative;
|
|
52
|
+
width: 100%;
|
|
53
|
+
height: 100%;
|
|
54
|
+
|
|
55
|
+
/***** Parameretre modifiable *****/
|
|
56
|
+
transform-style: preserve-3d;
|
|
57
|
+
transition: transform 0.5s;
|
|
58
|
+
|
|
59
|
+
&.flip {
|
|
60
|
+
/***** Parameretre modifiable *****/
|
|
61
|
+
transform: rotateY(180deg);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.front-card,
|
|
65
|
+
.back-card {
|
|
66
|
+
position: absolute;
|
|
67
|
+
width: 100%;
|
|
68
|
+
height: 100%;
|
|
69
|
+
-webkit-backface-visibility: hidden;
|
|
70
|
+
backface-visibility: hidden;
|
|
71
|
+
|
|
72
|
+
.img-flip-card {
|
|
73
|
+
width: 90%;
|
|
74
|
+
height: auto;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.back-card {
|
|
79
|
+
/***** Parameretre modifiable *****/
|
|
80
|
+
transform: rotateY(180deg);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
</style>
|
|
@@ -29,6 +29,8 @@
|
|
|
29
29
|
/>
|
|
30
30
|
</nav>
|
|
31
31
|
<base-module :m-data="$data">
|
|
32
|
+
|
|
33
|
+
|
|
32
34
|
<v-container
|
|
33
35
|
id="wrapper-content"
|
|
34
36
|
fluid
|
|
@@ -184,7 +186,6 @@ export default {
|
|
|
184
186
|
appReady() {
|
|
185
187
|
return this.getAppStatus === 'ready' ? true : false
|
|
186
188
|
},
|
|
187
|
-
|
|
188
189
|
hasMedia() {
|
|
189
190
|
return typeof this.hasMediaElOrTimeline === 'object'
|
|
190
191
|
},
|
|
@@ -203,7 +204,6 @@ export default {
|
|
|
203
204
|
return true
|
|
204
205
|
else return false
|
|
205
206
|
},
|
|
206
|
-
|
|
207
207
|
/**
|
|
208
208
|
* @description Set the id the module
|
|
209
209
|
*/
|
|
@@ -233,7 +233,6 @@ export default {
|
|
|
233
233
|
description = this.moduleConfig.description
|
|
234
234
|
return description
|
|
235
235
|
},
|
|
236
|
-
|
|
237
236
|
/**
|
|
238
237
|
* @description set Previous/Next can allow navigation between activities.
|
|
239
238
|
*
|
|
@@ -338,7 +337,6 @@ export default {
|
|
|
338
337
|
|
|
339
338
|
return sidebarSettings
|
|
340
339
|
},
|
|
341
|
-
|
|
342
340
|
navigationHistory() {
|
|
343
341
|
return this.getRouteHistory
|
|
344
342
|
}
|
|
@@ -521,7 +519,7 @@ export default {
|
|
|
521
519
|
lessonLabel = this.$t('text.lesson')
|
|
522
520
|
lessonNumber = this.moduleConfig.id.replace('module_', '')
|
|
523
521
|
lessonTitle = this.theTitle
|
|
524
|
-
titleString = lessonLabel + ' ' + lessonNumber + '
|
|
522
|
+
titleString = lessonLabel + ' ' + lessonNumber + ' – ' + lessonTitle
|
|
525
523
|
|
|
526
524
|
//Remove prefix for introduction or conclusion, according to isIntroConclu setting in Module.vue
|
|
527
525
|
if (typeof this.moduleConfig.isIntroConclu !== 'undefined') {
|
|
@@ -626,7 +624,7 @@ export default {
|
|
|
626
624
|
async handleKeyboardControls(evt) {
|
|
627
625
|
let { code } = evt
|
|
628
626
|
|
|
629
|
-
if (code === 'Escape' && this.rightSidebarVisible){
|
|
627
|
+
if (code === 'Escape' && this.rightSidebarVisible) {
|
|
630
628
|
this.closeSidebar(this.dynamicSidebarContent._context)
|
|
631
629
|
}
|
|
632
630
|
},
|
|
@@ -661,15 +659,15 @@ export default {
|
|
|
661
659
|
//delay animation
|
|
662
660
|
this.rightSidebarVisible = true
|
|
663
661
|
this.updatesideBIsOpen(this.rightSidebarVisible)
|
|
664
|
-
setTimeout(() => {
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
}, 100)
|
|
662
|
+
// setTimeout(() => {
|
|
663
|
+
const rightSidebarContent = this.getRightSidebar() // Emelent displayed in the sidebar-body
|
|
664
|
+
if (!rightSidebarContent) return
|
|
665
|
+
rightSidebarContent.scrollTop = 0
|
|
666
|
+
const rSidebar = document.querySelector('#right-sidebar') // the sidebar
|
|
667
|
+
rSidebar.dispatchEvent(this.rightSidebarEvent)
|
|
668
|
+
rSidebar.setAttribute('tabindex', -1)
|
|
669
|
+
this.resetFocus(rSidebar) //set focus on the sidebar
|
|
670
|
+
// }, 100)
|
|
673
671
|
},
|
|
674
672
|
/**
|
|
675
673
|
* @description close the right sidebar component
|
|
@@ -682,6 +680,7 @@ export default {
|
|
|
682
680
|
this.rightSidebarVisible = false //
|
|
683
681
|
setTimeout(() => {
|
|
684
682
|
const rSidebar = document.querySelector('#right-sidebar') // the sidebar
|
|
683
|
+
if (!rSidebar) return
|
|
685
684
|
rSidebar.setAttribute('style', 'display:none')
|
|
686
685
|
rSidebar.dispatchEvent(this.rightSidebarEvent) //this will allow to run the animation of sidebar closing 1rst
|
|
687
686
|
}, 100)
|
|
@@ -785,7 +784,6 @@ export default {
|
|
|
785
784
|
openBranchContent(branchID) {
|
|
786
785
|
this.branchingVisible = true
|
|
787
786
|
this.compID = branchID //set compenent ID
|
|
788
|
-
|
|
789
787
|
setTimeout(() => {
|
|
790
788
|
const rightSidebar = this.getRightSidebar()
|
|
791
789
|
//Should indicate that page is completed when the Rightsidebar content heigh is less then window height
|
|
@@ -847,7 +845,7 @@ export default {
|
|
|
847
845
|
|
|
848
846
|
return new Promise((res) => {
|
|
849
847
|
this.$bus.$emit('set-comp-status', 'appBaseModule', 'loading')
|
|
850
|
-
this.updateCurrentTimeline(
|
|
848
|
+
this.updateCurrentTimeline(null)
|
|
851
849
|
this.updateCurrentMediaElements([])
|
|
852
850
|
// this.updateCurrentPage({})
|
|
853
851
|
this.$bus.$emit('set-comp-status', 'appBaseModule', 'ready')
|
|
@@ -6,6 +6,24 @@
|
|
|
6
6
|
-->
|
|
7
7
|
<template>
|
|
8
8
|
<div :id="pageData.id" :key="pageData.id" class="app-page" role="main">
|
|
9
|
+
<div v-if="appDebugMode" class="debug-pageInfo" :class="{ open: push }">
|
|
10
|
+
<button class="w-btn" @click="push = !push"><</button>
|
|
11
|
+
<div class="ctn">
|
|
12
|
+
Activity info: Route : {{ $route.path }}
|
|
13
|
+
<br />
|
|
14
|
+
|
|
15
|
+
Activity id : {{ getDebugModeInfo.id }}
|
|
16
|
+
<br />
|
|
17
|
+
Nombre de page : {{ getDebugModeInfo.size }}
|
|
18
|
+
<br />
|
|
19
|
+
Page complete :
|
|
20
|
+
<ul>
|
|
21
|
+
<li v-for="(value, key) in getDebugModeInfo.progression" :key="key">
|
|
22
|
+
{{ value }}
|
|
23
|
+
</li>
|
|
24
|
+
</ul>
|
|
25
|
+
</div>
|
|
26
|
+
</div>
|
|
9
27
|
<slot v-if="!errorPage.length" name="content">Page</slot>
|
|
10
28
|
<app-base-error-display
|
|
11
29
|
v-else
|
|
@@ -98,7 +116,8 @@ export default {
|
|
|
98
116
|
drModeActive: null,
|
|
99
117
|
error: null,
|
|
100
118
|
id: this.pageID,
|
|
101
|
-
type: this.pageType
|
|
119
|
+
type: this.pageType,
|
|
120
|
+
push: false
|
|
102
121
|
|
|
103
122
|
//======== End PageMisins values ===================
|
|
104
123
|
}
|
|
@@ -107,8 +126,13 @@ export default {
|
|
|
107
126
|
...mapState(useAppStore, [
|
|
108
127
|
'getDataNoteCredit',
|
|
109
128
|
'getAllActivities',
|
|
110
|
-
'getApplicationSettings'
|
|
129
|
+
'getApplicationSettings',
|
|
130
|
+
'getAppDebugMode'
|
|
111
131
|
]),
|
|
132
|
+
|
|
133
|
+
appDebugMode() {
|
|
134
|
+
return this.getAppDebugMode
|
|
135
|
+
},
|
|
112
136
|
getRouteHistory() {
|
|
113
137
|
return this.store.getRouteHistory
|
|
114
138
|
},
|
|
@@ -130,7 +154,6 @@ export default {
|
|
|
130
154
|
},
|
|
131
155
|
|
|
132
156
|
getCurrentPage() {
|
|
133
|
-
console.log('📘 ', this.store.getCurrentPage)
|
|
134
157
|
return this.store.getCurrentPage
|
|
135
158
|
},
|
|
136
159
|
|
|
@@ -329,6 +352,25 @@ export default {
|
|
|
329
352
|
A11YTxt = A11YTxt.replace('activite', this.$t('text.activity'))
|
|
330
353
|
|
|
331
354
|
return A11YTxt.toLowerCase()
|
|
355
|
+
},
|
|
356
|
+
|
|
357
|
+
getDebugModeInfo() {
|
|
358
|
+
const allActivitiesState = JSON.parse(
|
|
359
|
+
JSON.stringify(this.getAllActivitiesState)
|
|
360
|
+
)
|
|
361
|
+
let size = allActivitiesState[this.pageData.activityRef]
|
|
362
|
+
? allActivitiesState[this.pageData.activityRef].size
|
|
363
|
+
: 0
|
|
364
|
+
|
|
365
|
+
let Pprogress = allActivitiesState[this.pageData.activityRef].progressions
|
|
366
|
+
|
|
367
|
+
let info = {
|
|
368
|
+
id: this.pageData.activityRef,
|
|
369
|
+
size: size,
|
|
370
|
+
progression: Pprogress
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
return info
|
|
332
374
|
}
|
|
333
375
|
},
|
|
334
376
|
watch: {
|
|
@@ -394,11 +436,12 @@ export default {
|
|
|
394
436
|
//Fix for firefox not updating aria-labelledby (was stuck saying Activite 1, page 1 on every pages)
|
|
395
437
|
this.$refs['page_info'].innerHTML = this.A11yPageInfo
|
|
396
438
|
|
|
397
|
-
|
|
398
|
-
this
|
|
439
|
+
// scrolling to top of only when is normal page
|
|
440
|
+
if (this.pageData && this.type === 'pg_normal')
|
|
441
|
+
this.$bus.$emit('move-to-target', 'page_info_section')
|
|
399
442
|
|
|
443
|
+
// set the state of the page when page is mounted : started or completed
|
|
400
444
|
if (this.userInteraction && this.userInteraction.state)
|
|
401
|
-
// set the state of the page to existing record if any
|
|
402
445
|
this.state = this.userInteraction.state
|
|
403
446
|
else if (
|
|
404
447
|
this.type === 'pg_menu' &&
|
|
@@ -408,7 +451,7 @@ export default {
|
|
|
408
451
|
} else this.state = 'started' // set the default state to started
|
|
409
452
|
|
|
410
453
|
this.userInteraction['state'] = this.state // add the state to the userInteraction
|
|
411
|
-
|
|
454
|
+
// handle completion status of the page.
|
|
412
455
|
if (
|
|
413
456
|
document.documentElement.scrollHeight <=
|
|
414
457
|
document.documentElement.clientHeight + 20 &&
|
|
@@ -421,15 +464,19 @@ export default {
|
|
|
421
464
|
this.updateCurrentBranchPage(this.$data)
|
|
422
465
|
}
|
|
423
466
|
|
|
424
|
-
if (this.type == 'pg_branch') return //do not proceed to add
|
|
467
|
+
if (this.type == 'pg_branch') return //do not proceed to add listener when branch page
|
|
425
468
|
|
|
426
469
|
window.addEventListener('scroll', this.onFirstScroll, { once: true }) //listener is removed when event fired
|
|
427
470
|
},
|
|
428
471
|
unmounted() {
|
|
472
|
+
//cleaning up all the event listener
|
|
429
473
|
this.$bus.$off('branch-page-viewed', this.completePageBranching)
|
|
430
474
|
this.$bus.$off('media-viewed', this.setMediaViewed)
|
|
431
475
|
this.$bus.$off('manage-media-players', this.managePlayingMedia)
|
|
432
476
|
this.$bus.$off('video-transcript-toggle', this.onVideoTranscriptToggle)
|
|
477
|
+
if (!this.isBranchingPage && this.type !== 'pg_branch')
|
|
478
|
+
this.updateCurrentBranching(null) //unset current branching when leaving a branching page
|
|
479
|
+
if (this.type == 'pg_branch') this.updateCurrentBranchPage(null) //unset current branch page when leaving a branch page
|
|
433
480
|
this.$bus.$off('save-quiz-answers', this.saveQuizAnswers)
|
|
434
481
|
window.removeEventListener('scroll', this.onFirstScroll, { once: true }) //in case user did not scroll
|
|
435
482
|
window.removeEventListener('scroll', this.handleScroll)
|
|
@@ -780,4 +827,40 @@ export default {
|
|
|
780
827
|
}
|
|
781
828
|
}
|
|
782
829
|
}
|
|
830
|
+
|
|
831
|
+
.debug-pageInfo {
|
|
832
|
+
position: fixed;
|
|
833
|
+
right: -250px;
|
|
834
|
+
bottom: 20px;
|
|
835
|
+
|
|
836
|
+
color: #333;
|
|
837
|
+
background-color: rgba(#eaabb6b3, 0.9);
|
|
838
|
+
|
|
839
|
+
display: flex;
|
|
840
|
+
flex-direction: row;
|
|
841
|
+
|
|
842
|
+
&.open {
|
|
843
|
+
right: 0;
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
.w-btn {
|
|
847
|
+
padding: 10px;
|
|
848
|
+
height: 100%;
|
|
849
|
+
cursor: pointer;
|
|
850
|
+
background: rgba(#fff, 0.05);
|
|
851
|
+
|
|
852
|
+
&:hover {
|
|
853
|
+
background: rgba(#fff, 0.1);
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
.ctn {
|
|
858
|
+
padding: 24px;
|
|
859
|
+
width: 250px;
|
|
860
|
+
|
|
861
|
+
ul {
|
|
862
|
+
margin-left: 15px;
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
}
|
|
783
866
|
</style>
|
|
@@ -1,41 +1,41 @@
|
|
|
1
|
-
<!--
|
|
2
|
-
@ Description: This component is used to create a popover that is accessible via keyboard navigation (tab + space/enter)
|
|
3
|
-
-->
|
|
4
|
-
<template>
|
|
5
|
-
<v-tooltip
|
|
6
|
-
ref="tooltip"
|
|
7
|
-
v-bind="$attrs"
|
|
8
|
-
v-model="show"
|
|
9
|
-
transition="false"
|
|
10
|
-
:open-on-click="true"
|
|
11
|
-
:persistent="false"
|
|
12
|
-
>
|
|
13
|
-
<slot></slot>
|
|
14
|
-
</v-tooltip>
|
|
15
|
-
</template>
|
|
16
|
-
|
|
17
|
-
<script>
|
|
18
|
-
export default {
|
|
19
|
-
name: 'AppBasePopover',
|
|
20
|
-
data() {
|
|
21
|
-
return {
|
|
22
|
-
show: false,
|
|
23
|
-
alertContainer: null
|
|
24
|
-
}
|
|
25
|
-
},
|
|
26
|
-
watch: {
|
|
27
|
-
show: {
|
|
28
|
-
handler(newValue) {
|
|
29
|
-
if (newValue) {
|
|
30
|
-
const content = this.$refs.tooltip.contentEl.textContent
|
|
31
|
-
this.alertContainer.textContent = ''
|
|
32
|
-
this.alertContainer.textContent = content
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
},
|
|
37
|
-
mounted() {
|
|
38
|
-
this.alertContainer = document.getElementById('hiddenAlertContainer')
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
</script>
|
|
1
|
+
<!--
|
|
2
|
+
@ Description: This component is used to create a popover that is accessible via keyboard navigation (tab + space/enter)
|
|
3
|
+
-->
|
|
4
|
+
<template>
|
|
5
|
+
<v-tooltip
|
|
6
|
+
ref="tooltip"
|
|
7
|
+
v-bind="$attrs"
|
|
8
|
+
v-model="show"
|
|
9
|
+
transition="false"
|
|
10
|
+
:open-on-click="true"
|
|
11
|
+
:persistent="false"
|
|
12
|
+
>
|
|
13
|
+
<slot></slot>
|
|
14
|
+
</v-tooltip>
|
|
15
|
+
</template>
|
|
16
|
+
|
|
17
|
+
<script>
|
|
18
|
+
export default {
|
|
19
|
+
name: 'AppBasePopover',
|
|
20
|
+
data() {
|
|
21
|
+
return {
|
|
22
|
+
show: false,
|
|
23
|
+
alertContainer: null
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
watch: {
|
|
27
|
+
show: {
|
|
28
|
+
handler(newValue) {
|
|
29
|
+
if (newValue) {
|
|
30
|
+
const content = this.$refs.tooltip.contentEl.textContent
|
|
31
|
+
this.alertContainer.textContent = ''
|
|
32
|
+
this.alertContainer.textContent = content
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
mounted() {
|
|
38
|
+
this.alertContainer = document.getElementById('hiddenAlertContainer')
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
</script>
|
|
@@ -6,7 +6,27 @@
|
|
|
6
6
|
<template>
|
|
7
7
|
<div class="skeleton-wrapper">
|
|
8
8
|
<div v-if="skeletonText" class="skeleton-text">{{ skeletonText }}</div>
|
|
9
|
-
<div v-for="line in skeletonLines" :key="line" class="skeleton-line"
|
|
9
|
+
<div v-for="line in skeletonLines" :key="line" class="skeleton-line" />
|
|
10
|
+
|
|
11
|
+
<div v-show="skeletonType == `quiz-choix`">
|
|
12
|
+
<v-skeleton-loader
|
|
13
|
+
type="heading, avatar,paragraph,
|
|
14
|
+
"
|
|
15
|
+
></v-skeleton-loader>
|
|
16
|
+
<v-skeleton-loader type="avatar,paragraph"></v-skeleton-loader>
|
|
17
|
+
<v-skeleton-loader type="avatar,paragraph"></v-skeleton-loader>
|
|
18
|
+
</div>
|
|
19
|
+
|
|
20
|
+
<div v-show="skeletonType == `quiz-texte`">
|
|
21
|
+
<v-skeleton-loader
|
|
22
|
+
type="heading, image,
|
|
23
|
+
"
|
|
24
|
+
></v-skeleton-loader>
|
|
25
|
+
</div>
|
|
26
|
+
|
|
27
|
+
<div v-show="skeletonType == `quiz-recall`">
|
|
28
|
+
<v-skeleton-loader type="heading, paragraph,image"></v-skeleton-loader>
|
|
29
|
+
</div>
|
|
10
30
|
</div>
|
|
11
31
|
</template>
|
|
12
32
|
|
|
@@ -14,8 +34,9 @@
|
|
|
14
34
|
export default {
|
|
15
35
|
name: 'AppBaseSkeleton',
|
|
16
36
|
props: {
|
|
17
|
-
skeletonLines: { type: Number, default:
|
|
18
|
-
skeletonText: { type: String, default:
|
|
37
|
+
skeletonLines: { type: Number, default: 0 }, //number of skeleton lines to display
|
|
38
|
+
skeletonText: { type: String, default: `` }, //number of skeleton lines to display
|
|
39
|
+
skeletonType: { type: String, default: `line` }
|
|
19
40
|
}
|
|
20
41
|
}
|
|
21
42
|
</script>
|
|
@@ -27,7 +27,12 @@
|
|
|
27
27
|
</div>
|
|
28
28
|
<!--Audio content-->
|
|
29
29
|
<div v-show="!isLoading && !hasSourceLoadingError" class="audio-content">
|
|
30
|
-
<img
|
|
30
|
+
<img
|
|
31
|
+
v-if="mPoster"
|
|
32
|
+
class="audio-img"
|
|
33
|
+
:src="mPoster"
|
|
34
|
+
aria-hidden="true"
|
|
35
|
+
/>
|
|
31
36
|
<div class="audio-media">
|
|
32
37
|
<span>{{ mTitle }}</span>
|
|
33
38
|
<div class="audio-media-player">
|
|
@@ -88,7 +93,6 @@ export default {
|
|
|
88
93
|
mSources: this.audData.mSources,
|
|
89
94
|
mTranscript: this.audData.mTranscript,
|
|
90
95
|
mPoster: this.audData.mPoster,
|
|
91
|
-
mAlt: this.audData.mAlt ? this.audData.mAlt : ' ',
|
|
92
96
|
isSet: false,
|
|
93
97
|
hasSourceLoadingError: false,
|
|
94
98
|
hasErr: validateAudioData(this.audData)
|
|
@@ -243,4 +247,10 @@ export default {
|
|
|
243
247
|
top: 0;
|
|
244
248
|
}
|
|
245
249
|
}
|
|
250
|
+
|
|
251
|
+
.debug {
|
|
252
|
+
&:focus {
|
|
253
|
+
border: 5px solid rgba(#fff, 0.05);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
246
256
|
</style>
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
v-for="(choixReponse, index) in inputData"
|
|
12
12
|
:Key="`div_chx_${id}_${choixReponse.id}`"
|
|
13
13
|
>
|
|
14
|
-
<div class="box-checkbox"
|
|
14
|
+
<div class="box-checkbox">
|
|
15
15
|
<label
|
|
16
16
|
:key="`lbl_chx_${id}-${choixReponse.id}`"
|
|
17
17
|
:for="`boxchx_${id}_${choixReponse.id}`"
|
|
@@ -36,7 +36,6 @@
|
|
|
36
36
|
<span
|
|
37
37
|
:id="`span_${id}_${choixReponse.id}`"
|
|
38
38
|
class="checkbox-contenu"
|
|
39
|
-
aria-hidden="true"
|
|
40
39
|
v-html="choixReponse.value"
|
|
41
40
|
></span>
|
|
42
41
|
<span
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
v-for="(choixReponse, index) in quizInputDataValue"
|
|
14
14
|
:Key="`div_chx_${id}-${choixReponse.id}`"
|
|
15
15
|
>
|
|
16
|
-
<div class="box-radio"
|
|
16
|
+
<div class="box-radio">
|
|
17
17
|
<label
|
|
18
18
|
:key="`lbl_chx_${id}_${choixReponse.id}`"
|
|
19
19
|
:for="`chx_${id}_${choixReponse.id}`"
|
|
@@ -37,7 +37,6 @@
|
|
|
37
37
|
|
|
38
38
|
<span
|
|
39
39
|
:id="`span_${id}_${choixReponse.id}`"
|
|
40
|
-
aria-hidden="true"
|
|
41
40
|
class="radio-contenu"
|
|
42
41
|
v-html="choixReponse.value"
|
|
43
42
|
/>
|
|
@@ -275,4 +274,11 @@ export default {
|
|
|
275
274
|
fieldset {
|
|
276
275
|
border: inherit;
|
|
277
276
|
}
|
|
277
|
+
|
|
278
|
+
.radio-label {
|
|
279
|
+
//position: relative;
|
|
280
|
+
span {
|
|
281
|
+
width: 90%;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
278
284
|
</style>
|