fcad-core-dragon 2.0.0-beta.5 → 2.0.0-beta.7
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.
- package/.editorconfig +33 -33
- package/.eslintignore +29 -29
- package/.eslintrc.cjs +81 -81
- package/CHANGELOG +395 -377
- package/README.md +71 -71
- package/bk.scss +117 -117
- package/package.json +61 -61
- package/src/$locales/en.json +23 -25
- package/src/$locales/fr.json +22 -23
- package/src/assets/data/onboardingMessages.json +47 -47
- package/src/components/AppBase.vue +166 -99
- package/src/components/AppBaseButton.vue +2 -0
- package/src/components/AppBaseErrorDisplay.vue +438 -438
- package/src/components/AppBaseFlipCard.vue +84 -84
- package/src/components/AppBaseModule.vue +124 -106
- package/src/components/AppBasePage.vue +14 -4
- package/src/components/AppBasePopover.vue +41 -41
- package/src/components/AppCompAudio.vue +20 -48
- package/src/components/AppCompBranchButtons.vue +7 -53
- package/src/components/{AppCompTranscript.vue → AppCompContainer.vue} +8 -1
- package/src/components/AppCompInputRadioNext.vue +152 -152
- package/src/components/AppCompInputTextToFillNext.vue +171 -171
- package/src/components/AppCompJauge.vue +74 -74
- package/src/components/AppCompMenu.vue +429 -428
- package/src/components/AppCompMenuItem.vue +228 -228
- package/src/components/AppCompNavigation.vue +2 -2
- package/src/components/AppCompPlayBarNext.vue +5 -0
- package/src/components/AppCompPlayBarProgress.vue +82 -82
- package/src/components/AppCompSVGNext.vue +2 -3
- package/src/components/AppCompSettingsMenu.vue +172 -172
- package/src/components/AppCompVideoPlayer.vue +17 -15
- package/src/composables/useQuiz.js +206 -206
- package/src/externalComps/ModuleView.vue +22 -22
- package/src/externalComps/SummaryView.vue +91 -91
- package/src/main.js +34 -29
- package/src/mixins/$mediaMixins.js +819 -819
- package/src/mixins/timerMixin.js +155 -155
- package/src/module/stores/appStore.js +1 -1
- package/src/module/xapi/ADL.js +144 -4
- package/src/module/xapi/Crypto/Hasher.js +241 -241
- package/src/module/xapi/Crypto/WordArray.js +278 -278
- package/src/module/xapi/Crypto/algorithms/BufferedBlockAlgorithm.js +103 -103
- package/src/module/xapi/Crypto/algorithms/C_algo.js +315 -315
- package/src/module/xapi/Crypto/algorithms/HMAC.js +9 -9
- package/src/module/xapi/Crypto/algorithms/SHA1.js +9 -9
- package/src/module/xapi/Crypto/encoders/Base.js +105 -105
- package/src/module/xapi/Crypto/encoders/Base64.js +99 -99
- package/src/module/xapi/Crypto/encoders/Hex.js +61 -61
- package/src/module/xapi/Crypto/encoders/Latin1.js +61 -61
- package/src/module/xapi/Crypto/encoders/Utf8.js +45 -45
- package/src/module/xapi/Statement/agent.js +55 -55
- package/src/module/xapi/Statement/index.js +259 -259
- package/src/module/xapi/Statement/statement.js +253 -253
- package/src/module/xapi/utils.js +167 -167
- package/src/module/xapi/verbs.js +294 -294
- package/src/module/xapi/wrapper copy.js +1963 -0
- package/src/module/xapi/wrapper.js +121 -188
- package/src/module/xapi/xapiStatement.js +444 -444
- package/src/plugins/bus.js +8 -8
- package/src/plugins/gsap.js +14 -14
- package/src/plugins/helper.js +0 -1
- package/src/plugins/i18n.js +44 -44
- package/src/plugins/save.js +37 -37
- package/src/plugins/scorm.js +287 -287
- package/src/plugins/xapi.js +11 -11
- package/src/public/index.html +33 -33
- package/src/router/index.js +2 -1
- package/src/shared/generalfuncs.js +210 -210
- package/src/shared/validators.js +2 -0
- package/src/components/AppCompPlayBar.vue +0 -1217
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
<audio
|
|
35
35
|
:id="id"
|
|
36
36
|
ref="m-audio"
|
|
37
|
-
@loadedmetadata="
|
|
37
|
+
@loadedmetadata="updateMediaDataAudio($event.target)"
|
|
38
38
|
>
|
|
39
39
|
<source
|
|
40
40
|
v-for="(aSource, index) in mSources"
|
|
@@ -128,75 +128,47 @@ export default {
|
|
|
128
128
|
|
|
129
129
|
methods: {
|
|
130
130
|
...mapActions(useAppStore, ['updateCurrentMediaElements']),
|
|
131
|
+
/**
|
|
132
|
+
* @description search the DOM for medias with duplicated ID declaration in the page
|
|
133
|
+
* @return return Array of all DOM MediaElement with same id
|
|
134
|
+
*/
|
|
135
|
+
checkDuplicatedID() {
|
|
136
|
+
const mediaList = document.querySelectorAll('.__media-container')
|
|
137
|
+
const duplicate = Array.from(mediaList).filter((media) =>
|
|
138
|
+
media.id.includes(this.id)
|
|
139
|
+
)
|
|
140
|
+
return duplicate
|
|
141
|
+
},
|
|
131
142
|
/**
|
|
132
143
|
* @description update the information for the mediaElement in the store
|
|
133
144
|
* @param {htmlElement} e
|
|
134
145
|
* @fires update-page to AppBaseModule.vue
|
|
135
146
|
*/
|
|
136
|
-
|
|
147
|
+
updateMediaDataAudio(e) {
|
|
137
148
|
//dispatch loading status of for this component
|
|
138
|
-
this.$bus.$emit('set-comp-status', '
|
|
149
|
+
this.$bus.$emit('set-comp-status', 'AppCompAudioPlayer', 'loading')
|
|
139
150
|
this.$bus.$emit('update-media-duration')
|
|
140
151
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
const hasEntry = mElements.findLastIndex(
|
|
145
|
-
(media) => media.id === e.target.id
|
|
146
|
-
)
|
|
147
|
-
|
|
148
|
-
if (hasEntry !== -1) {
|
|
149
|
-
// Should report Error to Console and Component template about this media
|
|
150
|
-
const errmsg = `Cet élément a le même ID q'un autre media. Vous ne devez pas avoir de médias avec le même ID dans une page.`
|
|
152
|
+
if (this.checkDuplicatedID().length > 1) {
|
|
153
|
+
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.`
|
|
151
154
|
|
|
152
155
|
console.warn(
|
|
153
|
-
`%c WARNING!>>> You cannot use the same ID in your media elements for your page.`,
|
|
156
|
+
`%c WARNING!>>> You cannot use the same ID (${this.id}) in your media elements for your page.`,
|
|
154
157
|
'background: orange; color: white; display: block; border-radius:5px; margin:5px;'
|
|
155
158
|
)
|
|
156
159
|
|
|
157
|
-
this.$bus.$emit('set-comp-status', '
|
|
160
|
+
this.$bus.$emit('set-comp-status', 'AppCompAudioPlayer', 'ready')
|
|
158
161
|
return this.hasErr.push(errmsg)
|
|
159
162
|
}
|
|
160
163
|
|
|
161
|
-
this.updateCurrentMediaElements(e
|
|
164
|
+
this.updateCurrentMediaElements(e).then(() => {
|
|
162
165
|
this.isSet = true
|
|
163
|
-
this.$bus.$emit('set-comp-status', '
|
|
166
|
+
this.$bus.$emit('set-comp-status', 'AppCompAudioPlayer', 'ready')
|
|
164
167
|
})
|
|
165
168
|
},
|
|
166
169
|
errorHandling(e) {
|
|
167
170
|
this.hasSourceLoadingError = true
|
|
168
|
-
},
|
|
169
|
-
// ===================================TEST TRANSCRIP================================================
|
|
170
|
-
/**
|
|
171
|
-
* @description Fetching method for transcript
|
|
172
|
-
* @summary Fetch a transcript from HTML file to display. File URL is defined in the media data
|
|
173
|
-
* and return its content for display
|
|
174
|
-
* @return {String} HTML string
|
|
175
|
-
*/
|
|
176
|
-
async fetchTranscript() {
|
|
177
|
-
try {
|
|
178
|
-
//const tFile = 'exemple_transcript2.html'
|
|
179
|
-
const { mTranscript } = this.mediaToPlay
|
|
180
|
-
const tFile = mTranscript
|
|
181
|
-
if (!tFile) throw new Error('Missing transcript File!')
|
|
182
|
-
|
|
183
|
-
// validate file types. Only .html are allowed
|
|
184
|
-
if (!tFile.endsWith('.html'))
|
|
185
|
-
throw new Error(
|
|
186
|
-
'Invalid valid transcript file. \n Expecting .html file'
|
|
187
|
-
)
|
|
188
|
-
|
|
189
|
-
const fileUrl = !tFile.includes('/') ? `./${tFile}` : tFile //allow passing file in Public folder
|
|
190
|
-
// const fileUrl = new URL(tFile, import.meta.url))
|
|
191
|
-
const res = await axios.get(fileUrl, { responseType: 'blob' })
|
|
192
|
-
const content = await res.data.text()
|
|
193
|
-
|
|
194
|
-
return content
|
|
195
|
-
} catch (err) {
|
|
196
|
-
console.warn("YOU'VE GOT AN ERROR!\n", err)
|
|
197
|
-
}
|
|
198
171
|
}
|
|
199
|
-
// ===================================TEST TRANSCRIP================================================
|
|
200
172
|
}
|
|
201
173
|
}
|
|
202
174
|
</script>
|
|
@@ -68,10 +68,8 @@ Si la composante est appelée sans prop, les boutons par défaut seront génér
|
|
|
68
68
|
<v-card class="mx-auto" max-width="15rem">
|
|
69
69
|
<v-img :src="branch.imgFile" :alt="`${branch.imgAlt}`" cover />
|
|
70
70
|
|
|
71
|
-
<v-card-title
|
|
72
|
-
<v-card-text>
|
|
73
|
-
{{ branch.text }}
|
|
74
|
-
</v-card-text>
|
|
71
|
+
<v-card-title v-html="branch.title"></v-card-title>
|
|
72
|
+
<v-card-text v-html="branch.text"></v-card-text>
|
|
75
73
|
|
|
76
74
|
<app-comp-button-progress
|
|
77
75
|
:set-target="sidebar"
|
|
@@ -136,35 +134,6 @@ export default {
|
|
|
136
134
|
break
|
|
137
135
|
}
|
|
138
136
|
}
|
|
139
|
-
//Start validation of required keys
|
|
140
|
-
if (isValid) {
|
|
141
|
-
const requiredKeys = ['imgFile', 'title', 'text', 'brchName']
|
|
142
|
-
|
|
143
|
-
for (let el of dataArray) {
|
|
144
|
-
//Validate that require key exist for each element in card
|
|
145
|
-
for (let k of requiredKeys) {
|
|
146
|
-
let index = dataArray.indexOf(el)
|
|
147
|
-
|
|
148
|
-
if (!el[k]) {
|
|
149
|
-
isValid = false
|
|
150
|
-
errMsg = `\n 💥 Missing 👉 ${k} 👈 in object ${
|
|
151
|
-
index + 1
|
|
152
|
-
} in ➡ card \n 🚩Allowed indexes are: 👉 ${requiredKeys}`
|
|
153
|
-
break
|
|
154
|
-
} else {
|
|
155
|
-
if (el[k].constructor !== String) {
|
|
156
|
-
errMsg = `\n 💥 Invalid 👉 ${k} 👈 declaration in ➡ object ${
|
|
157
|
-
index + 1
|
|
158
|
-
} ➡ of card. \n 🚩 Must be of type {String}`
|
|
159
|
-
isValid = false
|
|
160
|
-
break
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
if (!isValid) break
|
|
164
|
-
}
|
|
165
|
-
if (!isValid) break
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
137
|
}
|
|
169
138
|
|
|
170
139
|
if (errMsg) console.error(`🧱 app-comp-branch-buttons \n ${errMsg}`)
|
|
@@ -317,7 +286,11 @@ export default {
|
|
|
317
286
|
btnTitle
|
|
318
287
|
}
|
|
319
288
|
|
|
320
|
-
if (
|
|
289
|
+
if (
|
|
290
|
+
typeof branchData.imgAlt === 'undefined' &&
|
|
291
|
+
branchData.imgFile === 'undefined' &&
|
|
292
|
+
import.meta.env.DEV
|
|
293
|
+
) {
|
|
321
294
|
branchData.imgAlt = ''
|
|
322
295
|
console.warn(
|
|
323
296
|
`Bouton d’embranchement: ALT image sans valeur définie pour ${branchData.id}`
|
|
@@ -407,27 +380,8 @@ export default {
|
|
|
407
380
|
}
|
|
408
381
|
//Start validation of required keys
|
|
409
382
|
if (isValid) {
|
|
410
|
-
const requiredKeys = ['imgFile', 'title', 'text', 'brchName']
|
|
411
|
-
|
|
412
383
|
for (let el of this.cards) {
|
|
413
384
|
let index = this.cards.indexOf(el)
|
|
414
|
-
//Validate that require key exist for each element in card
|
|
415
|
-
for (let k of requiredKeys) {
|
|
416
|
-
if (!el[k]) {
|
|
417
|
-
isValid = false
|
|
418
|
-
errMsg = `l'Attribut 👉 ${k} 👈 pour la carte ${index + 1} n'as pas été défini`
|
|
419
|
-
break
|
|
420
|
-
} else {
|
|
421
|
-
if (el[k].constructor !== String) {
|
|
422
|
-
errMsg = `l'Attribut 👉 ${k} 👈 pour la carte ${
|
|
423
|
-
index + 1
|
|
424
|
-
} doit être de type {String}`
|
|
425
|
-
isValid = false
|
|
426
|
-
break
|
|
427
|
-
}
|
|
428
|
-
}
|
|
429
|
-
if (!isValid) break
|
|
430
|
-
}
|
|
431
385
|
|
|
432
386
|
// Start validation of existing branch for this element
|
|
433
387
|
let searchEl = this.branchs.find((b) =>
|
|
@@ -1,13 +1,20 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div id="
|
|
2
|
+
<div :id="id" v-html="content"></div>
|
|
3
3
|
</template>
|
|
4
4
|
<script>
|
|
5
5
|
export default {
|
|
6
6
|
props: {
|
|
7
|
+
id: {
|
|
8
|
+
type: String,
|
|
9
|
+
default: 'shadow-container'
|
|
10
|
+
},
|
|
7
11
|
content: {
|
|
8
12
|
type: String,
|
|
9
13
|
default: `Hello Wolrd!`
|
|
10
14
|
}
|
|
15
|
+
},
|
|
16
|
+
mounted() {
|
|
17
|
+
console.log('😶🌫️ ', this.$props.id)
|
|
11
18
|
}
|
|
12
19
|
}
|
|
13
20
|
</script>
|
|
@@ -1,152 +1,152 @@
|
|
|
1
|
-
<!-- About this Component--
|
|
2
|
-
* Renders a RADIO BUTTON input to display choices of response for the Quiz component
|
|
3
|
-
* Related Quiz to question: REPONSE_UNIQUE
|
|
4
|
-
* Receives the a data object defined by user
|
|
5
|
-
* Used by AppCompQuizNext
|
|
6
|
-
* Uses useQuiz composable
|
|
7
|
-
-->
|
|
8
|
-
|
|
9
|
-
<template>
|
|
10
|
-
<div class="input-box">
|
|
11
|
-
<fieldset>
|
|
12
|
-
<legend
|
|
13
|
-
:id="`lgd_${inputDataId}`"
|
|
14
|
-
class="sr-only"
|
|
15
|
-
tabindex="-1"
|
|
16
|
-
v-html="$t('quizState.answers')"
|
|
17
|
-
/>
|
|
18
|
-
|
|
19
|
-
<template
|
|
20
|
-
v-for="choixReponse in quizInputDataValue"
|
|
21
|
-
:Key="`div_chx_${inputDataId}-${choixReponse.id}`"
|
|
22
|
-
>
|
|
23
|
-
<div class="box-radio" role="group">
|
|
24
|
-
<label
|
|
25
|
-
:key="`lbl_chx_${inputDataId}_${choixReponse.id}`"
|
|
26
|
-
:for="`chx_${inputDataId}_${choixReponse.id}`"
|
|
27
|
-
:class="classInput(choixReponse.id)"
|
|
28
|
-
class="radio-label"
|
|
29
|
-
>
|
|
30
|
-
<input
|
|
31
|
-
:id="`chx_${inputDataId}_${choixReponse.id}`"
|
|
32
|
-
:key="`chx_${inputDataId}_${choixReponse.id}`"
|
|
33
|
-
v-model="inputUniqueValue"
|
|
34
|
-
:disabled="quizLimitActive"
|
|
35
|
-
type="radio"
|
|
36
|
-
:value="choixReponse.id"
|
|
37
|
-
:name="`btn-radios-${inputDataId}`"
|
|
38
|
-
class="radio-input"
|
|
39
|
-
:aria-labelledby="`span_${inputDataId}_${choixReponse.id}`"
|
|
40
|
-
/>
|
|
41
|
-
|
|
42
|
-
<span
|
|
43
|
-
:id="`span_${inputDataId}_${choixReponse.id}`"
|
|
44
|
-
aria-hidden="true"
|
|
45
|
-
class="radio-contenu"
|
|
46
|
-
v-html="choixReponse.value"
|
|
47
|
-
/>
|
|
48
|
-
<span
|
|
49
|
-
:id="`${inputDataId}_${choixReponse.id}-msg-erreur`"
|
|
50
|
-
:key="`msg_chx_${inputDataId}_${choixReponse.id}`"
|
|
51
|
-
class="sr-only"
|
|
52
|
-
>
|
|
53
|
-
{{ messageAccessibility(choixReponse.id) }}
|
|
54
|
-
</span>
|
|
55
|
-
</label>
|
|
56
|
-
</div>
|
|
57
|
-
</template>
|
|
58
|
-
</fieldset>
|
|
59
|
-
</div>
|
|
60
|
-
</template>
|
|
61
|
-
<script>
|
|
62
|
-
import { useQuiz } from '../composables/useQuiz'
|
|
63
|
-
import { toRefs } from 'vue'
|
|
64
|
-
export default {
|
|
65
|
-
name: 'AppCompInputRadioNext',
|
|
66
|
-
|
|
67
|
-
props: {
|
|
68
|
-
quizType: {
|
|
69
|
-
type: String,
|
|
70
|
-
default: ''
|
|
71
|
-
},
|
|
72
|
-
inputDataId: {
|
|
73
|
-
type: String,
|
|
74
|
-
default: ''
|
|
75
|
-
},
|
|
76
|
-
|
|
77
|
-
inputData: {
|
|
78
|
-
type: Array,
|
|
79
|
-
default: () => []
|
|
80
|
-
},
|
|
81
|
-
quizInputType: {
|
|
82
|
-
type: String,
|
|
83
|
-
default: ''
|
|
84
|
-
},
|
|
85
|
-
solution: {
|
|
86
|
-
type: String,
|
|
87
|
-
default: ''
|
|
88
|
-
}, //may be null
|
|
89
|
-
showSolution: {
|
|
90
|
-
type: Boolean,
|
|
91
|
-
default: false
|
|
92
|
-
},
|
|
93
|
-
shuffleAnswers: {
|
|
94
|
-
type: Boolean,
|
|
95
|
-
default: false
|
|
96
|
-
},
|
|
97
|
-
quizLimitActive: {
|
|
98
|
-
type: Boolean,
|
|
99
|
-
default: false
|
|
100
|
-
}, //use to set if quiz should be active or not
|
|
101
|
-
|
|
102
|
-
quizSubmit: {
|
|
103
|
-
type: Boolean,
|
|
104
|
-
default: false
|
|
105
|
-
} //use to call a submit
|
|
106
|
-
},
|
|
107
|
-
emits: ['input-change'],
|
|
108
|
-
setup(props) {
|
|
109
|
-
const { shuffleArray, classInput, messageAccessibility } = useQuiz(
|
|
110
|
-
toRefs(props)
|
|
111
|
-
)
|
|
112
|
-
|
|
113
|
-
return { shuffleArray, classInput, messageAccessibility }
|
|
114
|
-
},
|
|
115
|
-
data() {
|
|
116
|
-
return {
|
|
117
|
-
quizInputDataValue: [],
|
|
118
|
-
inputUniqueValue: null //not using quizInputUnique because quizInputUnique is a prop
|
|
119
|
-
}
|
|
120
|
-
},
|
|
121
|
-
|
|
122
|
-
computed: {},
|
|
123
|
-
|
|
124
|
-
watch: {
|
|
125
|
-
// /**
|
|
126
|
-
// * @description to pass value to AppCompQuiz
|
|
127
|
-
// * @fires input-change to AppCompQuiz.vue
|
|
128
|
-
// */
|
|
129
|
-
inputUniqueValue: {
|
|
130
|
-
deep: true,
|
|
131
|
-
handler(newValue) {
|
|
132
|
-
this.$emit('input-change', newValue)
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
},
|
|
136
|
-
|
|
137
|
-
mounted() {
|
|
138
|
-
this.initQuiz()
|
|
139
|
-
},
|
|
140
|
-
|
|
141
|
-
methods: {
|
|
142
|
-
initQuiz() {
|
|
143
|
-
this.inputUniqueValue = this.quizInputType
|
|
144
|
-
if (this.shuffleAnswers) {
|
|
145
|
-
this.quizInputDataValue = this.shuffleArray(this.inputData)
|
|
146
|
-
} else {
|
|
147
|
-
this.quizInputDataValue = this.inputData
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
</script>
|
|
1
|
+
<!-- About this Component--
|
|
2
|
+
* Renders a RADIO BUTTON input to display choices of response for the Quiz component
|
|
3
|
+
* Related Quiz to question: REPONSE_UNIQUE
|
|
4
|
+
* Receives the a data object defined by user
|
|
5
|
+
* Used by AppCompQuizNext
|
|
6
|
+
* Uses useQuiz composable
|
|
7
|
+
-->
|
|
8
|
+
|
|
9
|
+
<template>
|
|
10
|
+
<div class="input-box">
|
|
11
|
+
<fieldset>
|
|
12
|
+
<legend
|
|
13
|
+
:id="`lgd_${inputDataId}`"
|
|
14
|
+
class="sr-only"
|
|
15
|
+
tabindex="-1"
|
|
16
|
+
v-html="$t('quizState.answers')"
|
|
17
|
+
/>
|
|
18
|
+
|
|
19
|
+
<template
|
|
20
|
+
v-for="choixReponse in quizInputDataValue"
|
|
21
|
+
:Key="`div_chx_${inputDataId}-${choixReponse.id}`"
|
|
22
|
+
>
|
|
23
|
+
<div class="box-radio" role="group">
|
|
24
|
+
<label
|
|
25
|
+
:key="`lbl_chx_${inputDataId}_${choixReponse.id}`"
|
|
26
|
+
:for="`chx_${inputDataId}_${choixReponse.id}`"
|
|
27
|
+
:class="classInput(choixReponse.id)"
|
|
28
|
+
class="radio-label"
|
|
29
|
+
>
|
|
30
|
+
<input
|
|
31
|
+
:id="`chx_${inputDataId}_${choixReponse.id}`"
|
|
32
|
+
:key="`chx_${inputDataId}_${choixReponse.id}`"
|
|
33
|
+
v-model="inputUniqueValue"
|
|
34
|
+
:disabled="quizLimitActive"
|
|
35
|
+
type="radio"
|
|
36
|
+
:value="choixReponse.id"
|
|
37
|
+
:name="`btn-radios-${inputDataId}`"
|
|
38
|
+
class="radio-input"
|
|
39
|
+
:aria-labelledby="`span_${inputDataId}_${choixReponse.id}`"
|
|
40
|
+
/>
|
|
41
|
+
|
|
42
|
+
<span
|
|
43
|
+
:id="`span_${inputDataId}_${choixReponse.id}`"
|
|
44
|
+
aria-hidden="true"
|
|
45
|
+
class="radio-contenu"
|
|
46
|
+
v-html="choixReponse.value"
|
|
47
|
+
/>
|
|
48
|
+
<span
|
|
49
|
+
:id="`${inputDataId}_${choixReponse.id}-msg-erreur`"
|
|
50
|
+
:key="`msg_chx_${inputDataId}_${choixReponse.id}`"
|
|
51
|
+
class="sr-only"
|
|
52
|
+
>
|
|
53
|
+
{{ messageAccessibility(choixReponse.id) }}
|
|
54
|
+
</span>
|
|
55
|
+
</label>
|
|
56
|
+
</div>
|
|
57
|
+
</template>
|
|
58
|
+
</fieldset>
|
|
59
|
+
</div>
|
|
60
|
+
</template>
|
|
61
|
+
<script>
|
|
62
|
+
import { useQuiz } from '../composables/useQuiz'
|
|
63
|
+
import { toRefs } from 'vue'
|
|
64
|
+
export default {
|
|
65
|
+
name: 'AppCompInputRadioNext',
|
|
66
|
+
|
|
67
|
+
props: {
|
|
68
|
+
quizType: {
|
|
69
|
+
type: String,
|
|
70
|
+
default: ''
|
|
71
|
+
},
|
|
72
|
+
inputDataId: {
|
|
73
|
+
type: String,
|
|
74
|
+
default: ''
|
|
75
|
+
},
|
|
76
|
+
|
|
77
|
+
inputData: {
|
|
78
|
+
type: Array,
|
|
79
|
+
default: () => []
|
|
80
|
+
},
|
|
81
|
+
quizInputType: {
|
|
82
|
+
type: String,
|
|
83
|
+
default: ''
|
|
84
|
+
},
|
|
85
|
+
solution: {
|
|
86
|
+
type: String,
|
|
87
|
+
default: ''
|
|
88
|
+
}, //may be null
|
|
89
|
+
showSolution: {
|
|
90
|
+
type: Boolean,
|
|
91
|
+
default: false
|
|
92
|
+
},
|
|
93
|
+
shuffleAnswers: {
|
|
94
|
+
type: Boolean,
|
|
95
|
+
default: false
|
|
96
|
+
},
|
|
97
|
+
quizLimitActive: {
|
|
98
|
+
type: Boolean,
|
|
99
|
+
default: false
|
|
100
|
+
}, //use to set if quiz should be active or not
|
|
101
|
+
|
|
102
|
+
quizSubmit: {
|
|
103
|
+
type: Boolean,
|
|
104
|
+
default: false
|
|
105
|
+
} //use to call a submit
|
|
106
|
+
},
|
|
107
|
+
emits: ['input-change'],
|
|
108
|
+
setup(props) {
|
|
109
|
+
const { shuffleArray, classInput, messageAccessibility } = useQuiz(
|
|
110
|
+
toRefs(props)
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
return { shuffleArray, classInput, messageAccessibility }
|
|
114
|
+
},
|
|
115
|
+
data() {
|
|
116
|
+
return {
|
|
117
|
+
quizInputDataValue: [],
|
|
118
|
+
inputUniqueValue: null //not using quizInputUnique because quizInputUnique is a prop
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
|
|
122
|
+
computed: {},
|
|
123
|
+
|
|
124
|
+
watch: {
|
|
125
|
+
// /**
|
|
126
|
+
// * @description to pass value to AppCompQuiz
|
|
127
|
+
// * @fires input-change to AppCompQuiz.vue
|
|
128
|
+
// */
|
|
129
|
+
inputUniqueValue: {
|
|
130
|
+
deep: true,
|
|
131
|
+
handler(newValue) {
|
|
132
|
+
this.$emit('input-change', newValue)
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
|
|
137
|
+
mounted() {
|
|
138
|
+
this.initQuiz()
|
|
139
|
+
},
|
|
140
|
+
|
|
141
|
+
methods: {
|
|
142
|
+
initQuiz() {
|
|
143
|
+
this.inputUniqueValue = this.quizInputType
|
|
144
|
+
if (this.shuffleAnswers) {
|
|
145
|
+
this.quizInputDataValue = this.shuffleArray(this.inputData)
|
|
146
|
+
} else {
|
|
147
|
+
this.quizInputDataValue = this.inputData
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
</script>
|