fcad-core-dragon 2.0.0-beta.2 → 2.0.0-beta.4

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.
Files changed (72) hide show
  1. package/.eslintrc.cjs +1 -1
  2. package/CHANGELOG +9 -0
  3. package/package.json +26 -12
  4. package/src/$locales/en.json +37 -87
  5. package/src/$locales/fr.json +17 -106
  6. package/src/assets/data/onboardingMessages.json +1 -1
  7. package/src/components/AppBase.vue +241 -143
  8. package/src/components/AppBaseButton.vue +2 -6
  9. package/src/components/AppBaseErrorDisplay.vue +193 -183
  10. package/src/components/AppBaseFlipCard.vue +1 -0
  11. package/src/components/AppBaseModule.vue +195 -225
  12. package/src/components/AppBasePage.vue +519 -64
  13. package/src/components/AppBasePopover.vue +41 -0
  14. package/src/components/AppCompAudio.vue +32 -64
  15. package/src/components/AppCompBranchButtons.vue +52 -71
  16. package/src/components/AppCompButtonProgress.vue +12 -18
  17. package/src/components/AppCompCarousel.vue +102 -0
  18. package/src/components/{AppCompInputCheckBox.vue → AppCompInputCheckBoxNext.vue} +56 -94
  19. package/src/components/AppCompInputDropdownNext.vue +159 -0
  20. package/src/components/{AppCompInputRadio.vue → AppCompInputRadioNext.vue} +53 -63
  21. package/src/components/AppCompInputTextNext.vue +106 -0
  22. package/src/components/AppCompInputTextTableNext.vue +141 -0
  23. package/src/components/AppCompInputTextToFillDropdownNext.vue +230 -0
  24. package/src/components/{AppCompInputTextToFillText.vue → AppCompInputTextToFillNext.vue} +71 -64
  25. package/src/components/AppCompJauge.vue +16 -9
  26. package/src/components/AppCompMenu.vue +50 -29
  27. package/src/components/AppCompMenuItem.vue +52 -15
  28. package/src/components/AppCompNavigation.vue +225 -211
  29. package/src/components/AppCompNoteCall.vue +22 -30
  30. package/src/components/AppCompNoteCredit.vue +45 -20
  31. package/src/components/AppCompPlayBar.vue +55 -108
  32. package/src/components/AppCompPlayBarNext.vue +2052 -0
  33. package/src/components/AppCompPlayBarProgress.vue +10 -1
  34. package/src/components/AppCompPopUpNext.vue +503 -0
  35. package/src/components/{AppCompQuiz.vue → AppCompQuizNext.vue} +632 -703
  36. package/src/components/AppCompQuizRecall.vue +74 -75
  37. package/src/components/{AppCompSVG.vue → AppCompSVGNext.vue} +111 -99
  38. package/src/components/AppCompSettingsMenu.vue +11 -8
  39. package/src/components/AppCompTableOfContent.vue +78 -76
  40. package/src/components/AppCompTranscript.vue +5 -0
  41. package/src/components/AppCompVideoPlayer.vue +30 -42
  42. package/src/components/BaseModule.vue +1 -0
  43. package/src/composables/useQuiz.js +206 -0
  44. package/src/externalComps/ModuleView.vue +22 -0
  45. package/src/externalComps/SummaryView.vue +91 -0
  46. package/src/main.js +99 -90
  47. package/src/mixins/$mediaMixins.js +13 -21
  48. package/src/mixins/timerMixin.js +1 -1
  49. package/src/module/stores/appStore.js +901 -0
  50. package/src/module/xapi/ADL.js +8 -4
  51. package/src/plugins/bus.js +7 -2
  52. package/src/plugins/gsap.js +4 -7
  53. package/src/plugins/helper.js +33 -13
  54. package/src/plugins/i18n.js +2 -2
  55. package/src/plugins/idb.js +44 -29
  56. package/src/plugins/save.js +1 -1
  57. package/src/plugins/scorm.js +2 -2
  58. package/src/plugins/xapi.js +2 -2
  59. package/src/public/index.html +22 -10
  60. package/src/router/index.js +13 -10
  61. package/src/router/routes.js +20 -25
  62. package/src/shared/generalfuncs.js +33 -18
  63. package/src/shared/validators.js +116 -6
  64. package/src/components/AppCompInputDropdown.vue +0 -182
  65. package/src/components/AppCompInputTextBox.vue +0 -91
  66. package/src/components/AppCompInputTextTable.vue +0 -158
  67. package/src/components/AppCompInputTextToFillDropdown.vue +0 -257
  68. package/src/components/AppCompPopUp.vue +0 -583
  69. package/src/components/AppCompPopover.vue +0 -27
  70. package/src/mixins/$pageMixins.js +0 -415
  71. package/src/mixins/$quizMixins.js +0 -442
  72. package/src/module/store.js +0 -1014
@@ -4,79 +4,68 @@
4
4
  - validate the data for the App configuration
5
5
  - Send the xapi statement
6
6
  - Manage the fetching and setting of data from serveur
7
+ - Example of use: <app-base :app-config="$data"></app-base>
7
8
  @ Must be used.
8
9
  -->
9
10
  <template>
10
11
  <div id="App-base" fluid :class="{ iPad: resizeiPad }">
11
12
  <template v-if="error.length">
12
- <b-row>
13
- <b-col>
13
+ <v-row>
14
+ <v-col>
14
15
  <app-base-error-display
15
16
  :errors-list="error"
16
17
  error-type="appConfig"
17
18
  error-title="Configuration de l'application"
18
19
  />
19
- </b-col>
20
- </b-row>
20
+ </v-col>
21
+ </v-row>
21
22
  </template>
22
23
  <template v-else>
23
- <template>
24
- <transition name="bounce" mode="in-out">
25
- <div
26
- v-if="showBuildInfo && !buildInfoClicked"
27
- id="build-info"
28
- @click="buildInfoClicked = true"
29
- >
30
- <span>{{ getModuleInfo.courseID.toUpperCase() }}</span>
31
- <span>FCAD {{ $helper.getFcadVersion() }}</span>
32
- <span>{{ $helper.getBuildTime() }}</span>
33
- </div>
34
- </transition>
35
-
36
- <router-view class="box" />
37
-
38
- <app-icons />
39
- </template>
24
+ <transition name="bounce" mode="in-out">
25
+ <div
26
+ v-if="showBuildInfo && !buildInfoClicked"
27
+ id="build-info"
28
+ @click="buildInfoClicked = true"
29
+ >
30
+ <span>{{ getModuleInfo.courseID.toUpperCase() }}</span>
31
+ <span>FCAD {{ $helper.getFcadVersion() }}</span>
32
+ <span>template {{ $helper.getTemplateVersion() }}</span>
33
+ <span>{{ $helper.getBuildTime() }}</span>
34
+ </div>
35
+ </transition>
36
+
37
+ <router-view class="box" />
38
+
39
+ <app-icons-next :extra-icons="userExtraIcons" />
40
40
  </template>
41
- <b-overlay
42
- v-show="!appReady"
41
+
42
+ <v-overlay
43
43
  id="overlay_loading"
44
- :show="!appReady"
45
- rounded="lg"
46
- variant="white"
44
+ :model-value="!appReady"
45
+ class="align-center justify-center"
46
+ scrim="white"
47
47
  blur="3px"
48
48
  opacity="0.8"
49
49
  >
50
- <template #overlay>
51
- <div class="d-flex grp-spinners align-items-center">
52
- <b-spinner small type="grow" variant="secondary"></b-spinner>
53
- <b-spinner
54
- style="width: 1.2rem; height: 1.2rem"
55
- type="grow"
56
- variant="secondary"
57
- ></b-spinner>
58
-
59
- <b-spinner
60
- style="width: 1.8rem; height: 1.8rem"
61
- type="grow"
62
- variant="dark"
63
- ></b-spinner>
64
-
65
- <b-spinner
66
- style="width: 1.2rem; height: 1.2rem"
67
- type="grow"
68
- variant="secondary"
69
- ></b-spinner>
70
- <b-spinner small type="grow" variant="secondary"></b-spinner>
71
- <!-- We add an SR only text for screen readers -->
72
- <span class="sr-only">{{ $t('message.loading_state_msg') }}</span>
73
- </div>
74
- </template>
75
- </b-overlay>
50
+ <div class="text-center grp-spinners">
51
+ <v-progress-circular
52
+ :size="50"
53
+ :width="3"
54
+ color="#003552"
55
+ bg-color="#d3effe"
56
+ indeterminate
57
+ ></v-progress-circular>
58
+
59
+ <span class="sr-only">
60
+ {{ $t('message.loading_state_msg') }}
61
+ </span>
62
+ </div>
63
+ </v-overlay>
76
64
  </div>
77
65
  </template>
78
66
  <script>
79
- import { mapGetters } from 'vuex'
67
+ import { mapState, mapActions } from 'pinia'
68
+ import { useAppStore } from '../module/stores/appStore.js'
80
69
  import { timerMixin } from '../mixins/timerMixin'
81
70
  import { validateAppContent } from '../shared/validators'
82
71
  import AppBaseErrorDisplay from './AppBaseErrorDisplay.vue'
@@ -93,6 +82,10 @@ export default {
93
82
  }
94
83
  }
95
84
  },
85
+ setup() {
86
+ const store = useAppStore()
87
+ return { store }
88
+ },
96
89
 
97
90
  data() {
98
91
  return {
@@ -106,7 +99,7 @@ export default {
106
99
  }
107
100
  },
108
101
  computed: {
109
- ...mapGetters([
102
+ ...mapState(useAppStore, [
110
103
  'getCurrentBrowser',
111
104
  'getIsMobile',
112
105
  'getDeviceType',
@@ -118,7 +111,9 @@ export default {
118
111
  'getAllActivities',
119
112
  'getMediaPlaybarValues',
120
113
  'getAppConfigs',
121
- 'getErrorMenu'
114
+ 'getErrorMenu',
115
+ 'getRouteHistory',
116
+ 'getBookmarkEnabled'
122
117
  ]),
123
118
  getwidth() {
124
119
  return window.innerWidth
@@ -146,10 +141,22 @@ export default {
146
141
  lang = displayList.find((l) => l.includes(this.$i18n.locale))
147
142
  }
148
143
  return lang
144
+ },
145
+ userExtraIcons() {
146
+ const icons = this.$helper.getSettingsFromStore('extra_icons')
147
+ ? this.$helper.getSettingsFromStore('extra_icons')
148
+ : null
149
+ return icons
150
+ } /**
151
+ * @description Set default value for bookmark
152
+ */,
153
+ bookmarkActive() {
154
+ return this.getBookmarkEnabled
149
155
  }
150
156
  },
151
157
  watch: {
152
158
  getConnectionInfo: {
159
+ deep: true,
153
160
  //in development environment (localhost), don't wait for the axios call
154
161
  immediate: import.meta.env.DEV,
155
162
  handler() {
@@ -210,6 +217,7 @@ export default {
210
217
  },
211
218
 
212
219
  created() {
220
+ this.bookmarkActive
213
221
  if (import.meta.env.DEV) {
214
222
  this.checkForErrors()
215
223
  }
@@ -217,22 +225,22 @@ export default {
217
225
 
218
226
  if (!this.error.length) {
219
227
  this.updateTracker('appBase', 'loading')
220
- this.$store.dispatch('setAppConfigs', this.appConfig)
228
+ this.setAppConfigs(this.appConfig)
221
229
  }
222
230
 
223
231
  window.versionFCAD = this.$helper.getFcadVersionString()
224
232
  //check if this is running in a mobile environment and register state in the store
225
233
  const md = new mobileDetect(window.navigator.userAgent)
226
234
  md.mobile() !== null
227
- ? this.$store.dispatch('setMobileState', true)
228
- : this.$store.dispatch('setMobileState', false)
235
+ ? this.setMobileState(true)
236
+ : this.setMobileState(false)
229
237
  const currentBrowser = this.getBrowser() //get current browser vendor
230
238
 
231
239
  // register the current browser in the store
232
- this.$store.dispatch('setCurrentBrowser', currentBrowser)
240
+ this.setCurrentBrowser(currentBrowser)
233
241
 
234
242
  // register device type running the App in the store (ios, Android or Deskop)
235
- this.$store.dispatch('setDeviceType', this.detectDevice())
243
+ this.setDeviceType(this.detectDevice())
236
244
 
237
245
  this.$bus.$on('set-comp-status', this.updateTracker)
238
246
  this.$bus.$on('send-xapi-statement', this.sendXapiStatements)
@@ -264,8 +272,22 @@ export default {
264
272
  this.$bus.$off('reset-focus-on', this.resetFocus)
265
273
  this.$bus.$off('send-xapi-statement', this.sendXapiStatements)
266
274
  this.$bus.$off('move-to-target', this.moveTo)
275
+
276
+ if (this.getAppConfigs.remote) this.unsubscribeToSetConfig() //stop watching changing in store to save to local storage
267
277
  },
268
278
  methods: {
279
+ ...mapActions(useAppStore, [
280
+ 'setDeviceType',
281
+ 'updateDataFetchFromServer',
282
+ 'setUserMetaData',
283
+ 'setRouteHistory',
284
+ 'setApplicationSettings',
285
+ 'setMediaPlaybarValues',
286
+ 'updateCompStatusTracker',
287
+ 'setAppConfigs',
288
+ 'setMobileState',
289
+ 'setCurrentBrowser'
290
+ ]),
269
291
  /**
270
292
  * @description set the desired language for the app default is french
271
293
  * @param {String} [lang=fr]
@@ -349,20 +371,17 @@ export default {
349
371
  this.getConnectionInfo.actor.mbox.replace('mailto:', ''),
350
372
  this.getConnectionInfo.activity_id
351
373
  )
352
- const { routeHistory, ...userProgress } = progress
374
+ const { routeHistory = [], ...userProgress } = progress
353
375
 
354
376
  const completedState = await this.$xapi._getLessonStatus(
355
377
  this.getConnectionInfo.actor.mbox.replace('mailto:', ''),
356
378
  this.getConnectionInfo.activity_id
357
379
  )
358
380
 
359
- //=======UPCOMING: Uncomment lines bellow when these properties are integrated ========
360
- // Get existing record for user preferred settings
361
- // const applicationSettings = await this.$xapi._getPreferredSettings(
362
- // this.getConnectionInfo.actor.mbox.replace('mailto:', ''),
363
- // this.getConnectionInfo.activity_id
364
- // )
365
-
381
+ const lessonPosition = await this.$xapi._getLessonPosition(
382
+ this.getConnectionInfo.actor.mbox.replace('mailto:', ''),
383
+ this.getConnectionInfo.activity_id
384
+ )
366
385
  //======= End UPCOMING: Uncomment when this property are integrated ========
367
386
  //Get existing record for play bar settings. Play bar info is from the activity Parent ID and not activity id
368
387
  const _url = new URL(this.getConnectionInfo.activity_id)
@@ -371,28 +390,33 @@ export default {
371
390
  this.getConnectionInfo.actor.mbox.replace('mailto:', ''),
372
391
  parentID
373
392
  )
374
- const lessonPosition = await this.$xapi._getLessonPosition(
393
+
394
+ //=======UPCOMING: Uncomment lines bellow when these properties are integrated ========
395
+ // Get existing record for user preferred settings
396
+ const applicationSettings = await this.$xapi._getPreferredSettings(
375
397
  this.getConnectionInfo.actor.mbox.replace('mailto:', ''),
376
- this.getConnectionInfo.activity_id
398
+ parentID
377
399
  )
378
-
379
400
  //Update the App Store data
380
- this.$store.dispatch('updateDataFetchFromServer', {
401
+ this.updateDataFetchFromServer({
381
402
  userProgress,
382
403
  routeHistory,
383
404
  lessonPosition,
384
405
  completedState,
385
- playbarValues
406
+ playbarValues,
407
+ applicationSettings
408
+ }).then(() => {
409
+ // console.log('DATA FROM SERVER', {
410
+ // userProgress,
411
+ // routeHistory,
412
+ // lessonPosition,
413
+ // completedState,
414
+ // playbarValues,
415
+ // applicationSettings
416
+ // })// for testing
417
+
418
+ this.updateTracker('appBase_fetch', 'ready')
386
419
  })
387
- // console.log('DATA FROM SERVER', {
388
- // userProgress,
389
- // routeHistory,
390
- // lessonPosition,
391
- // completedState,
392
- // playbarValues
393
- // })
394
-
395
- this.updateTracker('appBase_fetch', 'ready')
396
420
  },
397
421
 
398
422
  executeCloseEventTriggered() {
@@ -430,8 +454,11 @@ export default {
430
454
  const userProgress = JSON.parse(scormRecord).userData
431
455
  const routeHistory = JSON.parse(scormRecord).routeHistory
432
456
 
433
- this.$store.dispatch('setUserMetaData', userProgress)
434
- this.$store.dispatch('setRouteHistory', routeHistory) // update store recored with existing record
457
+ this.setUserMetaData(userProgress)
458
+ this.setRouteHistory(routeHistory) // update store recored with existing record
459
+ //Should Redirect to the last Route in History
460
+ // const lastRoute = routeHistory.toReversed()[0]
461
+ // this.$router.push({ name: lastRoute.parent._namedRoute })
435
462
  }
436
463
 
437
464
  // No LMS use LocalStorage record
@@ -439,12 +466,10 @@ export default {
439
466
  this.$idb.openDB().then(() => {
440
467
  this.$idb.getFromDB(this.getModuleInfo.idbID).then((res) => {
441
468
  if (res && res.$record) {
442
- const { routeHistory, userSettings, ...userData } =
443
- res.$record
444
- this.$store.dispatch('setUserMetaData', userData) // update store record with existing record
445
- this.$store.dispatch('setRouteHistory', routeHistory) // update store record with existing route info
446
- if (userSettings)
447
- this.$store.dispatch('setApplicationSettings', userSettings) // update store record with existing user settings
469
+ const { routeHistory, userSettings, progress } = res.$record
470
+ this.setUserMetaData(...progress) // update store record with existing record
471
+ this.setRouteHistory(routeHistory) // update store record with existing route info
472
+ if (userSettings) this.setApplicationSettings(userSettings) // update store record with existing user settings
448
473
  }
449
474
  })
450
475
  })
@@ -461,30 +486,36 @@ export default {
461
486
  ) {
462
487
  if (!this.getDataFromServer) return
463
488
  //Try to get the user progress from LRS
464
- const { playbarValues, routeHistory, userProgress } =
465
- this.getDataFromServer
466
-
467
- this.$store.dispatch('setUserMetaData', userProgress) // update store record with existing record
468
- this.$store.dispatch('setRouteHistory', routeHistory) // update store record with existing record
469
- if (playbarValues)
470
- this.$store.dispatch('setMediaPLaybarValues', playbarValues) // update store record with existing record
471
- //Should update the playbar values
489
+ const {
490
+ playbarValues,
491
+ routeHistory,
492
+ userProgress,
493
+ lessonPosition,
494
+ applicationSettings
495
+ } = this.getDataFromServer
496
+
497
+ this.setUserMetaData(userProgress) // update store record with existing record
498
+ this.setRouteHistory(routeHistory) // update store record with existing record
499
+
500
+ if (playbarValues) this.setMediaPlaybarValues(playbarValues) // update store record with existing record
501
+
502
+ if (applicationSettings)
503
+ this.setApplicationSettings(applicationSettings) // set the user preferred settings
504
+
505
+ //Handel bookmark navigation
506
+ if (this.bookmarkActive && lessonPosition)
507
+ this.$router.push({ name: lessonPosition }) //Should Redirect to bookmark
472
508
  } else {
473
509
  //Get existing records for user data in local store
474
510
  this.$idb.openDB().then(() => {
475
511
  this.$idb.getFromDB(this.getModuleInfo.idbID).then((res) => {
476
512
  if (res && res.$record) {
477
- const { routeHistory, userSettings, ...userData } =
478
- res.$record
479
-
480
- this.$store.dispatch('setUserMetaData', userData) // update store record with existing record
481
- this.$store.dispatch('setRouteHistory', routeHistory) // update store record with existing route info
513
+ const { routeHistory, userSettings, progress } = res.$record
514
+ this.setUserMetaData(progress) // update store record with existing record
515
+ this.setRouteHistory(routeHistory) // update store record with existing route info
482
516
 
483
517
  if (userSettings) {
484
- this.$store.dispatch(
485
- 'setApplicationSettings',
486
- userSettings
487
- ) // update store record with existing user setting
518
+ this.setApplicationSettings(userSettings) // update store record with existing user setting
488
519
  }
489
520
  }
490
521
  })
@@ -494,11 +525,10 @@ export default {
494
525
 
495
526
  break
496
527
  }
497
-
498
528
  this.updateTracker('appBase', 'ready')
499
529
  },
500
530
  updateTracker(name, status) {
501
- this.$store.dispatch('updateCompStatusTracker', { name, status })
531
+ this.updateCompStatusTracker({ name, status })
502
532
  },
503
533
  //============================Multiple Satements Sending at once======================================
504
534
  /**
@@ -775,12 +805,22 @@ export default {
775
805
  extensions: [
776
806
  {
777
807
  id: 'ending-point',
778
- content: this.$route.name
808
+ content: (() =>
809
+ this.$route.name == 'menu'
810
+ ? this.$helper.getRoutesFromVueRouter().meta.children[0]
811
+ ._namedRoute
812
+ : this.$route.name)()
779
813
  },
780
814
  {
781
815
  id: 'user-data',
782
816
  content: {
783
- routeHistory: this.getRouteHistory,
817
+ routeHistory: (() => {
818
+ const history = this.getRouteHistory.toReversed() //get the route history from the last
819
+
820
+ history[0] = this.$route.meta // change the last recored route to the current route
821
+
822
+ return history.toReversed()
823
+ })(),
784
824
  ...lessonsData
785
825
  }
786
826
  }
@@ -809,9 +849,36 @@ export default {
809
849
  }
810
850
  ]
811
851
  }
812
- //================================STATEMENT FOR THE PLAYBAR ===============================================
852
+ //================================STATEMENT FOR THE SETTINGS ===============================================
813
853
 
814
- this.sendXapiStatements([stmtPlaybar, stmt, endStmt], null, option) //send xapi statement
854
+ //Creating custom statement
855
+ const stmtUserSettings = {
856
+ id: (() => {
857
+ if (this.getModuleInfo.courseID) return this.getModuleInfo.courseID
858
+ else return null
859
+ })(),
860
+ verb: 'preferred',
861
+ definition: text,
862
+ description: text,
863
+ extensions: [
864
+ {
865
+ id: 'application-settings',
866
+ content: {
867
+ ...this.getApplicationSettings
868
+ }
869
+ // content: {
870
+ // bookmark: false
871
+ // } //for testing
872
+ }
873
+ ]
874
+ }
875
+ //================================END STATEMENT ===============================================
876
+
877
+ this.sendXapiStatements(
878
+ [stmtPlaybar, stmtUserSettings, stmt, endStmt],
879
+ null,
880
+ option
881
+ ) //send xapi statement
815
882
 
816
883
  if (this.timerState === 'started') setTimeout(() => this.stopTimer(), 0) //clear the timer
817
884
 
@@ -826,8 +893,9 @@ export default {
826
893
  */
827
894
  async resetUserData() {
828
895
  this.$bus.$emit('set-comp-status', 'appBase', 'loading')
829
- this.$store.dispatch('setUserMetaData', {}) // resetting store record with existing for user data
830
- this.$store.dispatch('setRouteHistory', []) // resetting store record for all last visited pages
896
+ this.setUserMetaData({}) // resetting store record with existing for user data
897
+ this.setApplicationSettings({}) // resetting store record for settings
898
+ this.setRouteHistory([]) // resetting store record for all last visited pages
831
899
 
832
900
  this.$bus.$emit('stop-timer')
833
901
  if (this.getModuleInfo.packageType !== 'xapi') return
@@ -836,9 +904,7 @@ export default {
836
904
  return this.$idb.deleteDataInDB(this.getModuleInfo.idbID) //Must call the idb delete methode to reset indexDB store
837
905
 
838
906
  //Send a completion statement for the current activity
839
- let aTitle = `${this.$t('text.activity')} ${
840
- this.getConnectionInfo.activity_id
841
- }`
907
+ let aTitle = `${this.$t('text.activity')} ${this.getConnectionInfo.activity_id}`
842
908
 
843
909
  //Custom text for description and definition of the stament to be sent
844
910
  let text
@@ -849,7 +915,7 @@ export default {
849
915
  /*Dispatch a send statement event to method AppBaseModule sendXapiStatement(s)
850
916
  Content values are:
851
917
  User data URI: "host_address/course_ID/Lesson_ID/user-data" ex: "http://localhost:8080/330N01FD6001/m1l1/ // user-data" and
852
- User Bookmark URI: "host_address/course_ID/Lesson_ID/ending-point" ex: ""http://localhost:8080/330N01FD6001/m1l1/ending-point": "menu"
918
+ User Bookmark URI: "host_address/course_ID/Lesson_ID/ending-point" ex: ""http://localhost:8080/330N01FD6001/m1l1/ending-point": "introduction"
853
919
  */
854
920
  const baseStmt = {
855
921
  definition: text,
@@ -866,7 +932,11 @@ export default {
866
932
  extensions: [
867
933
  {
868
934
  id: 'ending-point',
869
- content: this.$route.name
935
+ content: (() =>
936
+ this.$route.name == 'menu'
937
+ ? this.$helper.getRoutesFromVueRouter().meta.children[0]
938
+ ._namedRoute
939
+ : this.$route.name)()
870
940
  },
871
941
  {
872
942
  id: 'user-data',
@@ -876,24 +946,53 @@ export default {
876
946
  duration: null,
877
947
  completion: false // Resetting completion state value to
878
948
  }
949
+ //================================STATEMENT FOR THE SETTINGS ===============================================
879
950
 
880
- this.sendXapiStatements([exitStmt, endStmt])
951
+ //Creating custom statement
952
+ const stmtUserSettings = {
953
+ ...baseStmt,
954
+ id: (() => {
955
+ if (this.getModuleInfo.courseID) return this.getModuleInfo.courseID
956
+ else return null
957
+ })(),
958
+
959
+ verb: 'preferred',
960
+ extensions: [
961
+ {
962
+ id: 'application-settings',
963
+ content: new Object()
964
+ }
965
+ ]
966
+ }
967
+ //================================END STATEMENT ===============================================
968
+
969
+ this.sendXapiStatements([stmtUserSettings, exitStmt, endStmt])
881
970
 
882
971
  this.$bus.$emit('set-comp-status', 'appBase', 'ready')
883
972
 
884
973
  // Creating a asynchronous fecth method that would resolve after a 2 second
885
974
  const fetchData = async () => {
886
- return new Promise((resolve) => {
887
- setTimeout(
888
- () =>
889
- resolve(
890
- this.$xapi._getProgress(
891
- this.getConnectionInfo.actor.mbox.replace('mailto:', ''),
892
- this.getConnectionInfo.activity_id
893
- )
894
- ),
895
- 2000
975
+ //funtion that will make a multiple request on the server
976
+ const requests = async () => {
977
+ const _url = new URL(this.getConnectionInfo.activity_id)
978
+ const parentID = `${_url.origin}/${this.getModuleInfo.courseID}` // redefining activity id for statement
979
+
980
+ const progress = await this.$xapi._getProgress(
981
+ this.getConnectionInfo.actor.mbox.replace('mailto:', ''),
982
+ this.getConnectionInfo.activity_id
983
+ )
984
+ const lessonPosition = await this.$xapi._getLessonPosition(
985
+ this.getConnectionInfo.actor.mbox.replace('mailto:', ''),
986
+ this.getConnectionInfo.activity_id
987
+ )
988
+ const applicationSettings = await this.$xapi._getPreferredSettings(
989
+ this.getConnectionInfo.actor.mbox.replace('mailto:', ''),
990
+ parentID
896
991
  )
992
+ return { progress, lessonPosition, applicationSettings }
993
+ }
994
+ return new Promise((resolve) => {
995
+ setTimeout(() => resolve(requests()), 2000)
897
996
  })
898
997
  }
899
998
 
@@ -928,11 +1027,11 @@ export default {
928
1027
  if (targetEl) skipTo = targetEl
929
1028
  }
930
1029
 
931
- opt.top = skipTo.offsetTop + opt.top // Set scroll top from target top
1030
+ if (skipTo) opt.top = skipTo.offsetTop + opt.top // Set scroll top from target top
932
1031
 
933
- skipTo.setAttribute('tabIndex', -1) //Allowing accessibility control with keyboard
1032
+ if (skipTo) skipTo.setAttribute('tabIndex', -1) //Allowing accessibility control with keyboard
934
1033
  window.scrollTo(opt)
935
- this.resetFocus(skipTo) //focus on the target
1034
+ if (skipTo) this.resetFocus(skipTo) //focus on the target
936
1035
  },
937
1036
 
938
1037
  /**
@@ -998,11 +1097,6 @@ export default {
998
1097
  }
999
1098
  </script>
1000
1099
  <style lang="scss">
1001
- body {
1002
- &:focus {
1003
- border: none !important;
1004
- }
1005
- }
1006
1100
  #App-base {
1007
1101
  width: 100%;
1008
1102
  height: 100%;
@@ -1015,10 +1109,6 @@ body {
1015
1109
  top: 0;
1016
1110
  left: 0;
1017
1111
  z-index: 9999;
1018
-
1019
- .grp-spinners span {
1020
- margin: 0px 2px;
1021
- }
1022
1112
  }
1023
1113
 
1024
1114
  #build-info {
@@ -1046,4 +1136,12 @@ body {
1046
1136
  position: relative;
1047
1137
  }
1048
1138
  }
1139
+ .grp-spinners {
1140
+ span {
1141
+ margin: 0px 2px;
1142
+ }
1143
+ .v-progress-circular {
1144
+ margin: 0.8rem !important;
1145
+ }
1146
+ }
1049
1147
  </style>
@@ -8,7 +8,7 @@
8
8
  :type="type"
9
9
  class="btn"
10
10
  :class="{ click: isClick, 'btn-visited': isVisited, md_disabled: isActive }"
11
- :aria-disabled="isActive"
11
+ :aria-disabled="isActive ? true : null"
12
12
  @click="click"
13
13
  @focus="focus"
14
14
  @blur="blur"
@@ -32,6 +32,7 @@ export default {
32
32
  default: 'button'
33
33
  }
34
34
  },
35
+ emits: ['click', 'focus', 'blur', 'mouseenter', 'mouseleave'],
35
36
  data() {
36
37
  return {
37
38
  isClick: false,
@@ -82,10 +83,5 @@ export default {
82
83
  .btn {
83
84
  display: flex;
84
85
  align-items: center;
85
-
86
- &.md_disabled {
87
- background-color: #80808066 !important;
88
- opacity: 0.5;
89
- }
90
86
  }
91
87
  </style>