fcad-core-dragon 2.0.0-beta.4 → 2.0.0-beta.6
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 +19 -0
- package/README.md +71 -71
- package/bk.scss +117 -117
- package/package.json +8 -8
- package/src/$locales/en.json +23 -23
- package/src/$locales/fr.json +22 -21
- package/src/assets/data/onboardingMessages.json +47 -47
- package/src/components/AppBase.vue +186 -116
- package/src/components/AppBaseButton.test.js +22 -0
- package/src/components/AppBaseButton.vue +13 -5
- package/src/components/AppBaseErrorDisplay.vue +438 -438
- package/src/components/AppBaseFlipCard.vue +84 -84
- package/src/components/AppBaseModule.vue +207 -128
- package/src/components/AppBasePage.vue +18 -45
- package/src/components/AppBasePopover.vue +41 -41
- package/src/components/AppCompAudio.vue +20 -17
- package/src/components/AppCompBranchButtons.vue +28 -70
- package/src/components/AppCompButtonProgress.vue +4 -9
- package/src/components/AppCompCarousel.vue +120 -90
- package/src/components/{AppCompTranscript.vue → AppCompContainer.vue} +8 -1
- package/src/components/AppCompInputCheckBoxNext.vue +5 -0
- package/src/components/AppCompInputDropdownNext.vue +50 -8
- package/src/components/AppCompInputRadioNext.vue +152 -152
- package/src/components/AppCompInputTextNext.vue +21 -2
- package/src/components/AppCompInputTextTableNext.vue +1 -0
- package/src/components/AppCompInputTextToFillDropdownNext.vue +8 -0
- package/src/components/AppCompInputTextToFillNext.vue +171 -171
- package/src/components/AppCompJauge.vue +74 -74
- package/src/components/AppCompMenu.vue +13 -7
- package/src/components/AppCompMenuItem.vue +228 -228
- package/src/components/AppCompNavigation.vue +43 -30
- package/src/components/AppCompNoteCall.vue +64 -38
- package/src/components/AppCompNoteCredit.vue +303 -105
- package/src/components/AppCompPlayBarNext.vue +25 -12
- package/src/components/AppCompPlayBarProgress.vue +82 -82
- package/src/components/AppCompPopUpNext.vue +1 -4
- package/src/components/AppCompQuizNext.vue +8 -4
- package/src/components/AppCompQuizRecall.vue +44 -22
- package/src/components/AppCompSVGNext.vue +2 -3
- package/src/components/AppCompSettingsMenu.vue +172 -172
- package/src/components/AppCompTableOfContent.vue +61 -62
- package/src/components/AppCompVideoPlayer.vue +17 -15
- package/src/components/AppCompViewDisplay.vue +6 -6
- package/src/components/BaseModule.vue +1 -18
- 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 +37 -32
- package/src/mixins/$mediaMixins.js +819 -819
- package/src/mixins/timerMixin.js +155 -155
- package/src/module/stores/appStore.js +59 -6
- package/src/module/xapi/ADL.js +144 -4
- 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/wrapper copy.js +1963 -0
- package/src/module/xapi/wrapper.js +121 -188
- 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 +52 -12
- package/src/plugins/i18n.js +44 -44
- 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 +8 -2
- package/src/router/routes.js +312 -312
- package/src/shared/generalfuncs.js +210 -210
- package/src/shared/validators.js +38 -179
- package/vitest.config.js +19 -0
- package/src/components/AppCompPlayBar.vue +0 -1218
|
@@ -1,228 +1,228 @@
|
|
|
1
|
-
<!--
|
|
2
|
-
@ Description: This component is used to display and create the link's to all the activity creation in module.
|
|
3
|
-
@ What it does: Goes trougth all the activity in the router and create a card that open the Table of content (appCompTableOfContent) that display the anchor.Display the title and subtitle enter in menu.json. Must be used with AppCompTableOfContent and AppCompMenu.
|
|
4
|
-
-->
|
|
5
|
-
<template>
|
|
6
|
-
<v-row v-if="activities.length" class="box-msa">
|
|
7
|
-
<v-col
|
|
8
|
-
v-for="activity of activities"
|
|
9
|
-
:key="activity.id"
|
|
10
|
-
cols="6"
|
|
11
|
-
class="menu-section-activity"
|
|
12
|
-
:aria-describedby="activity.id + '-subMenu'"
|
|
13
|
-
>
|
|
14
|
-
<router-link
|
|
15
|
-
:id="activity.id + '-subMenu'"
|
|
16
|
-
:title="activity.title"
|
|
17
|
-
:data-test="`item-menu-${activity.id}`"
|
|
18
|
-
class="btn-menu"
|
|
19
|
-
:to="{
|
|
20
|
-
name: createRoutes(activity.id)
|
|
21
|
-
}"
|
|
22
|
-
@click="startActivity(activity)"
|
|
23
|
-
>
|
|
24
|
-
<div class="menu-card" tag="article">
|
|
25
|
-
<v-row>
|
|
26
|
-
<div v-if="activity.subtitle === undefined" class="title">
|
|
27
|
-
<h4 v-html="activity.title"></h4>
|
|
28
|
-
</div>
|
|
29
|
-
<div v-else class="title">
|
|
30
|
-
<h4 v-html="`${activity.title} : ${activity.subtitle}`"></h4>
|
|
31
|
-
</div>
|
|
32
|
-
|
|
33
|
-
<div class="cnt-time">
|
|
34
|
-
<svg :aria-label="$t('label.timer')">
|
|
35
|
-
<use href="#clock-icon" />
|
|
36
|
-
</svg>
|
|
37
|
-
<p class="time">
|
|
38
|
-
{{ activity.time || '00:00' }}
|
|
39
|
-
</p>
|
|
40
|
-
</div>
|
|
41
|
-
<div class="box-gauge">
|
|
42
|
-
<app-comp-jauge
|
|
43
|
-
:max-value="getActivitySize(activity.id)"
|
|
44
|
-
:value="getPageComplete(activity.id)"
|
|
45
|
-
/>
|
|
46
|
-
</div>
|
|
47
|
-
</v-row>
|
|
48
|
-
</div>
|
|
49
|
-
</router-link>
|
|
50
|
-
</v-col>
|
|
51
|
-
</v-row>
|
|
52
|
-
</template>
|
|
53
|
-
<script>
|
|
54
|
-
// ...
|
|
55
|
-
import { mapState } from 'pinia'
|
|
56
|
-
import { useAppStore } from '../module/stores/appStore'
|
|
57
|
-
import AppCompJauge from './AppCompJauge.vue'
|
|
58
|
-
export default {
|
|
59
|
-
components: {
|
|
60
|
-
AppCompJauge
|
|
61
|
-
},
|
|
62
|
-
computed: {
|
|
63
|
-
...mapState(useAppStore, [
|
|
64
|
-
'getAllActivities',
|
|
65
|
-
'getAllActivitiesState',
|
|
66
|
-
'getAllCompleted',
|
|
67
|
-
'getAppConfigs',
|
|
68
|
-
'getMenuSettings',
|
|
69
|
-
'getModuleInfo'
|
|
70
|
-
]),
|
|
71
|
-
activities() {
|
|
72
|
-
// get the data for list of the page for this module from the store and
|
|
73
|
-
// get the route of the page from the router to build the menu with its routes
|
|
74
|
-
let count = 0
|
|
75
|
-
const collection = []
|
|
76
|
-
|
|
77
|
-
this.getAllActivities().list.forEach((value, key) => {
|
|
78
|
-
let theActivity,
|
|
79
|
-
activityTitle,
|
|
80
|
-
activitySubTitle,
|
|
81
|
-
activityTime = null,
|
|
82
|
-
activityPath = ''
|
|
83
|
-
|
|
84
|
-
if (this.menuInfo[key]) {
|
|
85
|
-
const { title, subTitle, time } = this.menuInfo[key] //get time subTitle time from menu info
|
|
86
|
-
//set the title
|
|
87
|
-
if (title && title != ' ') activityTitle = title
|
|
88
|
-
//set the subtitle
|
|
89
|
-
if (subTitle && subTitle != ' ') activitySubTitle = subTitle
|
|
90
|
-
//set the time
|
|
91
|
-
if (time && time != ' ') activityTime = time
|
|
92
|
-
}
|
|
93
|
-
// This is the Introduction
|
|
94
|
-
if (key === 'A00') {
|
|
95
|
-
activityTitle = activityTitle || this.$t('text.introduction')
|
|
96
|
-
activityPath = 'introduction'
|
|
97
|
-
} else if (key === 'A99') {
|
|
98
|
-
activityTitle = activityTitle || this.$t('text.conclusion')
|
|
99
|
-
activityPath = 'conclusion'
|
|
100
|
-
} else {
|
|
101
|
-
count++
|
|
102
|
-
activityTitle =
|
|
103
|
-
activityTitle || `${this.$t('text.activity')} ${count}`
|
|
104
|
-
activityPath = `activite_${count}`
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
theActivity = {
|
|
108
|
-
id: key,
|
|
109
|
-
title: activityTitle,
|
|
110
|
-
subtitle: activitySubTitle,
|
|
111
|
-
time: activityTime,
|
|
112
|
-
path: activityPath,
|
|
113
|
-
data: value
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
collection.push(theActivity) // push the activity in the collection
|
|
117
|
-
})
|
|
118
|
-
|
|
119
|
-
return collection
|
|
120
|
-
},
|
|
121
|
-
menuInfo() {
|
|
122
|
-
let menuInfo = this.getMenuSettings
|
|
123
|
-
return menuInfo
|
|
124
|
-
}
|
|
125
|
-
},
|
|
126
|
-
mounted() {},
|
|
127
|
-
methods: {
|
|
128
|
-
/**
|
|
129
|
-
* @description Gives gives length of completed page for an activity
|
|
130
|
-
* @param {String} idActivity
|
|
131
|
-
* @returns {Number}
|
|
132
|
-
*/
|
|
133
|
-
getPageComplete(idActivity) {
|
|
134
|
-
/// give all the page that are complete to the gauge
|
|
135
|
-
if (idActivity) {
|
|
136
|
-
let completed = []
|
|
137
|
-
if (this.getAllCompleted[idActivity]) {
|
|
138
|
-
completed = this.getAllCompleted[idActivity] //get all completed page for the activity
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
return completed.length
|
|
142
|
-
}
|
|
143
|
-
},
|
|
144
|
-
/**
|
|
145
|
-
* @description give the size of the state of the activity
|
|
146
|
-
* @param {String} activityID
|
|
147
|
-
* @returns {Number} size
|
|
148
|
-
*/
|
|
149
|
-
getActivitySize(activityID) {
|
|
150
|
-
/*
|
|
151
|
-
* Note:
|
|
152
|
-
* Assaging by reference would change the property of the getters when the valued are changed in the new object in. * To prevent this behaviour we will make a deep copy of the getter
|
|
153
|
-
* cf: https://reactgo.com/javascript-clone-object/
|
|
154
|
-
*/
|
|
155
|
-
|
|
156
|
-
const allActivitiesState = JSON.parse(
|
|
157
|
-
JSON.stringify(this.getAllActivitiesState)
|
|
158
|
-
)
|
|
159
|
-
let size = allActivitiesState[activityID]
|
|
160
|
-
? allActivitiesState[activityID].size
|
|
161
|
-
: 0
|
|
162
|
-
|
|
163
|
-
return size
|
|
164
|
-
},
|
|
165
|
-
createRoutes(data) {
|
|
166
|
-
let activity
|
|
167
|
-
|
|
168
|
-
if (data.charAt(1) == '0' || data.charAt(1) == 0) {
|
|
169
|
-
activity = data.substr(2)
|
|
170
|
-
} else {
|
|
171
|
-
activity = data.substr(1)
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
if (activity == 0 && activity == '0') return `introduction`
|
|
175
|
-
if (activity == '99') return `conclusion`
|
|
176
|
-
else return `activite_${activity}`
|
|
177
|
-
},
|
|
178
|
-
startActivity(a) {
|
|
179
|
-
//this.$bus.$emit('send-starting-event', a)
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
</script>
|
|
184
|
-
<style lang="scss">
|
|
185
|
-
.menu-card {
|
|
186
|
-
width: 100%;
|
|
187
|
-
padding: 24px;
|
|
188
|
-
|
|
189
|
-
.v-row {
|
|
190
|
-
margin: 0;
|
|
191
|
-
flex-direction: column;
|
|
192
|
-
|
|
193
|
-
.title {
|
|
194
|
-
flex-grow: 4;
|
|
195
|
-
width: 80%;
|
|
196
|
-
margin-bottom: 30px;
|
|
197
|
-
|
|
198
|
-
h3 {
|
|
199
|
-
text-align: left;
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
.cnt-time {
|
|
204
|
-
display: flex;
|
|
205
|
-
flex-direction: row;
|
|
206
|
-
align-items: center;
|
|
207
|
-
margin-bottom: 20px;
|
|
208
|
-
|
|
209
|
-
svg {
|
|
210
|
-
width: 18px;
|
|
211
|
-
height: 18px;
|
|
212
|
-
margin-right: 10px;
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
.box-gauge {
|
|
217
|
-
display: block;
|
|
218
|
-
width: 100%;
|
|
219
|
-
|
|
220
|
-
.box-g {
|
|
221
|
-
display: flex;
|
|
222
|
-
flex-direction: row;
|
|
223
|
-
align-items: center;
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
</style>
|
|
1
|
+
<!--
|
|
2
|
+
@ Description: This component is used to display and create the link's to all the activity creation in module.
|
|
3
|
+
@ What it does: Goes trougth all the activity in the router and create a card that open the Table of content (appCompTableOfContent) that display the anchor.Display the title and subtitle enter in menu.json. Must be used with AppCompTableOfContent and AppCompMenu.
|
|
4
|
+
-->
|
|
5
|
+
<template>
|
|
6
|
+
<v-row v-if="activities.length" class="box-msa">
|
|
7
|
+
<v-col
|
|
8
|
+
v-for="activity of activities"
|
|
9
|
+
:key="activity.id"
|
|
10
|
+
cols="6"
|
|
11
|
+
class="menu-section-activity"
|
|
12
|
+
:aria-describedby="activity.id + '-subMenu'"
|
|
13
|
+
>
|
|
14
|
+
<router-link
|
|
15
|
+
:id="activity.id + '-subMenu'"
|
|
16
|
+
:title="activity.title"
|
|
17
|
+
:data-test="`item-menu-${activity.id}`"
|
|
18
|
+
class="btn-menu"
|
|
19
|
+
:to="{
|
|
20
|
+
name: createRoutes(activity.id)
|
|
21
|
+
}"
|
|
22
|
+
@click="startActivity(activity)"
|
|
23
|
+
>
|
|
24
|
+
<div class="menu-card" tag="article">
|
|
25
|
+
<v-row>
|
|
26
|
+
<div v-if="activity.subtitle === undefined" class="title">
|
|
27
|
+
<h4 v-html="activity.title"></h4>
|
|
28
|
+
</div>
|
|
29
|
+
<div v-else class="title">
|
|
30
|
+
<h4 v-html="`${activity.title} : ${activity.subtitle}`"></h4>
|
|
31
|
+
</div>
|
|
32
|
+
|
|
33
|
+
<div class="cnt-time">
|
|
34
|
+
<svg :aria-label="$t('label.timer')">
|
|
35
|
+
<use href="#clock-icon" />
|
|
36
|
+
</svg>
|
|
37
|
+
<p class="time">
|
|
38
|
+
{{ activity.time || '00:00' }}
|
|
39
|
+
</p>
|
|
40
|
+
</div>
|
|
41
|
+
<div class="box-gauge">
|
|
42
|
+
<app-comp-jauge
|
|
43
|
+
:max-value="getActivitySize(activity.id)"
|
|
44
|
+
:value="getPageComplete(activity.id)"
|
|
45
|
+
/>
|
|
46
|
+
</div>
|
|
47
|
+
</v-row>
|
|
48
|
+
</div>
|
|
49
|
+
</router-link>
|
|
50
|
+
</v-col>
|
|
51
|
+
</v-row>
|
|
52
|
+
</template>
|
|
53
|
+
<script>
|
|
54
|
+
// ...
|
|
55
|
+
import { mapState } from 'pinia'
|
|
56
|
+
import { useAppStore } from '../module/stores/appStore'
|
|
57
|
+
import AppCompJauge from './AppCompJauge.vue'
|
|
58
|
+
export default {
|
|
59
|
+
components: {
|
|
60
|
+
AppCompJauge
|
|
61
|
+
},
|
|
62
|
+
computed: {
|
|
63
|
+
...mapState(useAppStore, [
|
|
64
|
+
'getAllActivities',
|
|
65
|
+
'getAllActivitiesState',
|
|
66
|
+
'getAllCompleted',
|
|
67
|
+
'getAppConfigs',
|
|
68
|
+
'getMenuSettings',
|
|
69
|
+
'getModuleInfo'
|
|
70
|
+
]),
|
|
71
|
+
activities() {
|
|
72
|
+
// get the data for list of the page for this module from the store and
|
|
73
|
+
// get the route of the page from the router to build the menu with its routes
|
|
74
|
+
let count = 0
|
|
75
|
+
const collection = []
|
|
76
|
+
|
|
77
|
+
this.getAllActivities().list.forEach((value, key) => {
|
|
78
|
+
let theActivity,
|
|
79
|
+
activityTitle,
|
|
80
|
+
activitySubTitle,
|
|
81
|
+
activityTime = null,
|
|
82
|
+
activityPath = ''
|
|
83
|
+
|
|
84
|
+
if (this.menuInfo[key]) {
|
|
85
|
+
const { title, subTitle, time } = this.menuInfo[key] //get time subTitle time from menu info
|
|
86
|
+
//set the title
|
|
87
|
+
if (title && title != ' ') activityTitle = title
|
|
88
|
+
//set the subtitle
|
|
89
|
+
if (subTitle && subTitle != ' ') activitySubTitle = subTitle
|
|
90
|
+
//set the time
|
|
91
|
+
if (time && time != ' ') activityTime = time
|
|
92
|
+
}
|
|
93
|
+
// This is the Introduction
|
|
94
|
+
if (key === 'A00') {
|
|
95
|
+
activityTitle = activityTitle || this.$t('text.introduction')
|
|
96
|
+
activityPath = 'introduction'
|
|
97
|
+
} else if (key === 'A99') {
|
|
98
|
+
activityTitle = activityTitle || this.$t('text.conclusion')
|
|
99
|
+
activityPath = 'conclusion'
|
|
100
|
+
} else {
|
|
101
|
+
count++
|
|
102
|
+
activityTitle =
|
|
103
|
+
activityTitle || `${this.$t('text.activity')} ${count}`
|
|
104
|
+
activityPath = `activite_${count}`
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
theActivity = {
|
|
108
|
+
id: key,
|
|
109
|
+
title: activityTitle,
|
|
110
|
+
subtitle: activitySubTitle,
|
|
111
|
+
time: activityTime,
|
|
112
|
+
path: activityPath,
|
|
113
|
+
data: value
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
collection.push(theActivity) // push the activity in the collection
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
return collection
|
|
120
|
+
},
|
|
121
|
+
menuInfo() {
|
|
122
|
+
let menuInfo = this.getMenuSettings
|
|
123
|
+
return menuInfo
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
mounted() {},
|
|
127
|
+
methods: {
|
|
128
|
+
/**
|
|
129
|
+
* @description Gives gives length of completed page for an activity
|
|
130
|
+
* @param {String} idActivity
|
|
131
|
+
* @returns {Number}
|
|
132
|
+
*/
|
|
133
|
+
getPageComplete(idActivity) {
|
|
134
|
+
/// give all the page that are complete to the gauge
|
|
135
|
+
if (idActivity) {
|
|
136
|
+
let completed = []
|
|
137
|
+
if (this.getAllCompleted[idActivity]) {
|
|
138
|
+
completed = this.getAllCompleted[idActivity] //get all completed page for the activity
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return completed.length
|
|
142
|
+
}
|
|
143
|
+
},
|
|
144
|
+
/**
|
|
145
|
+
* @description give the size of the state of the activity
|
|
146
|
+
* @param {String} activityID
|
|
147
|
+
* @returns {Number} size
|
|
148
|
+
*/
|
|
149
|
+
getActivitySize(activityID) {
|
|
150
|
+
/*
|
|
151
|
+
* Note:
|
|
152
|
+
* Assaging by reference would change the property of the getters when the valued are changed in the new object in. * To prevent this behaviour we will make a deep copy of the getter
|
|
153
|
+
* cf: https://reactgo.com/javascript-clone-object/
|
|
154
|
+
*/
|
|
155
|
+
|
|
156
|
+
const allActivitiesState = JSON.parse(
|
|
157
|
+
JSON.stringify(this.getAllActivitiesState)
|
|
158
|
+
)
|
|
159
|
+
let size = allActivitiesState[activityID]
|
|
160
|
+
? allActivitiesState[activityID].size
|
|
161
|
+
: 0
|
|
162
|
+
|
|
163
|
+
return size
|
|
164
|
+
},
|
|
165
|
+
createRoutes(data) {
|
|
166
|
+
let activity
|
|
167
|
+
|
|
168
|
+
if (data.charAt(1) == '0' || data.charAt(1) == 0) {
|
|
169
|
+
activity = data.substr(2)
|
|
170
|
+
} else {
|
|
171
|
+
activity = data.substr(1)
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
if (activity == 0 && activity == '0') return `introduction`
|
|
175
|
+
if (activity == '99') return `conclusion`
|
|
176
|
+
else return `activite_${activity}`
|
|
177
|
+
},
|
|
178
|
+
startActivity(a) {
|
|
179
|
+
//this.$bus.$emit('send-starting-event', a)
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
</script>
|
|
184
|
+
<style lang="scss">
|
|
185
|
+
.menu-card {
|
|
186
|
+
width: 100%;
|
|
187
|
+
padding: 24px;
|
|
188
|
+
|
|
189
|
+
.v-row {
|
|
190
|
+
margin: 0;
|
|
191
|
+
flex-direction: column;
|
|
192
|
+
|
|
193
|
+
.title {
|
|
194
|
+
flex-grow: 4;
|
|
195
|
+
width: 80%;
|
|
196
|
+
margin-bottom: 30px;
|
|
197
|
+
|
|
198
|
+
h3 {
|
|
199
|
+
text-align: left;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
.cnt-time {
|
|
204
|
+
display: flex;
|
|
205
|
+
flex-direction: row;
|
|
206
|
+
align-items: center;
|
|
207
|
+
margin-bottom: 20px;
|
|
208
|
+
|
|
209
|
+
svg {
|
|
210
|
+
width: 18px;
|
|
211
|
+
height: 18px;
|
|
212
|
+
margin-right: 10px;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
.box-gauge {
|
|
217
|
+
display: block;
|
|
218
|
+
width: 100%;
|
|
219
|
+
|
|
220
|
+
.box-g {
|
|
221
|
+
display: flex;
|
|
222
|
+
flex-direction: row;
|
|
223
|
+
align-items: center;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
</style>
|
|
@@ -16,14 +16,14 @@
|
|
|
16
16
|
<use href="#home-icon" />
|
|
17
17
|
</svg>
|
|
18
18
|
|
|
19
|
-
<span class="toolbar_label">{{
|
|
19
|
+
<span class="toolbar_label">{{ $t('button.menu') }}</span>
|
|
20
20
|
</template>
|
|
21
21
|
</router-link>
|
|
22
22
|
<div class="ctn-w">
|
|
23
23
|
<app-base-button
|
|
24
24
|
id="toc"
|
|
25
|
-
:title="$t('button.
|
|
26
|
-
:aria-label="$t('button.
|
|
25
|
+
:title="$t('button.toc_title')"
|
|
26
|
+
:aria-label="$t('button.toc_title')"
|
|
27
27
|
@click="openToc()"
|
|
28
28
|
>
|
|
29
29
|
<svg class="toc-icon">
|
|
@@ -38,9 +38,9 @@
|
|
|
38
38
|
id="btn_infos"
|
|
39
39
|
:title="$t('button.info')"
|
|
40
40
|
:aria-label="$t('button.info')"
|
|
41
|
-
:disabled="noInfo"
|
|
42
|
-
:class="{ md_disabled: noInfo }"
|
|
43
|
-
@click="
|
|
41
|
+
:aria-disabled="!noInfo"
|
|
42
|
+
:class="{ md_disabled: !noInfo }"
|
|
43
|
+
@click="openCreditsNotes()"
|
|
44
44
|
>
|
|
45
45
|
<svg class="info-icon">
|
|
46
46
|
<use href="#info-icon" />
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
class="nav_main_btn primary_nav_btn"
|
|
62
62
|
:title="$t('button.go_to_previous_page')"
|
|
63
63
|
:aria-label="$t('button.go_to_previous_page')"
|
|
64
|
-
:is-
|
|
64
|
+
:is-disabled="!backAllowed"
|
|
65
65
|
@click="goPrevious"
|
|
66
66
|
>
|
|
67
67
|
<svg>
|
|
@@ -83,7 +83,7 @@
|
|
|
83
83
|
class="nav_main_btn primary_nav_btn"
|
|
84
84
|
:aria-label="$t('button.go_to_next_page')"
|
|
85
85
|
:title="$t('button.go_to_next_page')"
|
|
86
|
-
:is-
|
|
86
|
+
:is-disabled="!nextAllowed"
|
|
87
87
|
@click="goNext"
|
|
88
88
|
>
|
|
89
89
|
<svg>
|
|
@@ -145,7 +145,9 @@ export default {
|
|
|
145
145
|
anchors: [],
|
|
146
146
|
pageInfo: null,
|
|
147
147
|
nextActivity: null,
|
|
148
|
-
nextActivityRoute: null
|
|
148
|
+
nextActivityRoute: null,
|
|
149
|
+
notes: null,
|
|
150
|
+
credits: null
|
|
149
151
|
}
|
|
150
152
|
},
|
|
151
153
|
computed: {
|
|
@@ -159,16 +161,26 @@ export default {
|
|
|
159
161
|
'getBifChoice',
|
|
160
162
|
'getMenuSettings',
|
|
161
163
|
'getWidgetOpen',
|
|
162
|
-
'getDataNoteCredit',
|
|
163
164
|
'getPopStatus',
|
|
164
|
-
'getEndPopUp'
|
|
165
|
+
'getEndPopUp',
|
|
166
|
+
'getNotes',
|
|
167
|
+
'getCredits'
|
|
165
168
|
]),
|
|
166
169
|
noInfo() {
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
+
return this.infoNotes.length > 0 || this.infoCredits.length > 0
|
|
171
|
+
},
|
|
172
|
+
infoNotes() {
|
|
173
|
+
let active = this.$route.meta.activity_ref
|
|
174
|
+
let page = this.$route.meta.id
|
|
175
|
+
let notes = this.getNotes(active, page)
|
|
176
|
+
return notes
|
|
177
|
+
},
|
|
178
|
+
infoCredits() {
|
|
179
|
+
let active = this.$route.meta.activity_ref
|
|
180
|
+
let page = this.$route.meta.id
|
|
181
|
+
let credits = this.getCredits(active, page)
|
|
182
|
+
return credits
|
|
170
183
|
},
|
|
171
|
-
|
|
172
184
|
/// MUST BE MODIFY BECAUSE MENU IS VIEW NOW
|
|
173
185
|
pagination() {
|
|
174
186
|
let p = { counter: null, total: null }
|
|
@@ -248,12 +260,13 @@ export default {
|
|
|
248
260
|
const activityRoutes = this.$helper.getRoutesFromVueRouter()
|
|
249
261
|
//Get the 1st route from the list of routes
|
|
250
262
|
const bckRoute = activityRoutes.meta.children[0]
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
263
|
+
const btnObj = {
|
|
264
|
+
title: noMenu
|
|
265
|
+
? this.$t('button.go_to_first_page')
|
|
266
|
+
: this.$t('button.go_to_menu'),
|
|
267
|
+
route: noMenu ? bckRoute._namedRoute : 'menu'
|
|
268
|
+
}
|
|
269
|
+
return btnObj
|
|
257
270
|
},
|
|
258
271
|
|
|
259
272
|
endActivityPopup() {
|
|
@@ -339,10 +352,12 @@ export default {
|
|
|
339
352
|
beforeUnmount() {
|
|
340
353
|
this.$bus.$off('mediaPlaybackEnded', this.onMediaEnded)
|
|
341
354
|
this.$bus.$off('quizNoAnswer', this.showPopupNoAnswer)
|
|
355
|
+
this.$bus.$off('open-notes', this.openCreditsNotes)
|
|
342
356
|
},
|
|
343
357
|
mounted() {
|
|
344
358
|
this.$bus.$on('mediaPlaybackEnded', this.onMediaEnded)
|
|
345
359
|
this.$bus.$on('quizNoAnswer', this.showPopupNoAnswer)
|
|
360
|
+
this.$bus.$on('open-notes', this.openCreditsNotes)
|
|
346
361
|
|
|
347
362
|
this.setNavigation()
|
|
348
363
|
setTimeout(() => {
|
|
@@ -374,8 +389,6 @@ export default {
|
|
|
374
389
|
this.$helper.getNextLessonEnv(this.nextLesson)
|
|
375
390
|
)
|
|
376
391
|
|
|
377
|
-
if (!path) return this.$bus.$emit('close-popup')
|
|
378
|
-
|
|
379
392
|
this.$router.push({
|
|
380
393
|
name: path
|
|
381
394
|
})
|
|
@@ -582,10 +595,6 @@ export default {
|
|
|
582
595
|
}
|
|
583
596
|
},
|
|
584
597
|
setNavigation() {
|
|
585
|
-
// Close the info widget before navigation
|
|
586
|
-
if (this.getWidgetOpen) {
|
|
587
|
-
this.$bus.$emit('close-widget')
|
|
588
|
-
}
|
|
589
598
|
// current Route is module
|
|
590
599
|
this.currentActivity = this.$router.currentRoute.value.meta.activity_ref
|
|
591
600
|
this.currentPageId = this.$router.currentRoute.value.meta.id
|
|
@@ -815,14 +824,18 @@ export default {
|
|
|
815
824
|
/**
|
|
816
825
|
* @description - send information to open toc
|
|
817
826
|
*/ openToc() {
|
|
818
|
-
this.$bus.$emit('toggle-widget', 'toc')
|
|
827
|
+
this.$bus.$emit('toggle-widget', { type: 'toc', content: null })
|
|
819
828
|
this.$bus.$emit('info-activity', this.getCurrentPage.activityRef)
|
|
820
829
|
},
|
|
821
830
|
/**
|
|
822
831
|
* @description - send information to open credit and note
|
|
823
832
|
*/
|
|
824
|
-
|
|
825
|
-
this
|
|
833
|
+
openCreditsNotes() {
|
|
834
|
+
if (!this.noInfo) return
|
|
835
|
+
this.$bus.$emit('toggle-widget', {
|
|
836
|
+
type: 'noteCredit',
|
|
837
|
+
content: { notes: this.infoNotes, credits: this.infoCredits }
|
|
838
|
+
})
|
|
826
839
|
}
|
|
827
840
|
}
|
|
828
841
|
}
|