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

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 (163) hide show
  1. package/.editorconfig +6 -31
  2. package/.prettierrc +11 -0
  3. package/.vscode/extensions.json +8 -0
  4. package/.vscode/settings.json +16 -0
  5. package/CHANGELOG +153 -0
  6. package/README.md +28 -43
  7. package/documentation/.vitepress/config.js +114 -0
  8. package/documentation/api-examples.md +49 -0
  9. package/documentation/composants/app-base-button.md +58 -0
  10. package/documentation/composants/app-base-error-display.md +59 -0
  11. package/documentation/composants/app-base-popover.md +68 -0
  12. package/documentation/composants/app-comp-audio.md +75 -0
  13. package/documentation/composants/app-comp-branch-buttons.md +111 -0
  14. package/documentation/composants/app-comp-button-progress.md +53 -0
  15. package/documentation/composants/app-comp-carousel.md +53 -0
  16. package/documentation/composants/app-comp-container.md +53 -0
  17. package/documentation/composants/app-comp-input-checkbox-next.md +42 -0
  18. package/documentation/composants/app-comp-input-dropdown-next.md +34 -0
  19. package/documentation/composants/app-comp-input-radio-next.md +39 -0
  20. package/documentation/composants/app-comp-input-text-next.md +35 -0
  21. package/documentation/composants/app-comp-input-text-table-next.md +34 -0
  22. package/documentation/composants/app-comp-input-text-to-fill-dropdown-next.md +53 -0
  23. package/documentation/composants/app-comp-input-text-to-fill-next.md +31 -0
  24. package/documentation/composants/app-comp-jauge.md +31 -0
  25. package/documentation/composants/app-comp-menu-item.md +55 -0
  26. package/documentation/composants/app-comp-menu.md +29 -0
  27. package/documentation/composants/app-comp-navigation.md +41 -0
  28. package/documentation/composants/app-comp-note-call.md +53 -0
  29. package/documentation/composants/app-comp-note-credit.md +53 -0
  30. package/documentation/composants/app-comp-play-bar-next.md +53 -0
  31. package/documentation/composants/app-comp-pop-up-next.md +93 -0
  32. package/documentation/composants/app-comp-quiz-next.md +235 -0
  33. package/documentation/composants/app-comp-quiz-recall.md +53 -0
  34. package/documentation/composants/app-comp-svg-next.md +53 -0
  35. package/documentation/composants/app-comp-table-of-content.md +50 -0
  36. package/documentation/composants/app-comp-video-player.md +82 -0
  37. package/documentation/composants.md +46 -0
  38. package/documentation/composants_critiques/ModelPageComposant.md +53 -0
  39. package/documentation/composants_critiques/app-base-module.md +43 -0
  40. package/documentation/composants_critiques/app-base-page.md +48 -0
  41. package/documentation/composants_critiques/app-base.md +311 -0
  42. package/documentation/composants_critiques/main.md +15 -0
  43. package/documentation/demarrage.md +50 -0
  44. package/documentation/deploiement.md +58 -0
  45. package/documentation/index.md +33 -0
  46. package/documentation/markdown-examples.md +85 -0
  47. package/documentation/public/npm_version.png +0 -0
  48. package/documentation/public/vite.svg +15 -0
  49. package/documentation/public/vuejs.svg +2 -0
  50. package/documentation/public/vuetify.svg +6 -0
  51. package/eslint.config.js +60 -0
  52. package/package.json +43 -47
  53. package/src/$locales/en.json +86 -108
  54. package/src/$locales/fr.json +66 -127
  55. package/src/assets/data/onboardingMessages.json +1 -1
  56. package/src/components/AppBase.vue +960 -405
  57. package/src/components/AppBaseButton.test.js +21 -0
  58. package/src/components/AppBaseButton.vue +42 -10
  59. package/src/components/AppBaseErrorDisplay.vue +207 -189
  60. package/src/components/AppBaseFlipCard.vue +1 -0
  61. package/src/components/AppBaseModule.vue +769 -977
  62. package/src/components/AppBasePage.vue +635 -81
  63. package/src/components/AppBasePopover.vue +41 -0
  64. package/src/components/AppBaseSkeleton.vue +66 -0
  65. package/src/components/AppCompAudio.vue +256 -0
  66. package/src/components/AppCompBranchButtons.vue +79 -153
  67. package/src/components/AppCompButtonProgress.vue +21 -36
  68. package/src/components/AppCompCarousel.vue +231 -87
  69. package/src/components/{AppCompTranscript.vue → AppCompContainer.vue} +12 -2
  70. package/src/components/AppCompInputCheckBoxNx.vue +323 -0
  71. package/src/components/AppCompInputDropdownNx.vue +299 -0
  72. package/src/components/AppCompInputRadioNx.vue +284 -0
  73. package/src/components/AppCompInputTextNx.vue +153 -0
  74. package/src/components/AppCompInputTextTableNx.vue +202 -0
  75. package/src/components/AppCompInputTextToFillDropdownNx.vue +340 -0
  76. package/src/components/AppCompInputTextToFillNx.vue +313 -0
  77. package/src/components/AppCompJauge.vue +36 -10
  78. package/src/components/AppCompMenu.vue +246 -32
  79. package/src/components/AppCompMenuItem.vue +87 -21
  80. package/src/components/AppCompNavigation.vue +470 -447
  81. package/src/components/AppCompNoteCall.vue +93 -58
  82. package/src/components/AppCompNoteCredit.vue +423 -96
  83. package/src/components/AppCompPlayBarNext.vue +2288 -0
  84. package/src/components/AppCompPopUpNext.vue +504 -0
  85. package/src/components/AppCompQuizNext.vue +510 -0
  86. package/src/components/AppCompQuizRecall.vue +199 -99
  87. package/src/components/AppCompSVGNext.vue +346 -0
  88. package/src/components/AppCompSettingsMenu.vue +17 -16
  89. package/src/components/AppCompTableOfContent.vue +262 -99
  90. package/src/components/AppCompVideoPlayer.vue +183 -142
  91. package/src/components/BaseModule.vue +8 -20
  92. package/src/components/tests__/AppBaseButton.spec.js +53 -0
  93. package/src/components/tests__/useTimer.spec.js +91 -0
  94. package/src/composables/useIdleDetector.js +56 -0
  95. package/src/composables/useQuiz.js +89 -0
  96. package/src/composables/useTimer.js +172 -0
  97. package/src/directives/nvdaFix.js +53 -0
  98. package/src/externalComps/ModuleView.vue +22 -0
  99. package/src/externalComps/SummaryView.vue +91 -0
  100. package/src/main.js +397 -148
  101. package/src/module/stores/appStore.js +947 -0
  102. package/src/module/xapi/ADL.js +241 -60
  103. package/src/module/xapi/Crypto/Hasher.js +8 -8
  104. package/src/module/xapi/Crypto/WordArray.js +6 -6
  105. package/src/module/xapi/Crypto/algorithms/BufferedBlockAlgorithm.js +4 -4
  106. package/src/module/xapi/Crypto/algorithms/C_algo.js +14 -18
  107. package/src/module/xapi/Crypto/algorithms/HMAC.js +1 -1
  108. package/src/module/xapi/Crypto/algorithms/SHA1.js +1 -1
  109. package/src/module/xapi/Crypto/encoders/Base.js +7 -7
  110. package/src/module/xapi/Crypto/encoders/Base64.js +3 -3
  111. package/src/module/xapi/Crypto/encoders/Hex.js +2 -2
  112. package/src/module/xapi/Crypto/encoders/Latin1.js +3 -3
  113. package/src/module/xapi/Crypto/encoders/Utf8.js +3 -3
  114. package/src/module/xapi/Statement/index.js +3 -3
  115. package/src/module/xapi/launch.js +10 -10
  116. package/src/module/xapi/utils.js +17 -17
  117. package/src/module/xapi/wrapper.js +219 -214
  118. package/src/module/xapi/xapiStatement.js +29 -29
  119. package/src/plugins/analytics.js +34 -0
  120. package/src/plugins/bus.js +7 -2
  121. package/src/plugins/gsap.js +5 -7
  122. package/src/plugins/helper.js +97 -34
  123. package/src/plugins/i18n.js +13 -18
  124. package/src/plugins/idb.js +45 -30
  125. package/src/plugins/save.js +1 -1
  126. package/src/plugins/scorm.js +15 -15
  127. package/src/plugins/xapi.js +2 -2
  128. package/src/public/index.html +22 -10
  129. package/src/router/index.js +29 -13
  130. package/src/router/routes.js +29 -54
  131. package/src/shared/generalfuncs.js +186 -30
  132. package/src/shared/validators.js +809 -40
  133. package/vitest.config.js +19 -0
  134. package/.eslintignore +0 -29
  135. package/.eslintrc.js +0 -86
  136. package/.prettierrc.js +0 -5
  137. package/babel.config.js +0 -3
  138. package/src/components/AppBaseDragChoice.vue +0 -91
  139. package/src/components/AppBaseDropZone.vue +0 -112
  140. package/src/components/AppCompBif.vue +0 -120
  141. package/src/components/AppCompDragAndDrop.vue +0 -339
  142. package/src/components/AppCompInputAssociation.vue +0 -332
  143. package/src/components/AppCompInputCheckBox.vue +0 -227
  144. package/src/components/AppCompInputDropdown.vue +0 -184
  145. package/src/components/AppCompInputRadio.vue +0 -169
  146. package/src/components/AppCompInputTextBox.vue +0 -91
  147. package/src/components/AppCompInputTextTable.vue +0 -155
  148. package/src/components/AppCompInputTextToFillDropdown.vue +0 -255
  149. package/src/components/AppCompInputTextToFillText.vue +0 -164
  150. package/src/components/AppCompMediaPlayer.vue +0 -397
  151. package/src/components/AppCompPlayBar.vue +0 -1319
  152. package/src/components/AppCompPopUp.vue +0 -522
  153. package/src/components/AppCompPopover.vue +0 -27
  154. package/src/components/AppCompQuiz.vue +0 -2989
  155. package/src/components/AppCompSVG.vue +0 -309
  156. package/src/mixins/$pageMixins.js +0 -459
  157. package/src/mixins/$quizMixins.js +0 -456
  158. package/src/mixins/timerMixin.js +0 -156
  159. package/src/module/store.js +0 -895
  160. package/src/plugins/timeManager.js +0 -77
  161. package/src/routes_bckp.js +0 -313
  162. package/src/routes_static.js +0 -344
  163. package/vue.config.js +0 -83
@@ -0,0 +1,41 @@
1
+ <!--
2
+ @ Description: This component is used to create a popover that is accessible via keyboard navigation (tab + space/enter)
3
+ -->
4
+ <template>
5
+ <v-tooltip
6
+ ref="tooltip"
7
+ v-bind="$attrs"
8
+ v-model="show"
9
+ transition="false"
10
+ :open-on-click="true"
11
+ :persistent="false"
12
+ >
13
+ <slot></slot>
14
+ </v-tooltip>
15
+ </template>
16
+
17
+ <script>
18
+ export default {
19
+ name: 'AppBasePopover',
20
+ data() {
21
+ return {
22
+ show: false,
23
+ alertContainer: null
24
+ }
25
+ },
26
+ watch: {
27
+ show: {
28
+ handler(newValue) {
29
+ if (newValue) {
30
+ const content = this.$refs.tooltip.contentEl.textContent
31
+ this.alertContainer.textContent = ''
32
+ this.alertContainer.textContent = content
33
+ }
34
+ }
35
+ }
36
+ },
37
+ mounted() {
38
+ this.alertContainer = document.getElementById('hiddenAlertContainer')
39
+ }
40
+ }
41
+ </script>
@@ -0,0 +1,66 @@
1
+ <!--
2
+ @ Description: This component is used to display skeleton screens while content is loading.
3
+
4
+ -->
5
+
6
+ <template>
7
+ <div class="skeleton-wrapper">
8
+ <div v-if="skeletonText" class="skeleton-text">{{ skeletonText }}</div>
9
+ <div v-for="line in skeletonLines" :key="line" class="skeleton-line" />
10
+
11
+ <div v-show="skeletonType == `quiz-choix`">
12
+ <v-skeleton-loader
13
+ type="heading, avatar,paragraph,
14
+ "
15
+ ></v-skeleton-loader>
16
+ <v-skeleton-loader type="avatar,paragraph"></v-skeleton-loader>
17
+ <v-skeleton-loader type="avatar,paragraph"></v-skeleton-loader>
18
+ </div>
19
+
20
+ <div v-show="skeletonType == `quiz-texte`">
21
+ <v-skeleton-loader
22
+ type="heading, image,
23
+ "
24
+ ></v-skeleton-loader>
25
+ </div>
26
+
27
+ <div v-show="skeletonType == `quiz-recall`">
28
+ <v-skeleton-loader type="heading, paragraph,image"></v-skeleton-loader>
29
+ </div>
30
+ </div>
31
+ </template>
32
+
33
+ <script>
34
+ export default {
35
+ name: 'AppBaseSkeleton',
36
+ props: {
37
+ skeletonLines: { type: Number, default: 0 }, //number of skeleton lines to display
38
+ skeletonText: { type: String, default: `` }, //number of skeleton lines to display
39
+ skeletonType: { type: String, default: `line` }
40
+ }
41
+ }
42
+ </script>
43
+
44
+ <style lang="scss">
45
+ .skeleton-wrapper {
46
+ display: flex;
47
+ flex-direction: column;
48
+ width: 100%;
49
+ gap: 8px;
50
+ }
51
+ skeleton-text {
52
+ font-size: larger;
53
+ }
54
+ .skeleton-line {
55
+ height: 25px;
56
+ background: linear-gradient(90deg, #ddd, #eee, #ddd);
57
+ background-size: 200% 100%;
58
+ animation: skeleton-loading 1.2s infinite linear;
59
+ border-radius: 4px;
60
+ }
61
+ @keyframes skeleton-loading {
62
+ to {
63
+ background-position-x: -200%;
64
+ }
65
+ }
66
+ </style>
@@ -0,0 +1,256 @@
1
+ <template>
2
+ <section
3
+ :id="'audio_' + id"
4
+ ref="$media-container"
5
+ class="__media-container"
6
+ aria-label="Audio"
7
+ >
8
+ <!--Integration error display-->
9
+ <app-base-error-display
10
+ v-if="hasErr.length"
11
+ :error-group="'component'"
12
+ :error-title="`ERREUR: COMPOSANT D'AUDIO`"
13
+ :errors-list="hasErr"
14
+ />
15
+
16
+ <div v-else class="audio-card">
17
+ <!--Waiting and loading error -- skeleton-->
18
+ <div
19
+ v-if="isLoading || hasSourceLoadingError"
20
+ class="skeleton audio"
21
+ :class="{ isloading: isLoading, error: hasSourceLoadingError }"
22
+ >
23
+ <p v-if="hasSourceLoadingError">
24
+ Une erreur s'est produite lors du chargement du média, veuillez
25
+ réessayer
26
+ </p>
27
+ </div>
28
+ <!--Audio content-->
29
+ <div v-show="!isLoading && !hasSourceLoadingError" class="audio-content">
30
+ <img
31
+ v-if="mPoster"
32
+ class="audio-img"
33
+ :src="mPoster"
34
+ aria-hidden="true"
35
+ />
36
+ <div class="audio-media">
37
+ <span>{{ mTitle }}</span>
38
+ <div class="audio-media-player">
39
+ <audio
40
+ :id="id"
41
+ ref="m-audio"
42
+ @loadedmetadata="updateMediaDataAudio($event.target)"
43
+ >
44
+ <source
45
+ v-for="(aSource, index) in mSources"
46
+ :key="index"
47
+ :src="aSource.src"
48
+ :type="aSource.type ? `audio/${aSource.type}` : 'audio/mp3'"
49
+ @error="errorHandling($event)"
50
+ />
51
+ </audio>
52
+ <app-comp-play-bar-next
53
+ v-if="$audElement"
54
+ :ref="`plyr_${id}`"
55
+ :media-to-play="$audElement"
56
+ />
57
+ </div>
58
+ </div>
59
+ </div>
60
+ <div class="audio-transcript">
61
+ <v-expansion-panels class="audio">
62
+ <v-expansion-panel>
63
+ <v-expansion-panel-title>
64
+ {{ $t('text.transcript') }}
65
+ </v-expansion-panel-title>
66
+ <v-expansion-panel-text>
67
+ <div v-html="mTranscript"></div>
68
+ </v-expansion-panel-text>
69
+ </v-expansion-panel>
70
+ </v-expansion-panels>
71
+ </div>
72
+ </div>
73
+ </section>
74
+ </template>
75
+ <script>
76
+ import { mapState, mapActions } from 'pinia'
77
+ import { useAppStore } from '../module/stores/appStore'
78
+ import { validateAudioData } from '../shared/validators'
79
+ import AppCompPlayBarNext from './AppCompPlayBarNext.vue'
80
+
81
+ export default {
82
+ components: { AppCompPlayBarNext },
83
+ props: {
84
+ audData: {
85
+ type: Object,
86
+ required: true
87
+ }
88
+ },
89
+ data() {
90
+ return {
91
+ id: this.audData.id,
92
+ mTitle: this.audData.mTitle,
93
+ mSources: this.audData.mSources,
94
+ mTranscript: this.audData.mTranscript,
95
+ mPoster: this.audData.mPoster,
96
+ isSet: false,
97
+ hasSourceLoadingError: false,
98
+ hasErr: validateAudioData(this.audData)
99
+ }
100
+ },
101
+ computed: {
102
+ ...mapState(useAppStore, ['getCurrentBrowser', 'getCurrentPage']),
103
+ $audElement() {
104
+ if (!this.isSet) return null
105
+ return {
106
+ id: this.id,
107
+ mTranscript: null,
108
+ mType: 'audio',
109
+ mSubtitles: null,
110
+ mElement: this.$refs['m-audio']
111
+ }
112
+ },
113
+ //MediaElement
114
+ mediaElement() {
115
+ if (!this.$audElement) return null
116
+ const { mElement } = this.$audElement
117
+ let thisElement = null
118
+
119
+ if (!mElement) return null
120
+ thisElement = mElement
121
+
122
+ return thisElement
123
+ },
124
+ //Loading display
125
+ isLoading() {
126
+ if (!this.isSet && !this.hasSourceLoadingError) return true
127
+ else return false
128
+ }
129
+ },
130
+ mounted() {},
131
+ beforeUnmount() {},
132
+
133
+ methods: {
134
+ ...mapActions(useAppStore, ['updateCurrentMediaElements']),
135
+ /**
136
+ * @description search the DOM for medias with duplicated ID declaration in the page
137
+ * @return return Array of all DOM MediaElement with same id
138
+ */
139
+ checkDuplicatedID() {
140
+ const mediaList = document.querySelectorAll('.__media-container')
141
+ const duplicate = Array.from(mediaList).filter((media) =>
142
+ media.id.includes(this.id)
143
+ )
144
+ return duplicate
145
+ },
146
+ /**
147
+ * @description update the information for the mediaElement in the store
148
+ * @param {htmlElement} e
149
+ * @fires update-page to AppBaseModule.vue
150
+ */
151
+ updateMediaDataAudio(e) {
152
+ //dispatch loading status of for this component
153
+ this.$bus.$emit('set-comp-status', 'AppCompAudioPlayer', 'loading')
154
+ this.$bus.$emit('update-media-duration')
155
+
156
+ if (this.checkDuplicatedID().length > 1) {
157
+ const errmsg = `Cet élément a le même ID <b>${this.id}</b>q'un autre media. Vous ne devez pas avoir de médias avec le même ID dans une page.`
158
+
159
+ console.warn(
160
+ `%c WARNING!>>> You cannot use the same ID (${this.id}) in your media elements for your page.`,
161
+ 'background: orange; color: white; display: block; border-radius:5px; margin:5px;'
162
+ )
163
+
164
+ this.$bus.$emit('set-comp-status', 'AppCompAudioPlayer', 'ready')
165
+ return this.hasErr.push(errmsg)
166
+ }
167
+
168
+ this.updateCurrentMediaElements(e).then(() => {
169
+ this.isSet = true
170
+ this.$bus.$emit('set-comp-status', 'AppCompAudioPlayer', 'ready')
171
+ })
172
+ },
173
+ errorHandling(e) {
174
+ this.hasSourceLoadingError = true
175
+ }
176
+ }
177
+ }
178
+ </script>
179
+ <style scoped lang="scss">
180
+ .audio-card {
181
+ position: relative;
182
+ border-radius: 4px;
183
+ padding: 24px;
184
+ min-width: 425px;
185
+ max-width: 600px;
186
+ box-shadow: 0px 3px 6px rgb(26 25 25 / 0.16);
187
+
188
+ @media screen and (max-width: 1000px) {
189
+ display: flex;
190
+ flex-direction: column;
191
+ }
192
+ .audio-img {
193
+ width: 128px;
194
+ margin-right: 24px;
195
+ }
196
+ .audio-content {
197
+ display: flex;
198
+ flex-direction: row;
199
+ align-items: center;
200
+ padding-bottom: 24px;
201
+
202
+ @media screen and (max-width: 1000px) {
203
+ display: flex;
204
+ flex-direction: column;
205
+ }
206
+ .audio-media {
207
+ width: 100%;
208
+ h5 {
209
+ margin-bottom: 16px;
210
+ }
211
+ }
212
+ }
213
+ .audio-transcript {
214
+ padding-top: 24px;
215
+ }
216
+ .audio-transcript-header {
217
+ display: flex;
218
+ justify-content: space-between;
219
+ align-items: center;
220
+ }
221
+
222
+ .audio-transcript-button {
223
+ height: 52px;
224
+ width: 52px;
225
+ display: flex;
226
+ justify-content: center;
227
+ align-items: center;
228
+ svg {
229
+ max-width: 18px;
230
+ height: 10.25px;
231
+ }
232
+ &.rotate svg {
233
+ transition: transform 0.5s;
234
+ transform-origin: center;
235
+ }
236
+ &.rotate.click svg {
237
+ transform: rotate(180deg);
238
+ }
239
+ }
240
+ }
241
+
242
+ .skeleton {
243
+ &.audio {
244
+ height: 100%;
245
+ width: 100%;
246
+ left: 0;
247
+ top: 0;
248
+ }
249
+ }
250
+
251
+ .debug {
252
+ &:focus {
253
+ border: 5px solid rgba(#fff, 0.05);
254
+ }
255
+ }
256
+ </style>