fcad-core-dragon 2.0.0-beta.2 → 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.
- package/.editorconfig +33 -33
- package/.eslintignore +29 -29
- package/.eslintrc.cjs +81 -81
- package/CHANGELOG +364 -364
- package/README.md +71 -71
- package/bk.scss +117 -117
- package/package.json +61 -47
- package/src/$locales/en.json +143 -193
- package/src/$locales/fr.json +105 -194
- package/src/assets/data/onboardingMessages.json +47 -47
- package/src/components/AppBase.vue +1054 -1049
- package/src/components/AppBaseButton.vue +87 -91
- package/src/components/AppBaseErrorDisplay.vue +438 -428
- package/src/components/AppBaseFlipCard.vue +84 -83
- package/src/components/AppBaseModule.vue +1673 -1666
- package/src/components/AppBasePage.vue +779 -324
- package/src/components/AppBasePopover.vue +41 -0
- package/src/components/AppCompAudio.vue +234 -266
- package/src/components/AppCompBranchButtons.vue +552 -571
- package/src/components/AppCompButtonProgress.vue +126 -132
- package/src/components/AppCompCarousel.vue +298 -196
- package/src/components/{AppCompInputCheckBox.vue → AppCompInputCheckBoxNext.vue} +195 -233
- package/src/components/AppCompInputDropdownNext.vue +159 -0
- package/src/components/{AppCompInputRadio.vue → AppCompInputRadioNext.vue} +152 -162
- package/src/components/{AppCompInputTextBox.vue → AppCompInputTextNext.vue} +106 -91
- package/src/components/AppCompInputTextTableNext.vue +141 -0
- package/src/components/AppCompInputTextToFillDropdownNext.vue +230 -0
- package/src/components/{AppCompInputTextToFillText.vue → AppCompInputTextToFillNext.vue} +171 -164
- package/src/components/AppCompJauge.vue +74 -67
- package/src/components/AppCompMenu.vue +413 -402
- package/src/components/AppCompMenuItem.vue +228 -191
- package/src/components/AppCompNavigation.vue +960 -945
- package/src/components/AppCompNoteCall.vue +133 -141
- package/src/components/AppCompNoteCredit.vue +292 -267
- package/src/components/AppCompPlayBar.vue +1218 -1271
- package/src/components/AppCompPlayBarNext.vue +2052 -0
- package/src/components/AppCompPlayBarProgress.vue +82 -73
- package/src/components/AppCompPopUpNext.vue +503 -0
- package/src/components/{AppCompQuiz.vue → AppCompQuizNext.vue} +2904 -2975
- package/src/components/AppCompQuizRecall.vue +276 -277
- package/src/components/{AppCompSVG.vue → AppCompSVGNext.vue} +347 -335
- package/src/components/AppCompSettingsMenu.vue +172 -169
- package/src/components/AppCompTableOfContent.vue +387 -385
- package/src/components/AppCompTranscript.vue +24 -19
- package/src/components/AppCompVideoPlayer.vue +368 -380
- package/src/components/AppCompViewDisplay.vue +6 -6
- package/src/components/BaseModule.vue +72 -71
- package/src/composables/useQuiz.js +206 -0
- package/src/externalComps/ModuleView.vue +22 -0
- package/src/externalComps/SummaryView.vue +91 -0
- package/src/main.js +272 -263
- package/src/mixins/$mediaMixins.js +819 -827
- package/src/mixins/timerMixin.js +155 -155
- package/src/module/stores/appStore.js +893 -0
- package/src/module/xapi/ADL.js +376 -376
- 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/Crypto/index.js +53 -53
- package/src/module/xapi/Statement/activity.js +47 -47
- package/src/module/xapi/Statement/agent.js +55 -55
- package/src/module/xapi/Statement/group.js +26 -26
- package/src/module/xapi/Statement/index.js +259 -259
- package/src/module/xapi/Statement/statement.js +253 -253
- package/src/module/xapi/Statement/statementRef.js +23 -23
- package/src/module/xapi/Statement/substatement.js +22 -22
- package/src/module/xapi/Statement/verb.js +36 -36
- package/src/module/xapi/activitytypes.js +17 -17
- package/src/module/xapi/launch.js +157 -157
- package/src/module/xapi/utils.js +167 -167
- package/src/module/xapi/verbs.js +294 -294
- package/src/module/xapi/wrapper.js +1963 -1963
- package/src/module/xapi/xapiStatement.js +444 -444
- package/src/plugins/bus.js +8 -3
- package/src/plugins/gsap.js +14 -17
- package/src/plugins/helper.js +308 -294
- package/src/plugins/i18n.js +44 -44
- package/src/plugins/idb.js +219 -212
- 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 -21
- package/src/router/index.js +43 -40
- package/src/router/routes.js +312 -317
- package/src/shared/generalfuncs.js +210 -195
- package/src/shared/validators.js +1069 -959
- package/vite.config.js +27 -0
- package/src/components/AppCompInputDropdown.vue +0 -182
- package/src/components/AppCompInputTextTable.vue +0 -158
- package/src/components/AppCompInputTextToFillDropdown.vue +0 -257
- package/src/components/AppCompPopUp.vue +0 -583
- package/src/components/AppCompPopover.vue +0 -27
- package/src/mixins/$pageMixins.js +0 -415
- package/src/mixins/$quizMixins.js +0 -442
- package/src/module/store.js +0 -1014
package/vite.config.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// vite.config.js
|
|
2
|
+
import { resolve } from 'path'
|
|
3
|
+
import { defineConfig } from 'vite'
|
|
4
|
+
|
|
5
|
+
export default defineConfig({
|
|
6
|
+
build: {
|
|
7
|
+
lib: {
|
|
8
|
+
// Could also be a dictionary or array of multiple entry points
|
|
9
|
+
entry: resolve(__dirname, 'lib/main.js'),
|
|
10
|
+
name: 'FcadLib',
|
|
11
|
+
// the proper extensions will be added
|
|
12
|
+
fileName: 'fcad-lib'
|
|
13
|
+
},
|
|
14
|
+
rollupOptions: {
|
|
15
|
+
// make sure to externalize deps that shouldn't be bundled
|
|
16
|
+
// into your library
|
|
17
|
+
external: ['vue'],
|
|
18
|
+
output: {
|
|
19
|
+
// Provide global variables to use in the UMD build
|
|
20
|
+
// for externalized deps
|
|
21
|
+
globals: {
|
|
22
|
+
vue: 'Vue'
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
})
|
|
@@ -1,182 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div class="input-box">
|
|
3
|
-
<div
|
|
4
|
-
v-for="singleDropdown in inputData"
|
|
5
|
-
:key="singleDropdown.id"
|
|
6
|
-
:class="`dropdownlist-${singleDropdown.id} ${classInput(singleDropdown.id)}`"
|
|
7
|
-
>
|
|
8
|
-
<label
|
|
9
|
-
:for="`${inputDataId}_${singleDropdown.id}`"
|
|
10
|
-
v-html="singleDropdown.ennonce"
|
|
11
|
-
></label>
|
|
12
|
-
<b-form-select
|
|
13
|
-
:id="inputDataId + '_' + singleDropdown.id"
|
|
14
|
-
v-model="quizSelectedValue[singleDropdown.id]"
|
|
15
|
-
:options="singleDropdown.option"
|
|
16
|
-
:disabled="quizCompleted"
|
|
17
|
-
></b-form-select>
|
|
18
|
-
</div>
|
|
19
|
-
</div>
|
|
20
|
-
</template>
|
|
21
|
-
<script>
|
|
22
|
-
import $extendsQuiz from '../mixins/$quizMixins'
|
|
23
|
-
export default {
|
|
24
|
-
name: 'AppCompInputDropdown',
|
|
25
|
-
mixins: [$extendsQuiz],
|
|
26
|
-
|
|
27
|
-
props: {
|
|
28
|
-
inputType: {
|
|
29
|
-
type: String,
|
|
30
|
-
default: ''
|
|
31
|
-
},
|
|
32
|
-
inputDataId: {
|
|
33
|
-
type: String,
|
|
34
|
-
default: ''
|
|
35
|
-
},
|
|
36
|
-
inputData: {
|
|
37
|
-
type: Array,
|
|
38
|
-
default: () => []
|
|
39
|
-
},
|
|
40
|
-
quizCompleted: {
|
|
41
|
-
type: Boolean,
|
|
42
|
-
default: false
|
|
43
|
-
},
|
|
44
|
-
solution: {
|
|
45
|
-
type: Array,
|
|
46
|
-
default: () => []
|
|
47
|
-
},
|
|
48
|
-
showSolution: {
|
|
49
|
-
type: Boolean,
|
|
50
|
-
default: false
|
|
51
|
-
},
|
|
52
|
-
shuffleAnswers: {
|
|
53
|
-
type: Boolean,
|
|
54
|
-
default: false
|
|
55
|
-
},
|
|
56
|
-
quizSelected: {
|
|
57
|
-
type: Array,
|
|
58
|
-
default: () => []
|
|
59
|
-
}, //use to pass the value of the input
|
|
60
|
-
quizSubmit: {
|
|
61
|
-
type: Boolean,
|
|
62
|
-
default: false
|
|
63
|
-
} //use to call a submit
|
|
64
|
-
},
|
|
65
|
-
|
|
66
|
-
data() {
|
|
67
|
-
return {
|
|
68
|
-
quizSelectedValue: [] //not using quizSelected because quizSelected is a prop
|
|
69
|
-
}
|
|
70
|
-
},
|
|
71
|
-
|
|
72
|
-
computed: {},
|
|
73
|
-
|
|
74
|
-
watch: {
|
|
75
|
-
/**
|
|
76
|
-
* @description to pass value to AppCompQuiz
|
|
77
|
-
* @emits input-change
|
|
78
|
-
*/
|
|
79
|
-
quizSelectedValue(newValue) {
|
|
80
|
-
this.$emit('input-change', newValue)
|
|
81
|
-
},
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* @description to pass the value from AppCompQuiz
|
|
85
|
-
*/
|
|
86
|
-
quizSelected(newValue) {
|
|
87
|
-
this.quizSelectedValue = newValue
|
|
88
|
-
}
|
|
89
|
-
},
|
|
90
|
-
|
|
91
|
-
mounted() {
|
|
92
|
-
if (this.solution !== null)
|
|
93
|
-
this.solution.sort(function (a, b) {
|
|
94
|
-
return a.question_id - b.question_id
|
|
95
|
-
})
|
|
96
|
-
//to show the defaultAnswer
|
|
97
|
-
const defaultAnswer = {
|
|
98
|
-
value: null,
|
|
99
|
-
disabled: true,
|
|
100
|
-
text: this.$t('message.first_option_dropdown')
|
|
101
|
-
}
|
|
102
|
-
let selectedChoices = []
|
|
103
|
-
for (let i = 0; i < this.inputData.length; i++) {
|
|
104
|
-
let singleDropdown
|
|
105
|
-
if (this.shuffleAnswers) {
|
|
106
|
-
singleDropdown = this.inputData[i]
|
|
107
|
-
singleDropdown.option = this.shuffleArray(singleDropdown.option)
|
|
108
|
-
} else {
|
|
109
|
-
singleDropdown = this.inputData[i]
|
|
110
|
-
}
|
|
111
|
-
if (
|
|
112
|
-
this.inputData[i].option[0].text !==
|
|
113
|
-
this.$t('message.first_option_dropdown')
|
|
114
|
-
) {
|
|
115
|
-
singleDropdown.option.unshift(defaultAnswer)
|
|
116
|
-
}
|
|
117
|
-
selectedChoices.push(null)
|
|
118
|
-
}
|
|
119
|
-
if (this.quizSelected.length == 0) {
|
|
120
|
-
this.quizSelectedValue = selectedChoices
|
|
121
|
-
} else {
|
|
122
|
-
this.quizSelectedValue = this.quizSelected
|
|
123
|
-
}
|
|
124
|
-
},
|
|
125
|
-
|
|
126
|
-
methods: {
|
|
127
|
-
/**
|
|
128
|
-
* @description used by the dropdown quiz
|
|
129
|
-
* @param {Array} answers what the user has answered
|
|
130
|
-
* @param {Array} solution the correct choices
|
|
131
|
-
* @returns {Boolean}
|
|
132
|
-
* @todo Add a catching for error if the 2 question_id dont match
|
|
133
|
-
*/
|
|
134
|
-
compareSelectedAnswers(answers, solution) {
|
|
135
|
-
for (let index = 0; index < answers.length; index++) {
|
|
136
|
-
const elementAnswers = answers[index]
|
|
137
|
-
const elementSolution = solution[index]
|
|
138
|
-
if (elementAnswers.question_id == elementSolution.question_id) {
|
|
139
|
-
if (elementAnswers.reponse_id !== elementSolution.reponse_id) {
|
|
140
|
-
return false
|
|
141
|
-
}
|
|
142
|
-
} else {
|
|
143
|
-
return //if it return nothing there is a bug since this means the 2 question_id dont match
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
return true
|
|
147
|
-
},
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
* @description check if a values exists in a array
|
|
151
|
-
* @param {Array} array
|
|
152
|
-
* @param value
|
|
153
|
-
* @returns {Boolean}
|
|
154
|
-
*/
|
|
155
|
-
containsValue(array, value) {
|
|
156
|
-
return array.includes(value)
|
|
157
|
-
},
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* @description shuffles an array used to randomized the option order if shuffleAnswers is true
|
|
161
|
-
* @param {Array} array
|
|
162
|
-
* @returns {Array}
|
|
163
|
-
*/
|
|
164
|
-
shuffleArray(array) {
|
|
165
|
-
let newArray = []
|
|
166
|
-
let newArray2 = []
|
|
167
|
-
|
|
168
|
-
for (let i = 0; i < array.length; i++) {
|
|
169
|
-
const element = array[i]
|
|
170
|
-
//todo remove null values
|
|
171
|
-
newArray.push(element)
|
|
172
|
-
}
|
|
173
|
-
while (newArray.length > 0) {
|
|
174
|
-
let pos = Math.floor(newArray.length * Math.random())
|
|
175
|
-
newArray2.push(newArray[pos])
|
|
176
|
-
newArray.splice(pos, 1)
|
|
177
|
-
}
|
|
178
|
-
return newArray2
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
</script>
|
|
@@ -1,158 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div>
|
|
3
|
-
<div v-for="textInput in inputDataValue" :key="textInput.id">
|
|
4
|
-
<label
|
|
5
|
-
:id="`${inputDataId}_${textInput.id}-label`"
|
|
6
|
-
aria-hidden="true"
|
|
7
|
-
v-html="textInput.ennonce"
|
|
8
|
-
></label>
|
|
9
|
-
<div class="cnt-input" :class="classInput(textInput.id)">
|
|
10
|
-
<b-form-input
|
|
11
|
-
:id="`${inputDataId}_${textInput.id}-champ`"
|
|
12
|
-
v-model="quizTextTableValue[textInput.id]"
|
|
13
|
-
:placeholder="$t('text.place_holder.for_textarea')"
|
|
14
|
-
:disabled="quizCompleted"
|
|
15
|
-
rows="1"
|
|
16
|
-
no-resize
|
|
17
|
-
:aria-describedby="`${inputDataId}_${textInput.id}-msg-erreur`"
|
|
18
|
-
:aria-labelledby="`${inputDataId}_${textInput.id}-label`"
|
|
19
|
-
></b-form-input>
|
|
20
|
-
</div>
|
|
21
|
-
<span :id="`${inputDataId}_${textInput.id}-msg-erreur`" class="sr-only">
|
|
22
|
-
{{ messageAccessibility(textInput.id) }}
|
|
23
|
-
</span>
|
|
24
|
-
</div>
|
|
25
|
-
</div>
|
|
26
|
-
</template>
|
|
27
|
-
<script>
|
|
28
|
-
import $extendsQuiz from '../mixins/$quizMixins'
|
|
29
|
-
export default {
|
|
30
|
-
name: 'AppCompInputTextTable',
|
|
31
|
-
mixins: [$extendsQuiz],
|
|
32
|
-
|
|
33
|
-
props: {
|
|
34
|
-
inputType: {
|
|
35
|
-
type: String,
|
|
36
|
-
default: ''
|
|
37
|
-
},
|
|
38
|
-
inputDataId: {
|
|
39
|
-
type: String,
|
|
40
|
-
default: ''
|
|
41
|
-
},
|
|
42
|
-
inputData: {
|
|
43
|
-
type: Array,
|
|
44
|
-
default: () => []
|
|
45
|
-
},
|
|
46
|
-
quizCompleted: {
|
|
47
|
-
type: Boolean,
|
|
48
|
-
default: false
|
|
49
|
-
},
|
|
50
|
-
solution: {
|
|
51
|
-
type: Array,
|
|
52
|
-
default: () => []
|
|
53
|
-
},
|
|
54
|
-
showSolution: {
|
|
55
|
-
type: Boolean,
|
|
56
|
-
default: false
|
|
57
|
-
},
|
|
58
|
-
shuffleAnswers: {
|
|
59
|
-
type: Boolean,
|
|
60
|
-
default: false
|
|
61
|
-
},
|
|
62
|
-
quizTextTable: {
|
|
63
|
-
type: Array,
|
|
64
|
-
default: () => []
|
|
65
|
-
}, //use to pass the value of the input
|
|
66
|
-
quizSubmit: {
|
|
67
|
-
type: Boolean,
|
|
68
|
-
default: false
|
|
69
|
-
} //use to call a submit
|
|
70
|
-
},
|
|
71
|
-
|
|
72
|
-
data() {
|
|
73
|
-
return {
|
|
74
|
-
inputDataValue: [],
|
|
75
|
-
quizTextTableValue: [] //not using quizTextTable because quizTextTable is a prop
|
|
76
|
-
}
|
|
77
|
-
},
|
|
78
|
-
|
|
79
|
-
computed: {},
|
|
80
|
-
|
|
81
|
-
watch: {
|
|
82
|
-
/**
|
|
83
|
-
* @description to pass value to AppCompQuiz
|
|
84
|
-
* @fires input-change to AppCompQuiz.vue
|
|
85
|
-
*/
|
|
86
|
-
quizTextTableValue(newValue) {
|
|
87
|
-
this.$emit('input-change', newValue)
|
|
88
|
-
},
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* @description to pass the value from AppCompQuiz
|
|
92
|
-
*/
|
|
93
|
-
quizTextTable(newValue) {
|
|
94
|
-
this.quizTextTableValue = newValue
|
|
95
|
-
}
|
|
96
|
-
},
|
|
97
|
-
|
|
98
|
-
mounted() {
|
|
99
|
-
if (this.solution !== null) {
|
|
100
|
-
this.solution.sort(function (a, b) {
|
|
101
|
-
return a.question_id - b.question_id
|
|
102
|
-
})
|
|
103
|
-
}
|
|
104
|
-
let textChoices = []
|
|
105
|
-
|
|
106
|
-
for (let i = 0; i < this.inputData.length; i++) {
|
|
107
|
-
textChoices.push('')
|
|
108
|
-
}
|
|
109
|
-
//apply previous answers
|
|
110
|
-
if (this.quizTextTable && this.quizTextTable.length == 0) {
|
|
111
|
-
this.quizTextTableValue = textChoices
|
|
112
|
-
} else {
|
|
113
|
-
this.quizTextTableValue = this.quizTextTable
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
if (this.shuffleAnswers) {
|
|
117
|
-
this.inputDataValue = this.shuffleArray(this.inputData)
|
|
118
|
-
} else {
|
|
119
|
-
this.inputDataValue = this.inputData
|
|
120
|
-
}
|
|
121
|
-
},
|
|
122
|
-
|
|
123
|
-
methods: {
|
|
124
|
-
/**
|
|
125
|
-
* @description check if a values exists in a array
|
|
126
|
-
* @param {Array} array
|
|
127
|
-
* @param value
|
|
128
|
-
* @returns {Boolean}
|
|
129
|
-
*/
|
|
130
|
-
containsValue(array, value) {
|
|
131
|
-
return array.includes(value)
|
|
132
|
-
},
|
|
133
|
-
|
|
134
|
-
/**
|
|
135
|
-
* @description shuffles an array used to randomized the option order if shuffleAnswers is true
|
|
136
|
-
* @param {Array} array
|
|
137
|
-
* @returns {Array}
|
|
138
|
-
*/
|
|
139
|
-
shuffleArray(array) {
|
|
140
|
-
let newArray = []
|
|
141
|
-
let newArray2 = []
|
|
142
|
-
|
|
143
|
-
for (let i = 0; i < array.length; i++) {
|
|
144
|
-
const element = array[i]
|
|
145
|
-
//todo remove null values
|
|
146
|
-
newArray.push(element)
|
|
147
|
-
}
|
|
148
|
-
while (newArray.length > 0) {
|
|
149
|
-
let pos = Math.floor(newArray.length * Math.random())
|
|
150
|
-
newArray2.push(newArray[pos])
|
|
151
|
-
newArray.splice(pos, 1)
|
|
152
|
-
}
|
|
153
|
-
return newArray2
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
</script>
|
|
158
|
-
<style lang="scss" scoped></style>
|
|
@@ -1,257 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div>
|
|
3
|
-
<div
|
|
4
|
-
v-for="singleDropdown in theInputData"
|
|
5
|
-
:key="singleDropdown.id"
|
|
6
|
-
class="texteatrou"
|
|
7
|
-
>
|
|
8
|
-
<span v-if="!singleDropdown.type" v-html="singleDropdown.content"></span>
|
|
9
|
-
<label
|
|
10
|
-
:for="`${inputDataId}_${singleDropdown.id}-champ`"
|
|
11
|
-
style="display: none"
|
|
12
|
-
>
|
|
13
|
-
{{ $t('text.quiz') }}
|
|
14
|
-
</label>
|
|
15
|
-
<div class="cnt-input" :class="classInput(singleDropdown.id)">
|
|
16
|
-
<b-form-select
|
|
17
|
-
v-if="singleDropdown.type == 'dropdown'"
|
|
18
|
-
:id="`${inputDataId}_${singleDropdown.id}-champ`"
|
|
19
|
-
v-model="quizSelectedValue[singleDropdown.id]"
|
|
20
|
-
:options="singleDropdown.option"
|
|
21
|
-
:disabled="quizCompleted"
|
|
22
|
-
:aria-describedby="`${inputDataId}_${singleDropdown.id}-msg-erreur`"
|
|
23
|
-
></b-form-select>
|
|
24
|
-
</div>
|
|
25
|
-
|
|
26
|
-
<span
|
|
27
|
-
v-if="showSolution"
|
|
28
|
-
:id="`${inputDataId}_${singleDropdown.id}-msg-erreur`"
|
|
29
|
-
class="sr-only"
|
|
30
|
-
>
|
|
31
|
-
{{ messageAccessibility(singleDropdown.id) }}
|
|
32
|
-
</span>
|
|
33
|
-
</div>
|
|
34
|
-
</div>
|
|
35
|
-
</template>
|
|
36
|
-
<script>
|
|
37
|
-
import $extendsQuiz from '../mixins/$quizMixins'
|
|
38
|
-
export default {
|
|
39
|
-
name: 'AppCompInputTextToFillDropdown',
|
|
40
|
-
mixins: [$extendsQuiz],
|
|
41
|
-
|
|
42
|
-
props: {
|
|
43
|
-
inputType: {
|
|
44
|
-
type: String,
|
|
45
|
-
default: ''
|
|
46
|
-
},
|
|
47
|
-
inputDataId: {
|
|
48
|
-
type: String,
|
|
49
|
-
default: ''
|
|
50
|
-
},
|
|
51
|
-
inputData: {
|
|
52
|
-
type: Array,
|
|
53
|
-
default: () => []
|
|
54
|
-
},
|
|
55
|
-
textBase: {
|
|
56
|
-
type: String,
|
|
57
|
-
default: ''
|
|
58
|
-
},
|
|
59
|
-
quizCompleted: {
|
|
60
|
-
type: Boolean,
|
|
61
|
-
default: false
|
|
62
|
-
},
|
|
63
|
-
solution: {
|
|
64
|
-
type: Array,
|
|
65
|
-
default: () => []
|
|
66
|
-
},
|
|
67
|
-
showSolution: {
|
|
68
|
-
type: Boolean,
|
|
69
|
-
default: false
|
|
70
|
-
},
|
|
71
|
-
shuffleAnswers: {
|
|
72
|
-
type: Boolean,
|
|
73
|
-
default: false
|
|
74
|
-
},
|
|
75
|
-
quizSelected: {
|
|
76
|
-
type: Array,
|
|
77
|
-
default: () => []
|
|
78
|
-
}, //use to pass the value of the input
|
|
79
|
-
quizSubmit: {
|
|
80
|
-
type: Boolean,
|
|
81
|
-
default: false
|
|
82
|
-
} //use to call a submit
|
|
83
|
-
},
|
|
84
|
-
|
|
85
|
-
data() {
|
|
86
|
-
return {
|
|
87
|
-
quizSelectedValue: [], //not using quizSelected because quizSelected is a prop
|
|
88
|
-
theInputData: [] //to create the list of drop down and text mixed togeter
|
|
89
|
-
}
|
|
90
|
-
},
|
|
91
|
-
|
|
92
|
-
computed: {},
|
|
93
|
-
|
|
94
|
-
watch: {
|
|
95
|
-
/**
|
|
96
|
-
* @description to pass value to AppCompQuiz
|
|
97
|
-
* @fires input-change to AppCompQuiz.vue
|
|
98
|
-
*/
|
|
99
|
-
quizSelectedValue(newValue) {
|
|
100
|
-
this.$emit('input-change', newValue)
|
|
101
|
-
},
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* @description to pass the value from AppCompQuiz
|
|
105
|
-
*/
|
|
106
|
-
quizSelected(newValue) {
|
|
107
|
-
this.quizSelectedValue = newValue
|
|
108
|
-
}
|
|
109
|
-
},
|
|
110
|
-
|
|
111
|
-
mounted() {
|
|
112
|
-
if (this.solution !== null) {
|
|
113
|
-
this.solution.sort(function (a, b) {
|
|
114
|
-
return a.question_id - b.question_id
|
|
115
|
-
})
|
|
116
|
-
}
|
|
117
|
-
//to show the defaultAnswer
|
|
118
|
-
const defaultAnswer = {
|
|
119
|
-
value: null,
|
|
120
|
-
disabled: true,
|
|
121
|
-
text: this.$t('message.first_option_dropdown')
|
|
122
|
-
}
|
|
123
|
-
let selectedChoices = []
|
|
124
|
-
for (let i = 0; i < this.inputData.length; i++) {
|
|
125
|
-
let singleDropdown = {}
|
|
126
|
-
if (this.shuffleAnswers) {
|
|
127
|
-
singleDropdown = this.inputData[i]
|
|
128
|
-
singleDropdown[Object.keys(this.inputData[i])[0].toString()] =
|
|
129
|
-
this.shuffleArray(Object.values(this.inputData[i])[0])
|
|
130
|
-
} else {
|
|
131
|
-
singleDropdown = this.inputData[i]
|
|
132
|
-
}
|
|
133
|
-
for (
|
|
134
|
-
let index = 0;
|
|
135
|
-
index < Object.values(singleDropdown)[0].length;
|
|
136
|
-
index++
|
|
137
|
-
) {
|
|
138
|
-
const element = Object.values(singleDropdown)[0][index]
|
|
139
|
-
if (
|
|
140
|
-
element.text &&
|
|
141
|
-
element.text == this.$t('message.first_option_dropdown')
|
|
142
|
-
) {
|
|
143
|
-
Object.values(singleDropdown)[0].splice(index, 1)
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
Object.values(singleDropdown)[0].unshift(defaultAnswer)
|
|
147
|
-
|
|
148
|
-
selectedChoices.push(null)
|
|
149
|
-
}
|
|
150
|
-
if (this.quizSelected.length == 0) {
|
|
151
|
-
this.quizSelectedValue = selectedChoices
|
|
152
|
-
} else {
|
|
153
|
-
this.quizSelectedValue = this.quizSelected
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
this.createTextWithInput(this.textBase)
|
|
157
|
-
},
|
|
158
|
-
|
|
159
|
-
methods: {
|
|
160
|
-
/**
|
|
161
|
-
* @description create the object to genate the text and inputs
|
|
162
|
-
* @param {String} str the text with holes to fill
|
|
163
|
-
*/
|
|
164
|
-
createTextWithInput(str) {
|
|
165
|
-
const regex = /\$%\S*%\$/g // regex pattern to match exp: $%number%$
|
|
166
|
-
let matchAll = str.split(regex)
|
|
167
|
-
let listInput = []
|
|
168
|
-
for (let i = 0; i < this.inputData.length; i++) {
|
|
169
|
-
const element = this.inputData[i]
|
|
170
|
-
listInput.push({ id: 't' + i, content: matchAll[i] })
|
|
171
|
-
listInput.push({
|
|
172
|
-
id: i,
|
|
173
|
-
type: 'dropdown',
|
|
174
|
-
option: Object.values(element)[0]
|
|
175
|
-
})
|
|
176
|
-
}
|
|
177
|
-
let lastItem = matchAll.length - 1
|
|
178
|
-
listInput.push({ id: 't' + lastItem, content: matchAll[lastItem] })
|
|
179
|
-
this.theInputData = listInput
|
|
180
|
-
},
|
|
181
|
-
/**
|
|
182
|
-
* @description used by the dropdown quiz
|
|
183
|
-
* @param {Array} answers what the user has answered
|
|
184
|
-
* @param {Array} solution the correct choices
|
|
185
|
-
* @returns {Boolean}
|
|
186
|
-
* @todo Add a catching for error if the 2 question_id dont match
|
|
187
|
-
*/
|
|
188
|
-
compareSelectedAnswers(answers, solution) {
|
|
189
|
-
for (let index = 0; index < answers.length; index++) {
|
|
190
|
-
const elementAnswers = answers[index]
|
|
191
|
-
const elementSolution = solution[index]
|
|
192
|
-
if (elementAnswers.question_id == elementSolution.question_id) {
|
|
193
|
-
if (elementAnswers.reponse_id !== elementSolution.reponse_id) {
|
|
194
|
-
return false
|
|
195
|
-
}
|
|
196
|
-
} else {
|
|
197
|
-
return //if it return nothing there is a bug since this means the 2 question_id dont match
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
return true
|
|
201
|
-
},
|
|
202
|
-
|
|
203
|
-
/**
|
|
204
|
-
* @description check if a values exists in a array
|
|
205
|
-
* @param {Array} array
|
|
206
|
-
* @param value
|
|
207
|
-
* @returns {Boolean}
|
|
208
|
-
*/
|
|
209
|
-
containsValue(array, value) {
|
|
210
|
-
return array.includes(value)
|
|
211
|
-
},
|
|
212
|
-
|
|
213
|
-
/**
|
|
214
|
-
* @description shuffles an array used to randomized the option order if shuffleAnswers is true
|
|
215
|
-
* @param {Array} array
|
|
216
|
-
* @returns {Array}
|
|
217
|
-
*/
|
|
218
|
-
shuffleArray(array) {
|
|
219
|
-
let newArray = []
|
|
220
|
-
let newArray2 = []
|
|
221
|
-
|
|
222
|
-
for (let i = 0; i < array.length; i++) {
|
|
223
|
-
const element = array[i]
|
|
224
|
-
//todo remove null values
|
|
225
|
-
newArray.push(element)
|
|
226
|
-
}
|
|
227
|
-
while (newArray.length > 0) {
|
|
228
|
-
let pos = Math.floor(newArray.length * Math.random())
|
|
229
|
-
newArray2.push(newArray[pos])
|
|
230
|
-
newArray.splice(pos, 1)
|
|
231
|
-
}
|
|
232
|
-
return newArray2
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
</script>
|
|
237
|
-
<style lang="scss" scoped>
|
|
238
|
-
select {
|
|
239
|
-
&.custom-select {
|
|
240
|
-
background-image: inherit;
|
|
241
|
-
|
|
242
|
-
&:focus {
|
|
243
|
-
border-color: inherit;
|
|
244
|
-
box-shadow: inherit;
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
/***** style dev *****/
|
|
250
|
-
.texteatrou {
|
|
251
|
-
display: inline;
|
|
252
|
-
}
|
|
253
|
-
.texteatrou > select {
|
|
254
|
-
display: inline;
|
|
255
|
-
width: auto;
|
|
256
|
-
}
|
|
257
|
-
</style>
|