fcad-core-dragon 2.1.2 → 2.2.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 (33) hide show
  1. package/.gitlab-ci.yml +24 -42
  2. package/.vscode/settings.json +0 -30
  3. package/CHANGELOG +16 -0
  4. package/artifacts/playwright-report/index.html +85 -0
  5. package/package.json +29 -26
  6. package/src/components/AppBasePage.vue +3 -8
  7. package/src/components/AppCompAudio.vue +3 -3
  8. package/src/components/AppCompBranchButtons.vue +6 -3
  9. package/src/components/AppCompInputCheckBoxNx.vue +2 -1
  10. package/src/components/AppCompInputDropdownNx.vue +5 -5
  11. package/src/components/AppCompInputRadioNx.vue +2 -1
  12. package/src/components/AppCompInputTextNx.vue +0 -2
  13. package/src/components/AppCompInputTextTableNx.vue +4 -4
  14. package/src/components/AppCompInputTextToFillDropdownNx.vue +4 -6
  15. package/src/components/AppCompInputTextToFillNx.vue +1 -24
  16. package/src/components/AppCompNoteCredit.vue +9 -7
  17. package/src/components/AppCompPlayBarNext.vue +17 -11
  18. package/src/components/AppCompQuizRecall.vue +10 -6
  19. package/src/components/AppCompVideoPlayer.vue +2 -1
  20. package/src/main.js +20 -6
  21. package/src/plugins/i18n.js +8 -7
  22. package/tests/mocks/routes.mock.js +2 -0
  23. package/tests/unit/AppCompAudio.spec.js +139 -0
  24. package/tests/unit/AppCompBranchButtons.spec.js +172 -0
  25. package/tests/unit/AppCompCarousel.spec.js +62 -0
  26. package/tests/unit/AppCompNoteCredit.spec.js +49 -0
  27. package/tests/unit/AppCompVideoPlayer.spec.js +97 -102
  28. package/tests/unit/useQuiz.spec.js +72 -0
  29. package/tests/utility/colors.js +10 -0
  30. package/vitest.config.js +49 -23
  31. package/vitest.setup.js +70 -1
  32. package/junit-report.xml +0 -182
  33. package/tests/unit/AppCompQuizNext.spec.js +0 -114
package/package.json CHANGED
@@ -1,33 +1,12 @@
1
1
  {
2
- "name": "fcad-core-dragon",
3
- "version": "2.1.2",
4
- "private": false,
5
- "type": "module",
6
- "main": "./src/main.js",
7
- "scripts": {
8
- "build": "vite build",
9
- "dev": "vite",
10
- "docs:build": "vitepress build documentation",
11
- "docs:dev": "vitepress dev documentation",
12
- "docs:preview": "vitepress preview documentation",
13
- "lintfix": "eslint --fix src",
14
- "lintreport": "eslint ./src",
15
- "preview": "vite preview",
16
- "reset": "rm -rf ./node_modules package-lock.json .cache dist && npm i && npm run watch",
17
- "test:unit": "vitest",
18
- "vue": "vue",
19
- "watch": "nodemon -e js,vue,html,json -x yalc publish --push",
20
- "format": "prettier --write src/",
21
- "test-ct": "playwright test -c playwright-ct.config.js"
22
- },
23
- "config": {
24
- "projname": ""
25
- },
26
2
  "browserslist": [
27
3
  "> 1%",
28
4
  "last 2 versions",
29
5
  "not dead"
30
6
  ],
7
+ "config": {
8
+ "projname": ""
9
+ },
31
10
  "dependencies": {
32
11
  "axios": "^1.6.8",
33
12
  "gsap": "^3.12.5",
@@ -44,23 +23,47 @@
44
23
  "@playwright/test": "^1.56.1",
45
24
  "@types/node": "^24.10.0",
46
25
  "@vitejs/plugin-vue": "^6.0.1",
26
+ "@vitest/coverage-v8": "^4.0.15",
47
27
  "@vue/eslint-config-prettier": "^10.2.0",
48
28
  "@vue/test-utils": "^2.4.6",
49
29
  "eslint": "^9.38.0",
50
30
  "eslint-plugin-cypress": "^5.1.0",
51
31
  "eslint-plugin-vue": "~10.3.0",
52
32
  "globals": "^16.4.0",
33
+ "happy-dom": "^20.0.10",
53
34
  "jsdom": "^25.0.1",
54
35
  "nodemon": "^3.1.0",
55
36
  "prettier": "^3.6.2",
56
37
  "sass-embedded": "^1.91.0",
57
38
  "vitepress": "^1.6.3",
58
- "vitest": "^3.2.4",
39
+ "vitest": "^4.0.15",
59
40
  "vue-i18n": "^11.1.12",
60
41
  "vue-router": "^4.4.5",
61
42
  "vuetify": "^3.10.10"
62
43
  },
63
44
  "engines": {
64
45
  "node": ">0.11.9"
65
- }
46
+ },
47
+ "main": "./src/main.js",
48
+ "name": "fcad-core-dragon",
49
+ "private": false,
50
+ "scripts": {
51
+ "build": "vite build",
52
+ "dev": "vite",
53
+ "docs:build": "vitepress build documentation",
54
+ "docs:dev": "vitepress dev documentation",
55
+ "docs:preview": "vitepress preview documentation",
56
+ "format": "prettier --write src/",
57
+ "lintfix": "eslint --fix src",
58
+ "lintreport": "eslint ./src",
59
+ "preview": "vite preview",
60
+ "reset": "rm -rf ./node_modules package-lock.json .cache dist && npm i && npm run watch",
61
+ "test-ct": "playwright test -c playwright-ct.config.js",
62
+ "test:unit": "vitest",
63
+ "test:unit:coverage": "vitest --coverage",
64
+ "vue": "vue",
65
+ "watch": "nodemon -e js,vue,html,json -x yalc publish --push"
66
+ },
67
+ "type": "module",
68
+ "version": "2.2.0-beta.2"
66
69
  }
@@ -11,7 +11,6 @@
11
11
  <div class="ctn">
12
12
  Activity info: Route : {{ $route.path }}
13
13
  <br />
14
-
15
14
  Activity id : {{ getDebugModeInfo.id }}
16
15
  <br />
17
16
  Nombre de page : {{ getDebugModeInfo.size }}
@@ -96,6 +95,7 @@ export default {
96
95
  }
97
96
  },
98
97
  setup(props) {
98
+ //console.log('dans setup')
99
99
  const store = useAppStore()
100
100
  const { activityRef, id: pageID, type: pageType } = props.pageData
101
101
  const { t } = useI18n()
@@ -167,35 +167,29 @@ export default {
167
167
  getModuleInfo() {
168
168
  return this.store.getModuleInfo
169
169
  },
170
-
171
170
  getAllActivities() {
172
171
  return this.store.getAllActivities()
173
172
  },
174
173
  getConnectionInfo() {
175
174
  return this.store.getConnectionInfo
176
175
  },
177
-
178
176
  getAnchorsForActivity() {
179
177
  return this.store.getAnchorsForActivity()
180
178
  },
181
179
  getBifChoice() {
182
180
  return this.store.getBifChoice
183
181
  },
184
-
185
182
  isBranchingPage() {
186
183
  return this.$route.meta.type === 'branching' && this.type !== 'pg_branch'
187
184
  },
188
-
189
185
  //================================================
190
186
  settingsOptions() {
191
187
  return this.settingsOptionsELPlus
192
188
  },
193
-
194
189
  settingsSelected() {
195
190
  const setting = this.getApplicationSettings
196
191
  return setting
197
192
  },
198
-
199
193
  errorPage() {
200
194
  let err = false
201
195
  if (import.meta.env.DEV) {
@@ -380,7 +374,8 @@ export default {
380
374
  /**
381
375
  * Observe changes in the number of poperties to dispatch updates in the userdata in the Store
382
376
  */
383
-
377
+ // console.log('ici')
378
+ //console.log(this.userInteraction)
384
379
  if (newValue && Object.entries(this.userInteraction).length) {
385
380
  await this.store.updateUserMetaData({
386
381
  activityRef: this.pageData.activityRef,
@@ -107,11 +107,11 @@ export default {
107
107
  ...mapState(useAppStore, ['getCurrentBrowser', 'getCurrentPage']),
108
108
  $audElement() {
109
109
  if (!this.isSet) return null
110
+ const { id, mTranscript } = this.audData
110
111
  return {
111
- id: this.id,
112
- mTranscript: null,
112
+ id,
113
+ mTranscript,
113
114
  mType: 'audio',
114
- mSubtitles: null,
115
115
  mElement: this.$refs['m-audio']
116
116
  }
117
117
  },
@@ -250,6 +250,7 @@ export default {
250
250
  this.isCard = this.cards && Object.keys(this.cards).length != 0
251
251
  this.idActivity = this.$router.currentRoute.value.meta.activity_ref
252
252
  this.branchs = this.$router.currentRoute.value.meta.children
253
+
253
254
  this.getbranchsData()
254
255
  },
255
256
  methods: {
@@ -271,7 +272,7 @@ export default {
271
272
  branchData.progression = progression
272
273
  if (isNaN(branchData.progression)) branchData.progression = 0
273
274
 
274
- if (this.isCard) {
275
+ if (this.isCard && this.getMatchingElement(branchData.id)) {
275
276
  const { title, text, imgFile, imgAlt, btnTitle } =
276
277
  this.getMatchingElement(branchData.id)
277
278
 
@@ -476,12 +477,14 @@ export default {
476
477
  * @return {Object} Matching element from
477
478
  */
478
479
  getMatchingElement(id) {
480
+ let matchingBranch = null
479
481
  if (this.isCustomButton) {
480
- return this.customButtons.find((c) => c.brchName === id)
482
+ matchingBranch = this.customButtons.find((c) => c.brchName === id)
481
483
  }
482
484
  if (this.isCard) {
483
- return this.cards.find((c) => c.brchName === id)
485
+ matchingBranch = this.cards.find((c) => c.brchName === id)
484
486
  }
487
+ return matchingBranch ? matchingBranch : null
485
488
  }
486
489
  }
487
490
  }
@@ -168,7 +168,8 @@ export default {
168
168
  )
169
169
  const { errorList, errorInConsole } = errors
170
170
 
171
- if (errorList.length || errorInConsole.length) return errors
171
+ if (!errorList || !errorInConsole) return null
172
+ return errors
172
173
  }
173
174
 
174
175
  return errors
@@ -29,6 +29,7 @@
29
29
  :items="getItemOptions(index)"
30
30
  :open-text="`${$t('message.dropdown_list')}_${singleDropdown.ennonce}`"
31
31
  :aria-describedby="`${id}_${singleDropdown.id}-msg-erreur`"
32
+ menu-icon="mdi-chevron-down"
32
33
  @update:model-value="onSelectUpdate($event, index)"
33
34
  ></v-select>
34
35
 
@@ -169,11 +170,10 @@ export default {
169
170
  null,
170
171
  `liste déroulante #${i + 1}`
171
172
  )
172
-
173
- if (e.errorInConsole.length && e.errorList.length) {
174
- errors.errorInConsole.push(e.errorInConsole[0])
175
- errors.errorList.push(e.errorList[0])
176
- }
173
+ if (!e || !e.errorList || !e.errorInConsole) return null
174
+ const { errorList, errorInConsole } = e
175
+ if (errorInConsole.length) errors.errorInConsole.push(errorInConsole[0])
176
+ if (errorList.length) errors.errorList.push(errorList[0])
177
177
  }
178
178
 
179
179
  return errors
@@ -197,7 +197,8 @@ export default {
197
197
  )
198
198
  const { errorList, errorInConsole } = errors
199
199
 
200
- if (errorList.length || errorInConsole.length) return errors
200
+ if (!errorList || !errorInConsole) return null
201
+ return errors
201
202
  }
202
203
 
203
204
  return errors
@@ -99,9 +99,7 @@ export default {
99
99
  methods: {
100
100
  validateInputData() {
101
101
  let errors = null //array for errors dectected
102
-
103
102
  if (this.inputData != undefined) return errors
104
-
105
103
  return errors
106
104
  },
107
105
  /**
@@ -129,10 +129,10 @@ export default {
129
129
  `texte tableau #${i + 1}`
130
130
  )
131
131
 
132
- if (e.errorInConsole.length && e.errorList.length) {
133
- errors.errorInConsole.push(e.errorInConsole[0])
134
- errors.errorList.push(e.errorList[0])
135
- }
132
+ if (!e || !e.errorList || !e.errorInConsole) return null
133
+ const { errorList, errorInConsole } = e
134
+ if (errorInConsole.length) errors.errorInConsole.push(errorInConsole[0])
135
+ if (errorList.length) errors.errorList.push(errorList[0])
136
136
  }
137
137
 
138
138
  return errors
@@ -34,6 +34,7 @@
34
34
  :items="getItemOptions(textInput.index)"
35
35
  :aria-describedby="`${id}_${textInput.id}-msg-erreur`"
36
36
  :aria-labelledby="`${id}_${textInput.id}-label`"
37
+ menu-icon="mdi-chevron-down"
37
38
  @update:model-value="onSelectUpdate($event, textInput.index)"
38
39
  />
39
40
  <span
@@ -173,7 +174,7 @@ export default {
173
174
  let splittedText = str.split(regex)
174
175
  let listInput = []
175
176
 
176
- for (let i = 0; i < splittedText.length - 1; i++) {
177
+ for (let i = 0; i < splittedText.length; i++) {
177
178
  listInput.push({
178
179
  id: `text-${i}`,
179
180
  type: 'text',
@@ -183,9 +184,10 @@ export default {
183
184
  if (i < splittedText.length - 1)
184
185
  listInput.push({ id: `select-${i}`, type: 'select', index: i })
185
186
  }
187
+
186
188
  let lI = listInput.findLast((element) => element.type == 'select')
187
- this.inputCount = lI.index + 1
188
189
 
190
+ this.inputCount = lI.index + 1
189
191
  this.inputElements = listInput
190
192
  },
191
193
  /**
@@ -299,14 +301,11 @@ fieldset {
299
301
  div.texteatrou {
300
302
  display: inline !important;
301
303
 
302
-
303
304
  .cnt-input {
304
305
  display: inline;
305
306
  .v-input {
306
307
  display: inline-block !important;
307
308
 
308
-
309
-
310
309
  :deep(.v-input__control),
311
310
  :deep(.v-field) {
312
311
  width: 240px !important;
@@ -339,5 +338,4 @@ div.texteatrou {
339
338
  }
340
339
  }
341
340
  }
342
-
343
341
  </style>
@@ -132,29 +132,6 @@ export default {
132
132
  mounted() {},
133
133
 
134
134
  methods: {
135
- /**
136
- * @description validate the raw data received by the component to render is view
137
- * @returns {Object} errors - errorList: to display in view and errorConsole, to be displayed in console
138
- */
139
- validateInputData() {
140
- let errors = null //array for errors dectected
141
- let stringType = ['id', 'value']
142
-
143
- if (!this.inputData.length) return errors
144
- for (let i = 0; i < this.inputData.length; i++) {
145
- errors = validateObjType(
146
- this.inputData[i],
147
- { stringType },
148
- null,
149
- `choix_reponse #${i + 1}`
150
- )
151
- const { errorList, errorInConsole } = errors
152
-
153
- if (errorList.length || errorInConsole.length) return errors
154
- }
155
-
156
- return errors
157
- },
158
135
  /**
159
136
  * @description create the object to genate the text and inputs
160
137
  * @param {String} str the text with holes to fill
@@ -165,7 +142,7 @@ export default {
165
142
  let splittedText = str.split(regex)
166
143
  let listInput = []
167
144
 
168
- for (let i = 0; i < splittedText.length - 1; i++) {
145
+ for (let i = 0; i < splittedText.length; i++) {
169
146
  listInput.push({
170
147
  id: `text-${i}`,
171
148
  type: 'text',
@@ -26,7 +26,7 @@
26
26
  :error-text="`Vous avez une/des erreur(s) dans la création des notes/crédits.`"
27
27
  ></app-base-error-display>
28
28
  <template v-else>
29
- <div v-if="notes" class="ctn-note">
29
+ <div v-if="hasNotes" class="ctn-note">
30
30
  <p class="t-note">{{ $t('text.title_note') }}</p>
31
31
  <div id="notes-list">
32
32
  <template
@@ -62,7 +62,7 @@
62
62
  </template>
63
63
  </div>
64
64
  </div>
65
- <div v-if="credits" class="ctn-credit">
65
+ <div v-if="hasCredits" class="ctn-credit">
66
66
  <p class="t-crdt">{{ $t('text.title_credit') }}</p>
67
67
 
68
68
  <ul id="credits-list">
@@ -109,7 +109,13 @@ export default {
109
109
  'getCurrentPage',
110
110
  'getNotes',
111
111
  'getCredits'
112
- ])
112
+ ]),
113
+ hasNotes() {
114
+ return this.notes && this.notes.length
115
+ },
116
+ hasCredits() {
117
+ return this.credits && this.credits.length
118
+ }
113
119
  },
114
120
  created() {},
115
121
  beforeUnmount() {
@@ -414,10 +420,6 @@ export default {
414
420
  }
415
421
  }
416
422
 
417
- // .note-txt {
418
- // pointer-events: none;
419
- // }
420
-
421
423
  .box-nc {
422
424
  margin-top: 54px;
423
425
  overflow-y: auto;
@@ -460,6 +460,7 @@ export default {
460
460
  const timer = reactive(new Timer(id)) // Making Timer instance reactive to be able to track changes
461
461
  const { t } = useI18n()
462
462
  return { id, store, timer, t }
463
+ //return { id, store, timer }
463
464
  },
464
465
  data() {
465
466
  return {
@@ -913,7 +914,7 @@ export default {
913
914
  * @description - handle all the listeners for medias
914
915
  */
915
916
  setMediaHandlers() {
916
- if (this.mediaElement) {
917
+ if (this.mediaElement && this.mediaElement.addEventListener) {
917
918
  //Prevent default on keys used for navigation in the player (prevent scrollbar to be trigger when changing volume)
918
919
  this.pbContainer.addEventListener('keydown', this.keysPreventDefault)
919
920
  //progressBar events
@@ -921,7 +922,7 @@ export default {
921
922
  //window handlers for playbar progress
922
923
  window.addEventListener('mousemove', this.progressWindowMove)
923
924
  window.addEventListener('mouseup', this.progressWindowUp)
924
-
925
+ // console.log('⚠️--- TEST AppCompPlayBarNext---', this.mediaElement)
925
926
  //Update data when media as a timeupdate/ended
926
927
  this.mediaElement.addEventListener(
927
928
  'timeupdate',
@@ -1580,7 +1581,10 @@ export default {
1580
1581
  */
1581
1582
  setVideoHandlers() {
1582
1583
  //Tooltip
1584
+ if (!this.progressArea || !this.progressArea.addEventListener) return
1583
1585
  this.progressArea.addEventListener('mousemove', this.updateSeekTooltip)
1586
+
1587
+ if (!this.mediaContainer || !this.mediaContainer.addEventListener) return
1584
1588
  //Fullscreen
1585
1589
  this.mediaContainer.addEventListener(
1586
1590
  'fullscreenchange',
@@ -1594,7 +1598,10 @@ export default {
1594
1598
  */
1595
1599
  removeVideoHandlers() {
1596
1600
  //Tooltip
1601
+ if (!this.progressArea || !this.progressArea.addEventListener) return
1597
1602
  this.progressArea.removeEventListener('mousemove', this.updateSeekTooltip)
1603
+ if (!this.mediaContainer || !this.mediaContainer.removeEventListener)
1604
+ return
1598
1605
  //Fullscreen
1599
1606
  this.mediaContainer.removeEventListener(
1600
1607
  'fullscreenchange',
@@ -1628,7 +1635,7 @@ export default {
1628
1635
  */
1629
1636
  toggleFullScreen() {
1630
1637
  const fullscreenElement = this.mediaContainer
1631
- console.log(fullscreenElement)
1638
+ //console.log(fullscreenElement)
1632
1639
 
1633
1640
  if (document.fullscreenElement) {
1634
1641
  // exitFullscreen is only available on the Document object.
@@ -1777,7 +1784,8 @@ export default {
1777
1784
  */
1778
1785
 
1779
1786
  hideControls() {
1780
- if (this.mediaElement.paused) return
1787
+ //Always show playbar when paused or not in fullscreen mode
1788
+ if (this.mediaElement.paused || !document.fullscreenElement) return
1781
1789
 
1782
1790
  this.hideTimer = setTimeout(() => {
1783
1791
  this.showControlsValue = false
@@ -1795,12 +1803,10 @@ export default {
1795
1803
  </script>
1796
1804
  <style lang="scss" scoped>
1797
1805
  .pb-container.video {
1798
- position: absolute;
1799
1806
  height: 100%;
1800
1807
  width: 100%;
1801
1808
  justify-content: center;
1802
1809
  display: flex;
1803
- margin-bottom: 78px;
1804
1810
  }
1805
1811
 
1806
1812
  .playback-button {
@@ -1808,7 +1814,7 @@ export default {
1808
1814
  bottom: 0;
1809
1815
  left: 0;
1810
1816
  width: 100%;
1811
- height: 94%;
1817
+ height: 100%;
1812
1818
  display: flex;
1813
1819
  flex-flow: column wrap;
1814
1820
  justify-content: center;
@@ -1837,8 +1843,6 @@ export default {
1837
1843
  width: 100%;
1838
1844
  display: flex;
1839
1845
  flex-direction: column;
1840
- position: absolute;
1841
- bottom: -78px;
1842
1846
  opacity: 0;
1843
1847
  z-index: 2;
1844
1848
 
@@ -2260,8 +2264,10 @@ export default {
2260
2264
 
2261
2265
  .FS {
2262
2266
  &:fullscreen {
2263
- .pb-wrapper {
2264
- bottom: -45px;
2267
+ .pb-container {
2268
+ position: absolute;
2269
+ bottom: 0;
2270
+ height: 78px;
2265
2271
  }
2266
2272
  }
2267
2273
  }
@@ -104,19 +104,14 @@ export default {
104
104
  getUserInteraction: {
105
105
  async handler(newValue) {
106
106
  if (!this.getUserInteraction) return
107
-
108
107
  const { activityId, pageId } = this.quizRecallData
109
108
  const interaction = this.getPageInteraction(
110
109
  activityId,
111
110
  pageId
112
111
  ).userInteraction
113
-
114
- if (!interaction) return
115
112
  //Get quizRecall answer
116
113
  if (this.quizRecallData && this.quizData) {
117
114
  await this.getQuizRecallAnswer(interaction)
118
- } else {
119
- this.quizRecall.done == false
120
115
  }
121
116
  },
122
117
  immediate: true,
@@ -209,6 +204,13 @@ export default {
209
204
  //Get datas from quizRecallData and userData and add them to quizRecall object
210
205
  async getQuizRecallAnswer(userData) {
211
206
  await this.$nextTick() //wait for the DOM to update
207
+ //userData will be undefined if the page containing the target quiz was never visited
208
+ if (typeof userData === 'undefined') {
209
+ this.quizRecall.done = false //set quiz recall message (quiz not completed)
210
+ this.isReady = true //hide the skeleton
211
+ return
212
+ }
213
+
212
214
  const { quizId, hypertext_done, hypertext_undone, title, titletag } =
213
215
  this.quizRecallData
214
216
 
@@ -216,6 +218,7 @@ export default {
216
218
  if (hypertext_done) {
217
219
  this.quizRecall.hypertext_done = hypertext_done
218
220
  }
221
+
219
222
  if (hypertext_undone) {
220
223
  this.quizRecall.hypertext_undone = hypertext_undone
221
224
  }
@@ -231,6 +234,7 @@ export default {
231
234
  }
232
235
  }
233
236
  //Get the quiz answers from userData
237
+
234
238
  const answers = userData.quizAnswers || {}
235
239
  let quizAnswer = answers[quizId] || null
236
240
 
@@ -243,7 +247,6 @@ export default {
243
247
  this.quizRecall.answer = quizAnswer.value[0].filled || ''
244
248
  this.quizRecall.ennonce = this.quizData.ennonce
245
249
  }
246
- this.quizRecall
247
250
  this.isReady = true //Set isReady to true to display the component
248
251
  },
249
252
 
@@ -301,6 +304,7 @@ export default {
301
304
  )
302
305
  this.hasError.push(msgErr)
303
306
  }
307
+
304
308
  //Validate if all required properties are present in quizRecallData
305
309
  if (missingRequired.length > 0) {
306
310
  let msgErr = `QuizRecallData missing required ${missingRequired} property`
@@ -282,6 +282,7 @@ export default {
282
282
  resizeVideo(size, container) {
283
283
  let defaultSize = 100
284
284
  if (size == 'sm') defaultSize = 68
285
+
285
286
  //const videoElement = document.querySelector('.__media-container')
286
287
  const videoElement = this.$vidElement.mMediaContainer
287
288
  setTimeout(() => {
@@ -304,7 +305,7 @@ $widthVideo: 100%;
304
305
 
305
306
  .app-video-player {
306
307
  display: flex;
307
- flex-direction: row;
308
+ flex-direction: column;
308
309
  flex-wrap: wrap;
309
310
  position: relative;
310
311
  align-items: center;
package/src/main.js CHANGED
@@ -28,7 +28,7 @@ import GsapPlugin from './plugins/gsap'
28
28
  import eventBus from './plugins/bus'
29
29
  import helper from './plugins/helper'
30
30
  import analytics from './plugins/analytics'
31
- import mergeLocales from './plugins/i18n'
31
+ import initLocalisation from './plugins/i18n'
32
32
  import { scormPlugin } from './plugins/scorm'
33
33
  import { xapiPlugin } from './plugins/xapi'
34
34
  import { $idb } from './plugins/idb'
@@ -41,19 +41,33 @@ import VueSafeTeleport from 'vue-safe-teleport'
41
41
  import { FocusTrap } from 'focus-trap-vue'
42
42
  import nvdaFix from './directives/nvdaFix.js'
43
43
  import pckg from '../package.json'
44
+ import fcadRouter from './router/index.js'
45
+ import '@mdi/font/css/materialdesignicons.css'
46
+ import 'vuetify/styles'
47
+ import { createVuetify } from 'vuetify'
48
+ import { fr, en } from 'vuetify/locale'
49
+
44
50
  const pinia = createPinia()
45
51
 
46
52
  export default {
47
53
  install(app, options) {
54
+ app.use(fcadRouter)
48
55
  app.use(pinia)
49
56
  app.use(scormPlugin)
50
57
  app.use(GsapPlugin)
51
58
  app.use(xapiPlugin)
52
59
  app.use(VueSafeTeleport)
53
60
  app.component('FocusTrap', FocusTrap)
54
-
55
61
  app.use(eventBus)
56
62
  app.use($idb)
63
+ const vuetify = createVuetify({
64
+ locale: {
65
+ locale: 'fr',
66
+ fallback: 'en',
67
+ messages: { fr, en }
68
+ }
69
+ })
70
+ app.use(vuetify)
57
71
 
58
72
  app.component('AppBase', AppBase)
59
73
  app.component('AppBaseButton', AppBaseButton)
@@ -332,7 +346,6 @@ export default {
332
346
 
333
347
  let server = remote ? specification : 'local'
334
348
  //falback to idb when scorm and origin is localhost
335
- //falback to idb when scorm and origin is localhost
336
349
  if (
337
350
  (specification == 'scorm' && window.location.hostname == 'localhost') ||
338
351
  !window.location.hostname.includes('cegepadistance.ca')
@@ -476,9 +489,10 @@ export default {
476
489
 
477
490
  appStore.applicationSettings = settingsOptions
478
491
  //=================================END SETTING PREFERENCES ====================================//
479
-
480
- //mergeLocales
481
- mergeLocales(options.i18n.global)
492
+ // const appi18b = options.i18n
493
+ // console.log('i18n options received in appBase plugin...', appi18b)
494
+ const i18n = initLocalisation(options.i18n)
495
+ app.use(i18n)
482
496
  app.use(helper)
483
497
  app.use(analytics)
484
498