fcad-core-dragon 2.1.0-beta.4 → 2.1.0

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 (70) hide show
  1. package/.editorconfig +8 -33
  2. package/.prettierrc +11 -0
  3. package/.vscode/extensions.json +8 -0
  4. package/.vscode/settings.json +16 -0
  5. package/CHANGELOG +20 -0
  6. package/eslint.config.js +60 -0
  7. package/package.json +9 -9
  8. package/src/$locales/en.json +3 -3
  9. package/src/$locales/fr.json +3 -3
  10. package/src/assets/data/onboardingMessages.json +47 -47
  11. package/src/components/AppBase.vue +5 -6
  12. package/src/components/AppBaseErrorDisplay.vue +438 -438
  13. package/src/components/AppBaseFlipCard.vue +84 -84
  14. package/src/components/AppBaseModule.vue +15 -17
  15. package/src/components/AppBasePage.vue +866 -783
  16. package/src/components/AppBasePopover.vue +41 -41
  17. package/src/components/AppBaseSkeleton.vue +24 -3
  18. package/src/components/AppCompAudio.vue +12 -2
  19. package/src/components/AppCompInputCheckBoxNx.vue +1 -2
  20. package/src/components/AppCompInputRadioNx.vue +8 -2
  21. package/src/components/AppCompInputTextToFillDropdownNx.vue +45 -0
  22. package/src/components/AppCompMenu.vue +424 -423
  23. package/src/components/AppCompNavigation.vue +2 -2
  24. package/src/components/AppCompPlayBarNext.vue +123 -94
  25. package/src/components/AppCompPopUpNext.vue +2 -2
  26. package/src/components/AppCompQuizNext.vue +12 -2
  27. package/src/components/AppCompQuizRecall.vue +10 -4
  28. package/src/components/AppCompSettingsMenu.vue +172 -172
  29. package/src/components/AppCompTableOfContent.vue +1 -4
  30. package/src/components/AppCompVideoPlayer.vue +7 -0
  31. package/src/components/AppCompViewDisplay.vue +6 -6
  32. package/src/composables/useTimer.js +17 -20
  33. package/src/externalComps/ModuleView.vue +22 -22
  34. package/src/externalComps/SummaryView.vue +91 -91
  35. package/src/module/stores/appStore.js +0 -1
  36. package/src/module/xapi/Crypto/Hasher.js +241 -241
  37. package/src/module/xapi/Crypto/WordArray.js +278 -278
  38. package/src/module/xapi/Crypto/algorithms/BufferedBlockAlgorithm.js +103 -103
  39. package/src/module/xapi/Crypto/algorithms/C_algo.js +315 -315
  40. package/src/module/xapi/Crypto/algorithms/HMAC.js +9 -9
  41. package/src/module/xapi/Crypto/algorithms/SHA1.js +9 -9
  42. package/src/module/xapi/Crypto/encoders/Base.js +105 -105
  43. package/src/module/xapi/Crypto/encoders/Base64.js +99 -99
  44. package/src/module/xapi/Crypto/encoders/Hex.js +61 -61
  45. package/src/module/xapi/Crypto/encoders/Latin1.js +61 -61
  46. package/src/module/xapi/Crypto/encoders/Utf8.js +45 -45
  47. package/src/module/xapi/Crypto/index.js +53 -53
  48. package/src/module/xapi/Statement/activity.js +47 -47
  49. package/src/module/xapi/Statement/agent.js +55 -55
  50. package/src/module/xapi/Statement/group.js +26 -26
  51. package/src/module/xapi/Statement/index.js +259 -259
  52. package/src/module/xapi/Statement/statement.js +253 -253
  53. package/src/module/xapi/Statement/statementRef.js +23 -23
  54. package/src/module/xapi/Statement/substatement.js +22 -22
  55. package/src/module/xapi/Statement/verb.js +36 -36
  56. package/src/module/xapi/activitytypes.js +17 -17
  57. package/src/module/xapi/utils.js +167 -167
  58. package/src/module/xapi/verbs.js +294 -294
  59. package/src/module/xapi/xapiStatement.js +444 -444
  60. package/src/plugins/bus.js +8 -8
  61. package/src/plugins/helper.js +4 -0
  62. package/src/plugins/save.js +37 -37
  63. package/src/plugins/scorm.js +287 -287
  64. package/src/plugins/xapi.js +11 -11
  65. package/src/public/index.html +33 -33
  66. package/src/router/index.js +1 -1
  67. package/src/shared/validators.js +22 -6
  68. package/.eslintignore +0 -29
  69. package/.eslintrc.cjs +0 -81
  70. package/bk.scss +0 -117
@@ -1,423 +1,424 @@
1
- <!--
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's AppCompMenuItem
4
- -->
5
- <template>
6
- <div class="menu-container">
7
- <div
8
- id="page_info_section"
9
- class="sr-only"
10
- aria-labelledby="page_info"
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
- <div class="contain-lr">
20
- <div class="wrapper-lasRoute">
21
- <div class="box-menu">
22
- <h1>{{ getLessonid }}</h1>
23
- <h2 v-html="getLessonTitle"></h2>
24
-
25
- <p class="lesson-progess">
26
- {{ $t('message.progress_card') }} {{ lessonProg() }}
27
- </p>
28
- <router-link
29
- id="btn_last_route"
30
- class="nav_last_route btn-main"
31
- :title="handelLabel"
32
- :to="{ name: GoToLastRoute() }"
33
- data-test="menu-back-btn"
34
- >
35
- {{ handelLabel }}
36
- </router-link>
37
- </div>
38
- </div>
39
- <v-row justify="center" align="center" class="r-menu">
40
- <v-col id="menu-main" md="10" class="wrapper-MenuItem">
41
- <h3>{{ $t('text.activity_title') }}</h3>
42
-
43
- <app-comp-menu-item></app-comp-menu-item>
44
- </v-col>
45
- </v-row>
46
- </div>
47
- <v-row justify="center" align="center">
48
- <v-col md="7">
49
- <div v-show="appDebugMode" id="_debug-area">
50
- <h5>Mode de débogage activé</h5>
51
- <p>
52
- Cliquez sur le bouton pour réinitialiser toutes les données de ce
53
- paquet.
54
- </p>
55
-
56
- <app-base-button
57
- :id="`btn-quiz`"
58
- class="btn lk-btn"
59
- title="Réinitialiser la leçon"
60
- :is-disabled="resetStatus !== false"
61
- @click="askResetUserData"
62
- >
63
- Réinitialiser la leçon
64
- </app-base-button>
65
- <div v-show="resetStatus !== false" id="resetOverlay">
66
- <div
67
- v-show="resetStatus === resetState.LOADING"
68
- class="lds-ellipsis"
69
- >
70
- <div></div>
71
- <div></div>
72
- <div></div>
73
- <div></div>
74
- </div>
75
- <span v-show="resetStatus === resetState.COMPLETE" id="reset_label">
76
- Opération réussie!
77
- </span>
78
- </div>
79
- </div>
80
- </v-col>
81
- </v-row>
82
- <span id="page_info" class="sr-only" aria-hidden="true">
83
- {{ $t('text.title_content_view') }}
84
- </span>
85
- </div>
86
- </template>
87
- <script>
88
- // ...
89
- import { mapState } from 'pinia'
90
- import { useAppStore } from '../module/stores/appStore'
91
- export default {
92
- name: 'AppCompMenu',
93
- data() {
94
- return {
95
- totalAttempts: 0,
96
- resetStatus: false,
97
- resetState: { LOADING: 'LOADING', COMPLETE: 'COMPLETE' }
98
- }
99
- },
100
-
101
- computed: {
102
- ...mapState(useAppStore, [
103
- 'getRouteHistory',
104
- 'getAllActivitiesState',
105
- 'getAllCompleted',
106
- 'getModuleInfo',
107
- 'getMenuSettings',
108
- 'getAppDebugMode',
109
- 'getAppConfigs',
110
- 'getAllCompleted'
111
- ]),
112
- appDebugMode() {
113
- return this.getAppDebugMode
114
- },
115
- handelLabel() {
116
- let label = ''
117
- const { allActivitiesState, allCompleted } = this.progressWithMenu()
118
-
119
- let activity = Object.values(allActivitiesState)
120
- let completeActivity = Object.values(allCompleted)
121
-
122
- if (this.noProgress(activity)) {
123
- label = this.$t('button.menu_item.start')
124
- } else {
125
- if (activity.length == completeActivity.length) {
126
- label = this.$t('button.menu_item.end')
127
- } else {
128
- label = this.$t('button.menu_item.end')
129
- }
130
- }
131
- return label
132
- },
133
- getLessonid() {
134
- let lessonLabel = this.$t('text.lesson')
135
- let lessonId
136
- if (this.getMenuSettings.lessonNumber) {
137
- lessonId = this.getMenuSettings.lessonNumber
138
- } else {
139
- lessonId =
140
- 'La variable lessonNumber est introuvable dans menu.setting.js'
141
- }
142
- return `${lessonLabel} ${lessonId}`
143
- },
144
- getLessonTitle() {
145
- let lessonT
146
- if (this.getMenuSettings.lessonTitle) {
147
- lessonT = this.getMenuSettings.lessonTitle
148
- } else {
149
- lessonT = 'Entrer un titre à pour votre leçon dans menu setting svp.'
150
- }
151
- return `${lessonT}`
152
- }
153
- },
154
- mounted() {
155
- setTimeout(() => {
156
- this.$bus.$emit('move-to-target', 'page_info_section')
157
- }, 200)
158
- },
159
- beforeUnmount() {
160
- this.$bus.$off('reset-complete', this.onResetComplete)
161
- },
162
- methods: {
163
- //When server responds after a reset request
164
- onResetComplete() {
165
- this.$bus.$off('reset-complete', this.onResetComplete)
166
- //show Operation reussie! for 2 seconds then exit debugmode
167
- this.resetStatus = this.resetState.COMPLETE
168
- setTimeout(() => {
169
- window.setDebugMode(false)
170
- if (this.resetStatus) {
171
- this.resetStatus = false
172
- }
173
- }, 2000)
174
- },
175
- //Go to the last route you were before the menu
176
- GoToLastRoute() {
177
- let lastRoute
178
- let path
179
- //Get all activity state (menu not included)
180
- const { allActivitiesState } = this.progressWithMenu()
181
- let state = Object.values(allActivitiesState)
182
-
183
- if (this.getRouteHistory && this.getRouteHistory.length) {
184
- if (this.getRouteHistory.length == 1) {
185
- lastRoute = this.getRouteHistory[0]
186
- } else {
187
- lastRoute = this.getRouteHistory[this.getRouteHistory.length - 1]
188
- }
189
- }
190
-
191
- //if course was not started bring you to the introduction
192
- if (this.noProgress(state)) {
193
- path = 'introduction'
194
- return path
195
- }
196
-
197
- // create path from the last you saw
198
- if (lastRoute) path = this.createdRoute(lastRoute)
199
-
200
- return path
201
- },
202
-
203
- noProgress(obj) {
204
- //validator to see if anything was seen before
205
- for (let i = 0; i < obj.length; i++) {
206
- if (obj[i].progressions.length != 0) return false //something was seen
207
- }
208
- return true //nothing was seen
209
- },
210
- createdRoute(objRoute) {
211
- // create link for activity
212
- let newRoute = objRoute
213
- let activity
214
- let page
215
- let path
216
-
217
- const typesToCatch = ['menu', 'introduction', 'conclusion']
218
- //Define activity
219
- if (typesToCatch.includes(newRoute.type)) {
220
- activity = newRoute.type
221
- } else {
222
- activity =
223
- newRoute.activity_ref && newRoute.activity_ref.charAt(1) == '0'
224
- ? `activite_${newRoute.activity_ref.substring(2)}`
225
- : `activite_${newRoute.activity_ref.substring(1)}`
226
- }
227
-
228
- //Define page
229
- const idToIgnore = ['P01', 'pg_menu']
230
- page = idToIgnore.includes(newRoute.id) ? ' ' : newRoute.id.substring(2)
231
-
232
- //Define path
233
- path = page !== ' ' ? `${activity}.page_${page}` : activity
234
- return path
235
- },
236
- progressWithMenu() {
237
- /*
238
- * Note:
239
- * 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
240
- * cf: https://reactgo.com/javascript-clone-object/
241
- */
242
-
243
- const allActivitiesState = JSON.parse(
244
- JSON.stringify(this.getAllActivitiesState)
245
- )
246
-
247
- const allCompleted = JSON.parse(JSON.stringify(this.getAllCompleted))
248
-
249
- for (let activity in allActivitiesState) {
250
- if (
251
- activity === 'A00' &&
252
- allActivitiesState[activity] &&
253
- allCompleted[activity]
254
- ) {
255
- let completedIntro = allCompleted[activity]
256
-
257
- if (!completedIntro.length) completedIntro = []
258
-
259
- allCompleted[activity] = completedIntro
260
- }
261
- }
262
-
263
- return {
264
- allActivitiesState,
265
- allCompleted
266
- }
267
- },
268
- lessonProg() {
269
- let lstActivity = Object.keys(this.getAllActivitiesState)
270
- let progress = null
271
- let info = this.progressWithMenu()
272
- let page = null
273
- let pageCmplt = null
274
-
275
- lstActivity.forEach((element) => {
276
- //Get the total of all the page
277
- page += info.allActivitiesState[element].size
278
-
279
- if (info.allCompleted[element]) {
280
- // GEt all page complete
281
- pageCmplt += Object.values(info.allCompleted[element]).length
282
- }
283
- })
284
-
285
- // Create pourcentage complete
286
- progress = Math.round((pageCmplt * 100) / page)
287
-
288
- return this.getAppConfigs.lang.toLowerCase() == 'en'
289
- ? `${progress}%`
290
- : `${progress} %`
291
- },
292
- askResetUserData() {
293
- //show loader animation
294
- this.resetStatus = this.resetState.LOADING
295
- //callback on server response
296
- this.$bus.$on('reset-complete', this.onResetComplete)
297
- //launch reset call
298
- this.$bus.$emit('reset-userdata')
299
- }
300
- }
301
- }
302
- </script>
303
- <style lang="scss">
304
- .contain-lr {
305
- display: flex;
306
- flex-direction: column;
307
- flex-wrap: wrap;
308
- width: 100%;
309
-
310
- .wrapper-lasRoute {
311
- display: flex;
312
- justify-content: flex-end;
313
-
314
- .nav_last_route {
315
- display: inline-block;
316
- }
317
- }
318
- }
319
-
320
- .menu-container {
321
- width: 100%;
322
- height: 100%;
323
-
324
- .r-menu {
325
- margin: 0 0 0 0;
326
- }
327
- }
328
-
329
- #_debug-area {
330
- display: flex;
331
- flex-direction: column;
332
- align-items: center;
333
- justify-content: center;
334
- margin: 25px;
335
- padding: 20px;
336
- background-color: #eaabb6b3;
337
- border-block: dotted yellow 5px;
338
- p {
339
- padding: 15px;
340
- text-align: center;
341
- font-size: 1em;
342
- }
343
- button {
344
- background-color: #8dff95;
345
- font-size: 1.3em;
346
- padding: 5px 12px;
347
- }
348
- #resetOverlay {
349
- position: absolute;
350
- display: flex;
351
- flex-direction: column;
352
- width: 33%;
353
- height: 40%;
354
- align-items: center;
355
- justify-content: center;
356
- background-color: rgba($color: #000000, $alpha: 0.9);
357
- border-radius: 10px;
358
- box-shadow: 2px 2px 4px 0px rgba($color: #000000, $alpha: 0.2);
359
- }
360
- #reset_label {
361
- font-family: arial;
362
- color: #fff;
363
- font-weight: bold;
364
- font-size: 18px;
365
- }
366
- .lds-ellipsis {
367
- display: flex;
368
- display: inline-block;
369
- position: relative;
370
- width: 80px;
371
- height: 80px;
372
- }
373
- .lds-ellipsis div {
374
- position: absolute;
375
- top: 33px;
376
- width: 13px;
377
- height: 13px;
378
- border-radius: 50%;
379
- background: #fff;
380
- animation-timing-function: cubic-bezier(0, 1, 1, 0);
381
- }
382
- .lds-ellipsis div:nth-child(1) {
383
- left: 8px;
384
- animation: lds-ellipsis1 0.6s infinite;
385
- }
386
- .lds-ellipsis div:nth-child(2) {
387
- left: 8px;
388
- animation: lds-ellipsis2 0.6s infinite;
389
- }
390
- .lds-ellipsis div:nth-child(3) {
391
- left: 32px;
392
- animation: lds-ellipsis2 0.6s infinite;
393
- }
394
- .lds-ellipsis div:nth-child(4) {
395
- left: 56px;
396
- animation: lds-ellipsis3 0.6s infinite;
397
- }
398
- @keyframes lds-ellipsis1 {
399
- 0% {
400
- transform: scale(0);
401
- }
402
- 100% {
403
- transform: scale(1);
404
- }
405
- }
406
- @keyframes lds-ellipsis3 {
407
- 0% {
408
- transform: scale(1);
409
- }
410
- 100% {
411
- transform: scale(0);
412
- }
413
- }
414
- @keyframes lds-ellipsis2 {
415
- 0% {
416
- transform: translate(0, 0);
417
- }
418
- 100% {
419
- transform: translate(24px, 0);
420
- }
421
- }
422
- }
423
- </style>
1
+ <!--
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's AppCompMenuItem
4
+ -->
5
+ <template>
6
+ <div class="menu-container">
7
+ test sss
8
+ <div
9
+ id="page_info_section"
10
+ class="sr-only"
11
+ aria-labelledby="page_info"
12
+ ></div>
13
+ <a
14
+ class="skip-link"
15
+ href=""
16
+ @click.prevent="$bus.$emit('move-to-target', 'menu-main')"
17
+ >
18
+ {{ $t('message.skip_content') }}
19
+ </a>
20
+ <div class="contain-lr">
21
+ <div class="wrapper-lasRoute">
22
+ <div class="box-menu">
23
+ <h1>{{ getLessonid }}</h1>
24
+ <h2 v-html="getLessonTitle"></h2>
25
+
26
+ <p class="lesson-progess">
27
+ {{ $t('message.progress_card') }} {{ lessonProg() }}
28
+ </p>
29
+ <router-link
30
+ id="btn_last_route"
31
+ class="nav_last_route btn-main"
32
+ :title="handelLabel"
33
+ :to="{ name: GoToLastRoute() }"
34
+ data-test="menu-back-btn"
35
+ >
36
+ {{ handelLabel }}
37
+ </router-link>
38
+ </div>
39
+ </div>
40
+ <v-row justify="center" align="center" class="r-menu">
41
+ <v-col id="menu-main" md="10" class="wrapper-MenuItem">
42
+ <h3>{{ $t('text.activity_title') }}</h3>
43
+
44
+ <app-comp-menu-item></app-comp-menu-item>
45
+ </v-col>
46
+ </v-row>
47
+ </div>
48
+ <v-row justify="center" align="center">
49
+ <v-col md="7">
50
+ <div v-show="appDebugMode" id="_debug-area">
51
+ <h5>Mode de débogage activé</h5>
52
+ <p>
53
+ Cliquez sur le bouton pour réinitialiser toutes les données de ce
54
+ paquet.
55
+ </p>
56
+
57
+ <app-base-button
58
+ :id="`btn-quiz`"
59
+ class="btn lk-btn"
60
+ title="Réinitialiser la leçon"
61
+ :is-disabled="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
+ </v-col>
82
+ </v-row>
83
+ <span id="page_info" class="sr-only" aria-hidden="true">
84
+ {{ $t('text.title_content_view') }}
85
+ </span>
86
+ </div>
87
+ </template>
88
+ <script>
89
+ // ...
90
+ import { mapState } from 'pinia'
91
+ import { useAppStore } from '../module/stores/appStore'
92
+ export default {
93
+ name: 'AppCompMenu',
94
+ data() {
95
+ return {
96
+ totalAttempts: 0,
97
+ resetStatus: false,
98
+ resetState: { LOADING: 'LOADING', COMPLETE: 'COMPLETE' }
99
+ }
100
+ },
101
+
102
+ computed: {
103
+ ...mapState(useAppStore, [
104
+ 'getRouteHistory',
105
+ 'getAllActivitiesState',
106
+ 'getAllCompleted',
107
+ 'getModuleInfo',
108
+ 'getMenuSettings',
109
+ 'getAppDebugMode',
110
+ 'getAppConfigs',
111
+ 'getAllCompleted'
112
+ ]),
113
+ appDebugMode() {
114
+ return this.getAppDebugMode
115
+ },
116
+ handelLabel() {
117
+ let label = ''
118
+ const { allActivitiesState, allCompleted } = this.progressWithMenu()
119
+
120
+ let activity = Object.values(allActivitiesState)
121
+ let completeActivity = Object.values(allCompleted)
122
+
123
+ if (this.noProgress(activity)) {
124
+ label = this.$t('button.menu_item.start')
125
+ } else {
126
+ if (activity.length == completeActivity.length) {
127
+ label = this.$t('button.menu_item.end')
128
+ } else {
129
+ label = this.$t('button.menu_item.end')
130
+ }
131
+ }
132
+ return label
133
+ },
134
+ getLessonid() {
135
+ let lessonLabel = this.$t('text.lesson')
136
+ let lessonId
137
+ if (this.getMenuSettings.lessonNumber) {
138
+ lessonId = this.getMenuSettings.lessonNumber
139
+ } else {
140
+ lessonId =
141
+ 'La variable lessonNumber est introuvable dans menu.setting.js'
142
+ }
143
+ return `${lessonLabel} ${lessonId}`
144
+ },
145
+ getLessonTitle() {
146
+ let lessonT
147
+ if (this.getMenuSettings.lessonTitle) {
148
+ lessonT = this.getMenuSettings.lessonTitle
149
+ } else {
150
+ lessonT = 'Entrer un titre à pour votre leçon dans menu setting svp.'
151
+ }
152
+ return `${lessonT}`
153
+ }
154
+ },
155
+ mounted() {
156
+ setTimeout(() => {
157
+ this.$bus.$emit('move-to-target', 'page_info_section')
158
+ }, 200)
159
+ },
160
+ beforeUnmount() {
161
+ this.$bus.$off('reset-complete', this.onResetComplete)
162
+ },
163
+ methods: {
164
+ //When server responds after a reset request
165
+ onResetComplete() {
166
+ this.$bus.$off('reset-complete', this.onResetComplete)
167
+ //show Operation reussie! for 2 seconds then exit debugmode
168
+ this.resetStatus = this.resetState.COMPLETE
169
+ setTimeout(() => {
170
+ window.setDebugMode(false)
171
+ if (this.resetStatus) {
172
+ this.resetStatus = false
173
+ }
174
+ }, 2000)
175
+ },
176
+ //Go to the last route you were before the menu
177
+ GoToLastRoute() {
178
+ let lastRoute
179
+ let path
180
+ //Get all activity state (menu not included)
181
+ const { allActivitiesState } = this.progressWithMenu()
182
+ let state = Object.values(allActivitiesState)
183
+
184
+ if (this.getRouteHistory && this.getRouteHistory.length) {
185
+ if (this.getRouteHistory.length == 1) {
186
+ lastRoute = this.getRouteHistory[0]
187
+ } else {
188
+ lastRoute = this.getRouteHistory[this.getRouteHistory.length - 1]
189
+ }
190
+ }
191
+
192
+ //if course was not started bring you to the introduction
193
+ if (this.noProgress(state)) {
194
+ path = 'introduction'
195
+ return path
196
+ }
197
+
198
+ // create path from the last you saw
199
+ if (lastRoute) path = this.createdRoute(lastRoute)
200
+
201
+ return path
202
+ },
203
+
204
+ noProgress(obj) {
205
+ //validator to see if anything was seen before
206
+ for (let i = 0; i < obj.length; i++) {
207
+ if (obj[i].progressions.length != 0) return false //something was seen
208
+ }
209
+ return true //nothing was seen
210
+ },
211
+ createdRoute(objRoute) {
212
+ // create link for activity
213
+ let newRoute = objRoute
214
+ let activity
215
+ let page
216
+ let path
217
+
218
+ const typesToCatch = ['menu', 'introduction', 'conclusion']
219
+ //Define activity
220
+ if (typesToCatch.includes(newRoute.type)) {
221
+ activity = newRoute.type
222
+ } else {
223
+ activity =
224
+ newRoute.activity_ref && newRoute.activity_ref.charAt(1) == '0'
225
+ ? `activite_${newRoute.activity_ref.substring(2)}`
226
+ : `activite_${newRoute.activity_ref.substring(1)}`
227
+ }
228
+
229
+ //Define page
230
+ const idToIgnore = ['P01', 'pg_menu']
231
+ page = idToIgnore.includes(newRoute.id) ? ' ' : newRoute.id.substring(2)
232
+
233
+ //Define path
234
+ path = page !== ' ' ? `${activity}.page_${page}` : activity
235
+ return path
236
+ },
237
+ progressWithMenu() {
238
+ /*
239
+ * Note:
240
+ * 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
241
+ * cf: https://reactgo.com/javascript-clone-object/
242
+ */
243
+
244
+ const allActivitiesState = JSON.parse(
245
+ JSON.stringify(this.getAllActivitiesState)
246
+ )
247
+
248
+ const allCompleted = JSON.parse(JSON.stringify(this.getAllCompleted))
249
+
250
+ for (let activity in allActivitiesState) {
251
+ if (
252
+ activity === 'A00' &&
253
+ allActivitiesState[activity] &&
254
+ allCompleted[activity]
255
+ ) {
256
+ let completedIntro = allCompleted[activity]
257
+
258
+ if (!completedIntro.length) completedIntro = []
259
+
260
+ allCompleted[activity] = completedIntro
261
+ }
262
+ }
263
+
264
+ return {
265
+ allActivitiesState,
266
+ allCompleted
267
+ }
268
+ },
269
+ lessonProg() {
270
+ let lstActivity = Object.keys(this.getAllActivitiesState)
271
+ let progress = null
272
+ let info = this.progressWithMenu()
273
+ let page = null
274
+ let pageCmplt = null
275
+
276
+ lstActivity.forEach((element) => {
277
+ //Get the total of all the page
278
+ page += info.allActivitiesState[element].size
279
+
280
+ if (info.allCompleted[element]) {
281
+ // GEt all page complete
282
+ pageCmplt += Object.values(info.allCompleted[element]).length
283
+ }
284
+ })
285
+
286
+ // Create pourcentage complete
287
+ progress = Math.round((pageCmplt * 100) / page)
288
+
289
+ return this.getAppConfigs.lang.toLowerCase() == 'en'
290
+ ? `${progress}%`
291
+ : `${progress} %`
292
+ },
293
+ askResetUserData() {
294
+ //show loader animation
295
+ this.resetStatus = this.resetState.LOADING
296
+ //callback on server response
297
+ this.$bus.$on('reset-complete', this.onResetComplete)
298
+ //launch reset call
299
+ this.$bus.$emit('reset-userdata')
300
+ }
301
+ }
302
+ }
303
+ </script>
304
+ <style lang="scss">
305
+ .contain-lr {
306
+ display: flex;
307
+ flex-direction: column;
308
+ flex-wrap: wrap;
309
+ width: 100%;
310
+
311
+ .wrapper-lasRoute {
312
+ display: flex;
313
+ justify-content: flex-end;
314
+
315
+ .nav_last_route {
316
+ display: inline-block;
317
+ }
318
+ }
319
+ }
320
+
321
+ .menu-container {
322
+ width: 100%;
323
+ height: 100%;
324
+
325
+ .r-menu {
326
+ margin: 0 0 0 0;
327
+ }
328
+ }
329
+
330
+ #_debug-area {
331
+ display: flex;
332
+ flex-direction: column;
333
+ align-items: center;
334
+ justify-content: center;
335
+ margin: 25px;
336
+ padding: 20px;
337
+ background-color: #eaabb6b3;
338
+ border-block: dotted yellow 5px;
339
+ p {
340
+ padding: 15px;
341
+ text-align: center;
342
+ font-size: 1em;
343
+ }
344
+ button {
345
+ background-color: #8dff95;
346
+ font-size: 1.3em;
347
+ padding: 5px 12px;
348
+ }
349
+ #resetOverlay {
350
+ position: absolute;
351
+ display: flex;
352
+ flex-direction: column;
353
+ width: 33%;
354
+ height: 40%;
355
+ align-items: center;
356
+ justify-content: center;
357
+ background-color: rgba($color: #000000, $alpha: 0.9);
358
+ border-radius: 10px;
359
+ box-shadow: 2px 2px 4px 0px rgba($color: #000000, $alpha: 0.2);
360
+ }
361
+ #reset_label {
362
+ font-family: arial;
363
+ color: #fff;
364
+ font-weight: bold;
365
+ font-size: 18px;
366
+ }
367
+ .lds-ellipsis {
368
+ display: flex;
369
+ display: inline-block;
370
+ position: relative;
371
+ width: 80px;
372
+ height: 80px;
373
+ }
374
+ .lds-ellipsis div {
375
+ position: absolute;
376
+ top: 33px;
377
+ width: 13px;
378
+ height: 13px;
379
+ border-radius: 50%;
380
+ background: #fff;
381
+ animation-timing-function: cubic-bezier(0, 1, 1, 0);
382
+ }
383
+ .lds-ellipsis div:nth-child(1) {
384
+ left: 8px;
385
+ animation: lds-ellipsis1 0.6s infinite;
386
+ }
387
+ .lds-ellipsis div:nth-child(2) {
388
+ left: 8px;
389
+ animation: lds-ellipsis2 0.6s infinite;
390
+ }
391
+ .lds-ellipsis div:nth-child(3) {
392
+ left: 32px;
393
+ animation: lds-ellipsis2 0.6s infinite;
394
+ }
395
+ .lds-ellipsis div:nth-child(4) {
396
+ left: 56px;
397
+ animation: lds-ellipsis3 0.6s infinite;
398
+ }
399
+ @keyframes lds-ellipsis1 {
400
+ 0% {
401
+ transform: scale(0);
402
+ }
403
+ 100% {
404
+ transform: scale(1);
405
+ }
406
+ }
407
+ @keyframes lds-ellipsis3 {
408
+ 0% {
409
+ transform: scale(1);
410
+ }
411
+ 100% {
412
+ transform: scale(0);
413
+ }
414
+ }
415
+ @keyframes lds-ellipsis2 {
416
+ 0% {
417
+ transform: translate(0, 0);
418
+ }
419
+ 100% {
420
+ transform: translate(24px, 0);
421
+ }
422
+ }
423
+ }
424
+ </style>