fcad-core-dragon 2.0.0-beta.1 → 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.
Files changed (78) hide show
  1. package/{.eslintrc.js → .eslintrc.cjs} +13 -18
  2. package/bk.scss +117 -0
  3. package/package.json +23 -39
  4. package/src/$locales/en.json +30 -16
  5. package/src/$locales/fr.json +29 -16
  6. package/src/components/AppBase.vue +740 -305
  7. package/src/components/AppBaseButton.vue +33 -5
  8. package/src/components/AppBaseErrorDisplay.vue +43 -35
  9. package/src/components/AppBaseModule.vue +447 -623
  10. package/src/components/AppBasePage.vue +37 -25
  11. package/src/components/AppCompAudio.vue +266 -0
  12. package/src/components/AppCompBranchButtons.vue +52 -63
  13. package/src/components/AppCompButtonProgress.vue +1 -16
  14. package/src/components/AppCompCarousel.vue +43 -39
  15. package/src/components/AppCompInputCheckBox.vue +9 -3
  16. package/src/components/AppCompInputDropdown.vue +2 -4
  17. package/src/components/AppCompInputRadio.vue +8 -15
  18. package/src/components/AppCompInputTextTable.vue +15 -12
  19. package/src/components/AppCompInputTextToFillDropdown.vue +16 -14
  20. package/src/components/AppCompInputTextToFillText.vue +2 -2
  21. package/src/components/AppCompJauge.vue +13 -1
  22. package/src/components/AppCompMenu.vue +203 -10
  23. package/src/components/AppCompMenuItem.vue +20 -3
  24. package/src/components/AppCompNavigation.vue +351 -355
  25. package/src/components/AppCompNoteCall.vue +62 -47
  26. package/src/components/AppCompNoteCredit.vue +182 -79
  27. package/src/components/AppCompPlayBar.vue +975 -1023
  28. package/src/components/AppCompPlayBarProgress.vue +73 -0
  29. package/src/components/AppCompPopUp.vue +175 -114
  30. package/src/components/AppCompQuiz.vue +67 -81
  31. package/src/components/AppCompQuizRecall.vue +32 -5
  32. package/src/components/AppCompSVG.vue +66 -40
  33. package/src/components/AppCompSettingsMenu.vue +6 -8
  34. package/src/components/AppCompTableOfContent.vue +166 -45
  35. package/src/components/AppCompVideoPlayer.vue +154 -110
  36. package/src/components/BaseModule.vue +21 -17
  37. package/src/main.js +124 -88
  38. package/src/mixins/$mediaMixins.js +827 -0
  39. package/src/mixins/$pageMixins.js +65 -109
  40. package/src/mixins/$quizMixins.js +12 -26
  41. package/src/mixins/timerMixin.js +8 -9
  42. package/src/module/store.js +187 -68
  43. package/src/module/xapi/ADL.js +90 -53
  44. package/src/module/xapi/Crypto/Hasher.js +8 -8
  45. package/src/module/xapi/Crypto/WordArray.js +6 -6
  46. package/src/module/xapi/Crypto/algorithms/BufferedBlockAlgorithm.js +4 -4
  47. package/src/module/xapi/Crypto/algorithms/C_algo.js +14 -18
  48. package/src/module/xapi/Crypto/algorithms/HMAC.js +1 -1
  49. package/src/module/xapi/Crypto/algorithms/SHA1.js +1 -1
  50. package/src/module/xapi/Crypto/encoders/Base.js +7 -7
  51. package/src/module/xapi/Crypto/encoders/Base64.js +3 -3
  52. package/src/module/xapi/Crypto/encoders/Hex.js +2 -2
  53. package/src/module/xapi/Crypto/encoders/Latin1.js +3 -3
  54. package/src/module/xapi/Crypto/encoders/Utf8.js +3 -3
  55. package/src/module/xapi/Statement/index.js +1 -1
  56. package/src/module/xapi/launch.js +10 -10
  57. package/src/module/xapi/utils.js +17 -17
  58. package/src/module/xapi/wrapper.js +123 -50
  59. package/src/module/xapi/xapiStatement.js +29 -29
  60. package/src/plugins/helper.js +8 -9
  61. package/src/plugins/i18n.js +23 -10
  62. package/src/plugins/scorm.js +14 -14
  63. package/src/router/index.js +3 -4
  64. package/src/router/routes.js +10 -30
  65. package/src/shared/generalfuncs.js +31 -24
  66. package/src/shared/validators.js +730 -20
  67. package/.prettierrc.js +0 -5
  68. package/babel.config.js +0 -3
  69. package/src/components/AppBaseDragChoice.vue +0 -91
  70. package/src/components/AppBaseDropZone.vue +0 -112
  71. package/src/components/AppCompBif.vue +0 -120
  72. package/src/components/AppCompDragAndDrop.vue +0 -339
  73. package/src/components/AppCompInputAssociation.vue +0 -332
  74. package/src/components/AppCompMediaPlayer.vue +0 -397
  75. package/src/plugins/timeManager.js +0 -77
  76. package/src/routes_bckp.js +0 -313
  77. package/src/routes_static.js +0 -344
  78. package/vue.config.js +0 -83
package/src/main.js CHANGED
@@ -7,9 +7,10 @@ import AppBasePage from './components/AppBasePage.vue'
7
7
  import AppBaseFlipCard from './components/AppBaseFlipCard.vue'
8
8
  import AppCompJauge from './components/AppCompJauge.vue'
9
9
  import AppBaseErrorDisplay from './components/AppBaseErrorDisplay.vue'
10
- import AppCompBif from './components/AppCompBif.vue'
11
- import AppCompBranchButtons from './components/AppCompBranchButtons'
12
- import AppCompCarousel from './components/AppCompCarousel'
10
+ //import AppCompBif from './components/AppCompBif.vue'
11
+ import AppCompAudio from './components/AppCompAudio.vue'
12
+ import AppCompBranchButtons from './components/AppCompBranchButtons.vue'
13
+ import AppCompCarousel from './components/AppCompCarousel.vue'
13
14
  import AppCompViewDisplay from './components/AppCompViewDisplay.vue'
14
15
  import AppCompTableOfContent from './components/AppCompTableOfContent.vue'
15
16
  import AppCompMenu from './components/AppCompMenu.vue'
@@ -19,8 +20,9 @@ import AppCompNavigation from './components/AppCompNavigation.vue'
19
20
  import AppCompNoteCall from './components/AppCompNoteCall.vue'
20
21
  import AppCompNoteCredit from './components/AppCompNoteCredit.vue'
21
22
  import AppCompPopover from './components/AppCompPopover.vue'
22
- import AppCompVideoPlayer from './components/AppCompVideoPlayer'
23
- import AppCompPlayBar from './components/AppCompPlayBar'
23
+ import AppCompVideoPlayer from './components/AppCompVideoPlayer.vue'
24
+ import AppCompPlayBar from './components/AppCompPlayBar.vue'
25
+ //import AppCompPlayBarAudio from './components/AppCompPlayBarAudio'
24
26
  import AppCompQuizRecall from './components/AppCompQuizRecall.vue'
25
27
  import store from './module/store'
26
28
  import GsapPlugin from './plugins/gsap'
@@ -31,14 +33,16 @@ import { scormPlugin } from './plugins/scorm'
31
33
  import { xapiPlugin } from './plugins/xapi'
32
34
  import { $idb } from './plugins/idb'
33
35
  import PortalVue from 'portal-vue'
36
+ import { validatefileContent } from './shared/validators.js'
37
+
34
38
  import axios from 'axios'
35
- import AppCompSVG from './components/AppCompSVG'
39
+ import VueAxios from 'vue-axios'
40
+ import AppCompSVG from './components/AppCompSVG.vue'
36
41
  Vue.config.productionTip = false
37
42
 
38
43
  export default {
39
44
  install(Vue, options) {
40
45
  Vue.use(PortalVue)
41
-
42
46
  Vue.use(GsapPlugin, '$gsap')
43
47
  Vue.use(scormPlugin, '$scorm')
44
48
  Vue.use(xapiPlugin, '$xapi')
@@ -46,37 +50,39 @@ export default {
46
50
  Vue.use(BootstrapVue)
47
51
  Vue.use(IconsPlugin)
48
52
  Vue.use($idb)
53
+ Vue.use(VueAxios, axios)
49
54
 
50
- Vue.component('app-base', AppBase)
51
- Vue.component('app-base-button', AppBaseButton)
52
- Vue.component('app-base-module', AppBaseModule)
53
- Vue.component('app-base-page', AppBasePage)
54
- Vue.component('app-base-flip-card', AppBaseFlipCard)
55
- Vue.component('app-base-error-display', AppBaseErrorDisplay)
56
- Vue.component('app-comp-menu', AppCompMenu)
57
- Vue.component('app-comp-bif', AppCompBif)
58
- Vue.component('app-comp-branch-buttons', AppCompBranchButtons)
59
- Vue.component('app-comp-carousel', AppCompCarousel)
60
- Vue.component('app-comp-menu-item', AppCompMenuItem)
61
- Vue.component('app-comp-jauge', AppCompJauge)
62
- Vue.component('app-comp-table-of-content', AppCompTableOfContent)
63
- Vue.component('app-comp-pop-up', AppCompPopUp)
64
- Vue.component('app-comp-navigation', AppCompNavigation)
65
- Vue.component('app-comp-note-credit', AppCompNoteCredit)
66
- Vue.component('app-comp-note-call', AppCompNoteCall)
67
-
68
- Vue.component('app-comp-popover', AppCompPopover)
69
- Vue.component('app-comp-video-player', AppCompVideoPlayer)
70
- Vue.component('app-comp-play-bar', AppCompPlayBar)
71
- Vue.component('app-icons', AppCompSVG)
72
- Vue.component('app-comp-quiz-recall', AppCompQuizRecall)
55
+ Vue.component('AppBase', AppBase)
56
+ Vue.component('AppBaseButton', AppBaseButton)
57
+ Vue.component('AppBaseModule', AppBaseModule)
58
+ Vue.component('AppBasePage', AppBasePage)
59
+ Vue.component('AppBaseFlipCard', AppBaseFlipCard)
60
+ Vue.component('AppBaseErrorDisplay', AppBaseErrorDisplay)
61
+ Vue.component('AppCompMenu', AppCompMenu)
62
+ //Vue.component('app-comp-bif', AppCompBif)
63
+ Vue.component('AppCompAudioPlayer', AppCompAudio)
64
+ Vue.component('AppCompBranchButtons', AppCompBranchButtons)
65
+ Vue.component('AppCompCarousel', AppCompCarousel)
66
+ Vue.component('AppCompMenuItem', AppCompMenuItem)
67
+ Vue.component('AppCompJauge', AppCompJauge)
68
+ Vue.component('AppCompTableOfContent', AppCompTableOfContent)
69
+ Vue.component('AppCompPopUp', AppCompPopUp)
70
+ Vue.component('AppCompNavigation', AppCompNavigation)
71
+ Vue.component('AppCompNoteCredit', AppCompNoteCredit)
72
+ Vue.component('AppCompNoteCall', AppCompNoteCall)
73
+
74
+ Vue.component('AppCompPopover', AppCompPopover)
75
+ Vue.component('AppCompVideoPlayer', AppCompVideoPlayer)
76
+ Vue.component('AppCompPlayBar', AppCompPlayBar)
77
+ //Vue.component('app-comp-play-bar-audio', AppCompPlayBarAudio)
78
+ Vue.component('AppIcons', AppCompSVG)
79
+ Vue.component('AppCompQuizRecall', AppCompQuizRecall)
73
80
  Vue.component(AppCompViewDisplay)
74
81
 
75
- const requiredOptions = ['store', 'i18n', 'appSettings', 'menuSettings']
82
+ const requiredOptions = ['store', 'i18n', 'menuSettings']
76
83
  const errorMissing = {
77
84
  store: { a: 'Store', b: 'vuex' },
78
85
  i18n: { a: 'Internationalisation', b: 'vue-I18n' },
79
- appSettings: { a: 'App Settings file', b: 'appSettings' },
80
86
  menuSettings: { a: 'Menu Settings file', b: 'menuSettings' }
81
87
  /// nom de composante avec l'error avec la string comme en haut
82
88
  }
@@ -84,6 +90,35 @@ export default {
84
90
  throw new Error(
85
91
  '💥You did not provide i18n and vuex store. Please install and provide them.'
86
92
  )
93
+
94
+ /*Watch for appBase data received in the store
95
+ *To set connection Info
96
+ *To set the connection with indexDB
97
+ *To set document lang
98
+ */
99
+
100
+ options.store.subscribe(async (mutation, state) => {
101
+ if (mutation.type === 'SET_APP_CONFIGS') {
102
+ let { appConfigs } = state.$appStore
103
+
104
+ //Configure connection with the Data from appBase
105
+ configConnection(appConfigs).then((c) => {
106
+ //Save LRS CONFIGURATION TO STORE
107
+ store.mutations.SET_LRS_CONFIG(store.state, c)
108
+ // Subscribe to changes in the state to save progress in localStorage when application is not in remote mode
109
+ if (!c.remote)
110
+ Vue.prototype.$idb
111
+ .openDB()
112
+ .then(() =>
113
+ Vue.prototype.$idb.saveState(options.store, appConfigs.idb_id)
114
+ )
115
+ })
116
+ //Set document lang attribute (wcag request)
117
+ document.documentElement.setAttribute('lang', appConfigs.lang)
118
+ }
119
+ })
120
+
121
+ /* Check that required options are provided */
87
122
  requiredOptions.forEach((key) => {
88
123
  // required key is missing in $data that was passed for the page
89
124
  if (!Object.keys(options).includes(key)) {
@@ -91,38 +126,43 @@ export default {
91
126
  `👉${errorMissing[key].a}👈 is not provided. Please install and provide 👉${errorMissing[key].b}👈.`
92
127
  )
93
128
  }
129
+
130
+ if (key === 'menuSettings') {
131
+ const mapAct = store.state.thisModule.activities
132
+ const keys4Lesson = ['lessonTitle', ...mapAct.keys()]
133
+ const keys4ActivityOpt = ['title', 'subTitle']
134
+ const keys4ActivityMando = ['time', 'anchors']
135
+ const keys4Anchors = ['anchorName', 'pageRef', 'page']
136
+
137
+ const errChecked = validatefileContent(
138
+ 'menuSettings',
139
+ options.menuSettings,
140
+ {
141
+ keys4Lesson,
142
+ keys4ActivityMando,
143
+ keys4ActivityOpt,
144
+ keys4Anchors
145
+ }
146
+ )
147
+ if (errChecked) {
148
+ store.mutations.SET_ERROR_MENU(store.state, errChecked)
149
+ } else {
150
+ store.mutations.SET_ERROR_MENU(store.state, false)
151
+ }
152
+ }
94
153
  })
95
154
 
96
- //Update the module info of the Store
97
- //Separate data we want to display for the module information and data we want to only display for the app configuration
98
- let {
99
- id,
100
- crs_id: courseID = null,
101
- idb_id: idbID,
102
- specification: packageType = 'scorm',
103
- actor = {
104
- mbox: 'mailto:totoescargot@email.com',
105
- name: 'Toto Escargot',
106
- objectType: 'Agent'
107
- },
108
- endpointConfig = null,
109
- remote = null,
110
- dr_mode,
111
- ...others
112
- } = options.appSettings
113
-
114
- //============================== SET LRS INFO =======================================
115
-
116
- const configConnection = async () => {
117
- if (!packageType === 'xapi') return
155
+ window.App_DEBUGMODE = false
156
+
157
+ /* Local Method to configurate the connection info */
158
+ const configConnection = async (data) => {
159
+ if (data && data.specification !== 'xapi') return
118
160
 
119
161
  switch (true) {
120
162
  case window.location.origin.includes('cegepadistance.ca'): {
121
163
  try {
122
164
  let connectionInfo
123
165
 
124
- store.mutations.UPDATE_APP_STATUS(store.state, 'loading')
125
-
126
166
  // Accessing User && Activity Info from Url parametters
127
167
  const queryString = window.location.search
128
168
  const urlParams = new URLSearchParams(queryString)
@@ -152,9 +192,22 @@ export default {
152
192
  break
153
193
  }
154
194
  case window.location.origin.includes('localhost'): {
195
+ if (!data) return
196
+ let {
197
+ id,
198
+ crs_id = null,
199
+ actor = {
200
+ mbox: 'mailto:totoescargot@email.com',
201
+ name: 'Toto Escargot',
202
+ objectType: 'Agent'
203
+ },
204
+ endpointConfig = null,
205
+ remote = null
206
+ } = data
207
+
155
208
  const origin = window.location.origin
156
- const activity_id = courseID
157
- ? `${origin}/${courseID}/${id}`
209
+ const activity_id = crs_id
210
+ ? `${origin}/${crs_id}/${id}`
158
211
  : `${origin}/${id}`
159
212
 
160
213
  if (remote == null) remote = false
@@ -162,8 +215,7 @@ export default {
162
215
  if (endpointConfig == null)
163
216
  endpointConfig = {
164
217
  endpoint: 'https://learninglocker.cegepadistance.ca/data/xAPI/',
165
- auth:
166
- 'Basic MmU4ZGQ3NTY1NDRiZWUxNmUxZWYzZDZiOThjNWVjY2YxNjVhZjIyNzpkY2Q5Zjk4OWZlYjU3MmZlZjBhNDkxZDIxNmYyNmQyY2M1YTQ4Nzlh'
218
+ auth: 'Basic MmU4ZGQ3NTY1NDRiZWUxNmUxZWYzZDZiOThjNWVjY2YxNjVhZjIyNzpkY2Q5Zjk4OWZlYjU3MmZlZjBhNDkxZDIxNmYyNmQyY2M1YTQ4Nzlh'
167
219
  }
168
220
 
169
221
  let connectionInfo = {
@@ -179,38 +231,22 @@ export default {
179
231
  }
180
232
 
181
233
  //=================================END SET LRS INFO ====================================
234
+ window.setDebugMode = (mode) => {
235
+ store.mutations.SET_APP_DEBUG_MODE(store.state, mode)
236
+ const msg = mode ? 'DEBUG MODE ON' : 'DEBUG MODE OFF'
237
+ console.log(`🚩 ${msg}`)
238
+ }
182
239
 
183
- store.mutations.SET_APP_CONFIGS(store.state, others)
184
240
  store.mutations.SET_MENU(store.state, options.menuSettings)
185
- store.mutations.UPDATE_MODULE(store.state, {
186
- key: 'info',
187
- data: { id, courseID, idbID, packageType }
188
- })
189
241
 
190
- configConnection().then((c) => {
191
- store.mutations.SET_LRS_CONFIG(store.state, c)
192
- // Suscribe to changes in the state to save progress in localStorage when application is not in remote mode
193
- if (!c.remote)
194
- Vue.prototype.$idb
195
- .openDB()
196
- .then(() => Vue.prototype.$idb.saveState(options.store, idbID))
197
-
198
- store.mutations.UPDATE_APP_STATUS(store.state, 'ready')
199
- })
200
242
  //=================================SETTING PREFERENCES ====================================
201
243
 
202
244
  //define the settings option for user preference according to the mode of App
203
- let settingsOptions = (() => {
204
- return dr_mode
205
- ? {
206
- onboarding: null
207
- }
208
- : {
209
- autoplay: null
210
- // onboarding: null,// Uncomment when ready to add onboarding in settings
211
- // subtitles: null,// Uncomment when ready to add subtitle in settings
212
- }
213
- })()
245
+ let settingsOptions = {
246
+ autoplay: null
247
+ // onboarding: null,// Uncomment when ready to add onboarding in settings
248
+ // subtitles: null,// Uncomment when ready to add subtitle in settings
249
+ }
214
250
 
215
251
  store.mutations.SET_APPLICATION_SETTINGS(store.state, settingsOptions)
216
252
  //=================================END SETTING PREFERENCES ====================================
@@ -221,7 +257,7 @@ export default {
221
257
  //mergeLocales
222
258
  mergeLocales(options.i18n)
223
259
  Vue.use(helper, '$helper')
224
- //set document lang attribute (wcag request)
225
- document.documentElement.setAttribute('lang', options.appSettings.lang)
260
+
261
+ window.app = Vue
226
262
  }
227
263
  }