fcad-core-dragon 2.0.0-beta.0 → 2.0.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/{.eslintrc.js → .eslintrc.cjs} +13 -18
- package/README.md +1 -1
- package/bk.scss +117 -0
- package/package.json +22 -40
- package/src/$locales/en.json +57 -19
- package/src/$locales/fr.json +66 -28
- package/src/components/AppBase.vue +790 -376
- package/src/components/AppBaseButton.vue +33 -5
- package/src/components/AppBaseErrorDisplay.vue +62 -25
- package/src/components/AppBaseModule.vue +831 -754
- package/src/components/AppBasePage.vue +60 -74
- package/src/components/AppCompAudio.vue +266 -0
- package/src/components/AppCompBranchButtons.vue +79 -89
- package/src/components/AppCompButtonProgress.vue +35 -61
- package/src/components/AppCompCarousel.vue +160 -249
- package/src/components/AppCompInputCheckBox.vue +9 -3
- package/src/components/AppCompInputDropdown.vue +2 -4
- package/src/components/AppCompInputRadio.vue +8 -15
- package/src/components/AppCompInputTextTable.vue +15 -12
- package/src/components/AppCompInputTextToFillDropdown.vue +16 -14
- package/src/components/AppCompInputTextToFillText.vue +2 -2
- package/src/components/AppCompJauge.vue +14 -3
- package/src/components/AppCompMenu.vue +284 -85
- package/src/components/AppCompMenuItem.vue +67 -92
- package/src/components/AppCompNavigation.vue +945 -0
- package/src/components/AppCompNoteCall.vue +141 -0
- package/src/components/AppCompNoteCredit.vue +267 -0
- package/src/components/AppCompPlayBar.vue +1122 -1391
- package/src/components/AppCompPlayBarProgress.vue +73 -0
- package/src/components/AppCompPopUp.vue +195 -135
- package/src/components/AppCompPopover.vue +27 -0
- package/src/components/AppCompQuiz.vue +90 -113
- package/src/components/AppCompQuizRecall.vue +277 -0
- package/src/components/AppCompSVG.vue +335 -0
- package/src/components/AppCompSettingsMenu.vue +7 -8
- package/src/components/AppCompTableOfContent.vue +264 -88
- package/src/components/AppCompTranscript.vue +19 -0
- package/src/components/AppCompVideoPlayer.vue +380 -0
- package/src/components/BaseModule.vue +37 -114
- package/src/main.js +130 -85
- package/src/mixins/$mediaMixins.js +827 -0
- package/src/mixins/$pageMixins.js +149 -115
- package/src/mixins/$quizMixins.js +12 -26
- package/src/mixins/timerMixin.js +39 -16
- package/src/module/store.js +218 -78
- package/src/module/xapi/ADL.js +90 -53
- package/src/module/xapi/Crypto/Hasher.js +8 -8
- package/src/module/xapi/Crypto/WordArray.js +6 -6
- package/src/module/xapi/Crypto/algorithms/BufferedBlockAlgorithm.js +4 -4
- package/src/module/xapi/Crypto/algorithms/C_algo.js +14 -18
- package/src/module/xapi/Crypto/algorithms/HMAC.js +1 -1
- package/src/module/xapi/Crypto/algorithms/SHA1.js +1 -1
- package/src/module/xapi/Crypto/encoders/Base.js +7 -7
- package/src/module/xapi/Crypto/encoders/Base64.js +3 -3
- package/src/module/xapi/Crypto/encoders/Hex.js +4 -3
- package/src/module/xapi/Crypto/encoders/Latin1.js +3 -3
- package/src/module/xapi/Crypto/encoders/Utf8.js +3 -3
- package/src/module/xapi/Statement/index.js +1 -1
- package/src/module/xapi/launch.js +10 -10
- package/src/module/xapi/utils.js +17 -17
- package/src/module/xapi/wrapper.js +127 -54
- package/src/module/xapi/xapiStatement.js +29 -29
- package/src/plugins/gsap.js +4 -1
- package/src/plugins/helper.js +58 -24
- package/src/plugins/i18n.js +23 -10
- package/src/plugins/idb.js +1 -0
- package/src/plugins/scorm.js +14 -14
- package/src/public/index.html +1 -1
- package/src/router/index.js +40 -0
- package/src/router/routes.js +317 -0
- package/src/shared/generalfuncs.js +91 -9
- package/src/shared/validators.js +959 -0
- package/.prettierrc.js +0 -5
- package/babel.config.js +0 -3
- package/src/components/AppBaseDragChoice.vue +0 -91
- package/src/components/AppBaseDropZone.vue +0 -112
- package/src/components/AppCompDragAndDrop.vue +0 -339
- package/src/components/AppCompInputAssociation.vue +0 -332
- package/src/components/AppCompMediaPlayer.vue +0 -365
- package/src/components/AppCompNavigationFull.vue +0 -1791
- package/src/components/AppCompToolTip.vue +0 -94
- package/src/plugins/timeManager.js +0 -77
- package/src/routes.js +0 -734
- package/vue.config.js +0 -83
|
@@ -1,45 +1,54 @@
|
|
|
1
1
|
<!--
|
|
2
|
+
----------------- MUST ADD ERROR GESTION ------------------
|
|
3
|
+
----------------- MUST ADD label terminer ------------------
|
|
4
|
+
----------------- MUST ADD css ------------------
|
|
5
|
+
|
|
2
6
|
@ Description: This component is used to display the sub menu to show the anchor of a activity.
|
|
3
7
|
@ What it does: The component show the data that was enter in menu.json and create de link to the anchor from those information. This componant must be use with app-comp-menu-Item and app-comp-menu.
|
|
4
8
|
-->
|
|
5
9
|
|
|
6
10
|
<template>
|
|
7
|
-
<
|
|
8
|
-
<
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
11
|
+
<div v-if="error" id="sidebar-submenu" :class="{ isOpen: open }">
|
|
12
|
+
<app-base-button
|
|
13
|
+
id="close-toc"
|
|
14
|
+
:title="$t('button.closePopUp')"
|
|
15
|
+
@click="close()"
|
|
16
|
+
>
|
|
17
|
+
X
|
|
18
|
+
</app-base-button>
|
|
12
19
|
|
|
13
|
-
|
|
14
|
-
<div class="box-ttl">
|
|
15
|
-
<h2>{{ title }}</h2>
|
|
20
|
+
<p class="t-act" v-html="title"></p>
|
|
16
21
|
|
|
17
|
-
|
|
18
|
-
|
|
22
|
+
<div class="box-prog-act">
|
|
23
|
+
<p>
|
|
24
|
+
{{ $t('text.activity_progress') }}
|
|
25
|
+
<span>{{ actProgress }}</span>
|
|
26
|
+
</p>
|
|
27
|
+
</div>
|
|
19
28
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
>
|
|
34
|
-
<span @click="scrollToAnchor($event)">
|
|
35
|
-
{{ anchor.anchorName }}
|
|
36
|
-
</span>
|
|
37
|
-
</b-link>
|
|
38
|
-
</div>
|
|
29
|
+
<div class="box-anchor">
|
|
30
|
+
<p class="t-toc">{{ $t('text.toc') }}</p>
|
|
31
|
+
|
|
32
|
+
<b-link
|
|
33
|
+
v-for="(anchor, index) of anchors"
|
|
34
|
+
:key="anchor.title"
|
|
35
|
+
class="toc-item"
|
|
36
|
+
:done="sectionProgress(index)"
|
|
37
|
+
@click="closeAndNextPage(anchor.path)"
|
|
38
|
+
>
|
|
39
|
+
<div class="box-text-anchor">
|
|
40
|
+
<p class="anchor-t" v-html="anchor.title"></p>
|
|
41
|
+
<p class="state">{{ $t('text.complete') }}</p>
|
|
39
42
|
</div>
|
|
40
|
-
</
|
|
43
|
+
</b-link>
|
|
41
44
|
</div>
|
|
42
|
-
</
|
|
45
|
+
</div>
|
|
46
|
+
<div v-else id="sidebar-submenu" :class="{ isOpen: open }">
|
|
47
|
+
<p>
|
|
48
|
+
Cette activité n'existe pas dans menu setting, svp l'ajouter à votre menu
|
|
49
|
+
setting
|
|
50
|
+
</p>
|
|
51
|
+
</div>
|
|
43
52
|
</template>
|
|
44
53
|
|
|
45
54
|
<script>
|
|
@@ -48,53 +57,116 @@ import { mapGetters } from 'vuex'
|
|
|
48
57
|
export default {
|
|
49
58
|
data() {
|
|
50
59
|
return {
|
|
51
|
-
//activitiSubMenu: [],
|
|
52
|
-
activityId: null,
|
|
53
60
|
title: '',
|
|
54
|
-
subtitle: '',
|
|
55
|
-
time: '',
|
|
56
61
|
anchors: [],
|
|
57
|
-
activity: ''
|
|
62
|
+
activity: '',
|
|
63
|
+
open: false,
|
|
64
|
+
menuInfo: null,
|
|
65
|
+
actProgress: null,
|
|
66
|
+
error: true
|
|
58
67
|
}
|
|
59
68
|
},
|
|
60
69
|
computed: {
|
|
61
|
-
...mapGetters([
|
|
70
|
+
...mapGetters([
|
|
71
|
+
'getMenuSettings',
|
|
72
|
+
'getAnchorsForActivity',
|
|
73
|
+
'getBifChoice',
|
|
74
|
+
'getAllCompleted',
|
|
75
|
+
'getAllActivitiesState'
|
|
76
|
+
])
|
|
77
|
+
},
|
|
78
|
+
beforeUnmount() {
|
|
79
|
+
this.$bus.$off('toggle-widget', this.onToggleWidget)
|
|
80
|
+
this.$bus.$off('close-widget', this.onCloseWidget)
|
|
81
|
+
this.$bus.$off('info-activity', this.onInfoActivity)
|
|
62
82
|
},
|
|
63
83
|
mounted() {
|
|
64
|
-
this.$bus.$on('
|
|
84
|
+
this.$bus.$on('toggle-widget', this.onToggleWidget)
|
|
85
|
+
this.$bus.$on('close-widget', this.onCloseWidget)
|
|
86
|
+
this.$bus.$on('info-activity', this.onInfoActivity)
|
|
87
|
+
},
|
|
88
|
+
methods: {
|
|
89
|
+
onInfoActivity(data) {
|
|
65
90
|
//should be condition to avoid event fireing multiple time on call
|
|
91
|
+
|
|
66
92
|
if (data) {
|
|
93
|
+
this.reset()
|
|
67
94
|
this.activity = data
|
|
68
|
-
|
|
69
|
-
this.
|
|
95
|
+
|
|
96
|
+
if (!this.getMenuSettings[data]) {
|
|
97
|
+
return (this.error = false)
|
|
98
|
+
} else {
|
|
99
|
+
this.getInfoSubMenu(data)
|
|
100
|
+
this.getProgressActivity(data)
|
|
101
|
+
}
|
|
70
102
|
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
|
|
103
|
+
},
|
|
104
|
+
onCloseWidget(data) {
|
|
105
|
+
this.open = false
|
|
106
|
+
this.$store.dispatch('updateWidgetOpen', false)
|
|
107
|
+
this.reset()
|
|
108
|
+
},
|
|
109
|
+
onToggleWidget(data) {
|
|
110
|
+
if (data == 'toc') {
|
|
111
|
+
this.open = !this.open
|
|
112
|
+
this.$store.dispatch('updateWidgetOpen', true)
|
|
113
|
+
} else {
|
|
114
|
+
this.$store.dispatch('updateWidgetOpen', false)
|
|
115
|
+
this.open = false
|
|
116
|
+
}
|
|
117
|
+
},
|
|
74
118
|
/* @Description:Get and set the section to output
|
|
75
119
|
* @params: activity {Object}: the activity which sections need to be output
|
|
76
120
|
*/
|
|
77
121
|
//
|
|
78
122
|
getInfoSubMenu(activity) {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
123
|
+
//get the anchors for this activity from the store
|
|
124
|
+
let menuInfo = this.getMenuSettings
|
|
125
|
+
|
|
126
|
+
let nb = null
|
|
127
|
+
|
|
128
|
+
//Get title are if no title construct acitivty
|
|
129
|
+
if (menuInfo[activity] && menuInfo[activity].title)
|
|
130
|
+
this.title = menuInfo[activity].title
|
|
131
|
+
|
|
132
|
+
if (activity.charAt(1) == '0' || activity.charAt(1) == 0)
|
|
133
|
+
nb = activity.substr(2)
|
|
134
|
+
else nb = activity.substr(1)
|
|
135
|
+
|
|
136
|
+
this.title = `${this.$t('text.activity')} ${nb} : ${
|
|
137
|
+
menuInfo[activity].subTitle
|
|
138
|
+
}`
|
|
139
|
+
|
|
140
|
+
let count = 0
|
|
141
|
+
|
|
142
|
+
//create anchors title and path
|
|
143
|
+
if (menuInfo[activity] && menuInfo[activity].anchors) {
|
|
144
|
+
menuInfo[activity].anchors.forEach((element) => {
|
|
145
|
+
count++
|
|
146
|
+
|
|
147
|
+
//
|
|
148
|
+
let _path = null
|
|
149
|
+
let b = null
|
|
150
|
+
if (nb == 0 || nb == '0') {
|
|
151
|
+
b = `introduction`
|
|
152
|
+
} else {
|
|
153
|
+
b = `activite_${nb}`
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (element.page == 'page_1') {
|
|
157
|
+
_path = `${b}`
|
|
158
|
+
} else {
|
|
159
|
+
_path = `${b}.${element.page}`
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
let info = {
|
|
163
|
+
title: `${element.anchorName}`,
|
|
164
|
+
path: _path
|
|
165
|
+
}
|
|
166
|
+
this.anchors.push(info)
|
|
167
|
+
})
|
|
95
168
|
}
|
|
96
169
|
},
|
|
97
|
-
|
|
98
170
|
disable(data) {
|
|
99
171
|
let page = data.pageRef
|
|
100
172
|
let act = this.getAct(data.path)
|
|
@@ -112,7 +184,7 @@ export default {
|
|
|
112
184
|
}
|
|
113
185
|
},
|
|
114
186
|
getAct(data) {
|
|
115
|
-
//return
|
|
187
|
+
//return the id need it
|
|
116
188
|
if (data) {
|
|
117
189
|
if (data.substring(data.indexOf('_') + 1).length == 1) {
|
|
118
190
|
return `A0${data.substring(data.indexOf('_') + 1)}`
|
|
@@ -121,49 +193,142 @@ export default {
|
|
|
121
193
|
}
|
|
122
194
|
}
|
|
123
195
|
},
|
|
124
|
-
|
|
196
|
+
/**
|
|
197
|
+
* @description Gives gives length of completed page for an activity
|
|
198
|
+
* @param {String} idActivity
|
|
199
|
+
* @returns {Number}
|
|
125
200
|
*/
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
let
|
|
130
|
-
if (
|
|
131
|
-
|
|
132
|
-
|
|
201
|
+
getProgressActivity(idActivity) {
|
|
202
|
+
/// give all the page that are complete to the gauge
|
|
203
|
+
if (idActivity) {
|
|
204
|
+
let completed = []
|
|
205
|
+
if (this.getAllCompleted[idActivity]) {
|
|
206
|
+
completed = this.getAllCompleted[idActivity] //get all completed page for the activity
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
const allActivitiesState = JSON.parse(
|
|
210
|
+
JSON.stringify(this.getAllActivitiesState)
|
|
211
|
+
)
|
|
212
|
+
let size = allActivitiesState[idActivity]
|
|
213
|
+
? allActivitiesState[idActivity].size
|
|
214
|
+
: 0
|
|
215
|
+
|
|
216
|
+
// return pourcent of activity completion
|
|
217
|
+
this.actProgress = `${Math.round((completed.length * 100) / size)} %`
|
|
133
218
|
}
|
|
134
|
-
this.anchors = anchors
|
|
135
219
|
},
|
|
220
|
+
close() {
|
|
221
|
+
this.open = !this.open
|
|
222
|
+
this.$store.dispatch('updateWidgetOpen', this.open)
|
|
223
|
+
},
|
|
224
|
+
closeAndNextPage(NextPage) {
|
|
225
|
+
this.$router.push({ name: NextPage })
|
|
226
|
+
this.open = !this.open
|
|
227
|
+
this.$store.dispatch('updateWidgetOpen', this.open)
|
|
228
|
+
},
|
|
229
|
+
reset() {
|
|
230
|
+
this.anchors = []
|
|
231
|
+
this.activity = ''
|
|
232
|
+
},
|
|
233
|
+
sectionProgress(index) {
|
|
234
|
+
let menuInfo = this.getMenuSettings
|
|
235
|
+
let nextIndex = index + 1
|
|
236
|
+
let nextSec
|
|
237
|
+
let curSec = menuInfo[this.activity].anchors[index].pageRef
|
|
136
238
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
this.$bus.$emit('target-to-scroll', event.target)
|
|
239
|
+
let nb
|
|
240
|
+
let tabPageSec = []
|
|
241
|
+
let tabcomplete = []
|
|
242
|
+
|
|
243
|
+
if (nextIndex < menuInfo[this.activity].anchors.length) {
|
|
244
|
+
nextSec = menuInfo[this.activity].anchors[nextIndex].pageRef
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
if (nextSec != undefined) {
|
|
248
|
+
nb = parseInt(nextSec.substring(1))
|
|
249
|
+
|
|
250
|
+
while (nb > parseInt(curSec.substring(1))) {
|
|
251
|
+
nb--
|
|
252
|
+
if (nb < 10) tabPageSec.push(`P0${nb}`)
|
|
253
|
+
else tabPageSec.push(`P${nb}`)
|
|
153
254
|
}
|
|
154
|
-
}
|
|
255
|
+
} else {
|
|
256
|
+
if (menuInfo[this.activity].anchors.length == 1) {
|
|
257
|
+
let numPage = this.getAllActivitiesState[this.activity].size
|
|
258
|
+
|
|
259
|
+
for (let g = 1; g == numPage; g++) {
|
|
260
|
+
tabPageSec.push(`P${g}`)
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
if (
|
|
264
|
+
this.getAllCompleted[this.activity].length !==
|
|
265
|
+
this.getAllActivitiesState[this.activity].size
|
|
266
|
+
)
|
|
267
|
+
return false
|
|
268
|
+
}
|
|
269
|
+
tabPageSec.push(curSec)
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
let completeActPage = this.getAllCompleted[this.activity]
|
|
273
|
+
|
|
274
|
+
if (completeActPage) {
|
|
275
|
+
completeActPage.find((value) => {
|
|
276
|
+
let w = Object.keys(value)
|
|
277
|
+
tabcomplete.push(w[0])
|
|
278
|
+
})
|
|
279
|
+
|
|
280
|
+
const isSubset = (array1, array2) =>
|
|
281
|
+
array2.every((element) => array1.includes(element))
|
|
282
|
+
|
|
283
|
+
return isSubset(tabcomplete, tabPageSec)
|
|
284
|
+
}
|
|
155
285
|
}
|
|
156
286
|
}
|
|
157
287
|
}
|
|
158
288
|
</script>
|
|
159
289
|
<style lang="scss">
|
|
160
290
|
#sidebar-submenu {
|
|
291
|
+
display: none;
|
|
292
|
+
position: absolute;
|
|
293
|
+
left: 75px;
|
|
294
|
+
top: 0;
|
|
295
|
+
transition: left 0.5s ease-in-out;
|
|
296
|
+
|
|
297
|
+
&::before {
|
|
298
|
+
content: '';
|
|
299
|
+
display: block;
|
|
300
|
+
width: 0;
|
|
301
|
+
height: 0;
|
|
302
|
+
border-top: 10px solid transparent;
|
|
303
|
+
border-bottom: 10px solid transparent;
|
|
304
|
+
border-right: 10px solid;
|
|
305
|
+
|
|
306
|
+
position: absolute;
|
|
307
|
+
left: -10px;
|
|
308
|
+
top: 10px;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
&.isOpen {
|
|
312
|
+
display: block;
|
|
313
|
+
}
|
|
314
|
+
|
|
161
315
|
.b-sidebar-header {
|
|
162
316
|
display: none;
|
|
163
317
|
pointer-events: none;
|
|
164
318
|
}
|
|
165
319
|
|
|
166
|
-
.box {
|
|
320
|
+
.box-anchor {
|
|
321
|
+
.toc-item {
|
|
322
|
+
.state {
|
|
323
|
+
display: none;
|
|
324
|
+
}
|
|
325
|
+
&[done='true'] {
|
|
326
|
+
.state {
|
|
327
|
+
display: block;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
|
|
167
332
|
.box-time {
|
|
168
333
|
width: 100%;
|
|
169
334
|
padding: 10px 20px;
|
|
@@ -206,4 +371,15 @@ export default {
|
|
|
206
371
|
}
|
|
207
372
|
}
|
|
208
373
|
}
|
|
374
|
+
|
|
375
|
+
.navbar {
|
|
376
|
+
&.show,
|
|
377
|
+
&:hover {
|
|
378
|
+
.ctn-w {
|
|
379
|
+
#sidebar-submenu {
|
|
380
|
+
left: 120px;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
}
|
|
209
385
|
</style>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div id="transcript-container" v-html="content"></div>
|
|
3
|
+
</template>
|
|
4
|
+
<script>
|
|
5
|
+
export default {
|
|
6
|
+
props: {
|
|
7
|
+
content: {
|
|
8
|
+
type: String,
|
|
9
|
+
default: `Hello Wolrd!`
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
<style lang="scss">
|
|
16
|
+
#transcript-container {
|
|
17
|
+
padding: 30px;
|
|
18
|
+
}
|
|
19
|
+
</style>
|