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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/{.eslintrc.js → .eslintrc.cjs} +13 -18
  2. package/README.md +1 -1
  3. package/bk.scss +117 -0
  4. package/package.json +22 -40
  5. package/src/$locales/en.json +57 -19
  6. package/src/$locales/fr.json +66 -28
  7. package/src/components/AppBase.vue +790 -376
  8. package/src/components/AppBaseButton.vue +33 -5
  9. package/src/components/AppBaseErrorDisplay.vue +62 -25
  10. package/src/components/AppBaseModule.vue +831 -754
  11. package/src/components/AppBasePage.vue +60 -74
  12. package/src/components/AppCompAudio.vue +266 -0
  13. package/src/components/AppCompBranchButtons.vue +79 -89
  14. package/src/components/AppCompButtonProgress.vue +35 -61
  15. package/src/components/AppCompCarousel.vue +160 -249
  16. package/src/components/AppCompInputCheckBox.vue +9 -3
  17. package/src/components/AppCompInputDropdown.vue +2 -4
  18. package/src/components/AppCompInputRadio.vue +8 -15
  19. package/src/components/AppCompInputTextTable.vue +15 -12
  20. package/src/components/AppCompInputTextToFillDropdown.vue +16 -14
  21. package/src/components/AppCompInputTextToFillText.vue +2 -2
  22. package/src/components/AppCompJauge.vue +14 -3
  23. package/src/components/AppCompMenu.vue +284 -85
  24. package/src/components/AppCompMenuItem.vue +67 -92
  25. package/src/components/AppCompNavigation.vue +945 -0
  26. package/src/components/AppCompNoteCall.vue +141 -0
  27. package/src/components/AppCompNoteCredit.vue +267 -0
  28. package/src/components/AppCompPlayBar.vue +1122 -1391
  29. package/src/components/AppCompPlayBarProgress.vue +73 -0
  30. package/src/components/AppCompPopUp.vue +195 -135
  31. package/src/components/AppCompPopover.vue +27 -0
  32. package/src/components/AppCompQuiz.vue +90 -113
  33. package/src/components/AppCompQuizRecall.vue +277 -0
  34. package/src/components/AppCompSVG.vue +335 -0
  35. package/src/components/AppCompSettingsMenu.vue +7 -8
  36. package/src/components/AppCompTableOfContent.vue +264 -88
  37. package/src/components/AppCompTranscript.vue +19 -0
  38. package/src/components/AppCompVideoPlayer.vue +380 -0
  39. package/src/components/BaseModule.vue +37 -114
  40. package/src/main.js +130 -85
  41. package/src/mixins/$mediaMixins.js +827 -0
  42. package/src/mixins/$pageMixins.js +149 -115
  43. package/src/mixins/$quizMixins.js +12 -26
  44. package/src/mixins/timerMixin.js +39 -16
  45. package/src/module/store.js +218 -78
  46. package/src/module/xapi/ADL.js +90 -53
  47. package/src/module/xapi/Crypto/Hasher.js +8 -8
  48. package/src/module/xapi/Crypto/WordArray.js +6 -6
  49. package/src/module/xapi/Crypto/algorithms/BufferedBlockAlgorithm.js +4 -4
  50. package/src/module/xapi/Crypto/algorithms/C_algo.js +14 -18
  51. package/src/module/xapi/Crypto/algorithms/HMAC.js +1 -1
  52. package/src/module/xapi/Crypto/algorithms/SHA1.js +1 -1
  53. package/src/module/xapi/Crypto/encoders/Base.js +7 -7
  54. package/src/module/xapi/Crypto/encoders/Base64.js +3 -3
  55. package/src/module/xapi/Crypto/encoders/Hex.js +4 -3
  56. package/src/module/xapi/Crypto/encoders/Latin1.js +3 -3
  57. package/src/module/xapi/Crypto/encoders/Utf8.js +3 -3
  58. package/src/module/xapi/Statement/index.js +1 -1
  59. package/src/module/xapi/launch.js +10 -10
  60. package/src/module/xapi/utils.js +17 -17
  61. package/src/module/xapi/wrapper.js +127 -54
  62. package/src/module/xapi/xapiStatement.js +29 -29
  63. package/src/plugins/gsap.js +4 -1
  64. package/src/plugins/helper.js +58 -24
  65. package/src/plugins/i18n.js +23 -10
  66. package/src/plugins/idb.js +1 -0
  67. package/src/plugins/scorm.js +14 -14
  68. package/src/public/index.html +1 -1
  69. package/src/router/index.js +40 -0
  70. package/src/router/routes.js +317 -0
  71. package/src/shared/generalfuncs.js +91 -9
  72. package/src/shared/validators.js +959 -0
  73. package/.prettierrc.js +0 -5
  74. package/babel.config.js +0 -3
  75. package/src/components/AppBaseDragChoice.vue +0 -91
  76. package/src/components/AppBaseDropZone.vue +0 -112
  77. package/src/components/AppCompDragAndDrop.vue +0 -339
  78. package/src/components/AppCompInputAssociation.vue +0 -332
  79. package/src/components/AppCompMediaPlayer.vue +0 -365
  80. package/src/components/AppCompNavigationFull.vue +0 -1791
  81. package/src/components/AppCompToolTip.vue +0 -94
  82. package/src/plugins/timeManager.js +0 -77
  83. package/src/routes.js +0 -734
  84. package/vue.config.js +0 -83
@@ -1,8 +1,7 @@
1
1
  <template>
2
- <div v-if="!error" class="box-gauge" :class="state">
2
+ <div v-if="!error" class="box-g" :class="state">
3
3
  <b-progress class="jauge" :value="value" :max="maxValue"></b-progress>
4
- <p v-if="pourcent">{{ getPourcent }} %</p>
5
- <p v-if="fraction">{{ value }} / {{ maxValue }}</p>
4
+ <p>{{ getPourcent }} %</p>
6
5
  </div>
7
6
  <div v-else>
8
7
  <div class="warning">
@@ -54,3 +53,15 @@ export default {
54
53
  methods: {}
55
54
  }
56
55
  </script>
56
+ <style lang="scss">
57
+ .box-g {
58
+ width: 100%;
59
+ display: flex;
60
+ flex-direction: row;
61
+ flex-wrap: wrap;
62
+
63
+ .jauge {
64
+ width: 80%;
65
+ }
66
+ }
67
+ </style>
@@ -1,33 +1,88 @@
1
1
  <!--
2
2
  @ Description: This component is used to create the menu and the ard that will bring you back where you were before the menu.
3
- @ What it does: Look in the store what was the last page you saw before you came to the menu and create the the link for the card. It display AppCompMenuItem and AppCompTableOfContent
3
+ @ What it does: Look in the store what was the last page you saw before you came to the menu and create the the link for the card. It display's AppCompMenuItem
4
4
  -->
5
5
  <template>
6
6
  <div class="menu-container">
7
- <b-row>
8
- <b-col md="4" class="wrapper-lasRoute">
9
- <b-link
10
- id="btn_last_route"
11
- class="nav_last_route"
12
- :to="{ name: GoToLastRoute() }"
13
- :title="handelLabel"
14
- >
15
- <div class="box-menu">
16
- <slot name="inside-last-route" />
17
-
18
- <div class="vsl-tmp">
19
- <p>
20
- {{ handelLabel }}
21
- </p>
22
- </div>
23
- </div>
24
- </b-link>
25
- </b-col>
7
+ <div
8
+ id="page_info_section"
9
+ aria-labelledby="page_info"
10
+ aria-live="true"
11
+ ></div>
12
+ <a
13
+ class="skip-link"
14
+ href=""
15
+ @click.prevent="$bus.$emit('move-to-target', 'menu-main')"
16
+ >
17
+ {{ $t('message.skip_content') }}
18
+ </a>
19
+ <b-row align-v="center" align-h="center" class="r-menu">
20
+ <div class="wrapper-lasRoute">
21
+ <div class="box-menu">
22
+ <h1>{{ getLessonid }}</h1>
23
+ <h2 v-html="getLessonTitle"></h2>
24
+ <p class="lesson-progess">
25
+ {{ $t('message.progress_card') }} {{ lessonProg() }}
26
+ </p>
27
+ <b-link
28
+ id="btn_last_route"
29
+ class="nav_last_route btn-main"
30
+ :title="handelLabel"
31
+ :to="{ name: GoToLastRoute() }"
32
+ >
33
+ {{ handelLabel }}
34
+ </b-link>
35
+ </div>
36
+ </div>
37
+
38
+ <b-col
39
+ id="menu-main"
40
+ md="10"
41
+ class="wrapper-MenuItem"
42
+ title="table of content for this lesson"
43
+ >
44
+ <h3>{{ $t('text.activity_title') }}</h3>
26
45
 
27
- <b-col md="8" class="wrapper-MenuItem">
28
46
  <app-comp-menu-item></app-comp-menu-item>
29
47
  </b-col>
30
48
  </b-row>
49
+ <b-row align-v="center" align-h="center">
50
+ <b-col md="7">
51
+ <div v-show="appDebugMode" id="_debug-area">
52
+ <h5>Mode de débogage activé</h5>
53
+ <p>
54
+ Cliquez sur le bouton pour réinitialiser toutes les données de ce
55
+ paquet.
56
+ </p>
57
+
58
+ <app-base-button
59
+ :id="`btn-quiz`"
60
+ class="btn lk-btn"
61
+ :is-active="resetStatus !== false"
62
+ @click="askResetUserData"
63
+ >
64
+ Réinitialiser la leçon
65
+ </app-base-button>
66
+ <div v-show="resetStatus !== false" id="resetOverlay">
67
+ <div
68
+ v-show="resetStatus === resetState.LOADING"
69
+ class="lds-ellipsis"
70
+ >
71
+ <div></div>
72
+ <div></div>
73
+ <div></div>
74
+ <div></div>
75
+ </div>
76
+ <span v-show="resetStatus === resetState.COMPLETE" id="reset_label">
77
+ Opération réussie!
78
+ </span>
79
+ </div>
80
+ </div>
81
+ </b-col>
82
+ </b-row>
83
+ <div id="page_info" class="sr-only" aria-hidden="true">
84
+ {{ $t('text.title_content_view') }}
85
+ </div>
31
86
  </div>
32
87
  </template>
33
88
  <script>
@@ -36,22 +91,40 @@ import { mapGetters } from 'vuex'
36
91
 
37
92
  export default {
38
93
  name: 'AppCompMenu',
94
+ data() {
95
+ return {
96
+ totalAttempts: 0,
97
+ resetStatus: false,
98
+ resetState: { LOADING: 'LOADING', COMPLETE: 'COMPLETE' }
99
+ }
100
+ },
101
+
39
102
  computed: {
40
103
  ...mapGetters([
41
104
  'getRouteHistory',
42
105
  'getAllActivitiesState',
106
+ 'getAllCompleted',
107
+ 'getModuleInfo',
108
+ 'getMenuSettings',
109
+ 'getAppDebugMode',
43
110
  'getAllCompleted'
44
111
  ]),
112
+ appDebugMode() {
113
+ return this.getAppDebugMode
114
+ },
45
115
  handelLabel() {
46
116
  let label = ''
47
- const { allActivitiesState, allCompleted } = this.progressWithoutMenu()
117
+ const { allActivitiesState, allCompleted } = this.progressWithMenu()
48
118
 
49
119
  let activity = Object.values(allActivitiesState)
50
120
  let completeActivity = Object.values(allCompleted)
51
121
 
52
122
  if (this.noProgress(activity)) {
123
+ //console.log('dans handleLabel no progress a true')
53
124
  label = this.$t('button.menu_item.start')
54
125
  } else {
126
+ // console.log('dans handleLabel no progress a false')
127
+
55
128
  if (activity.length == completeActivity.length) {
56
129
  label = this.$t('button.menu_item.end')
57
130
  } else {
@@ -59,24 +132,57 @@ export default {
59
132
  }
60
133
  }
61
134
  return label
135
+ },
136
+ getLessonid() {
137
+ // ATTENDRE UX*UI poure voir si on garde le concept ou pas
138
+ let lessonLabel = this.$t('text.lesson')
139
+ let lessonId = 99
140
+ return `${lessonLabel} ${lessonId}`
141
+ },
142
+ getLessonTitle() {
143
+ let lessonT
144
+ if (this.getMenuSettings.lessonTitle) {
145
+ lessonT = this.getMenuSettings.lessonTitle
146
+ } else {
147
+ lessonT = 'Entrer un titre à pour votre leçon dans menu setting svp.'
148
+ }
149
+ return `${lessonT}`
62
150
  }
63
151
  },
64
- created() {},
65
- beforeDestroy() {},
152
+ mounted() {
153
+ setTimeout(() => {
154
+ this.$bus.$emit('move-to-target', 'page_info_section')
155
+ }, 200)
156
+ },
157
+ beforeUnmount() {
158
+ this.$bus.$off('reset-complete', this.onResetComplete)
159
+ },
66
160
  methods: {
161
+ //When server responds after a reset request
162
+ onResetComplete() {
163
+ this.$bus.$off('reset-complete', this.onResetComplete)
164
+ //show Operation reussie! for 2 seconds then exit debugmode
165
+ this.resetStatus = this.resetState.COMPLETE
166
+ setTimeout(() => {
167
+ window.setDebugMode(false)
168
+ if (this.resetStatus) {
169
+ this.resetStatus = false
170
+ }
171
+ }, 2000)
172
+ },
67
173
  GoToLastRoute() {
68
174
  let lastRoute
69
175
  let path
70
176
 
71
177
  //Get all activity state (menu not included)
72
- const { allActivitiesState } = this.progressWithoutMenu()
178
+ const { allActivitiesState } = this.progressWithMenu()
73
179
  let state = Object.values(allActivitiesState)
74
180
 
75
181
  if (this.getRouteHistory.length) {
76
182
  if (this.getRouteHistory.length == 1) {
77
183
  lastRoute = this.getRouteHistory[0]
78
184
  } else {
79
- lastRoute = this.getRouteHistory[this.getRouteHistory.length - 2]
185
+ lastRoute = this.getRouteHistory[this.getRouteHistory.length - 1]
80
186
  }
81
187
  }
82
188
 
@@ -85,11 +191,12 @@ export default {
85
191
  path = 'introduction'
86
192
  return path
87
193
  }
88
-
89
194
  // create path from the last you saw
90
195
  if (lastRoute) path = this.createdRoute(lastRoute)
196
+
91
197
  return path
92
198
  },
199
+
93
200
  noProgress(obj) {
94
201
  //validator to see if anything was seen before
95
202
  for (let i = 0; i < obj.length; i++) {
@@ -104,54 +211,27 @@ export default {
104
211
  let page
105
212
  let path
106
213
 
107
- if (
108
- (newRoute.activity_ref && newRoute.activity_ref.charAt(1) == '0') ||
109
- (newRoute.activity_ref && newRoute.activity_ref.charAt(1) == 0)
110
- ) {
111
- activity = newRoute.activity_ref.substr(2)
214
+ const typesToCatch = ['menu', 'introduction', 'conclusion']
215
+ //Define activity
216
+ if (typesToCatch.includes(newRoute.type)) {
217
+ activity = newRoute.type
112
218
  } else {
113
- activity = newRoute.activity_ref.substr(1)
219
+ activity =
220
+ newRoute.activity_ref.charAt(1) == '0'
221
+ ? `activite_${newRoute.activity_ref.substring(2)}`
222
+ : `activite_${newRoute.activity_ref.substring(1)}`
114
223
  }
115
- if (newRoute.activity_ref && newRoute.activity_ref !== 'A00') {
116
- // create link for page when you are in the intro
117
- if (newRoute.id.charAt(1) == '0' || newRoute.id.charAt(1) == 0) {
118
- page = newRoute.id.substr(2)
119
- } else {
120
- page = newRoute.id.substr(1)
121
- }
122
- // create link for any ativity
123
- if (page == '1' || page == 1) {
124
- path = `activite_${activity}`
125
- } else {
126
- path = `activite_${activity}.page_${page}`
127
- }
128
- } else {
129
- // create link for page when you are not in the intro
130
- let str = newRoute.id.substr(newRoute.id.indexOf('-') + 1)
131
224
 
132
- if (str.charAt(1) == '0' || str.charAt(1) == 0) {
133
- page = str.substr(2)
134
- } else {
135
- page = str.substr(1)
136
- }
225
+ //Define page
226
+ const idToIgnore = ['P01', 'pg_menu']
227
+ page = idToIgnore.includes(newRoute.id) ? ' ' : newRoute.id.substring(2)
228
+
229
+ //Define path
230
+ path = page !== ' ' ? `${activity}.page_${page}` : activity
137
231
 
138
- // CREATE LINK if it was the intro
139
- if (page == '1' || page == 1) {
140
- path = `introduction`
141
- } else if (page == '0' || page == 0) {
142
- path = `menu`
143
- } else {
144
- path = `introduction.page_${page}`
145
- }
146
- }
147
232
  return path
148
233
  },
149
- progressWithoutMenu() {
150
- //get the page which is defined as the menu
151
- const toIgnore = this.$helper
152
- .getRoutesFromVueRouter('A00')
153
- .all_routes.find((el) => el.name === 'menu').meta.id
154
-
234
+ progressWithMenu() {
155
235
  /*
156
236
  * Note:
157
237
  * 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
@@ -172,32 +252,151 @@ export default {
172
252
  ) {
173
253
  let completedIntro = allCompleted[activity]
174
254
 
175
- //remove the "menu page from the completed in intro
176
- completedIntro = completedIntro.filter(
177
- (el) => Object.keys(el)[0] !== toIgnore
178
- )
179
-
180
255
  if (!completedIntro.length) completedIntro = []
181
256
 
182
257
  allCompleted[activity] = completedIntro
183
-
184
- // Remove menu page from the activity state tracking
185
- let introState = allActivitiesState[activity].progressions
186
- if (introState.length) {
187
- introState = introState.filter(
188
- (el) => Object.keys(el)[0] !== toIgnore
189
- )
190
-
191
- allActivitiesState[activity].progressions = introState
192
- allActivitiesState[activity].size -= 1
193
- }
194
258
  }
195
259
  }
260
+
196
261
  return {
197
262
  allActivitiesState,
198
263
  allCompleted
199
264
  }
265
+ },
266
+ lessonProg() {
267
+ let lstActivity = Object.keys(this.getAllActivitiesState)
268
+ let progress = null
269
+ let info = this.progressWithMenu()
270
+ let page = null
271
+ let pageCmplt = null
272
+
273
+ lstActivity.forEach((element) => {
274
+ //Get the total of all the page
275
+ page += info.allActivitiesState[element].size
276
+
277
+ if (info.allCompleted[element]) {
278
+ // GEt all page complete
279
+ pageCmplt += Object.values(info.allCompleted[element]).length
280
+ }
281
+ })
282
+
283
+ // Create pourcentage complete
284
+ progress = Math.round((pageCmplt * 100) / page)
285
+
286
+ return `${progress}%`
287
+ },
288
+ askResetUserData() {
289
+ //show loader animation
290
+ this.resetStatus = this.resetState.LOADING
291
+ //callback on server response
292
+ this.$bus.$on('reset-complete', this.onResetComplete)
293
+ //launch reset call
294
+ this.$bus.$emit('reset-userdata')
200
295
  }
201
296
  }
202
297
  }
203
298
  </script>
299
+ <style lang="scss">
300
+ .menu-container {
301
+ width: 100%;
302
+ height: 100%;
303
+
304
+ .r-menu {
305
+ margin: 0 0 0 0;
306
+ }
307
+ }
308
+
309
+ #_debug-area {
310
+ display: flex;
311
+ flex-direction: column;
312
+ align-items: center;
313
+ justify-content: center;
314
+ margin: 25px;
315
+ padding: 20px;
316
+ background-color: #eaabb685;
317
+ border-block: dotted yellow 5px;
318
+ p {
319
+ padding: 15px;
320
+ text-align: center;
321
+ font-size: 1em;
322
+ }
323
+ button {
324
+ background-color: #8dff95;
325
+ font-size: 1.3em;
326
+ }
327
+ #resetOverlay {
328
+ position: absolute;
329
+ display: flex;
330
+ flex-direction: column;
331
+ width: 33%;
332
+ height: 40%;
333
+ align-items: center;
334
+ justify-content: center;
335
+ background-color: rgba($color: #000000, $alpha: 0.9);
336
+ border-radius: 10px;
337
+ box-shadow: 2px 2px 4px 0px rgba($color: #000000, $alpha: 0.2);
338
+ }
339
+ #reset_label {
340
+ font-family: arial;
341
+ color: #fff;
342
+ font-weight: bold;
343
+ font-size: 18px;
344
+ }
345
+ .lds-ellipsis {
346
+ display: flex;
347
+ display: inline-block;
348
+ position: relative;
349
+ width: 80px;
350
+ height: 80px;
351
+ }
352
+ .lds-ellipsis div {
353
+ position: absolute;
354
+ top: 33px;
355
+ width: 13px;
356
+ height: 13px;
357
+ border-radius: 50%;
358
+ background: #fff;
359
+ animation-timing-function: cubic-bezier(0, 1, 1, 0);
360
+ }
361
+ .lds-ellipsis div:nth-child(1) {
362
+ left: 8px;
363
+ animation: lds-ellipsis1 0.6s infinite;
364
+ }
365
+ .lds-ellipsis div:nth-child(2) {
366
+ left: 8px;
367
+ animation: lds-ellipsis2 0.6s infinite;
368
+ }
369
+ .lds-ellipsis div:nth-child(3) {
370
+ left: 32px;
371
+ animation: lds-ellipsis2 0.6s infinite;
372
+ }
373
+ .lds-ellipsis div:nth-child(4) {
374
+ left: 56px;
375
+ animation: lds-ellipsis3 0.6s infinite;
376
+ }
377
+ @keyframes lds-ellipsis1 {
378
+ 0% {
379
+ transform: scale(0);
380
+ }
381
+ 100% {
382
+ transform: scale(1);
383
+ }
384
+ }
385
+ @keyframes lds-ellipsis3 {
386
+ 0% {
387
+ transform: scale(1);
388
+ }
389
+ 100% {
390
+ transform: scale(0);
391
+ }
392
+ }
393
+ @keyframes lds-ellipsis2 {
394
+ 0% {
395
+ transform: translate(0, 0);
396
+ }
397
+ 100% {
398
+ transform: translate(24px, 0);
399
+ }
400
+ }
401
+ }
402
+ </style>