fcad-core-dragon 2.0.0-beta.5 → 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 +392 -377
- package/README.md +71 -71
- package/bk.scss +117 -117
- package/package.json +61 -61
- package/src/$locales/en.json +23 -25
- package/src/$locales/fr.json +22 -23
- package/src/assets/data/onboardingMessages.json +47 -47
- package/src/components/AppBase.vue +166 -99
- package/src/components/AppBaseButton.vue +2 -0
- package/src/components/AppBaseErrorDisplay.vue +438 -438
- package/src/components/AppBaseFlipCard.vue +84 -84
- package/src/components/AppBaseModule.vue +164 -106
- package/src/components/AppBasePage.vue +14 -4
- package/src/components/AppBasePopover.vue +41 -41
- package/src/components/AppCompAudio.vue +20 -48
- package/src/components/AppCompBranchButtons.vue +7 -53
- package/src/components/{AppCompTranscript.vue → AppCompContainer.vue} +8 -1
- package/src/components/AppCompInputRadioNext.vue +152 -152
- package/src/components/AppCompInputTextToFillNext.vue +171 -171
- package/src/components/AppCompJauge.vue +74 -74
- package/src/components/AppCompMenu.vue +429 -428
- package/src/components/AppCompMenuItem.vue +228 -228
- package/src/components/AppCompNavigation.vue +2 -2
- package/src/components/AppCompPlayBarNext.vue +5 -0
- package/src/components/AppCompPlayBarProgress.vue +82 -82
- package/src/components/AppCompSVGNext.vue +2 -3
- package/src/components/AppCompSettingsMenu.vue +172 -172
- package/src/components/AppCompVideoPlayer.vue +17 -15
- 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 +34 -29
- package/src/mixins/$mediaMixins.js +819 -819
- package/src/mixins/timerMixin.js +155 -155
- package/src/module/stores/appStore.js +1 -1
- 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/Statement/agent.js +55 -55
- package/src/module/xapi/Statement/index.js +259 -259
- package/src/module/xapi/Statement/statement.js +253 -253
- package/src/module/xapi/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 +0 -1
- 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 +2 -1
- package/src/router/routes.js +312 -312
- package/src/shared/generalfuncs.js +210 -210
- package/src/shared/validators.js +2 -0
- package/src/components/AppCompPlayBar.vue +0 -1217
package/src/mixins/timerMixin.js
CHANGED
|
@@ -1,155 +1,155 @@
|
|
|
1
|
-
/*
|
|
2
|
-
@ Description: Mixins to extends general fonctionnalities in a page of an activity. Add time tracker in activities
|
|
3
|
-
@ Note: .
|
|
4
|
-
*/
|
|
5
|
-
export const timerMixin = {
|
|
6
|
-
data() {
|
|
7
|
-
return {
|
|
8
|
-
lessonTimeCounter: 0,
|
|
9
|
-
activityTimeCounter: 0,
|
|
10
|
-
elapsedCounter: 0, // count the elapse time since lesson started
|
|
11
|
-
activityInterval: null,
|
|
12
|
-
lessonInterval: null,
|
|
13
|
-
fullInterval: null,
|
|
14
|
-
timerState: 'stopped',
|
|
15
|
-
elapsedInterval: null // interval of passed time since the lesson is started. used only for saving purposed
|
|
16
|
-
}
|
|
17
|
-
},
|
|
18
|
-
methods: {
|
|
19
|
-
/* Start the timer */
|
|
20
|
-
startTimer(op) {
|
|
21
|
-
if (op && !['activity', 'lesson'].includes(op))
|
|
22
|
-
throw new Error('this is not a valid option for the timer')
|
|
23
|
-
if (this.timerState === 'stopped') {
|
|
24
|
-
switch (op) {
|
|
25
|
-
case 'activity':
|
|
26
|
-
this.activityInterval = setInterval(() => {
|
|
27
|
-
this.activityTimeCounter += 1
|
|
28
|
-
}, 1000)
|
|
29
|
-
this.timerState = 'started'
|
|
30
|
-
|
|
31
|
-
break
|
|
32
|
-
|
|
33
|
-
case 'lesson':
|
|
34
|
-
this.lessonInterval = setInterval(() => {
|
|
35
|
-
this.lessonTimeCounter += 1
|
|
36
|
-
}, 1000)
|
|
37
|
-
break
|
|
38
|
-
|
|
39
|
-
default:
|
|
40
|
-
this.fullInterval = setInterval(() => {
|
|
41
|
-
this.activityTimeCounter += 1
|
|
42
|
-
this.lessonTimeCounter += 1
|
|
43
|
-
}, 1000)
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
},
|
|
47
|
-
/* Stop the timer and reset thimer to zero */
|
|
48
|
-
stopTimer(op) {
|
|
49
|
-
if (op && !['activity', 'lesson'].includes(op))
|
|
50
|
-
throw new Error('this is not a valid parameter')
|
|
51
|
-
|
|
52
|
-
if (this.timerState === 'started') {
|
|
53
|
-
if (op === 'activity' && this.activityTimeCounter > 0) {
|
|
54
|
-
this.lessonTimeCounter =
|
|
55
|
-
this.lessonTimeCounter + this.activityTimeCounter //add to the lesson counter
|
|
56
|
-
clearInterval(this.activityInterval) //clear the interval
|
|
57
|
-
this.activityTimeCounter = 0 // reset the counter
|
|
58
|
-
this.timerState = 'stopped'
|
|
59
|
-
} else if (op === 'lesson' && this.lessonTimeCounter > 0) {
|
|
60
|
-
clearInterval(this.lessonInterval)
|
|
61
|
-
this.lessonTimeCounter = 0
|
|
62
|
-
} else {
|
|
63
|
-
clearInterval(this.fullInterval)
|
|
64
|
-
clearInterval(this.elapsedCounter)
|
|
65
|
-
clearInterval(this.elapsedInterval)
|
|
66
|
-
|
|
67
|
-
this.activityTimeCounter = 0
|
|
68
|
-
this.lessonTimeCounter = 0
|
|
69
|
-
this.elapsedCounter = 0
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
},
|
|
73
|
-
/* Pause the timer but does not reset to zero*/
|
|
74
|
-
pauseTimer(op) {
|
|
75
|
-
if (op && !['activity', 'lesson'].includes(op))
|
|
76
|
-
throw new Error('this is not a valid parameter')
|
|
77
|
-
|
|
78
|
-
if (op === 'activity' && this.activityTimeCounter > 0) {
|
|
79
|
-
clearInterval(this.activityInterval)
|
|
80
|
-
} else if (op === 'lesson') {
|
|
81
|
-
clearInterval(this.lessonInterval)
|
|
82
|
-
} else {
|
|
83
|
-
clearInterval(this.fullInterval)
|
|
84
|
-
clearInterval(this.elapsedInterval)
|
|
85
|
-
}
|
|
86
|
-
},
|
|
87
|
-
|
|
88
|
-
/* Format seconds to ISO 8601 format */
|
|
89
|
-
formatToISOString(seconds) {
|
|
90
|
-
let d = new Date(null) //create a default date ref
|
|
91
|
-
d.setSeconds(seconds) //set the time with passed numbers of seconds
|
|
92
|
-
//Example of ISO 8601 time format of 24 chars: "1970-01-04T14:50:00.000Z"
|
|
93
|
-
let ISOTime = d.toISOString()
|
|
94
|
-
|
|
95
|
-
return ISOTime // YYYY-MM-DDTHH:mm:ss.sssZ
|
|
96
|
-
},
|
|
97
|
-
|
|
98
|
-
/* Parse a ISO string time period to the format of HH:mm:ss */
|
|
99
|
-
ISOTimeParser(seconds) {
|
|
100
|
-
let ISOTimePeriod = this.formatToISOString(seconds).substring(8, 19) // only the time portion of it
|
|
101
|
-
ISOTimePeriod = ISOTimePeriod.split('T')
|
|
102
|
-
const DDToHrs = (parseInt(ISOTimePeriod[0]) - 1) * 24 // convert xxT to hrs
|
|
103
|
-
const periodOfTime = ISOTimePeriod[1] ? ISOTimePeriod[1].split(':') : null
|
|
104
|
-
|
|
105
|
-
if (!periodOfTime) return '00:00:00'
|
|
106
|
-
|
|
107
|
-
let timeString = ''
|
|
108
|
-
let HH = (DDToHrs + parseInt(periodOfTime[0])).toString()
|
|
109
|
-
let mm = periodOfTime[1]
|
|
110
|
-
let ss = periodOfTime[2]
|
|
111
|
-
|
|
112
|
-
if (HH.length === 1) HH = `0${HH}`
|
|
113
|
-
|
|
114
|
-
timeString = `${HH}:${mm}:${ss}`
|
|
115
|
-
|
|
116
|
-
return timeString
|
|
117
|
-
}
|
|
118
|
-
},
|
|
119
|
-
beforeUnmount() {
|
|
120
|
-
this.$bus.$off('start-timer', this.startTimer)
|
|
121
|
-
this.$bus.$off('stop-timer', this.stopTimer)
|
|
122
|
-
this.$bus.$off('pause-timer', this.pauseTimer)
|
|
123
|
-
},
|
|
124
|
-
mounted() {
|
|
125
|
-
this.$bus.$on('start-timer', this.startTimer)
|
|
126
|
-
|
|
127
|
-
this.$bus.$on('stop-timer', this.stopTimer)
|
|
128
|
-
|
|
129
|
-
this.$bus.$on('pause-timer', this.pauseTimer)
|
|
130
|
-
|
|
131
|
-
this.elapsedInterval = setInterval(() => {
|
|
132
|
-
this.elapsedCounter += 1
|
|
133
|
-
}, 1000)
|
|
134
|
-
},
|
|
135
|
-
computed: {
|
|
136
|
-
activityDuration() {
|
|
137
|
-
let duration
|
|
138
|
-
if (this.activityTimeCounter > 0)
|
|
139
|
-
duration = this.ISOTimeParser(this.activityTimeCounter)
|
|
140
|
-
else duration = '00:00:00'
|
|
141
|
-
|
|
142
|
-
return duration
|
|
143
|
-
},
|
|
144
|
-
lessonDuration() {
|
|
145
|
-
this.lessonTimeCounter = this.lessonTimeCounter + this.activityTimeCounter
|
|
146
|
-
|
|
147
|
-
let duration = this.ISOTimeParser(this.lessonTimeCounter)
|
|
148
|
-
return duration
|
|
149
|
-
},
|
|
150
|
-
elapsedTime() {
|
|
151
|
-
const eTime = this.elapsedCounter
|
|
152
|
-
return eTime
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
}
|
|
1
|
+
/*
|
|
2
|
+
@ Description: Mixins to extends general fonctionnalities in a page of an activity. Add time tracker in activities
|
|
3
|
+
@ Note: .
|
|
4
|
+
*/
|
|
5
|
+
export const timerMixin = {
|
|
6
|
+
data() {
|
|
7
|
+
return {
|
|
8
|
+
lessonTimeCounter: 0,
|
|
9
|
+
activityTimeCounter: 0,
|
|
10
|
+
elapsedCounter: 0, // count the elapse time since lesson started
|
|
11
|
+
activityInterval: null,
|
|
12
|
+
lessonInterval: null,
|
|
13
|
+
fullInterval: null,
|
|
14
|
+
timerState: 'stopped',
|
|
15
|
+
elapsedInterval: null // interval of passed time since the lesson is started. used only for saving purposed
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
methods: {
|
|
19
|
+
/* Start the timer */
|
|
20
|
+
startTimer(op) {
|
|
21
|
+
if (op && !['activity', 'lesson'].includes(op))
|
|
22
|
+
throw new Error('this is not a valid option for the timer')
|
|
23
|
+
if (this.timerState === 'stopped') {
|
|
24
|
+
switch (op) {
|
|
25
|
+
case 'activity':
|
|
26
|
+
this.activityInterval = setInterval(() => {
|
|
27
|
+
this.activityTimeCounter += 1
|
|
28
|
+
}, 1000)
|
|
29
|
+
this.timerState = 'started'
|
|
30
|
+
|
|
31
|
+
break
|
|
32
|
+
|
|
33
|
+
case 'lesson':
|
|
34
|
+
this.lessonInterval = setInterval(() => {
|
|
35
|
+
this.lessonTimeCounter += 1
|
|
36
|
+
}, 1000)
|
|
37
|
+
break
|
|
38
|
+
|
|
39
|
+
default:
|
|
40
|
+
this.fullInterval = setInterval(() => {
|
|
41
|
+
this.activityTimeCounter += 1
|
|
42
|
+
this.lessonTimeCounter += 1
|
|
43
|
+
}, 1000)
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
/* Stop the timer and reset thimer to zero */
|
|
48
|
+
stopTimer(op) {
|
|
49
|
+
if (op && !['activity', 'lesson'].includes(op))
|
|
50
|
+
throw new Error('this is not a valid parameter')
|
|
51
|
+
|
|
52
|
+
if (this.timerState === 'started') {
|
|
53
|
+
if (op === 'activity' && this.activityTimeCounter > 0) {
|
|
54
|
+
this.lessonTimeCounter =
|
|
55
|
+
this.lessonTimeCounter + this.activityTimeCounter //add to the lesson counter
|
|
56
|
+
clearInterval(this.activityInterval) //clear the interval
|
|
57
|
+
this.activityTimeCounter = 0 // reset the counter
|
|
58
|
+
this.timerState = 'stopped'
|
|
59
|
+
} else if (op === 'lesson' && this.lessonTimeCounter > 0) {
|
|
60
|
+
clearInterval(this.lessonInterval)
|
|
61
|
+
this.lessonTimeCounter = 0
|
|
62
|
+
} else {
|
|
63
|
+
clearInterval(this.fullInterval)
|
|
64
|
+
clearInterval(this.elapsedCounter)
|
|
65
|
+
clearInterval(this.elapsedInterval)
|
|
66
|
+
|
|
67
|
+
this.activityTimeCounter = 0
|
|
68
|
+
this.lessonTimeCounter = 0
|
|
69
|
+
this.elapsedCounter = 0
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
/* Pause the timer but does not reset to zero*/
|
|
74
|
+
pauseTimer(op) {
|
|
75
|
+
if (op && !['activity', 'lesson'].includes(op))
|
|
76
|
+
throw new Error('this is not a valid parameter')
|
|
77
|
+
|
|
78
|
+
if (op === 'activity' && this.activityTimeCounter > 0) {
|
|
79
|
+
clearInterval(this.activityInterval)
|
|
80
|
+
} else if (op === 'lesson') {
|
|
81
|
+
clearInterval(this.lessonInterval)
|
|
82
|
+
} else {
|
|
83
|
+
clearInterval(this.fullInterval)
|
|
84
|
+
clearInterval(this.elapsedInterval)
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
|
|
88
|
+
/* Format seconds to ISO 8601 format */
|
|
89
|
+
formatToISOString(seconds) {
|
|
90
|
+
let d = new Date(null) //create a default date ref
|
|
91
|
+
d.setSeconds(seconds) //set the time with passed numbers of seconds
|
|
92
|
+
//Example of ISO 8601 time format of 24 chars: "1970-01-04T14:50:00.000Z"
|
|
93
|
+
let ISOTime = d.toISOString()
|
|
94
|
+
|
|
95
|
+
return ISOTime // YYYY-MM-DDTHH:mm:ss.sssZ
|
|
96
|
+
},
|
|
97
|
+
|
|
98
|
+
/* Parse a ISO string time period to the format of HH:mm:ss */
|
|
99
|
+
ISOTimeParser(seconds) {
|
|
100
|
+
let ISOTimePeriod = this.formatToISOString(seconds).substring(8, 19) // only the time portion of it
|
|
101
|
+
ISOTimePeriod = ISOTimePeriod.split('T')
|
|
102
|
+
const DDToHrs = (parseInt(ISOTimePeriod[0]) - 1) * 24 // convert xxT to hrs
|
|
103
|
+
const periodOfTime = ISOTimePeriod[1] ? ISOTimePeriod[1].split(':') : null
|
|
104
|
+
|
|
105
|
+
if (!periodOfTime) return '00:00:00'
|
|
106
|
+
|
|
107
|
+
let timeString = ''
|
|
108
|
+
let HH = (DDToHrs + parseInt(periodOfTime[0])).toString()
|
|
109
|
+
let mm = periodOfTime[1]
|
|
110
|
+
let ss = periodOfTime[2]
|
|
111
|
+
|
|
112
|
+
if (HH.length === 1) HH = `0${HH}`
|
|
113
|
+
|
|
114
|
+
timeString = `${HH}:${mm}:${ss}`
|
|
115
|
+
|
|
116
|
+
return timeString
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
beforeUnmount() {
|
|
120
|
+
this.$bus.$off('start-timer', this.startTimer)
|
|
121
|
+
this.$bus.$off('stop-timer', this.stopTimer)
|
|
122
|
+
this.$bus.$off('pause-timer', this.pauseTimer)
|
|
123
|
+
},
|
|
124
|
+
mounted() {
|
|
125
|
+
this.$bus.$on('start-timer', this.startTimer)
|
|
126
|
+
|
|
127
|
+
this.$bus.$on('stop-timer', this.stopTimer)
|
|
128
|
+
|
|
129
|
+
this.$bus.$on('pause-timer', this.pauseTimer)
|
|
130
|
+
|
|
131
|
+
this.elapsedInterval = setInterval(() => {
|
|
132
|
+
this.elapsedCounter += 1
|
|
133
|
+
}, 1000)
|
|
134
|
+
},
|
|
135
|
+
computed: {
|
|
136
|
+
activityDuration() {
|
|
137
|
+
let duration
|
|
138
|
+
if (this.activityTimeCounter > 0)
|
|
139
|
+
duration = this.ISOTimeParser(this.activityTimeCounter)
|
|
140
|
+
else duration = '00:00:00'
|
|
141
|
+
|
|
142
|
+
return duration
|
|
143
|
+
},
|
|
144
|
+
lessonDuration() {
|
|
145
|
+
this.lessonTimeCounter = this.lessonTimeCounter + this.activityTimeCounter
|
|
146
|
+
|
|
147
|
+
let duration = this.ISOTimeParser(this.lessonTimeCounter)
|
|
148
|
+
return duration
|
|
149
|
+
},
|
|
150
|
+
elapsedTime() {
|
|
151
|
+
const eTime = this.elapsedCounter
|
|
152
|
+
return eTime
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
package/src/module/xapi/ADL.js
CHANGED
|
@@ -154,7 +154,7 @@ export default class ADL {
|
|
|
154
154
|
params['verb'] = this.verbs[vb].id // completed state
|
|
155
155
|
params['activity'] = activityId // this current activity define by this id
|
|
156
156
|
params['agent'] = `{"mbox": "mailto:${email}"}` // the user identify by this email
|
|
157
|
-
params['limit'] =
|
|
157
|
+
params['limit'] = 200 //limit of record to return by the LRS
|
|
158
158
|
params['ascending'] = true //ordered by the oldest statement recorded
|
|
159
159
|
|
|
160
160
|
let date = new Date()
|
|
@@ -191,6 +191,7 @@ export default class ADL {
|
|
|
191
191
|
} else {
|
|
192
192
|
userData = {}
|
|
193
193
|
}
|
|
194
|
+
|
|
194
195
|
return userData
|
|
195
196
|
} catch (err) {
|
|
196
197
|
console.log(err)
|
|
@@ -245,7 +246,7 @@ export default class ADL {
|
|
|
245
246
|
params['activity'] = activityId // this current activity define by this id
|
|
246
247
|
params['agent'] = `{"mbox": "mailto:${email}"}` // the user identify by this email
|
|
247
248
|
params['ascending'] = true //ordered by the oldest statement recorded
|
|
248
|
-
params['limit'] =
|
|
249
|
+
params['limit'] = 200 //limit of record to return by the LRS
|
|
249
250
|
|
|
250
251
|
let date = new Date()
|
|
251
252
|
let dd = new Date(date.setDate(date.getDate() + 1)).toISOString() //Date is set to next day(tomorrow) for Lrs to take in account statement registered today.
|
|
@@ -296,7 +297,7 @@ export default class ADL {
|
|
|
296
297
|
params['activity'] = activityId // this current activity define by this id
|
|
297
298
|
params['agent'] = `{"mbox": "mailto:${email}"}` // the user identify by this email
|
|
298
299
|
params['ascending'] = true //ordered by the oldest statement recorded
|
|
299
|
-
params['limit'] =
|
|
300
|
+
params['limit'] = 200 //limit of record to return by the LRS
|
|
300
301
|
|
|
301
302
|
let date = new Date()
|
|
302
303
|
let dd = new Date(date.setDate(date.getDate() + 1)).toISOString() //Date is set to next day(tomorrow) for Lrs to take in account statement registered today.
|
|
@@ -345,7 +346,7 @@ export default class ADL {
|
|
|
345
346
|
params['activity'] = activityId // this current activity define by this id
|
|
346
347
|
params['agent'] = `{"mbox": "mailto:${email}"}` // the user identify by this email
|
|
347
348
|
params['ascending'] = true //ordered by the oldest statement recorded
|
|
348
|
-
params['limit'] =
|
|
349
|
+
params['limit'] = 200 //limit of record to return by the LRS
|
|
349
350
|
|
|
350
351
|
let date = new Date()
|
|
351
352
|
let dd = new Date(date.setDate(date.getDate() + 1)).toISOString() //Date is set to next day(tomorrow) for Lrs to take in account statement registered today.
|
|
@@ -377,4 +378,143 @@ export default class ADL {
|
|
|
377
378
|
}
|
|
378
379
|
return playbarValues[0] ? playbarValues[0] : {}
|
|
379
380
|
}
|
|
381
|
+
/**
|
|
382
|
+
* Method to get a multiple concurent requests using promiseAll to the server
|
|
383
|
+
* and return all data at once.
|
|
384
|
+
* the following request are made to the server:
|
|
385
|
+
* get application-settings: saved value for the user preferred settings
|
|
386
|
+
* get user-data: saved values for user progression
|
|
387
|
+
* get playbar-value : saved value for the medias play-bar
|
|
388
|
+
* get lesson-status : saved value for the lession status
|
|
389
|
+
*
|
|
390
|
+
* @param {Array} searchParams - Array of Object with key value representing each search paremeter.
|
|
391
|
+
* a parameter object definition is expected to have the following signature:
|
|
392
|
+
* {
|
|
393
|
+
* email{String} agent email,
|
|
394
|
+
* verb {String} verb for the request,
|
|
395
|
+
* activityId {String} - activity id ,
|
|
396
|
+
* }
|
|
397
|
+
* @example here is an exemple of the search param:
|
|
398
|
+
* {email: 'wizardy0@mymailbox.com', verb: 'completed',activityId:'"http://localhost:5173/vuetify_p4/v3"' }
|
|
399
|
+
* @return {object} data with a collection of all the reponses
|
|
400
|
+
* from the promiseAll and the status of last request
|
|
401
|
+
*/
|
|
402
|
+
async _getBulkData(searchParams) {
|
|
403
|
+
const validVerbs = [
|
|
404
|
+
'progressed',
|
|
405
|
+
'completed',
|
|
406
|
+
'suspended',
|
|
407
|
+
'terminated',
|
|
408
|
+
'preferred',
|
|
409
|
+
'played',
|
|
410
|
+
'exited'
|
|
411
|
+
]
|
|
412
|
+
|
|
413
|
+
const paramList = []
|
|
414
|
+
// account statement registered today.
|
|
415
|
+
let date = new Date()
|
|
416
|
+
let dd = new Date(date.setDate(date.getDate() + 1)).toISOString() //Date is set to next day(tomorrow) for Lrs to take in
|
|
417
|
+
|
|
418
|
+
for (let param of searchParams) {
|
|
419
|
+
let { email, verb, activityId } = param
|
|
420
|
+
let vb = verb && validVerbs.includes(verb) ? verb : 'terminated'
|
|
421
|
+
const params = {}
|
|
422
|
+
|
|
423
|
+
params['verb'] = this.verbs[vb].id // completed state
|
|
424
|
+
params['activity'] = activityId // this current activity define by this id
|
|
425
|
+
params['agent'] = `{"mbox": "mailto:${email}"}` // the user identify by this email
|
|
426
|
+
params['ascending'] = true //ordered by the oldest statement recorded
|
|
427
|
+
params['limit'] = 250 //limit of record to return by the LRS
|
|
428
|
+
|
|
429
|
+
params['until'] = dd
|
|
430
|
+
paramList.push(params)
|
|
431
|
+
}
|
|
432
|
+
const { response } = await this.XAPIWrapper.getStatements(paramList)
|
|
433
|
+
|
|
434
|
+
let userData = {},
|
|
435
|
+
playbarValues = {},
|
|
436
|
+
preferredSettings = {},
|
|
437
|
+
lessonStatus = {},
|
|
438
|
+
savedPoint = ''
|
|
439
|
+
|
|
440
|
+
if (response && response.length > 0) {
|
|
441
|
+
for (const res of response) {
|
|
442
|
+
const { statements } = await res.json()
|
|
443
|
+
if (!statements || statements.length == 0) continue
|
|
444
|
+
|
|
445
|
+
let lastRecord = statements.toReversed()[0] // get last recorded statement
|
|
446
|
+
// Verify that the extensions value of the statement has elements
|
|
447
|
+
|
|
448
|
+
//Handeling Lession comppletion status
|
|
449
|
+
if (lastRecord.verb.id.includes('completed')) {
|
|
450
|
+
lessonStatus = lastRecord.result ? lastRecord.result : {}
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
if (
|
|
454
|
+
lastRecord.object.definition.extensions &&
|
|
455
|
+
Object.keys(lastRecord.object.definition.extensions).length
|
|
456
|
+
) {
|
|
457
|
+
const allExtensionsKeys = Object.keys(
|
|
458
|
+
lastRecord.object.definition.extensions
|
|
459
|
+
)
|
|
460
|
+
|
|
461
|
+
//Search for the user-data entry in the extensions
|
|
462
|
+
allExtensionsKeys.forEach((extension) => {
|
|
463
|
+
switch (true) {
|
|
464
|
+
case extension.includes('user-data'): {
|
|
465
|
+
//Search for the user-data entry in the extensions
|
|
466
|
+
const userDataExtension = allExtensionsKeys.filter(
|
|
467
|
+
(extension) => extension.includes('user-data')
|
|
468
|
+
)
|
|
469
|
+
userData =
|
|
470
|
+
lastRecord.object.definition.extensions[userDataExtension[0]]
|
|
471
|
+
|
|
472
|
+
break
|
|
473
|
+
}
|
|
474
|
+
case extension.includes('ending-point'): {
|
|
475
|
+
const userDataExtension = allExtensionsKeys.filter(
|
|
476
|
+
(extension) => extension.includes('ending-point')
|
|
477
|
+
)
|
|
478
|
+
savedPoint =
|
|
479
|
+
lastRecord.object.definition.extensions[userDataExtension[0]]
|
|
480
|
+
|
|
481
|
+
break
|
|
482
|
+
}
|
|
483
|
+
case extension.includes('application-settings'): {
|
|
484
|
+
const userDataExtension = allExtensionsKeys.filter(
|
|
485
|
+
(extension) => extension.includes('application-settings')
|
|
486
|
+
)
|
|
487
|
+
|
|
488
|
+
const settingsData =
|
|
489
|
+
lastRecord.object.definition.extensions[userDataExtension[0]]
|
|
490
|
+
|
|
491
|
+
preferredSettings = settingsData ? settingsData : {}
|
|
492
|
+
|
|
493
|
+
break
|
|
494
|
+
}
|
|
495
|
+
case extension.includes('playbar-values'): {
|
|
496
|
+
const userDataExtension = allExtensionsKeys.filter(
|
|
497
|
+
(extension) => extension.includes('playbar-values')
|
|
498
|
+
)
|
|
499
|
+
|
|
500
|
+
const playbarData =
|
|
501
|
+
lastRecord.object.definition.extensions[userDataExtension[0]]
|
|
502
|
+
playbarValues = playbarData ? playbarData : {}
|
|
503
|
+
|
|
504
|
+
break
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
})
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
return {
|
|
513
|
+
userData,
|
|
514
|
+
savedPoint,
|
|
515
|
+
preferredSettings,
|
|
516
|
+
playbarValues,
|
|
517
|
+
lessonStatus
|
|
518
|
+
}
|
|
519
|
+
}
|
|
380
520
|
}
|