fcad-core-dragon 2.0.0-beta.4 → 2.0.0-beta.5
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/CHANGELOG +377 -373
- package/package.json +61 -61
- package/src/$locales/en.json +3 -1
- package/src/$locales/fr.json +3 -1
- package/src/components/AppBase.vue +20 -17
- package/src/components/AppBaseButton.test.js +22 -0
- package/src/components/AppBaseButton.vue +11 -5
- package/src/components/AppBaseModule.vue +48 -27
- package/src/components/AppBasePage.vue +7 -44
- package/src/components/AppCompAudio.vue +31 -0
- package/src/components/AppCompBranchButtons.vue +20 -16
- package/src/components/AppCompButtonProgress.vue +4 -9
- package/src/components/AppCompCarousel.vue +120 -90
- package/src/components/AppCompInputCheckBoxNext.vue +5 -0
- package/src/components/AppCompInputDropdownNext.vue +50 -8
- package/src/components/AppCompInputTextNext.vue +21 -2
- package/src/components/AppCompInputTextTableNext.vue +1 -0
- package/src/components/AppCompInputTextToFillDropdownNext.vue +8 -0
- package/src/components/AppCompMenu.vue +428 -423
- package/src/components/AppCompNavigation.vue +41 -28
- package/src/components/AppCompNoteCall.vue +64 -38
- package/src/components/AppCompNoteCredit.vue +303 -105
- package/src/components/AppCompPlayBar.vue +4 -5
- package/src/components/AppCompPlayBarNext.vue +20 -12
- package/src/components/AppCompPopUpNext.vue +1 -4
- package/src/components/AppCompQuizNext.vue +8 -4
- package/src/components/AppCompQuizRecall.vue +44 -22
- package/src/components/AppCompTableOfContent.vue +61 -62
- package/src/components/AppCompViewDisplay.vue +6 -6
- package/src/components/BaseModule.vue +1 -18
- package/src/components/tests__/AppBaseButton.spec.js +53 -0
- package/src/main.js +3 -3
- package/src/module/stores/appStore.js +58 -5
- package/src/module/xapi/Crypto/index.js +53 -53
- package/src/module/xapi/Statement/activity.js +47 -47
- package/src/module/xapi/Statement/group.js +26 -26
- 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/plugins/helper.js +53 -12
- package/src/router/index.js +6 -1
- package/src/shared/validators.js +36 -179
- package/vitest.config.js +19 -0
|
@@ -165,7 +165,38 @@ export default {
|
|
|
165
165
|
},
|
|
166
166
|
errorHandling(e) {
|
|
167
167
|
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
|
+
}
|
|
168
198
|
}
|
|
199
|
+
// ===================================TEST TRANSCRIP================================================
|
|
169
200
|
}
|
|
170
201
|
}
|
|
171
202
|
</script>
|
|
@@ -38,7 +38,7 @@ Si la composante est appelée sans prop, les boutons par défaut seront génér
|
|
|
38
38
|
<v-row v-else>
|
|
39
39
|
<v-col
|
|
40
40
|
v-for="branch of branchsStateData"
|
|
41
|
-
:id="branch.id"
|
|
41
|
+
:id="`branch_${branch.id}`"
|
|
42
42
|
:key="branch.id"
|
|
43
43
|
class="branch-btn"
|
|
44
44
|
>
|
|
@@ -65,24 +65,20 @@ Si la composante est appelée sans prop, les boutons par défaut seront génér
|
|
|
65
65
|
v-else-if="isCard && cards.length"
|
|
66
66
|
class="branch-btn-wrapper branch-btn-card"
|
|
67
67
|
>
|
|
68
|
-
<v-card class="mx-auto" max-width="
|
|
69
|
-
<v-img :src="branch.imgFile" :alt="`${branch.imgAlt}`" cover
|
|
70
|
-
<v-toolbar color="transparent">
|
|
71
|
-
<template #append>
|
|
72
|
-
<app-comp-button-progress
|
|
73
|
-
:set-target="sidebar"
|
|
74
|
-
:percent="branch.progression ? branch.progression : 0"
|
|
75
|
-
:branch-data="branch"
|
|
76
|
-
:btn-title="getMatchingElement(branch.id).btnTitle"
|
|
77
|
-
></app-comp-button-progress>
|
|
78
|
-
</template>
|
|
79
|
-
</v-toolbar>
|
|
80
|
-
</v-img>
|
|
68
|
+
<v-card class="mx-auto" max-width="15rem">
|
|
69
|
+
<v-img :src="branch.imgFile" :alt="`${branch.imgAlt}`" cover />
|
|
81
70
|
|
|
82
71
|
<v-card-title>{{ branch.title }}</v-card-title>
|
|
83
72
|
<v-card-text>
|
|
84
73
|
{{ branch.text }}
|
|
85
74
|
</v-card-text>
|
|
75
|
+
|
|
76
|
+
<app-comp-button-progress
|
|
77
|
+
:set-target="sidebar"
|
|
78
|
+
:percent="branch.progression ? branch.progression : 0"
|
|
79
|
+
:branch-data="branch"
|
|
80
|
+
:btn-title="getMatchingElement(branch.id).btnTitle"
|
|
81
|
+
></app-comp-button-progress>
|
|
86
82
|
</v-card>
|
|
87
83
|
</div>
|
|
88
84
|
<div v-else class="branch-btn-wrapper">
|
|
@@ -98,7 +94,6 @@ Si la composante est appelée sans prop, les boutons par défaut seront génér
|
|
|
98
94
|
</v-row>
|
|
99
95
|
</template>
|
|
100
96
|
<script>
|
|
101
|
-
// ...
|
|
102
97
|
import { mapState } from 'pinia'
|
|
103
98
|
import { useAppStore } from '../module/stores/appStore'
|
|
104
99
|
import AppCompButtonProgress from './AppCompButtonProgress.vue'
|
|
@@ -304,7 +299,6 @@ export default {
|
|
|
304
299
|
let { state = 'new', progression = 0 } = this.getBranchProgression(
|
|
305
300
|
branchData.id
|
|
306
301
|
)
|
|
307
|
-
// if (!state || !progression) return
|
|
308
302
|
|
|
309
303
|
branchData.state = state
|
|
310
304
|
branchData.progression = progression
|
|
@@ -544,9 +538,19 @@ export default {
|
|
|
544
538
|
<style lang="scss">
|
|
545
539
|
.branch-btn-wrapper {
|
|
546
540
|
position: relative;
|
|
541
|
+
|
|
547
542
|
.branch-btn-custom {
|
|
548
543
|
background-color: transparent;
|
|
549
544
|
border: none;
|
|
550
545
|
}
|
|
551
546
|
}
|
|
547
|
+
|
|
548
|
+
.v-card {
|
|
549
|
+
position: relative;
|
|
550
|
+
.button-progress-wrapper {
|
|
551
|
+
position: absolute;
|
|
552
|
+
right: 55px;
|
|
553
|
+
top: 15px;
|
|
554
|
+
}
|
|
555
|
+
}
|
|
552
556
|
</style>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="button-progress-wrapper">
|
|
3
|
-
<button
|
|
3
|
+
<app-base-button
|
|
4
4
|
:id="`btn_branch_${branchData.id}`"
|
|
5
5
|
:target-ref="branchData.id"
|
|
6
6
|
:title="btnTitle || $t('text.place_holder.for_title_btn_progress')"
|
|
@@ -17,11 +17,13 @@
|
|
|
17
17
|
<svg v-if="branchData.state != status.COMPLETE">
|
|
18
18
|
<use href="#navigate-next-icon"></use>
|
|
19
19
|
</svg>
|
|
20
|
-
</button>
|
|
20
|
+
</app-base-button>
|
|
21
21
|
</div>
|
|
22
22
|
</template>
|
|
23
23
|
<script>
|
|
24
|
+
import AppBaseButton from './AppBaseButton.vue'
|
|
24
25
|
export default {
|
|
26
|
+
components: { AppBaseButton },
|
|
25
27
|
props: {
|
|
26
28
|
mini: {
|
|
27
29
|
type: Boolean,
|
|
@@ -63,7 +65,6 @@ export default {
|
|
|
63
65
|
},
|
|
64
66
|
|
|
65
67
|
created() {
|
|
66
|
-
// if (isNaN(this.percent)) this.percent = 0
|
|
67
68
|
this.$bus.$on('branching-hidden', this.resetIsActive)
|
|
68
69
|
},
|
|
69
70
|
|
|
@@ -98,12 +99,6 @@ export default {
|
|
|
98
99
|
.button-progress-wrapper {
|
|
99
100
|
&:not(.card-btn) {
|
|
100
101
|
.branch-btn-default {
|
|
101
|
-
// left: 4px;
|
|
102
|
-
// top: 4px;
|
|
103
|
-
// min-width: 42px;
|
|
104
|
-
// min-height: 42px;
|
|
105
|
-
right: 15px !important;
|
|
106
|
-
top: -15px !important;
|
|
107
102
|
min-width: 42px;
|
|
108
103
|
min-height: 42px;
|
|
109
104
|
}
|
|
@@ -3,82 +3,95 @@
|
|
|
3
3
|
@ What it does: Create an html element including an array of slides. These slides are objects including required property (imgSrc) and optional properties (imgAlt, Title, Hypertext).
|
|
4
4
|
-->
|
|
5
5
|
|
|
6
|
-
<template>
|
|
6
|
+
<template v-if="slides">
|
|
7
7
|
<section id="carousel" :aria-label="$t('text.carousel')">
|
|
8
|
-
<
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
next: currentSlide <= index
|
|
18
|
-
}"
|
|
19
|
-
role="group"
|
|
20
|
-
:aria-hidden="!(currentSlide == index + 1)"
|
|
21
|
-
>
|
|
22
|
-
<span class="sr-only">
|
|
23
|
-
{{
|
|
24
|
-
$t('text.slide') +
|
|
25
|
-
' ' +
|
|
26
|
-
(index + 1) +
|
|
27
|
-
' ' +
|
|
28
|
-
$t('text.of') +
|
|
29
|
-
' ' +
|
|
30
|
-
slideLength
|
|
31
|
-
}}
|
|
32
|
-
</span>
|
|
8
|
+
<app-base-error-display
|
|
9
|
+
v-if="errorsSlider.length"
|
|
10
|
+
:error-group="'component'"
|
|
11
|
+
:error-title="'ERREUR: CRÉATION CAROUSEL'"
|
|
12
|
+
:errors-list="errorsSlider"
|
|
13
|
+
></app-base-error-display>
|
|
14
|
+
<template v-else>
|
|
15
|
+
<div class="carousel-inner">
|
|
16
|
+
<div id="mycarousel-slides" class="carousel-slides" aria-live="polite">
|
|
33
17
|
<div
|
|
34
|
-
|
|
35
|
-
:
|
|
18
|
+
v-for="(slide, index) in slides"
|
|
19
|
+
:key="index"
|
|
20
|
+
class="carousel-slide"
|
|
21
|
+
:class="{
|
|
22
|
+
current: currentSlide == index + 1,
|
|
23
|
+
prev: currentSlide >= index + 2,
|
|
24
|
+
next: currentSlide <= index
|
|
25
|
+
}"
|
|
26
|
+
role="group"
|
|
27
|
+
:aria-hidden="!(currentSlide == index + 1)"
|
|
36
28
|
>
|
|
37
|
-
<
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
29
|
+
<span class="sr-only">
|
|
30
|
+
{{
|
|
31
|
+
$t('text.slide') +
|
|
32
|
+
' ' +
|
|
33
|
+
(index + 1) +
|
|
34
|
+
' ' +
|
|
35
|
+
$t('text.of') +
|
|
36
|
+
' ' +
|
|
37
|
+
slideLength
|
|
38
|
+
}}
|
|
39
|
+
</span>
|
|
40
|
+
<div
|
|
41
|
+
class="carousel-image"
|
|
42
|
+
:class="{ 'full-width': !(slide.title || slide.hypertext) }"
|
|
43
|
+
>
|
|
44
|
+
<img
|
|
45
|
+
:src="slide.imgSrc"
|
|
46
|
+
:alt="slide.imgAlt"
|
|
47
|
+
:aria-hidden="
|
|
48
|
+
slide.imgAlt == ' ' || !slide.imgAlt ? true : false
|
|
49
|
+
"
|
|
50
|
+
/>
|
|
51
|
+
</div>
|
|
52
|
+
<div v-if="slide.title || slide.hypertext" class="carousel-text">
|
|
53
|
+
<h3 v-if="slide.title">
|
|
54
|
+
{{ slide.title }}
|
|
55
|
+
</h3>
|
|
56
|
+
<div v-html="slide.hypertext"></div>
|
|
57
|
+
</div>
|
|
48
58
|
</div>
|
|
49
59
|
</div>
|
|
60
|
+
|
|
61
|
+
<div class="carousel-controls">
|
|
62
|
+
<app-base-button
|
|
63
|
+
id="carousel-btn-prev"
|
|
64
|
+
class="carousel-btn"
|
|
65
|
+
:aria-label="$t('button.carousel_prev')"
|
|
66
|
+
aria-controls="mycarousel-slides"
|
|
67
|
+
:title="$t('button.carousel_prev')"
|
|
68
|
+
:aria-disabled="disablePrev"
|
|
69
|
+
:is-disabled="disablePrev"
|
|
70
|
+
:disabled="disablePrev"
|
|
71
|
+
@click="prevSlide()"
|
|
72
|
+
>
|
|
73
|
+
<svg>
|
|
74
|
+
<use href="#fleche-gauche-icon"></use>
|
|
75
|
+
</svg>
|
|
76
|
+
</app-base-button>
|
|
77
|
+
<app-base-button
|
|
78
|
+
id="carousel-btn-next"
|
|
79
|
+
class="carousel-btn"
|
|
80
|
+
:aria-label="$t('button.carousel_next')"
|
|
81
|
+
aria-controls="mycarousel-slides"
|
|
82
|
+
:title="$t('button.carousel_next')"
|
|
83
|
+
:aria-disabled="disableNext"
|
|
84
|
+
:is-disabled="disableNext"
|
|
85
|
+
:disabled="disableNext"
|
|
86
|
+
@click="nextSlide()"
|
|
87
|
+
>
|
|
88
|
+
<svg>
|
|
89
|
+
<use href="#fleche-droite-icon"></use>
|
|
90
|
+
</svg>
|
|
91
|
+
</app-base-button>
|
|
92
|
+
</div>
|
|
50
93
|
</div>
|
|
51
|
-
|
|
52
|
-
<app-base-button
|
|
53
|
-
id="carousel-btn-prev"
|
|
54
|
-
class="carousel-btn"
|
|
55
|
-
:aria-label="$t('button.carousel_prev')"
|
|
56
|
-
aria-controls="mycarousel-slides"
|
|
57
|
-
:title="$t('button.carousel_prev')"
|
|
58
|
-
:disabled="disablePrev"
|
|
59
|
-
:aria-disabled="disablePrev"
|
|
60
|
-
@click="prevSlide()"
|
|
61
|
-
>
|
|
62
|
-
<svg>
|
|
63
|
-
<use href="#fleche-gauche-icon"></use>
|
|
64
|
-
</svg>
|
|
65
|
-
</app-base-button>
|
|
66
|
-
<app-base-button
|
|
67
|
-
id="carousel-btn-next"
|
|
68
|
-
class="carousel-btn"
|
|
69
|
-
:aria-label="$t('button.carousel_next')"
|
|
70
|
-
aria-controls="mycarousel-slides"
|
|
71
|
-
:title="$t('button.carousel_next')"
|
|
72
|
-
:disabled="disableNext"
|
|
73
|
-
:aria-disabled="disableNext"
|
|
74
|
-
@click="nextSlide()"
|
|
75
|
-
>
|
|
76
|
-
<svg>
|
|
77
|
-
<use href="#fleche-droite-icon"></use>
|
|
78
|
-
</svg>
|
|
79
|
-
</app-base-button>
|
|
80
|
-
</div>
|
|
81
|
-
</div>
|
|
94
|
+
</template>
|
|
82
95
|
<div class="carousel-index">
|
|
83
96
|
<p aria-hidden="true">{{ currentSlide }}/{{ slideLength }}</p>
|
|
84
97
|
</div>
|
|
@@ -86,16 +99,20 @@
|
|
|
86
99
|
</template>
|
|
87
100
|
|
|
88
101
|
<script>
|
|
102
|
+
import AppBaseErrorDisplay from './AppBaseErrorDisplay.vue'
|
|
89
103
|
export default {
|
|
90
104
|
name: 'AppCompSlider',
|
|
105
|
+
components: { AppBaseErrorDisplay },
|
|
91
106
|
props: {
|
|
92
|
-
slides: { type: Array, required: true } //Array of slides {imgSrc, imgAlt, title, hypertext}
|
|
107
|
+
slides: { type: Array, required: true }, //Array of slides {imgSrc, imgAlt, title, hypertext}
|
|
108
|
+
name: { type: String, default: 'toto cool' }
|
|
93
109
|
},
|
|
94
110
|
data() {
|
|
95
111
|
return {
|
|
96
|
-
currentSlide:
|
|
112
|
+
currentSlide: null, //Slide management
|
|
97
113
|
requiredProperties: ['imgSrc'], //For slides validation
|
|
98
|
-
optionalProperties: ['title', 'imgAlt', 'hypertext'] //For slides validation
|
|
114
|
+
optionalProperties: ['title', 'imgAlt', 'hypertext'], //For slides validation
|
|
115
|
+
errorsSlider: []
|
|
99
116
|
}
|
|
100
117
|
},
|
|
101
118
|
computed: {
|
|
@@ -106,26 +123,14 @@ export default {
|
|
|
106
123
|
return !(this.currentSlide < this.slideLength)
|
|
107
124
|
},
|
|
108
125
|
slideLength() {
|
|
109
|
-
return this.slides.length
|
|
126
|
+
return this.slides ? this.slides.length : 0
|
|
110
127
|
}
|
|
111
128
|
},
|
|
129
|
+
created() {
|
|
130
|
+
this.currentSlide = this.slides && this.slides.length ? 1 : 0
|
|
131
|
+
},
|
|
112
132
|
mounted() {
|
|
113
|
-
|
|
114
|
-
if (Array.isArray(this.slides) && this.slideLength > 0) {
|
|
115
|
-
//Validate properties for all the slides
|
|
116
|
-
for (const slide of this.slides) {
|
|
117
|
-
this.validateProperties(
|
|
118
|
-
this.requiredProperties,
|
|
119
|
-
this.optionalProperties,
|
|
120
|
-
slide
|
|
121
|
-
)
|
|
122
|
-
}
|
|
123
|
-
} else {
|
|
124
|
-
console.warn(
|
|
125
|
-
`%c WARNING!>>> AppCompSlider : slides must be an array of at least one item`,
|
|
126
|
-
'background: orange; color: white; display: block; margin:5px;'
|
|
127
|
-
)
|
|
128
|
-
}
|
|
133
|
+
this.validateCarousel()
|
|
129
134
|
},
|
|
130
135
|
methods: {
|
|
131
136
|
prevSlide() {
|
|
@@ -138,6 +143,27 @@ export default {
|
|
|
138
143
|
this.currentSlide++
|
|
139
144
|
}
|
|
140
145
|
},
|
|
146
|
+
validateCarousel() {
|
|
147
|
+
//Validating slides
|
|
148
|
+
|
|
149
|
+
if (Array.isArray(this.slides) && this.slideLength > 0) {
|
|
150
|
+
//Validate properties for all the slides
|
|
151
|
+
for (const slide of this.slides) {
|
|
152
|
+
this.validateProperties(
|
|
153
|
+
this.requiredProperties,
|
|
154
|
+
this.optionalProperties,
|
|
155
|
+
slide
|
|
156
|
+
)
|
|
157
|
+
}
|
|
158
|
+
} else {
|
|
159
|
+
let msg = `Le corrousel doit avoit au moins un element.`
|
|
160
|
+
this.errorsSlider.push(msg)
|
|
161
|
+
console.warn(
|
|
162
|
+
`%c WARNING!>>> AppCompSlider : slides must be an array of at least one item`,
|
|
163
|
+
'background: orange; color: white; display: block; margin:5px;'
|
|
164
|
+
)
|
|
165
|
+
}
|
|
166
|
+
},
|
|
141
167
|
//Validate the properties of a specific object (currentObject)
|
|
142
168
|
validateProperties(requiredProperties, optionalProperties, currentObject) {
|
|
143
169
|
let allProperties = requiredProperties.concat(optionalProperties)
|
|
@@ -154,6 +180,8 @@ export default {
|
|
|
154
180
|
`%c WARNING!>>> AppCompSlider : slides ${wrongProperties} invalid. Required properties: ${requiredProperties} . Optional properties: ${optionalProperties}`,
|
|
155
181
|
'background: orange; color: white; display: block; margin:5px;'
|
|
156
182
|
)
|
|
183
|
+
let msg = `Attribut(s) invalide(s): <i>${wrongProperties}</i> . Consultez la console pour plus de details.`
|
|
184
|
+
this.errorsSlider.push(msg)
|
|
157
185
|
}
|
|
158
186
|
//Validate if all required properties are present in currentObject
|
|
159
187
|
if (missingRequired.length > 0) {
|
|
@@ -161,6 +189,8 @@ export default {
|
|
|
161
189
|
`%c WARNING!>>> AppCompQuizSlider : slides missing required ${missingRequired} property. Required properties: ${requiredProperties} . Optional properties: ${optionalProperties}`,
|
|
162
190
|
'background: orange; color: white; display: block; margin:5px;'
|
|
163
191
|
)
|
|
192
|
+
let msg = `Une/certaines propriété(s) sont manquante(s). Consultez la console pour plus de details.`
|
|
193
|
+
this.errorsSlider.push(msg)
|
|
164
194
|
}
|
|
165
195
|
},
|
|
166
196
|
//Get all the invalids properties from the object
|
|
@@ -22,9 +22,12 @@
|
|
|
22
22
|
:id="inputDataId + '_' + singleDropdown.id"
|
|
23
23
|
v-model="quizInputTypeValue[singleDropdown.id]"
|
|
24
24
|
item-title="text"
|
|
25
|
+
:item-props="true"
|
|
25
26
|
:items="singleDropdown.option"
|
|
26
27
|
:disabled="quizLimitActive"
|
|
27
|
-
|
|
28
|
+
:open-text="$t('message.dropdown_list') + ' ' + singleDropdown.ennonce"
|
|
29
|
+
close-text=""
|
|
30
|
+
></v-select>
|
|
28
31
|
</div>
|
|
29
32
|
</div>
|
|
30
33
|
</template>
|
|
@@ -124,17 +127,15 @@ export default {
|
|
|
124
127
|
const defaultAnswer = {
|
|
125
128
|
value: null,
|
|
126
129
|
disabled: true,
|
|
127
|
-
text: this.$t('message.first_option_dropdown')
|
|
130
|
+
text: this.$t('message.first_option_dropdown'),
|
|
131
|
+
selected: true
|
|
128
132
|
}
|
|
129
133
|
let selectedChoices = []
|
|
130
134
|
for (let i = 0; i < this.inputData.length; i++) {
|
|
131
|
-
let singleDropdown
|
|
132
|
-
if (this.shuffleAnswers)
|
|
133
|
-
singleDropdown = this.inputData[i]
|
|
135
|
+
let singleDropdown = this.inputData[i]
|
|
136
|
+
if (this.shuffleAnswers)
|
|
134
137
|
singleDropdown.option = this.shuffleArray(singleDropdown.option)
|
|
135
|
-
|
|
136
|
-
singleDropdown = this.inputData[i]
|
|
137
|
-
}
|
|
138
|
+
|
|
138
139
|
if (
|
|
139
140
|
this.inputData[i].option[0].text !==
|
|
140
141
|
this.$t('message.first_option_dropdown')
|
|
@@ -156,4 +157,45 @@ export default {
|
|
|
156
157
|
.dropdown-container {
|
|
157
158
|
position: relative;
|
|
158
159
|
}
|
|
160
|
+
|
|
161
|
+
.texteatrou {
|
|
162
|
+
display: inline !important;
|
|
163
|
+
.cnt-input {
|
|
164
|
+
display: inline;
|
|
165
|
+
|
|
166
|
+
.v-input {
|
|
167
|
+
display: inline-block !important;
|
|
168
|
+
|
|
169
|
+
.v-input__control,
|
|
170
|
+
.v-field {
|
|
171
|
+
width: 240px !important;
|
|
172
|
+
grid-area: inherit !important;
|
|
173
|
+
|
|
174
|
+
.v-field__field {
|
|
175
|
+
height: 25px !important;
|
|
176
|
+
padding: 0 !important;
|
|
177
|
+
min-height: inherit !important;
|
|
178
|
+
|
|
179
|
+
.v-field__input {
|
|
180
|
+
padding-top: 0 !important;
|
|
181
|
+
padding-bottom: 0 !important;
|
|
182
|
+
min-height: inherit !important;
|
|
183
|
+
|
|
184
|
+
.v-select__selection {
|
|
185
|
+
min-height: inherit !important;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
.v-field__append-inner {
|
|
191
|
+
margin-right: 6px;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
.v-input__details {
|
|
196
|
+
display: none;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
159
201
|
</style>
|
|
@@ -100,7 +100,26 @@ export default {
|
|
|
100
100
|
}
|
|
101
101
|
}
|
|
102
102
|
</script>
|
|
103
|
-
<style>
|
|
104
|
-
.
|
|
103
|
+
<style lang="scss">
|
|
104
|
+
.quiz-texte-troue {
|
|
105
|
+
.texteatrou {
|
|
106
|
+
.v-input {
|
|
107
|
+
display: inline-block !important;
|
|
108
|
+
width: 150px;
|
|
109
|
+
|
|
110
|
+
.v-field {
|
|
111
|
+
height: 25px;
|
|
112
|
+
|
|
113
|
+
input {
|
|
114
|
+
padding: 0 24px;
|
|
115
|
+
min-height: 25px !important;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.v-input__details {
|
|
120
|
+
display: none;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
105
124
|
}
|
|
106
125
|
</style>
|
|
@@ -30,8 +30,11 @@
|
|
|
30
30
|
item-title="text"
|
|
31
31
|
class="dropdown"
|
|
32
32
|
:items="singleDropdown.option"
|
|
33
|
+
:item-props="true"
|
|
33
34
|
:disabled="quizLimitActive"
|
|
34
35
|
:aria-describedby="`${inputDataId}_${singleDropdown.id}-msg-erreur`"
|
|
36
|
+
:open-text="$t('message.dropdown_list')"
|
|
37
|
+
close-text=""
|
|
35
38
|
/>
|
|
36
39
|
</div>
|
|
37
40
|
|
|
@@ -163,16 +166,20 @@ export default {
|
|
|
163
166
|
const defaultAnswer = {
|
|
164
167
|
value: null,
|
|
165
168
|
disabled: true,
|
|
169
|
+
selected: true,
|
|
166
170
|
text: this.$t('message.first_option_dropdown')
|
|
167
171
|
}
|
|
168
172
|
let selectedChoices = []
|
|
173
|
+
|
|
169
174
|
for (let i = 0; i < this.inputData.length; i++) {
|
|
170
175
|
let singleDropdown = {}
|
|
171
176
|
if (this.shuffleAnswers) {
|
|
172
177
|
singleDropdown = this.inputData[i]
|
|
178
|
+
|
|
173
179
|
singleDropdown[Object.keys(this.inputData[i])[0].toString()] =
|
|
174
180
|
this.shuffleArray(Object.values(this.inputData[i])[0])
|
|
175
181
|
} else {
|
|
182
|
+
// this.inputData[i].splice(0, 0, defaultAnswer)
|
|
176
183
|
singleDropdown = this.inputData[i]
|
|
177
184
|
}
|
|
178
185
|
for (
|
|
@@ -188,6 +195,7 @@ export default {
|
|
|
188
195
|
Object.values(singleDropdown)[0].splice(index, 1)
|
|
189
196
|
}
|
|
190
197
|
}
|
|
198
|
+
|
|
191
199
|
Object.values(singleDropdown)[0].unshift(defaultAnswer)
|
|
192
200
|
|
|
193
201
|
selectedChoices.push(null)
|