fcad-core-dragon 2.0.0-beta.1 → 2.0.0-beta.3

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 (118) hide show
  1. package/.editorconfig +33 -33
  2. package/.eslintignore +29 -29
  3. package/{.eslintrc.js → .eslintrc.cjs} +81 -86
  4. package/CHANGELOG +364 -364
  5. package/README.md +71 -71
  6. package/bk.scss +117 -0
  7. package/package.json +61 -63
  8. package/src/$locales/en.json +143 -179
  9. package/src/$locales/fr.json +105 -181
  10. package/src/assets/data/onboardingMessages.json +47 -47
  11. package/src/components/AppBase.vue +1054 -614
  12. package/src/components/AppBaseButton.vue +87 -63
  13. package/src/components/AppBaseErrorDisplay.vue +438 -420
  14. package/src/components/AppBaseFlipCard.vue +84 -83
  15. package/src/components/AppBaseModule.vue +1673 -1842
  16. package/src/components/AppBasePage.vue +779 -312
  17. package/src/components/AppBasePopover.vue +41 -0
  18. package/src/components/AppCompAudio.vue +234 -0
  19. package/src/components/AppCompBranchButtons.vue +552 -582
  20. package/src/components/AppCompButtonProgress.vue +126 -147
  21. package/src/components/AppCompCarousel.vue +298 -192
  22. package/src/components/AppCompInputCheckBoxNext.vue +195 -0
  23. package/src/components/AppCompInputDropdownNext.vue +159 -0
  24. package/src/components/AppCompInputRadioNext.vue +152 -0
  25. package/src/components/{AppCompInputTextBox.vue → AppCompInputTextNext.vue} +106 -91
  26. package/src/components/AppCompInputTextTableNext.vue +141 -0
  27. package/src/components/AppCompInputTextToFillDropdownNext.vue +230 -0
  28. package/src/components/{AppCompInputTextToFillText.vue → AppCompInputTextToFillNext.vue} +171 -164
  29. package/src/components/AppCompJauge.vue +74 -55
  30. package/src/components/AppCompMenu.vue +413 -209
  31. package/src/components/AppCompMenuItem.vue +228 -174
  32. package/src/components/AppCompNavigation.vue +960 -949
  33. package/src/components/AppCompNoteCall.vue +133 -126
  34. package/src/components/AppCompNoteCredit.vue +292 -164
  35. package/src/components/AppCompPlayBar.vue +1218 -1319
  36. package/src/components/AppCompPlayBarNext.vue +2052 -0
  37. package/src/components/AppCompPlayBarProgress.vue +82 -0
  38. package/src/components/AppCompPopUpNext.vue +503 -0
  39. package/src/components/{AppCompQuiz.vue → AppCompQuizNext.vue} +2904 -2989
  40. package/src/components/AppCompQuizRecall.vue +276 -250
  41. package/src/components/AppCompSVGNext.vue +347 -0
  42. package/src/components/AppCompSettingsMenu.vue +172 -171
  43. package/src/components/AppCompTableOfContent.vue +387 -264
  44. package/src/components/AppCompTranscript.vue +24 -19
  45. package/src/components/AppCompVideoPlayer.vue +368 -336
  46. package/src/components/AppCompViewDisplay.vue +6 -6
  47. package/src/components/BaseModule.vue +72 -67
  48. package/src/composables/useQuiz.js +206 -0
  49. package/src/externalComps/ModuleView.vue +22 -0
  50. package/src/externalComps/SummaryView.vue +91 -0
  51. package/src/main.js +272 -227
  52. package/src/mixins/$mediaMixins.js +819 -0
  53. package/src/mixins/timerMixin.js +155 -156
  54. package/src/module/stores/appStore.js +893 -0
  55. package/src/module/xapi/ADL.js +376 -339
  56. package/src/module/xapi/Crypto/Hasher.js +241 -241
  57. package/src/module/xapi/Crypto/WordArray.js +278 -278
  58. package/src/module/xapi/Crypto/algorithms/BufferedBlockAlgorithm.js +103 -103
  59. package/src/module/xapi/Crypto/algorithms/C_algo.js +315 -319
  60. package/src/module/xapi/Crypto/algorithms/HMAC.js +9 -9
  61. package/src/module/xapi/Crypto/algorithms/SHA1.js +9 -9
  62. package/src/module/xapi/Crypto/encoders/Base.js +105 -105
  63. package/src/module/xapi/Crypto/encoders/Base64.js +99 -99
  64. package/src/module/xapi/Crypto/encoders/Hex.js +61 -61
  65. package/src/module/xapi/Crypto/encoders/Latin1.js +61 -61
  66. package/src/module/xapi/Crypto/encoders/Utf8.js +45 -45
  67. package/src/module/xapi/Crypto/index.js +53 -53
  68. package/src/module/xapi/Statement/activity.js +47 -47
  69. package/src/module/xapi/Statement/agent.js +55 -55
  70. package/src/module/xapi/Statement/group.js +26 -26
  71. package/src/module/xapi/Statement/index.js +259 -259
  72. package/src/module/xapi/Statement/statement.js +253 -253
  73. package/src/module/xapi/Statement/statementRef.js +23 -23
  74. package/src/module/xapi/Statement/substatement.js +22 -22
  75. package/src/module/xapi/Statement/verb.js +36 -36
  76. package/src/module/xapi/activitytypes.js +17 -17
  77. package/src/module/xapi/launch.js +157 -157
  78. package/src/module/xapi/utils.js +167 -167
  79. package/src/module/xapi/verbs.js +294 -294
  80. package/src/module/xapi/wrapper.js +1963 -1890
  81. package/src/module/xapi/xapiStatement.js +444 -444
  82. package/src/plugins/bus.js +8 -3
  83. package/src/plugins/gsap.js +14 -17
  84. package/src/plugins/helper.js +308 -295
  85. package/src/plugins/i18n.js +44 -31
  86. package/src/plugins/idb.js +219 -212
  87. package/src/plugins/save.js +37 -37
  88. package/src/plugins/scorm.js +287 -287
  89. package/src/plugins/xapi.js +11 -11
  90. package/src/public/index.html +33 -21
  91. package/src/router/index.js +43 -41
  92. package/src/router/routes.js +312 -337
  93. package/src/shared/generalfuncs.js +210 -188
  94. package/src/shared/validators.js +1069 -249
  95. package/vite.config.js +27 -0
  96. package/.prettierrc.js +0 -5
  97. package/babel.config.js +0 -3
  98. package/src/components/AppBaseDragChoice.vue +0 -91
  99. package/src/components/AppBaseDropZone.vue +0 -112
  100. package/src/components/AppCompBif.vue +0 -120
  101. package/src/components/AppCompDragAndDrop.vue +0 -339
  102. package/src/components/AppCompInputAssociation.vue +0 -332
  103. package/src/components/AppCompInputCheckBox.vue +0 -227
  104. package/src/components/AppCompInputDropdown.vue +0 -184
  105. package/src/components/AppCompInputRadio.vue +0 -169
  106. package/src/components/AppCompInputTextTable.vue +0 -155
  107. package/src/components/AppCompInputTextToFillDropdown.vue +0 -255
  108. package/src/components/AppCompMediaPlayer.vue +0 -397
  109. package/src/components/AppCompPopUp.vue +0 -522
  110. package/src/components/AppCompPopover.vue +0 -27
  111. package/src/components/AppCompSVG.vue +0 -309
  112. package/src/mixins/$pageMixins.js +0 -459
  113. package/src/mixins/$quizMixins.js +0 -456
  114. package/src/module/store.js +0 -895
  115. package/src/plugins/timeManager.js +0 -77
  116. package/src/routes_bckp.js +0 -313
  117. package/src/routes_static.js +0 -344
  118. package/vue.config.js +0 -83
@@ -1,192 +1,298 @@
1
- <!--
2
- @ Description: This component is used to display a carousel.
3
- @ What it does: Create an html element including an array of slides. These slides are objects including required property (imgSrc) and optional properties (imgAlt, Title, Hypertext).
4
- -->
5
-
6
- <template>
7
- <section id="carousel" :aria-label="$t('text.carousel')">
8
- <div class="carousel-inner">
9
- <div class="carousel-controls">
10
- <app-base-button
11
- id="carousel-btn-prev"
12
- class="carousel-btn"
13
- :aria-label="$t('button.carousel_prev')"
14
- aria-controls="mycarousel-slides"
15
- :title="$t('button.carousel_prev')"
16
- :class="{ md_disabled: disablePrev }"
17
- :disabled="disablePrev"
18
- :aria-disabled="disablePrev"
19
- @click="prevSlide()"
20
- >
21
- <svg>
22
- <use href="#fleche-gauche-icon"></use>
23
- </svg>
24
- </app-base-button>
25
- <app-base-button
26
- id="carousel-btn-next"
27
- class="carousel-btn"
28
- :aria-label="$t('button.carousel_next')"
29
- aria-controls="mycarousel-slides"
30
- :title="$t('button.carousel_next')"
31
- :class="{ md_disabled: disableNext }"
32
- :disabled="disableNext"
33
- :aria-disabled="disableNext"
34
- @click="nextSlide()"
35
- >
36
- <svg>
37
- <use href="#fleche-droite-icon"></use>
38
- </svg>
39
- </app-base-button>
40
- </div>
41
-
42
- <div id="mycarousel-slides" class="carousel-slides" aria-live="off">
43
- <div
44
- v-for="(slide, index) in slides"
45
- :key="index"
46
- class="carousel-slide"
47
- :class="{
48
- current: currentSlide == index + 1,
49
- prev: currentSlide >= index + 2,
50
- next: currentSlide <= index
51
- }"
52
- role="group"
53
- :aria-roledescription="$t('text.slide')"
54
- :aria-label="index + 1 + ' ' + $t('text.of') + ' ' + slideLength"
55
- :aria-hidden="!(currentSlide == index + 1)"
56
- >
57
- <div
58
- class="carousel-image"
59
- :class="{ 'full-width': !(slide.title || slide.hypertext) }"
60
- >
61
- <img
62
- :src="slide.imgSrc"
63
- :alt="slide.imgAlt"
64
- :aria-hidden="slide.imgAlt == ' ' || !slide.imgAlt ? true : false"
65
- />
66
- </div>
67
- <div v-if="slide.title || slide.hypertext" class="carousel-text">
68
- <h3 v-if="slide.title">
69
- {{ slide.title }}
70
- </h3>
71
- <div v-html="slide.hypertext"></div>
72
- </div>
73
- </div>
74
- </div>
75
- </div>
76
- <div class="carousel-index">
77
- <p aria-hidden="true">
78
- {{ $t('text.slide') + ' ' + currentSlide }}/{{ slideLength }}
79
- </p>
80
- </div>
81
- </section>
82
- </template>
83
-
84
- <script>
85
- export default {
86
- name: 'AppCompSlider',
87
- props: {
88
- slides: { type: Array, required: true } //Array of slides {imgSrc, imgAlt, title, hypertext}
89
- },
90
- data() {
91
- return {
92
- currentSlide: 1, //Slide management
93
- requiredProperties: ['imgSrc'], //For slides validation
94
- optionalProperties: ['title', 'imgAlt', 'hypertext'] //For slides validation
95
- }
96
- },
97
- computed: {
98
- disablePrev() {
99
- return !(this.currentSlide > 1)
100
- },
101
- disableNext() {
102
- return !(this.currentSlide < this.slideLength)
103
- },
104
- slideLength() {
105
- return this.slides.length
106
- }
107
- },
108
- mounted() {
109
- //Validating slides
110
- if (Array.isArray(this.slides) && this.slideLength > 0) {
111
- //Validate properties for all the slides
112
- for (const slide of this.slides) {
113
- this.validateProperties(
114
- this.requiredProperties,
115
- this.optionalProperties,
116
- slide
117
- )
118
- }
119
- } else {
120
- console.warn(
121
- `%c WARNING!>>> AppCompSlider : slides must be an array of at least one item`,
122
- 'background: orange; color: white; display: block; margin:5px;'
123
- )
124
- }
125
- },
126
- methods: {
127
- prevSlide() {
128
- if (this.currentSlide > 1) {
129
- this.currentSlide--
130
- }
131
- },
132
- nextSlide() {
133
- if (this.currentSlide < this.slideLength) {
134
- this.currentSlide++
135
- }
136
- },
137
- //Validate the properties of a specific object (currentObject)
138
- validateProperties(requiredProperties, optionalProperties, currentObject) {
139
- let allProperties = requiredProperties.concat(optionalProperties)
140
- let currentProperties = Object.keys(currentObject)
141
- let wrongProperties = this.checkerWrong(allProperties, currentProperties)
142
- let missingRequired = this.checkerMissing(
143
- requiredProperties,
144
- currentProperties
145
- )
146
-
147
- //Validate if all properties in currentObject are valid
148
- if (wrongProperties.length > 0) {
149
- console.warn(
150
- `%c WARNING!>>> AppCompSlider : slides ${wrongProperties} invalid. Required properties: ${requiredProperties} . Optional properties: ${optionalProperties}`,
151
- 'background: orange; color: white; display: block; margin:5px;'
152
- )
153
- }
154
- //Validate if all required properties are present in currentObject
155
- if (missingRequired.length > 0) {
156
- console.warn(
157
- `%c WARNING!>>> AppCompQuizSlider : slides missing required ${missingRequired} property. Required properties: ${requiredProperties} . Optional properties: ${optionalProperties}`,
158
- 'background: orange; color: white; display: block; margin:5px;'
159
- )
160
- }
161
- },
162
- //Get all the invalids properties from the object
163
- /*Add element from target array that are NOT in arr to the wrongArray*/
164
- checkerWrong(arr, target) {
165
- let wrongArray = []
166
- target.every((v) => {
167
- if (arr.includes(v)) {
168
- return true
169
- } else {
170
- wrongArray.push(v)
171
- return true
172
- }
173
- })
174
- return wrongArray
175
- },
176
- //Get all the required properties that are missing from the object
177
- /*Add element from the arr that are NOT in target arr to the missingArray*/
178
- checkerMissing(arr, target) {
179
- let missingArray = []
180
- arr.every((v) => {
181
- if (target.includes(v)) {
182
- return true
183
- } else {
184
- missingArray.push(v)
185
- return true
186
- }
187
- })
188
- return missingArray
189
- }
190
- }
191
- }
192
- </script>
1
+ <!--
2
+ @ Description: This component is used to display a carousel.
3
+ @ What it does: Create an html element including an array of slides. These slides are objects including required property (imgSrc) and optional properties (imgAlt, Title, Hypertext).
4
+ -->
5
+
6
+ <template>
7
+ <section id="carousel" :aria-label="$t('text.carousel')">
8
+ <div class="carousel-inner">
9
+ <div id="mycarousel-slides" class="carousel-slides" aria-live="polite">
10
+ <div
11
+ v-for="(slide, index) in slides"
12
+ :key="index"
13
+ class="carousel-slide"
14
+ :class="{
15
+ current: currentSlide == index + 1,
16
+ prev: currentSlide >= index + 2,
17
+ next: currentSlide <= index
18
+ }"
19
+ role="group"
20
+ :aria-hidden="!(currentSlide == index + 1)"
21
+ >
22
+ <span class="sr-only">
23
+ {{
24
+ $t('text.slide') +
25
+ ' ' +
26
+ (index + 1) +
27
+ ' ' +
28
+ $t('text.of') +
29
+ ' ' +
30
+ slideLength
31
+ }}
32
+ </span>
33
+ <div
34
+ class="carousel-image"
35
+ :class="{ 'full-width': !(slide.title || slide.hypertext) }"
36
+ >
37
+ <img
38
+ :src="slide.imgSrc"
39
+ :alt="slide.imgAlt"
40
+ :aria-hidden="slide.imgAlt == ' ' || !slide.imgAlt ? true : false"
41
+ />
42
+ </div>
43
+ <div v-if="slide.title || slide.hypertext" class="carousel-text">
44
+ <h3 v-if="slide.title">
45
+ {{ slide.title }}
46
+ </h3>
47
+ <div v-html="slide.hypertext"></div>
48
+ </div>
49
+ </div>
50
+ </div>
51
+ <div class="carousel-controls">
52
+ <app-base-button
53
+ id="carousel-btn-prev"
54
+ class="carousel-btn"
55
+ :aria-label="$t('button.carousel_prev')"
56
+ aria-controls="mycarousel-slides"
57
+ :title="$t('button.carousel_prev')"
58
+ :disabled="disablePrev"
59
+ :aria-disabled="disablePrev"
60
+ @click="prevSlide()"
61
+ >
62
+ <svg>
63
+ <use href="#fleche-gauche-icon"></use>
64
+ </svg>
65
+ </app-base-button>
66
+ <app-base-button
67
+ id="carousel-btn-next"
68
+ class="carousel-btn"
69
+ :aria-label="$t('button.carousel_next')"
70
+ aria-controls="mycarousel-slides"
71
+ :title="$t('button.carousel_next')"
72
+ :disabled="disableNext"
73
+ :aria-disabled="disableNext"
74
+ @click="nextSlide()"
75
+ >
76
+ <svg>
77
+ <use href="#fleche-droite-icon"></use>
78
+ </svg>
79
+ </app-base-button>
80
+ </div>
81
+ </div>
82
+ <div class="carousel-index">
83
+ <p aria-hidden="true">{{ currentSlide }}/{{ slideLength }}</p>
84
+ </div>
85
+ </section>
86
+ </template>
87
+
88
+ <script>
89
+ export default {
90
+ name: 'AppCompSlider',
91
+ props: {
92
+ slides: { type: Array, required: true } //Array of slides {imgSrc, imgAlt, title, hypertext}
93
+ },
94
+ data() {
95
+ return {
96
+ currentSlide: 1, //Slide management
97
+ requiredProperties: ['imgSrc'], //For slides validation
98
+ optionalProperties: ['title', 'imgAlt', 'hypertext'] //For slides validation
99
+ }
100
+ },
101
+ computed: {
102
+ disablePrev() {
103
+ return !(this.currentSlide > 1)
104
+ },
105
+ disableNext() {
106
+ return !(this.currentSlide < this.slideLength)
107
+ },
108
+ slideLength() {
109
+ return this.slides.length
110
+ }
111
+ },
112
+ mounted() {
113
+ //Validating slides
114
+ if (Array.isArray(this.slides) && this.slideLength > 0) {
115
+ //Validate properties for all the slides
116
+ for (const slide of this.slides) {
117
+ this.validateProperties(
118
+ this.requiredProperties,
119
+ this.optionalProperties,
120
+ slide
121
+ )
122
+ }
123
+ } else {
124
+ console.warn(
125
+ `%c WARNING!>>> AppCompSlider : slides must be an array of at least one item`,
126
+ 'background: orange; color: white; display: block; margin:5px;'
127
+ )
128
+ }
129
+ },
130
+ methods: {
131
+ prevSlide() {
132
+ if (this.currentSlide > 1) {
133
+ this.currentSlide--
134
+ }
135
+ },
136
+ nextSlide() {
137
+ if (this.currentSlide < this.slideLength) {
138
+ this.currentSlide++
139
+ }
140
+ },
141
+ //Validate the properties of a specific object (currentObject)
142
+ validateProperties(requiredProperties, optionalProperties, currentObject) {
143
+ let allProperties = requiredProperties.concat(optionalProperties)
144
+ let currentProperties = Object.keys(currentObject)
145
+ let wrongProperties = this.checkerWrong(allProperties, currentProperties)
146
+ let missingRequired = this.checkerMissing(
147
+ requiredProperties,
148
+ currentProperties
149
+ )
150
+
151
+ //Validate if all properties in currentObject are valid
152
+ if (wrongProperties.length > 0) {
153
+ console.warn(
154
+ `%c WARNING!>>> AppCompSlider : slides ${wrongProperties} invalid. Required properties: ${requiredProperties} . Optional properties: ${optionalProperties}`,
155
+ 'background: orange; color: white; display: block; margin:5px;'
156
+ )
157
+ }
158
+ //Validate if all required properties are present in currentObject
159
+ if (missingRequired.length > 0) {
160
+ console.warn(
161
+ `%c WARNING!>>> AppCompQuizSlider : slides missing required ${missingRequired} property. Required properties: ${requiredProperties} . Optional properties: ${optionalProperties}`,
162
+ 'background: orange; color: white; display: block; margin:5px;'
163
+ )
164
+ }
165
+ },
166
+ //Get all the invalids properties from the object
167
+ /*Add element from target array that are NOT in arr to the wrongArray*/
168
+ checkerWrong(arr, target) {
169
+ let wrongArray = []
170
+ target.every((v) => {
171
+ if (arr.includes(v)) {
172
+ return true
173
+ } else {
174
+ wrongArray.push(v)
175
+ return true
176
+ }
177
+ })
178
+ return wrongArray
179
+ },
180
+ //Get all the required properties that are missing from the object
181
+ /*Add element from the arr that are NOT in target arr to the missingArray*/
182
+ checkerMissing(arr, target) {
183
+ let missingArray = []
184
+ arr.every((v) => {
185
+ if (target.includes(v)) {
186
+ return true
187
+ } else {
188
+ missingArray.push(v)
189
+ return true
190
+ }
191
+ })
192
+ return missingArray
193
+ }
194
+ }
195
+ }
196
+ </script>
197
+ <style lang="scss">
198
+ #carousel {
199
+ width: max(100%, 350px);
200
+ }
201
+
202
+ .carousel-inner {
203
+ position: relative;
204
+ height: 100%;
205
+ width: 100%;
206
+ display: flex;
207
+ justify-content: center;
208
+ overflow: initial;
209
+ }
210
+
211
+ .carousel-slides {
212
+ position: relative;
213
+ height: 100%;
214
+ width: calc(
215
+ 100% - 136px
216
+ ); //add 68px each side of the carousel for the buttons
217
+ display: flex;
218
+ flex-direction: row;
219
+ overflow: hidden;
220
+ }
221
+
222
+ .carousel-slide {
223
+ min-width: 100%;
224
+ width: 100%;
225
+ display: flex;
226
+ flex-direction: row;
227
+ opacity: 0.5;
228
+ transition: all 0.6s ease-out;
229
+ position: relative;
230
+ @media screen and (max-width: 1000px) {
231
+ flex-direction: column;
232
+ }
233
+ &.current {
234
+ opacity: 1;
235
+ }
236
+ &.prev {
237
+ margin-left: -100%;
238
+ }
239
+ }
240
+
241
+ .carousel-image {
242
+ width: 60%;
243
+ height: 100%;
244
+ display: flex;
245
+ justify-content: center;
246
+ &.full-width {
247
+ width: 100%;
248
+ }
249
+ @media screen and (max-width: 1000px) {
250
+ width: 100%;
251
+ max-height: 250px;
252
+ }
253
+ img {
254
+ max-width: 100%;
255
+ width: 100%;
256
+ min-height: 300px;
257
+ object-fit: contain;
258
+ @media screen and (max-width: 1000px) {
259
+ min-height: 250px;
260
+ max-height: 250px;
261
+ }
262
+ }
263
+ }
264
+
265
+ .carousel-text {
266
+ width: 40%;
267
+ height: 100%;
268
+ padding: 48px 24px 32px 24px;
269
+
270
+ @media screen and (max-width: 1000px) {
271
+ width: 100%;
272
+ }
273
+ }
274
+
275
+ .carousel-index {
276
+ margin-top: 20px;
277
+ display: flex;
278
+ justify-content: center;
279
+ }
280
+
281
+ .carousel-controls {
282
+ position: absolute;
283
+ width: 75%;
284
+ top: calc(50% - 25px); //Center buttons
285
+
286
+ @media screen and (min-width: 510px) {
287
+ width: 100%;
288
+ }
289
+ & {
290
+ display: flex;
291
+ flex-direction: row;
292
+ justify-content: space-between;
293
+ z-index: 3;
294
+ user-select: none;
295
+ min-width: 300px;
296
+ }
297
+ }
298
+ </style>