fcad-core-dragon 2.0.0-beta.0 → 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 (161) 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 -49
  53. package/src/$locales/en.json +94 -92
  54. package/src/$locales/fr.json +77 -113
  55. package/src/assets/data/onboardingMessages.json +1 -1
  56. package/src/components/AppBase.vue +971 -437
  57. package/src/components/AppBaseButton.test.js +21 -0
  58. package/src/components/AppBaseButton.vue +42 -10
  59. package/src/components/AppBaseErrorDisplay.vue +209 -162
  60. package/src/components/AppBaseFlipCard.vue +1 -0
  61. package/src/components/AppBaseModule.vue +1021 -976
  62. package/src/components/AppBasePage.vue +656 -128
  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 +108 -181
  67. package/src/components/AppCompButtonProgress.vue +44 -70
  68. package/src/components/AppCompCarousel.vue +284 -233
  69. package/src/components/AppCompContainer.vue +29 -0
  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 -11
  78. package/src/components/AppCompMenu.vue +312 -92
  79. package/src/components/AppCompMenuItem.vue +129 -105
  80. package/src/components/AppCompNavigation.vue +972 -0
  81. package/src/components/AppCompNoteCall.vue +161 -0
  82. package/src/components/AppCompNoteCredit.vue +491 -0
  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 +350 -0
  87. package/src/components/AppCompSVGNext.vue +346 -0
  88. package/src/components/AppCompSettingsMenu.vue +18 -16
  89. package/src/components/AppCompTableOfContent.vue +340 -122
  90. package/src/components/AppCompVideoPlayer.vue +377 -0
  91. package/src/components/BaseModule.vue +24 -117
  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 +400 -142
  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 +4 -3
  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 +223 -218
  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 +9 -8
  122. package/src/plugins/helper.js +141 -43
  123. package/src/plugins/i18n.js +13 -18
  124. package/src/plugins/idb.js +46 -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 +23 -11
  129. package/src/router/index.js +57 -0
  130. package/src/router/routes.js +312 -0
  131. package/src/shared/generalfuncs.js +241 -10
  132. package/src/shared/validators.js +1018 -0
  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/AppCompDragAndDrop.vue +0 -339
  141. package/src/components/AppCompInputAssociation.vue +0 -332
  142. package/src/components/AppCompInputCheckBox.vue +0 -227
  143. package/src/components/AppCompInputDropdown.vue +0 -184
  144. package/src/components/AppCompInputRadio.vue +0 -169
  145. package/src/components/AppCompInputTextBox.vue +0 -91
  146. package/src/components/AppCompInputTextTable.vue +0 -155
  147. package/src/components/AppCompInputTextToFillDropdown.vue +0 -255
  148. package/src/components/AppCompInputTextToFillText.vue +0 -164
  149. package/src/components/AppCompMediaPlayer.vue +0 -365
  150. package/src/components/AppCompNavigationFull.vue +0 -1791
  151. package/src/components/AppCompPlayBar.vue +0 -1540
  152. package/src/components/AppCompPopUp.vue +0 -523
  153. package/src/components/AppCompQuiz.vue +0 -2998
  154. package/src/components/AppCompToolTip.vue +0 -94
  155. package/src/mixins/$pageMixins.js +0 -381
  156. package/src/mixins/$quizMixins.js +0 -456
  157. package/src/mixins/timerMixin.js +0 -132
  158. package/src/module/store.js +0 -874
  159. package/src/plugins/timeManager.js +0 -77
  160. package/src/routes.js +0 -734
  161. 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>