fcad-core-dragon 2.0.0-beta.3 → 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/.editorconfig +33 -33
- package/.eslintignore +29 -29
- package/.eslintrc.cjs +81 -81
- package/CHANGELOG +13 -0
- package/README.md +71 -71
- package/bk.scss +117 -117
- package/package.json +8 -8
- package/src/$locales/en.json +145 -143
- package/src/$locales/fr.json +107 -105
- package/src/assets/data/onboardingMessages.json +47 -47
- package/src/components/AppBase.vue +1150 -1054
- package/src/components/AppBaseButton.test.js +22 -0
- package/src/components/AppBaseButton.vue +93 -87
- package/src/components/AppBaseErrorDisplay.vue +438 -438
- package/src/components/AppBaseFlipCard.vue +84 -84
- package/src/components/AppBaseModule.vue +1657 -1673
- package/src/components/AppBasePage.vue +742 -779
- package/src/components/AppBasePopover.vue +41 -41
- package/src/components/AppCompAudio.vue +265 -234
- package/src/components/AppCompBranchButtons.vue +556 -552
- package/src/components/AppCompButtonProgress.vue +121 -126
- package/src/components/AppCompCarousel.vue +328 -298
- package/src/components/AppCompInputCheckBoxNext.vue +200 -195
- package/src/components/AppCompInputDropdownNext.vue +201 -159
- package/src/components/AppCompInputRadioNext.vue +152 -152
- package/src/components/AppCompInputTextNext.vue +125 -106
- package/src/components/AppCompInputTextTableNext.vue +142 -141
- package/src/components/AppCompInputTextToFillDropdownNext.vue +238 -230
- package/src/components/AppCompInputTextToFillNext.vue +171 -171
- package/src/components/AppCompJauge.vue +74 -74
- package/src/components/AppCompMenu.vue +25 -10
- package/src/components/AppCompMenuItem.vue +228 -228
- package/src/components/AppCompNavigation.vue +972 -960
- package/src/components/AppCompNoteCall.vue +159 -133
- package/src/components/AppCompNoteCredit.vue +490 -292
- package/src/components/AppCompPlayBar.vue +1217 -1218
- package/src/components/AppCompPlayBarNext.vue +2060 -2052
- package/src/components/AppCompPlayBarProgress.vue +82 -82
- package/src/components/AppCompPopUpNext.vue +500 -503
- package/src/components/AppCompQuizNext.vue +2908 -2904
- package/src/components/AppCompQuizRecall.vue +298 -276
- package/src/components/AppCompSVGNext.vue +347 -347
- package/src/components/AppCompSettingsMenu.vue +172 -172
- package/src/components/AppCompTableOfContent.vue +386 -387
- package/src/components/AppCompTranscript.vue +24 -24
- package/src/components/AppCompVideoPlayer.vue +368 -368
- package/src/components/BaseModule.vue +55 -72
- package/src/components/tests__/AppBaseButton.spec.js +53 -0
- 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 +272 -272
- package/src/mixins/$mediaMixins.js +819 -819
- package/src/mixins/timerMixin.js +155 -155
- package/src/module/stores/appStore.js +954 -893
- package/src/module/xapi/ADL.js +380 -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/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/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 -8
- package/src/plugins/gsap.js +14 -14
- package/src/plugins/helper.js +355 -308
- package/src/plugins/i18n.js +44 -44
- package/src/plugins/idb.js +227 -219
- 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 +48 -43
- package/src/router/routes.js +312 -312
- package/src/shared/generalfuncs.js +210 -210
- package/src/shared/validators.js +926 -1069
- package/vitest.config.js +19 -0
- package/vite.config.js +0 -27
|
@@ -1,171 +1,171 @@
|
|
|
1
|
-
<!-- About this Component--
|
|
2
|
-
* Renders a Series of inputs to collect input for the Quiz component.
|
|
3
|
-
* Related Quiz to question: TEXTE_TROUE
|
|
4
|
-
* Receives the a data object defined by user
|
|
5
|
-
* Used by AppCompQuizNext
|
|
6
|
-
* Uses useQuiz composable
|
|
7
|
-
-->
|
|
8
|
-
<template>
|
|
9
|
-
<div class="input-box">
|
|
10
|
-
<div
|
|
11
|
-
v-for="textInput in theInputData"
|
|
12
|
-
:key="textInput.id"
|
|
13
|
-
class="texteatrou"
|
|
14
|
-
>
|
|
15
|
-
<span v-if="!textInput.type" v-html="textInput.content"></span>
|
|
16
|
-
<label
|
|
17
|
-
:for="`${inputDataId}_${textInput.id}-champ`"
|
|
18
|
-
style="display: none"
|
|
19
|
-
>
|
|
20
|
-
{{ $t('text.quiz') }}
|
|
21
|
-
</label>
|
|
22
|
-
<v-text-field
|
|
23
|
-
v-if="textInput.type == 'inputText'"
|
|
24
|
-
:id="`${inputDataId}_${textInput.id}-champ`"
|
|
25
|
-
v-model="quizInputTypeValue[textInput.id]"
|
|
26
|
-
:placeholder="$t('text.place_holder.for_textarea')"
|
|
27
|
-
:disabled="quizLimitActive"
|
|
28
|
-
no-resize
|
|
29
|
-
:class="classInput(textInput.id, quizInputTypeValue)"
|
|
30
|
-
class="input-textatrou"
|
|
31
|
-
:aria-describedby="`${inputDataId}_${textInput.id}-msg-erreur`"
|
|
32
|
-
:aria-labelledby="`${inputDataId}_${textInput.id}-label`"
|
|
33
|
-
/>
|
|
34
|
-
<span :id="`${inputDataId}_${textInput.id}-msg-erreur`" class="sr-only">
|
|
35
|
-
{{ messageAccessibility(textInput.id, quizInputTypeValue) }}
|
|
36
|
-
</span>
|
|
37
|
-
</div>
|
|
38
|
-
</div>
|
|
39
|
-
</template>
|
|
40
|
-
<script>
|
|
41
|
-
import { useQuiz } from '../composables/useQuiz'
|
|
42
|
-
import { toRefs } from 'vue'
|
|
43
|
-
export default {
|
|
44
|
-
name: 'AppCompInputTextToFillNext',
|
|
45
|
-
props: {
|
|
46
|
-
quizType: {
|
|
47
|
-
type: String,
|
|
48
|
-
default: ''
|
|
49
|
-
},
|
|
50
|
-
inputDataId: {
|
|
51
|
-
type: String,
|
|
52
|
-
default: ''
|
|
53
|
-
},
|
|
54
|
-
inputData: {
|
|
55
|
-
type: Array,
|
|
56
|
-
default: () => []
|
|
57
|
-
},
|
|
58
|
-
inputType: {
|
|
59
|
-
type: String,
|
|
60
|
-
default: ''
|
|
61
|
-
},
|
|
62
|
-
textBase: {
|
|
63
|
-
type: String,
|
|
64
|
-
default: ''
|
|
65
|
-
},
|
|
66
|
-
quizInputType: {
|
|
67
|
-
type: Array,
|
|
68
|
-
default: () => []
|
|
69
|
-
},
|
|
70
|
-
solution: {
|
|
71
|
-
type: Array,
|
|
72
|
-
default: () => []
|
|
73
|
-
},
|
|
74
|
-
showSolution: {
|
|
75
|
-
type: Boolean,
|
|
76
|
-
default: false
|
|
77
|
-
},
|
|
78
|
-
quizLimitActive: {
|
|
79
|
-
type: Boolean,
|
|
80
|
-
default: false
|
|
81
|
-
}, //use to set if quiz should be active or not
|
|
82
|
-
quizSubmit: {
|
|
83
|
-
type: Boolean,
|
|
84
|
-
default: false
|
|
85
|
-
} //use to call a submit
|
|
86
|
-
},
|
|
87
|
-
emits: ['input-change'],
|
|
88
|
-
setup(props) {
|
|
89
|
-
const { shuffleArray, classInput, messageAccessibility } = useQuiz(
|
|
90
|
-
toRefs(props)
|
|
91
|
-
)
|
|
92
|
-
return { shuffleArray, classInput, messageAccessibility }
|
|
93
|
-
},
|
|
94
|
-
data() {
|
|
95
|
-
return {
|
|
96
|
-
quizInputTypeValue: [], //not using quizInputType because quizInputType is a prop
|
|
97
|
-
theInputData: [], //to create the list of drop down and text mixed togeter
|
|
98
|
-
quizSolution: null
|
|
99
|
-
}
|
|
100
|
-
},
|
|
101
|
-
|
|
102
|
-
watch: {
|
|
103
|
-
/**
|
|
104
|
-
* @description to pass value to AppCompQuiz
|
|
105
|
-
* @fires input-change to AppCompQuiz.vue
|
|
106
|
-
*/
|
|
107
|
-
quizInputTypeValue: {
|
|
108
|
-
deep: true,
|
|
109
|
-
handler(newValue) {
|
|
110
|
-
this.$emit('input-change', newValue)
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
},
|
|
114
|
-
|
|
115
|
-
mounted() {
|
|
116
|
-
this.initQuiz()
|
|
117
|
-
},
|
|
118
|
-
|
|
119
|
-
methods: {
|
|
120
|
-
initQuiz() {
|
|
121
|
-
this.quizSolution = this.solution
|
|
122
|
-
if (this.quizSolution !== null) {
|
|
123
|
-
this.quizSolution.sort(function (a, b) {
|
|
124
|
-
return a - b
|
|
125
|
-
})
|
|
126
|
-
}
|
|
127
|
-
let textChoices = []
|
|
128
|
-
|
|
129
|
-
const regex = /\$%\S*%\$/g // regex pattern to match exp: $%number%$
|
|
130
|
-
let matchAll = this.textBase.split(regex)
|
|
131
|
-
|
|
132
|
-
for (let i = 0; i < matchAll.length - 1; i++) {
|
|
133
|
-
textChoices.push('')
|
|
134
|
-
}
|
|
135
|
-
//apply previous answers
|
|
136
|
-
if (this.quizInputType && this.quizInputType.length == 0) {
|
|
137
|
-
this.quizInputTypeValue = textChoices
|
|
138
|
-
} else {
|
|
139
|
-
this.quizInputTypeValue = this.quizInputType
|
|
140
|
-
}
|
|
141
|
-
this.createTextWithInput(this.textBase)
|
|
142
|
-
},
|
|
143
|
-
/**
|
|
144
|
-
* @description create the object to genate the text and inputs
|
|
145
|
-
* @param {String} str the text with holes to fill
|
|
146
|
-
*/
|
|
147
|
-
createTextWithInput(str) {
|
|
148
|
-
const regex = /\$%\S*%\$/g // regex pattern to match exp: $%number%$
|
|
149
|
-
let matchAll = str.split(regex)
|
|
150
|
-
let listInput = []
|
|
151
|
-
for (let i = 0; i < matchAll.length - 1; i++) {
|
|
152
|
-
listInput.push({ id: 't' + i, content: matchAll[i] })
|
|
153
|
-
listInput.push({ id: i, type: 'inputText' })
|
|
154
|
-
}
|
|
155
|
-
let lastItem = matchAll.length - 1
|
|
156
|
-
listInput.push({ id: 't' + lastItem, content: matchAll[lastItem] })
|
|
157
|
-
this.theInputData = listInput
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
</script>
|
|
162
|
-
<style lang="scss" scoped>
|
|
163
|
-
.texteatrou {
|
|
164
|
-
display: inline;
|
|
165
|
-
position: relative;
|
|
166
|
-
}
|
|
167
|
-
.texteatrou > input {
|
|
168
|
-
display: inline;
|
|
169
|
-
width: auto;
|
|
170
|
-
}
|
|
171
|
-
</style>
|
|
1
|
+
<!-- About this Component--
|
|
2
|
+
* Renders a Series of inputs to collect input for the Quiz component.
|
|
3
|
+
* Related Quiz to question: TEXTE_TROUE
|
|
4
|
+
* Receives the a data object defined by user
|
|
5
|
+
* Used by AppCompQuizNext
|
|
6
|
+
* Uses useQuiz composable
|
|
7
|
+
-->
|
|
8
|
+
<template>
|
|
9
|
+
<div class="input-box">
|
|
10
|
+
<div
|
|
11
|
+
v-for="textInput in theInputData"
|
|
12
|
+
:key="textInput.id"
|
|
13
|
+
class="texteatrou"
|
|
14
|
+
>
|
|
15
|
+
<span v-if="!textInput.type" v-html="textInput.content"></span>
|
|
16
|
+
<label
|
|
17
|
+
:for="`${inputDataId}_${textInput.id}-champ`"
|
|
18
|
+
style="display: none"
|
|
19
|
+
>
|
|
20
|
+
{{ $t('text.quiz') }}
|
|
21
|
+
</label>
|
|
22
|
+
<v-text-field
|
|
23
|
+
v-if="textInput.type == 'inputText'"
|
|
24
|
+
:id="`${inputDataId}_${textInput.id}-champ`"
|
|
25
|
+
v-model="quizInputTypeValue[textInput.id]"
|
|
26
|
+
:placeholder="$t('text.place_holder.for_textarea')"
|
|
27
|
+
:disabled="quizLimitActive"
|
|
28
|
+
no-resize
|
|
29
|
+
:class="classInput(textInput.id, quizInputTypeValue)"
|
|
30
|
+
class="input-textatrou"
|
|
31
|
+
:aria-describedby="`${inputDataId}_${textInput.id}-msg-erreur`"
|
|
32
|
+
:aria-labelledby="`${inputDataId}_${textInput.id}-label`"
|
|
33
|
+
/>
|
|
34
|
+
<span :id="`${inputDataId}_${textInput.id}-msg-erreur`" class="sr-only">
|
|
35
|
+
{{ messageAccessibility(textInput.id, quizInputTypeValue) }}
|
|
36
|
+
</span>
|
|
37
|
+
</div>
|
|
38
|
+
</div>
|
|
39
|
+
</template>
|
|
40
|
+
<script>
|
|
41
|
+
import { useQuiz } from '../composables/useQuiz'
|
|
42
|
+
import { toRefs } from 'vue'
|
|
43
|
+
export default {
|
|
44
|
+
name: 'AppCompInputTextToFillNext',
|
|
45
|
+
props: {
|
|
46
|
+
quizType: {
|
|
47
|
+
type: String,
|
|
48
|
+
default: ''
|
|
49
|
+
},
|
|
50
|
+
inputDataId: {
|
|
51
|
+
type: String,
|
|
52
|
+
default: ''
|
|
53
|
+
},
|
|
54
|
+
inputData: {
|
|
55
|
+
type: Array,
|
|
56
|
+
default: () => []
|
|
57
|
+
},
|
|
58
|
+
inputType: {
|
|
59
|
+
type: String,
|
|
60
|
+
default: ''
|
|
61
|
+
},
|
|
62
|
+
textBase: {
|
|
63
|
+
type: String,
|
|
64
|
+
default: ''
|
|
65
|
+
},
|
|
66
|
+
quizInputType: {
|
|
67
|
+
type: Array,
|
|
68
|
+
default: () => []
|
|
69
|
+
},
|
|
70
|
+
solution: {
|
|
71
|
+
type: Array,
|
|
72
|
+
default: () => []
|
|
73
|
+
},
|
|
74
|
+
showSolution: {
|
|
75
|
+
type: Boolean,
|
|
76
|
+
default: false
|
|
77
|
+
},
|
|
78
|
+
quizLimitActive: {
|
|
79
|
+
type: Boolean,
|
|
80
|
+
default: false
|
|
81
|
+
}, //use to set if quiz should be active or not
|
|
82
|
+
quizSubmit: {
|
|
83
|
+
type: Boolean,
|
|
84
|
+
default: false
|
|
85
|
+
} //use to call a submit
|
|
86
|
+
},
|
|
87
|
+
emits: ['input-change'],
|
|
88
|
+
setup(props) {
|
|
89
|
+
const { shuffleArray, classInput, messageAccessibility } = useQuiz(
|
|
90
|
+
toRefs(props)
|
|
91
|
+
)
|
|
92
|
+
return { shuffleArray, classInput, messageAccessibility }
|
|
93
|
+
},
|
|
94
|
+
data() {
|
|
95
|
+
return {
|
|
96
|
+
quizInputTypeValue: [], //not using quizInputType because quizInputType is a prop
|
|
97
|
+
theInputData: [], //to create the list of drop down and text mixed togeter
|
|
98
|
+
quizSolution: null
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
|
|
102
|
+
watch: {
|
|
103
|
+
/**
|
|
104
|
+
* @description to pass value to AppCompQuiz
|
|
105
|
+
* @fires input-change to AppCompQuiz.vue
|
|
106
|
+
*/
|
|
107
|
+
quizInputTypeValue: {
|
|
108
|
+
deep: true,
|
|
109
|
+
handler(newValue) {
|
|
110
|
+
this.$emit('input-change', newValue)
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
|
|
115
|
+
mounted() {
|
|
116
|
+
this.initQuiz()
|
|
117
|
+
},
|
|
118
|
+
|
|
119
|
+
methods: {
|
|
120
|
+
initQuiz() {
|
|
121
|
+
this.quizSolution = this.solution
|
|
122
|
+
if (this.quizSolution !== null) {
|
|
123
|
+
this.quizSolution.sort(function (a, b) {
|
|
124
|
+
return a - b
|
|
125
|
+
})
|
|
126
|
+
}
|
|
127
|
+
let textChoices = []
|
|
128
|
+
|
|
129
|
+
const regex = /\$%\S*%\$/g // regex pattern to match exp: $%number%$
|
|
130
|
+
let matchAll = this.textBase.split(regex)
|
|
131
|
+
|
|
132
|
+
for (let i = 0; i < matchAll.length - 1; i++) {
|
|
133
|
+
textChoices.push('')
|
|
134
|
+
}
|
|
135
|
+
//apply previous answers
|
|
136
|
+
if (this.quizInputType && this.quizInputType.length == 0) {
|
|
137
|
+
this.quizInputTypeValue = textChoices
|
|
138
|
+
} else {
|
|
139
|
+
this.quizInputTypeValue = this.quizInputType
|
|
140
|
+
}
|
|
141
|
+
this.createTextWithInput(this.textBase)
|
|
142
|
+
},
|
|
143
|
+
/**
|
|
144
|
+
* @description create the object to genate the text and inputs
|
|
145
|
+
* @param {String} str the text with holes to fill
|
|
146
|
+
*/
|
|
147
|
+
createTextWithInput(str) {
|
|
148
|
+
const regex = /\$%\S*%\$/g // regex pattern to match exp: $%number%$
|
|
149
|
+
let matchAll = str.split(regex)
|
|
150
|
+
let listInput = []
|
|
151
|
+
for (let i = 0; i < matchAll.length - 1; i++) {
|
|
152
|
+
listInput.push({ id: 't' + i, content: matchAll[i] })
|
|
153
|
+
listInput.push({ id: i, type: 'inputText' })
|
|
154
|
+
}
|
|
155
|
+
let lastItem = matchAll.length - 1
|
|
156
|
+
listInput.push({ id: 't' + lastItem, content: matchAll[lastItem] })
|
|
157
|
+
this.theInputData = listInput
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
</script>
|
|
162
|
+
<style lang="scss" scoped>
|
|
163
|
+
.texteatrou {
|
|
164
|
+
display: inline;
|
|
165
|
+
position: relative;
|
|
166
|
+
}
|
|
167
|
+
.texteatrou > input {
|
|
168
|
+
display: inline;
|
|
169
|
+
width: auto;
|
|
170
|
+
}
|
|
171
|
+
</style>
|
|
@@ -1,74 +1,74 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div v-if="!error" class="box-g" :class="state">
|
|
3
|
-
<v-progress-linear
|
|
4
|
-
class="jauge"
|
|
5
|
-
:model-value="value"
|
|
6
|
-
:height="12"
|
|
7
|
-
:max="maxValue"
|
|
8
|
-
aria-hidden="true"
|
|
9
|
-
></v-progress-linear>
|
|
10
|
-
<p class="prcnt">{{ getPourcent }} %</p>
|
|
11
|
-
</div>
|
|
12
|
-
<div v-else>
|
|
13
|
-
<div class="warning">
|
|
14
|
-
<p class="title">Attention</p>
|
|
15
|
-
<p class="info">
|
|
16
|
-
Attention les valeurs que vous donnez au composant ne sont pas des
|
|
17
|
-
nombres.
|
|
18
|
-
</p>
|
|
19
|
-
</div>
|
|
20
|
-
</div>
|
|
21
|
-
</template>
|
|
22
|
-
<script>
|
|
23
|
-
export default {
|
|
24
|
-
props: {
|
|
25
|
-
// props Give value to show progress
|
|
26
|
-
state: {
|
|
27
|
-
type: String,
|
|
28
|
-
default: 'started'
|
|
29
|
-
},
|
|
30
|
-
maxValue: {
|
|
31
|
-
type: Number,
|
|
32
|
-
default: 100
|
|
33
|
-
},
|
|
34
|
-
value: { type: Number, default: 0 },
|
|
35
|
-
pourcent: { type: Boolean, default: false },
|
|
36
|
-
fraction: { type: Boolean, default: false }
|
|
37
|
-
},
|
|
38
|
-
data() {
|
|
39
|
-
return {}
|
|
40
|
-
},
|
|
41
|
-
computed: {
|
|
42
|
-
getPourcent() {
|
|
43
|
-
// Calculate on a 100%
|
|
44
|
-
let result = (this.value * 100) / this.maxValue
|
|
45
|
-
if (result > 100) return 100
|
|
46
|
-
else return Math.round(result)
|
|
47
|
-
},
|
|
48
|
-
error() {
|
|
49
|
-
if (typeof this.value != 'number' || typeof this.maxValue != 'number') {
|
|
50
|
-
return true
|
|
51
|
-
} else {
|
|
52
|
-
return false
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
},
|
|
56
|
-
methods: {}
|
|
57
|
-
}
|
|
58
|
-
</script>
|
|
59
|
-
<style lang="scss">
|
|
60
|
-
.box-g {
|
|
61
|
-
width: 100%;
|
|
62
|
-
display: flex;
|
|
63
|
-
flex-direction: row;
|
|
64
|
-
flex-wrap: wrap;
|
|
65
|
-
|
|
66
|
-
.jauge {
|
|
67
|
-
width: 70%;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
.prcnt {
|
|
71
|
-
margin-left: 10px;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
</style>
|
|
1
|
+
<template>
|
|
2
|
+
<div v-if="!error" class="box-g" :class="state">
|
|
3
|
+
<v-progress-linear
|
|
4
|
+
class="jauge"
|
|
5
|
+
:model-value="value"
|
|
6
|
+
:height="12"
|
|
7
|
+
:max="maxValue"
|
|
8
|
+
aria-hidden="true"
|
|
9
|
+
></v-progress-linear>
|
|
10
|
+
<p class="prcnt">{{ getPourcent }} %</p>
|
|
11
|
+
</div>
|
|
12
|
+
<div v-else>
|
|
13
|
+
<div class="warning">
|
|
14
|
+
<p class="title">Attention</p>
|
|
15
|
+
<p class="info">
|
|
16
|
+
Attention les valeurs que vous donnez au composant ne sont pas des
|
|
17
|
+
nombres.
|
|
18
|
+
</p>
|
|
19
|
+
</div>
|
|
20
|
+
</div>
|
|
21
|
+
</template>
|
|
22
|
+
<script>
|
|
23
|
+
export default {
|
|
24
|
+
props: {
|
|
25
|
+
// props Give value to show progress
|
|
26
|
+
state: {
|
|
27
|
+
type: String,
|
|
28
|
+
default: 'started'
|
|
29
|
+
},
|
|
30
|
+
maxValue: {
|
|
31
|
+
type: Number,
|
|
32
|
+
default: 100
|
|
33
|
+
},
|
|
34
|
+
value: { type: Number, default: 0 },
|
|
35
|
+
pourcent: { type: Boolean, default: false },
|
|
36
|
+
fraction: { type: Boolean, default: false }
|
|
37
|
+
},
|
|
38
|
+
data() {
|
|
39
|
+
return {}
|
|
40
|
+
},
|
|
41
|
+
computed: {
|
|
42
|
+
getPourcent() {
|
|
43
|
+
// Calculate on a 100%
|
|
44
|
+
let result = (this.value * 100) / this.maxValue
|
|
45
|
+
if (result > 100) return 100
|
|
46
|
+
else return Math.round(result)
|
|
47
|
+
},
|
|
48
|
+
error() {
|
|
49
|
+
if (typeof this.value != 'number' || typeof this.maxValue != 'number') {
|
|
50
|
+
return true
|
|
51
|
+
} else {
|
|
52
|
+
return false
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
methods: {}
|
|
57
|
+
}
|
|
58
|
+
</script>
|
|
59
|
+
<style lang="scss">
|
|
60
|
+
.box-g {
|
|
61
|
+
width: 100%;
|
|
62
|
+
display: flex;
|
|
63
|
+
flex-direction: row;
|
|
64
|
+
flex-wrap: wrap;
|
|
65
|
+
|
|
66
|
+
.jauge {
|
|
67
|
+
width: 70%;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.prcnt {
|
|
71
|
+
margin-left: 10px;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
</style>
|
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
<div class="menu-container">
|
|
7
7
|
<div
|
|
8
8
|
id="page_info_section"
|
|
9
|
+
class="sr-only"
|
|
9
10
|
aria-labelledby="page_info"
|
|
10
|
-
aria-live="true"
|
|
11
11
|
></div>
|
|
12
12
|
<a
|
|
13
13
|
class="skip-link"
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
<app-base-button
|
|
57
57
|
:id="`btn-quiz`"
|
|
58
58
|
class="btn lk-btn"
|
|
59
|
-
:is-
|
|
59
|
+
:is-disabled="resetStatus !== false"
|
|
60
60
|
@click="askResetUserData"
|
|
61
61
|
>
|
|
62
62
|
Réinitialiser la leçon
|
|
@@ -78,9 +78,9 @@
|
|
|
78
78
|
</div>
|
|
79
79
|
</v-col>
|
|
80
80
|
</v-row>
|
|
81
|
-
<
|
|
81
|
+
<span id="page_info" class="sr-only" aria-hidden="true">
|
|
82
82
|
{{ $t('text.title_content_view') }}
|
|
83
|
-
</
|
|
83
|
+
</span>
|
|
84
84
|
</div>
|
|
85
85
|
</template>
|
|
86
86
|
<script>
|
|
@@ -105,7 +105,8 @@ export default {
|
|
|
105
105
|
'getModuleInfo',
|
|
106
106
|
'getMenuSettings',
|
|
107
107
|
'getAppDebugMode',
|
|
108
|
-
'getAllCompleted'
|
|
108
|
+
'getAllCompleted',
|
|
109
|
+
'getDataFromServer'
|
|
109
110
|
]),
|
|
110
111
|
appDebugMode() {
|
|
111
112
|
return this.getAppDebugMode
|
|
@@ -129,9 +130,14 @@ export default {
|
|
|
129
130
|
return label
|
|
130
131
|
},
|
|
131
132
|
getLessonid() {
|
|
132
|
-
// ATTENDRE UX*UI poure voir si on garde le concept ou pas
|
|
133
133
|
let lessonLabel = this.$t('text.lesson')
|
|
134
|
-
let lessonId
|
|
134
|
+
let lessonId
|
|
135
|
+
if (this.getMenuSettings.lessonNumber) {
|
|
136
|
+
lessonId = this.getMenuSettings.lessonNumber
|
|
137
|
+
} else {
|
|
138
|
+
lessonId =
|
|
139
|
+
'La variable lessonNumber est introuvable dans menu.setting.js'
|
|
140
|
+
}
|
|
135
141
|
return `${lessonLabel} ${lessonId}`
|
|
136
142
|
},
|
|
137
143
|
getLessonTitle() {
|
|
@@ -165,10 +171,20 @@ export default {
|
|
|
165
171
|
}
|
|
166
172
|
}, 2000)
|
|
167
173
|
},
|
|
174
|
+
// GoToLastRoute() {
|
|
175
|
+
// let lastRoute
|
|
176
|
+
// //Get all activity state (menu not included)
|
|
177
|
+
|
|
178
|
+
// //No route history Should link to introduction route
|
|
179
|
+
// if (!this.getRouteHistory.length) return 'introduction'
|
|
180
|
+
// //last Route should be the last element in route history
|
|
181
|
+
// lastRoute = this.getRouteHistory.toReversed()[0]
|
|
182
|
+
// //create the route link and return it
|
|
183
|
+
// return this.createdRoute(lastRoute)
|
|
184
|
+
// },
|
|
168
185
|
GoToLastRoute() {
|
|
169
186
|
let lastRoute
|
|
170
187
|
let path
|
|
171
|
-
|
|
172
188
|
//Get all activity state (menu not included)
|
|
173
189
|
const { allActivitiesState } = this.progressWithMenu()
|
|
174
190
|
let state = Object.values(allActivitiesState)
|
|
@@ -212,7 +228,7 @@ export default {
|
|
|
212
228
|
activity = newRoute.type
|
|
213
229
|
} else {
|
|
214
230
|
activity =
|
|
215
|
-
newRoute.activity_ref.charAt(1) == '0'
|
|
231
|
+
newRoute.activity_ref && newRoute.activity_ref.charAt(1) == '0'
|
|
216
232
|
? `activite_${newRoute.activity_ref.substring(2)}`
|
|
217
233
|
: `activite_${newRoute.activity_ref.substring(1)}`
|
|
218
234
|
}
|
|
@@ -223,7 +239,6 @@ export default {
|
|
|
223
239
|
|
|
224
240
|
//Define path
|
|
225
241
|
path = page !== ' ' ? `${activity}.page_${page}` : activity
|
|
226
|
-
|
|
227
242
|
return path
|
|
228
243
|
},
|
|
229
244
|
progressWithMenu() {
|