fcad-core-dragon 2.0.0-beta.1 → 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.js → .eslintrc.cjs} +81 -86
- package/CHANGELOG +364 -364
- package/README.md +71 -71
- package/bk.scss +117 -0
- package/package.json +61 -63
- package/src/$locales/en.json +143 -179
- package/src/$locales/fr.json +105 -181
- package/src/assets/data/onboardingMessages.json +47 -47
- package/src/components/AppBase.vue +1054 -614
- package/src/components/AppBaseButton.vue +87 -63
- package/src/components/AppBaseErrorDisplay.vue +438 -420
- package/src/components/AppBaseFlipCard.vue +84 -83
- package/src/components/AppBaseModule.vue +1673 -1842
- package/src/components/AppBasePage.vue +779 -312
- package/src/components/AppBasePopover.vue +41 -0
- package/src/components/AppCompAudio.vue +234 -0
- package/src/components/AppCompBranchButtons.vue +552 -582
- package/src/components/AppCompButtonProgress.vue +126 -147
- package/src/components/AppCompCarousel.vue +298 -192
- package/src/components/AppCompInputCheckBoxNext.vue +195 -0
- package/src/components/AppCompInputDropdownNext.vue +159 -0
- package/src/components/AppCompInputRadioNext.vue +152 -0
- 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 -55
- package/src/components/AppCompMenu.vue +413 -209
- package/src/components/AppCompMenuItem.vue +228 -174
- package/src/components/AppCompNavigation.vue +960 -949
- package/src/components/AppCompNoteCall.vue +133 -126
- package/src/components/AppCompNoteCredit.vue +292 -164
- package/src/components/AppCompPlayBar.vue +1218 -1319
- package/src/components/AppCompPlayBarNext.vue +2052 -0
- package/src/components/AppCompPlayBarProgress.vue +82 -0
- package/src/components/AppCompPopUpNext.vue +503 -0
- package/src/components/{AppCompQuiz.vue → AppCompQuizNext.vue} +2904 -2989
- package/src/components/AppCompQuizRecall.vue +276 -250
- package/src/components/AppCompSVGNext.vue +347 -0
- package/src/components/AppCompSettingsMenu.vue +172 -171
- package/src/components/AppCompTableOfContent.vue +387 -264
- package/src/components/AppCompTranscript.vue +24 -19
- package/src/components/AppCompVideoPlayer.vue +368 -336
- package/src/components/AppCompViewDisplay.vue +6 -6
- package/src/components/BaseModule.vue +72 -67
- 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 -227
- package/src/mixins/$mediaMixins.js +819 -0
- package/src/mixins/timerMixin.js +155 -156
- package/src/module/stores/appStore.js +893 -0
- package/src/module/xapi/ADL.js +376 -339
- 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 -319
- 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 -1890
- 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 -295
- package/src/plugins/i18n.js +44 -31
- 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 -41
- package/src/router/routes.js +312 -337
- package/src/shared/generalfuncs.js +210 -188
- package/src/shared/validators.js +1069 -249
- package/vite.config.js +27 -0
- package/.prettierrc.js +0 -5
- package/babel.config.js +0 -3
- package/src/components/AppBaseDragChoice.vue +0 -91
- package/src/components/AppBaseDropZone.vue +0 -112
- package/src/components/AppCompBif.vue +0 -120
- package/src/components/AppCompDragAndDrop.vue +0 -339
- package/src/components/AppCompInputAssociation.vue +0 -332
- package/src/components/AppCompInputCheckBox.vue +0 -227
- package/src/components/AppCompInputDropdown.vue +0 -184
- package/src/components/AppCompInputRadio.vue +0 -169
- package/src/components/AppCompInputTextTable.vue +0 -155
- package/src/components/AppCompInputTextToFillDropdown.vue +0 -255
- package/src/components/AppCompMediaPlayer.vue +0 -397
- package/src/components/AppCompPopUp.vue +0 -522
- package/src/components/AppCompPopover.vue +0 -27
- package/src/components/AppCompSVG.vue +0 -309
- package/src/mixins/$pageMixins.js +0 -459
- package/src/mixins/$quizMixins.js +0 -456
- package/src/module/store.js +0 -895
- package/src/plugins/timeManager.js +0 -77
- package/src/routes_bckp.js +0 -313
- package/src/routes_static.js +0 -344
- package/vue.config.js +0 -83
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
|
+
})
|
package/.prettierrc.js
DELETED
package/babel.config.js
DELETED
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div
|
|
3
|
-
:id="choiceId"
|
|
4
|
-
class="quizDragDropChoice"
|
|
5
|
-
draggable
|
|
6
|
-
@drop="dropEvent($event)"
|
|
7
|
-
@dragstart="dragStartEvent($event)"
|
|
8
|
-
@dragover="dragOverEvent($event)"
|
|
9
|
-
>
|
|
10
|
-
<!---is img--->
|
|
11
|
-
<div v-if="choiceContenu.type == 'img'" class="quizChoiceWithImg">
|
|
12
|
-
<img :src="choiceContenu.affichage" :alt="choiceContenu.alt" />
|
|
13
|
-
</div>
|
|
14
|
-
<!---is text--->
|
|
15
|
-
<div v-if="choiceContenu.type == 'str'" class="quizChoiceWithText">
|
|
16
|
-
<div v-html="choiceContenu.affichage"></div>
|
|
17
|
-
</div>
|
|
18
|
-
</div>
|
|
19
|
-
</template>
|
|
20
|
-
|
|
21
|
-
<script>
|
|
22
|
-
export default {
|
|
23
|
-
name: 'AppBaseDragChoice',
|
|
24
|
-
props: {
|
|
25
|
-
choiceId: {
|
|
26
|
-
type: String,
|
|
27
|
-
default: ''
|
|
28
|
-
},
|
|
29
|
-
choiceValue: {
|
|
30
|
-
type: String,
|
|
31
|
-
default: ''
|
|
32
|
-
},
|
|
33
|
-
choiceContenu: {
|
|
34
|
-
type: Object,
|
|
35
|
-
default: () => {}
|
|
36
|
-
}
|
|
37
|
-
},
|
|
38
|
-
data() {
|
|
39
|
-
return {}
|
|
40
|
-
},
|
|
41
|
-
computed: {},
|
|
42
|
-
watch: {},
|
|
43
|
-
mounted() {},
|
|
44
|
-
methods: {
|
|
45
|
-
/**
|
|
46
|
-
* @param {Object} ev the event
|
|
47
|
-
* @description to control the ondrop
|
|
48
|
-
*/
|
|
49
|
-
dropEvent(ev) {
|
|
50
|
-
ev.preventDefault()
|
|
51
|
-
return ''
|
|
52
|
-
},
|
|
53
|
-
/**
|
|
54
|
-
* @param {Object} ev the event
|
|
55
|
-
* @description to control the ondragover
|
|
56
|
-
*/
|
|
57
|
-
dragOverEvent(ev) {
|
|
58
|
-
ev.preventDefault()
|
|
59
|
-
return ''
|
|
60
|
-
},
|
|
61
|
-
/**
|
|
62
|
-
* @param {Object} ev the event
|
|
63
|
-
* @description to control the onDragStart
|
|
64
|
-
*/
|
|
65
|
-
dragStartEvent(ev) {
|
|
66
|
-
ev.dataTransfer.setData('dataId', this.choiceId)
|
|
67
|
-
ev.dataTransfer.setData('zoneStart', this.$parent.zoneId)
|
|
68
|
-
ev.dataTransfer.dropEffect = 'move'
|
|
69
|
-
ev.dataTransfer.effectAllowed = 'move'
|
|
70
|
-
return ''
|
|
71
|
-
},
|
|
72
|
-
/**
|
|
73
|
-
* @param {Object} ev the event
|
|
74
|
-
* @description to open the sub menu for accessibility use
|
|
75
|
-
*/
|
|
76
|
-
openContextZone(ev) {
|
|
77
|
-
console.log(ev)
|
|
78
|
-
return ''
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
</script>
|
|
83
|
-
|
|
84
|
-
<style scoped>
|
|
85
|
-
.quizDragDropChoice {
|
|
86
|
-
display: flex;
|
|
87
|
-
height: 300px;
|
|
88
|
-
width: 300px;
|
|
89
|
-
border: solid black 1px;
|
|
90
|
-
}
|
|
91
|
-
</style>
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<!--zone is default position for choices-->
|
|
3
|
-
<div
|
|
4
|
-
v-if="zoneId === 'default'"
|
|
5
|
-
class="quizDragDropZoneDefault"
|
|
6
|
-
@drop="dropEvent($event)"
|
|
7
|
-
@dragover="dragOverEvent($event)"
|
|
8
|
-
>
|
|
9
|
-
<app-base-drag-choice
|
|
10
|
-
v-for="choice in choicesContenu"
|
|
11
|
-
:key="choice.choiceId"
|
|
12
|
-
:choice-value="choice.choiceValue"
|
|
13
|
-
:choice-id="choice.choiceId"
|
|
14
|
-
:choice-contenu="choice.choiceContenu"
|
|
15
|
-
/>
|
|
16
|
-
</div>
|
|
17
|
-
<!--zone is not default position for choices-->
|
|
18
|
-
<div
|
|
19
|
-
v-else
|
|
20
|
-
class="quizDragDropZone"
|
|
21
|
-
@drop="dropEvent($event)"
|
|
22
|
-
@dragover="dragOverEvent($event)"
|
|
23
|
-
>
|
|
24
|
-
<!--zone is img-->
|
|
25
|
-
<div v-if="zoneContenu.type == 'img'" class="quizZoneIsImg">
|
|
26
|
-
<img :src="zoneContenu.affichage" :alt="zoneContenu.alt" />
|
|
27
|
-
</div>
|
|
28
|
-
<!--zone is text-->
|
|
29
|
-
<div v-if="zoneContenu.type == 'str'" class="quizZoneIsText">
|
|
30
|
-
<div v-html="zoneContenu.affichage"></div>
|
|
31
|
-
</div>
|
|
32
|
-
<app-base-drag-choice
|
|
33
|
-
v-for="choice in choicesContenu"
|
|
34
|
-
:key="choice.choiceId"
|
|
35
|
-
:choice-value="choice.choiceValue"
|
|
36
|
-
:choice-id="choice.choiceId"
|
|
37
|
-
:choice-contenu="choice.choiceContenu"
|
|
38
|
-
/>
|
|
39
|
-
</div>
|
|
40
|
-
</template>
|
|
41
|
-
|
|
42
|
-
<script>
|
|
43
|
-
import AppBaseDragChoice from './AppBaseDragChoice.vue'
|
|
44
|
-
export default {
|
|
45
|
-
name: 'AppBaseDropZone',
|
|
46
|
-
components: {
|
|
47
|
-
AppBaseDragChoice
|
|
48
|
-
},
|
|
49
|
-
props: {
|
|
50
|
-
zoneId: {
|
|
51
|
-
type: String,
|
|
52
|
-
default: ''
|
|
53
|
-
},
|
|
54
|
-
zoneContenu: {
|
|
55
|
-
type: Object,
|
|
56
|
-
default: () => {}
|
|
57
|
-
},
|
|
58
|
-
choicesContenu: {
|
|
59
|
-
type: Array,
|
|
60
|
-
default: () => []
|
|
61
|
-
}
|
|
62
|
-
},
|
|
63
|
-
data() {
|
|
64
|
-
return {}
|
|
65
|
-
},
|
|
66
|
-
computed: {},
|
|
67
|
-
watch: {},
|
|
68
|
-
mounted() {},
|
|
69
|
-
methods: {
|
|
70
|
-
/**
|
|
71
|
-
* @description to control the ondrop
|
|
72
|
-
* @param {Object} ev the event
|
|
73
|
-
* @fires drop-event-zone to AppCompDragAndDrop.vue
|
|
74
|
-
*/
|
|
75
|
-
dropEvent(ev) {
|
|
76
|
-
ev.preventDefault()
|
|
77
|
-
const data = ev.dataTransfer.getData('dataId')
|
|
78
|
-
const zoneStart = ev.dataTransfer.getData('zoneStart')
|
|
79
|
-
const value = {
|
|
80
|
-
choiceId: data,
|
|
81
|
-
zoneEnd: this.zoneId,
|
|
82
|
-
zoneStart: zoneStart
|
|
83
|
-
}
|
|
84
|
-
this.$emit('drop-event-zone', value)
|
|
85
|
-
return ''
|
|
86
|
-
},
|
|
87
|
-
/**
|
|
88
|
-
* @description to control the ondragover
|
|
89
|
-
* @param {Object} ev the event
|
|
90
|
-
*/
|
|
91
|
-
dragOverEvent(ev) {
|
|
92
|
-
ev.preventDefault()
|
|
93
|
-
ev.dataTransfer.dropEffect = 'move'
|
|
94
|
-
return ''
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
</script>
|
|
99
|
-
<style scoped>
|
|
100
|
-
.quizDragDropZone,
|
|
101
|
-
.quizDragDropZoneDefault {
|
|
102
|
-
min-height: 300px;
|
|
103
|
-
border: solid black 1px;
|
|
104
|
-
}
|
|
105
|
-
.quizDragDropZone {
|
|
106
|
-
width: 300px;
|
|
107
|
-
}
|
|
108
|
-
.quizDragDropZoneDefault {
|
|
109
|
-
min-width: 300px;
|
|
110
|
-
display: flex;
|
|
111
|
-
}
|
|
112
|
-
</style>
|
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
<!--
|
|
2
|
-
*@ Description: This component is used to display button for each choice
|
|
3
|
-
*@ What it does: The component set value a or b to the store and go to the next page
|
|
4
|
-
*
|
|
5
|
-
*@Note :
|
|
6
|
-
This component effect TOC(disable if the choice is not made) and NavigationFull(make jump if choise is not made).
|
|
7
|
-
This component need Menu setting to declare where the branching start and when the branching end.
|
|
8
|
-
To switch between choice see getchoiceBif() in PageMixing
|
|
9
|
-
See template for usage exemple
|
|
10
|
-
-->
|
|
11
|
-
|
|
12
|
-
<template>
|
|
13
|
-
<div class="box-bif">
|
|
14
|
-
<app-base-button
|
|
15
|
-
id="btn-bif-a"
|
|
16
|
-
class="btn-bif"
|
|
17
|
-
:title="titleA"
|
|
18
|
-
@click="setChoice('A')"
|
|
19
|
-
>
|
|
20
|
-
<div class="choice-a">
|
|
21
|
-
<slot name="content-a" />
|
|
22
|
-
</div>
|
|
23
|
-
</app-base-button>
|
|
24
|
-
|
|
25
|
-
<app-base-button
|
|
26
|
-
id="btn-bif-b"
|
|
27
|
-
class="btn-bif"
|
|
28
|
-
:title="titleB"
|
|
29
|
-
@click="setChoice('B')"
|
|
30
|
-
>
|
|
31
|
-
<div class="choice-b">
|
|
32
|
-
<slot name="content-b" />
|
|
33
|
-
</div>
|
|
34
|
-
</app-base-button>
|
|
35
|
-
|
|
36
|
-
</div>
|
|
37
|
-
</template>
|
|
38
|
-
<script>
|
|
39
|
-
import AppBaseButton from './AppBaseButton.vue'
|
|
40
|
-
import { mapGetters } from 'vuex'
|
|
41
|
-
|
|
42
|
-
export default {
|
|
43
|
-
name: 'AppCompBif',
|
|
44
|
-
components: { AppBaseButton },
|
|
45
|
-
props: {
|
|
46
|
-
titleA: {
|
|
47
|
-
type: String,
|
|
48
|
-
default: ''
|
|
49
|
-
},
|
|
50
|
-
titleB: {
|
|
51
|
-
type: String,
|
|
52
|
-
default: ''
|
|
53
|
-
},
|
|
54
|
-
consigne: {
|
|
55
|
-
type: Boolean,
|
|
56
|
-
default: true
|
|
57
|
-
}
|
|
58
|
-
},
|
|
59
|
-
data() {
|
|
60
|
-
return {}
|
|
61
|
-
},
|
|
62
|
-
computed: {
|
|
63
|
-
...mapGetters(['getUserInteraction', 'getCurrentPage'])
|
|
64
|
-
},
|
|
65
|
-
mounted() {},
|
|
66
|
-
methods: {
|
|
67
|
-
setChoice(choix) {
|
|
68
|
-
const userInteraction = this.getProgress()
|
|
69
|
-
this.$set(userInteraction, 'bifChoice', choix)
|
|
70
|
-
|
|
71
|
-
let data
|
|
72
|
-
let num
|
|
73
|
-
let dataAct
|
|
74
|
-
|
|
75
|
-
// gestion go to next page
|
|
76
|
-
if (this.getCurrentPage.id.indexOf('0') == 1) {
|
|
77
|
-
data = this.getCurrentPage.id.substring(
|
|
78
|
-
this.getCurrentPage.id.indexOf('P') + 2
|
|
79
|
-
)
|
|
80
|
-
} else {
|
|
81
|
-
data = this.getCurrentPage.id.substring(
|
|
82
|
-
this.getCurrentPage.id.indexOf('P') + 1
|
|
83
|
-
)
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
num = parseInt(data)
|
|
87
|
-
|
|
88
|
-
// gestion go to next activity
|
|
89
|
-
if (this.$route.meta.activity_ref.indexOf('0') == 1) {
|
|
90
|
-
dataAct = this.$route.meta.activity_ref.substring(
|
|
91
|
-
this.$route.meta.activity_ref.indexOf('A') + 2
|
|
92
|
-
)
|
|
93
|
-
} else {
|
|
94
|
-
dataAct = this.$route.meta.activity_ref.substring(
|
|
95
|
-
this.$route.meta.activity_ref.indexOf('A') + 1
|
|
96
|
-
)
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
// go to next page
|
|
100
|
-
this.$router.push({
|
|
101
|
-
name: `activite_${dataAct}.page_${num + 1}`
|
|
102
|
-
})
|
|
103
|
-
},
|
|
104
|
-
getProgress() {
|
|
105
|
-
const { id, activity_ref } = this.$route.meta
|
|
106
|
-
|
|
107
|
-
const record = this.$store.getters.getUserInteraction
|
|
108
|
-
if (
|
|
109
|
-
Object.entries(record).length &&
|
|
110
|
-
record[activity_ref] &&
|
|
111
|
-
record[activity_ref][id]
|
|
112
|
-
) {
|
|
113
|
-
const { userInteraction } = record[activity_ref][id]
|
|
114
|
-
return userInteraction
|
|
115
|
-
}
|
|
116
|
-
return {}
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
</script>
|
|
@@ -1,339 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div class="input-box">
|
|
3
|
-
<!--choices-->
|
|
4
|
-
<div class="parentQuizChoices" style="display:flex">
|
|
5
|
-
<app-base-drop-zone
|
|
6
|
-
key="default"
|
|
7
|
-
zone-id="default"
|
|
8
|
-
:choices-contenu="listZoneChoices['default']"
|
|
9
|
-
@drop-event-zone="dropEventZone($event)"
|
|
10
|
-
/>
|
|
11
|
-
</div>
|
|
12
|
-
<!--zones-->
|
|
13
|
-
<div style="display:flex">
|
|
14
|
-
<div
|
|
15
|
-
v-for="singleDragDropZone in inputData.zone_depots"
|
|
16
|
-
:key="singleDragDropZone.id"
|
|
17
|
-
:class="
|
|
18
|
-
`dragdroplist-${singleDragDropZone.id} ` +
|
|
19
|
-
classInput(singleDragDropZone.id)
|
|
20
|
-
"
|
|
21
|
-
>
|
|
22
|
-
<label
|
|
23
|
-
:for="`${inputDataId}_${singleDragDropZone.id}`"
|
|
24
|
-
v-html="singleDragDropZone.contenu.alt"
|
|
25
|
-
></label>
|
|
26
|
-
<app-base-drop-zone
|
|
27
|
-
:zone-id="singleDragDropZone.id"
|
|
28
|
-
:zone-contenu="singleDragDropZone.contenu"
|
|
29
|
-
:choices-contenu="listZoneChoices[singleDragDropZone.id]"
|
|
30
|
-
@drop-event-zone="dropEventZone($event)"
|
|
31
|
-
/>
|
|
32
|
-
</div>
|
|
33
|
-
</div>
|
|
34
|
-
</div>
|
|
35
|
-
</template>
|
|
36
|
-
<script>
|
|
37
|
-
import $extendsQuiz from '../mixins/$quizMixins'
|
|
38
|
-
import AppBaseDropZone from './AppBaseDropZone.vue'
|
|
39
|
-
export default {
|
|
40
|
-
components: {
|
|
41
|
-
AppBaseDropZone
|
|
42
|
-
},
|
|
43
|
-
mixins: [$extendsQuiz],
|
|
44
|
-
|
|
45
|
-
props: {
|
|
46
|
-
inputType: {
|
|
47
|
-
type: String,
|
|
48
|
-
default: ''
|
|
49
|
-
},
|
|
50
|
-
inputDataId: {
|
|
51
|
-
type: String,
|
|
52
|
-
default: ''
|
|
53
|
-
},
|
|
54
|
-
inputData: {
|
|
55
|
-
type: Object,
|
|
56
|
-
default: () => {}
|
|
57
|
-
},
|
|
58
|
-
quizCompleted: {
|
|
59
|
-
type: Boolean,
|
|
60
|
-
default: false
|
|
61
|
-
},
|
|
62
|
-
solution: {
|
|
63
|
-
type: Object,
|
|
64
|
-
default: () => []
|
|
65
|
-
},
|
|
66
|
-
showSolution: {
|
|
67
|
-
type: Boolean,
|
|
68
|
-
default: false
|
|
69
|
-
},
|
|
70
|
-
shuffleAnswers: {
|
|
71
|
-
type: Boolean, //@todo add shuffle
|
|
72
|
-
default: false
|
|
73
|
-
},
|
|
74
|
-
quizDragDrop: {
|
|
75
|
-
type: Object,
|
|
76
|
-
default: () => {}
|
|
77
|
-
}, //use to pass the value of the input
|
|
78
|
-
quizSubmit: {
|
|
79
|
-
type: Boolean,
|
|
80
|
-
default: false
|
|
81
|
-
} //use to call a submit
|
|
82
|
-
},
|
|
83
|
-
|
|
84
|
-
data() {
|
|
85
|
-
return {
|
|
86
|
-
quizDragDropValue: {}, //not using quizDragDrop because quizDragDrop is a prop
|
|
87
|
-
listZoneChoices: {} //the choice in the actives zones
|
|
88
|
-
}
|
|
89
|
-
},
|
|
90
|
-
|
|
91
|
-
computed: {},
|
|
92
|
-
|
|
93
|
-
watch: {
|
|
94
|
-
/**
|
|
95
|
-
* @description to pass value to AppCompQuiz
|
|
96
|
-
* @param {Object} newValue
|
|
97
|
-
* @fires input-change
|
|
98
|
-
*/
|
|
99
|
-
quizDragDropValue(newValue) {
|
|
100
|
-
this.$emit('input-change', newValue)
|
|
101
|
-
},
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* @description to receive the value from AppCompQuiz
|
|
105
|
-
* @param {Object} newValue
|
|
106
|
-
*/
|
|
107
|
-
quizDragDrop(newValue) {
|
|
108
|
-
//check if all zone are empty
|
|
109
|
-
if (Object.keys(newValue).length > 0) {
|
|
110
|
-
let isReset = true
|
|
111
|
-
let isAnswered = false
|
|
112
|
-
for (const key in newValue) {
|
|
113
|
-
if (Object.hasOwnProperty.call(newValue, key)) {
|
|
114
|
-
const element = newValue[key]
|
|
115
|
-
if (element.length > 0) {
|
|
116
|
-
isReset = false
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
if (isReset) {
|
|
121
|
-
for (const key in this.listZoneChoices) {
|
|
122
|
-
if (Object.hasOwnProperty.call(this.listZoneChoices, key)) {
|
|
123
|
-
const element = this.listZoneChoices[key]
|
|
124
|
-
if (element.length > 0 && key !== 'default') {
|
|
125
|
-
isAnswered = true
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
if (isReset && isAnswered) {
|
|
131
|
-
//reset choice to default
|
|
132
|
-
this.listZoneChoices = { default: [] }
|
|
133
|
-
let listChoices = []
|
|
134
|
-
for (
|
|
135
|
-
let index2 = 0;
|
|
136
|
-
index2 < this.inputData.zone_depots.length;
|
|
137
|
-
index2++
|
|
138
|
-
) {
|
|
139
|
-
const element = this.inputData.zone_depots[index2]
|
|
140
|
-
this.$set(this.listZoneChoices, element.id, [])
|
|
141
|
-
}
|
|
142
|
-
//fill listZoneChoices to populate the zone
|
|
143
|
-
for (
|
|
144
|
-
let index = 0;
|
|
145
|
-
index < this.inputData.choix_deplaceable.length;
|
|
146
|
-
index++
|
|
147
|
-
) {
|
|
148
|
-
const choiceType = this.inputData.choix_deplaceable[index]
|
|
149
|
-
for (let repeat = 0; repeat < choiceType.repetition; repeat++) {
|
|
150
|
-
const singleChoice = {
|
|
151
|
-
choiceId: choiceType.id + '_' + repeat,
|
|
152
|
-
choiceValue: choiceType.id,
|
|
153
|
-
choiceContenu: choiceType.contenu
|
|
154
|
-
}
|
|
155
|
-
listChoices.push(singleChoice)
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
this.listZoneChoices['default'] = listChoices
|
|
159
|
-
}
|
|
160
|
-
this.quizDragDropValue = newValue
|
|
161
|
-
}
|
|
162
|
-
},
|
|
163
|
-
/**
|
|
164
|
-
* @description to change the value passed
|
|
165
|
-
* @fires input-change to AppCompQuiz.vue
|
|
166
|
-
*/
|
|
167
|
-
listZoneChoices: {
|
|
168
|
-
handler(newValue) {
|
|
169
|
-
let newDragDropValue = {}
|
|
170
|
-
for (const key in newValue) {
|
|
171
|
-
if (key !== 'default') {
|
|
172
|
-
this.$set(newDragDropValue, key, [])
|
|
173
|
-
if (Object.hasOwnProperty.call(newValue, key)) {
|
|
174
|
-
if (key !== 'default') {
|
|
175
|
-
const zone = newValue[key]
|
|
176
|
-
//each item in the array
|
|
177
|
-
zone.forEach((choice) => {
|
|
178
|
-
newDragDropValue[key].push(choice.choiceValue)
|
|
179
|
-
})
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
this.$emit('input-change', newDragDropValue)
|
|
185
|
-
},
|
|
186
|
-
deep: true,
|
|
187
|
-
immediate: true
|
|
188
|
-
}
|
|
189
|
-
},
|
|
190
|
-
|
|
191
|
-
mounted() {
|
|
192
|
-
this.listZoneChoices = { default: [] }
|
|
193
|
-
let listChoices = []
|
|
194
|
-
for (let index2 = 0; index2 < this.inputData.zone_depots.length; index2++) {
|
|
195
|
-
const element = this.inputData.zone_depots[index2]
|
|
196
|
-
this.$set(this.listZoneChoices, element.id, [])
|
|
197
|
-
}
|
|
198
|
-
//fill listZoneChoices to populate the zone
|
|
199
|
-
for (
|
|
200
|
-
let index = 0;
|
|
201
|
-
index < this.inputData.choix_deplaceable.length;
|
|
202
|
-
index++
|
|
203
|
-
) {
|
|
204
|
-
const choiceType = this.inputData.choix_deplaceable[index]
|
|
205
|
-
for (let repeat = 0; repeat < choiceType.repetition; repeat++) {
|
|
206
|
-
const singleChoice = {
|
|
207
|
-
choiceId: choiceType.id + '_' + repeat,
|
|
208
|
-
choiceValue: choiceType.id,
|
|
209
|
-
choiceContenu: choiceType.contenu
|
|
210
|
-
}
|
|
211
|
-
listChoices.push(singleChoice)
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
if (Object.keys(this.quizDragDrop).length > 0) {
|
|
216
|
-
for (const key in this.quizDragDrop) {
|
|
217
|
-
if (Object.hasOwnProperty.call(this.quizDragDrop, key)) {
|
|
218
|
-
const theZoneChoices = this.quizDragDrop[key]
|
|
219
|
-
for (let index3 = 0; index3 < theZoneChoices.length; index3++) {
|
|
220
|
-
const element = theZoneChoices[index3]
|
|
221
|
-
//find singleChoice
|
|
222
|
-
const theChoice = listChoices.filter(
|
|
223
|
-
(choice) => choice.choiceValue == element
|
|
224
|
-
)[0]
|
|
225
|
-
//add to zone
|
|
226
|
-
this.listZoneChoices[key].push(theChoice)
|
|
227
|
-
//remove from listChoices
|
|
228
|
-
listChoices = listChoices.filter(
|
|
229
|
-
(choice) => choice.choiceId !== theChoice.choiceId
|
|
230
|
-
)
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
//put the choices left in the default zone
|
|
236
|
-
this.listZoneChoices['default'] = listChoices
|
|
237
|
-
},
|
|
238
|
-
|
|
239
|
-
methods: {
|
|
240
|
-
/**
|
|
241
|
-
* @description check if a values exists in a array
|
|
242
|
-
* @param {Array} array
|
|
243
|
-
* @param value
|
|
244
|
-
* @returns {Boolean}
|
|
245
|
-
*/
|
|
246
|
-
containsValue(array, value) {
|
|
247
|
-
return array.includes(value)
|
|
248
|
-
},
|
|
249
|
-
|
|
250
|
-
/**
|
|
251
|
-
* @description shuffles an array used to randomized the option order if shuffleAnswers is true
|
|
252
|
-
* @param {Array} array
|
|
253
|
-
* @returns {Array}
|
|
254
|
-
* @todo redo shuffle
|
|
255
|
-
*/
|
|
256
|
-
shuffleArray(array) {
|
|
257
|
-
let newArray = []
|
|
258
|
-
let newArray2 = []
|
|
259
|
-
|
|
260
|
-
for (let i = 0; i < array.length; i++) {
|
|
261
|
-
const element = array[i]
|
|
262
|
-
//todo remove null values
|
|
263
|
-
newArray.push(element)
|
|
264
|
-
}
|
|
265
|
-
while (newArray.length > 0) {
|
|
266
|
-
let pos = Math.floor(newArray.length * Math.random())
|
|
267
|
-
newArray2.push(newArray[pos])
|
|
268
|
-
newArray.splice(pos, 1)
|
|
269
|
-
}
|
|
270
|
-
return newArray2
|
|
271
|
-
},
|
|
272
|
-
|
|
273
|
-
/**
|
|
274
|
-
* @description move 1 choice from zoneStart to zoneEnd
|
|
275
|
-
* @param {Object} value object with 3 attributes
|
|
276
|
-
* @param {String} value.zoneStart the original zone of the choice
|
|
277
|
-
* @param {String} value.zoneEnd the final zone of the choice
|
|
278
|
-
* @param {String} value.choiceId the choice
|
|
279
|
-
*/
|
|
280
|
-
dropEventZone(value) {
|
|
281
|
-
const zoneStart = value.zoneStart
|
|
282
|
-
const zoneEnd = value.zoneEnd
|
|
283
|
-
const choiceId = value.choiceId
|
|
284
|
-
if (zoneStart == zoneEnd) {
|
|
285
|
-
//do nothing or move
|
|
286
|
-
//@todo code here
|
|
287
|
-
console.log('same zone')
|
|
288
|
-
} else {
|
|
289
|
-
//find choice in zoneStart
|
|
290
|
-
const choicesList = this.listZoneChoices[zoneStart]
|
|
291
|
-
const theChoice = choicesList.filter(
|
|
292
|
-
(choice) => choice.choiceId == choiceId
|
|
293
|
-
)[0]
|
|
294
|
-
//move choice from zoneStart to zoneEnd
|
|
295
|
-
this.listZoneChoices[zoneEnd].push(theChoice)
|
|
296
|
-
const newChoicesList = choicesList.filter(
|
|
297
|
-
(choice) => choice.choiceId !== choiceId
|
|
298
|
-
)
|
|
299
|
-
this.listZoneChoices[zoneStart] = newChoicesList
|
|
300
|
-
}
|
|
301
|
-
},
|
|
302
|
-
/**
|
|
303
|
-
* @description compares 2 array
|
|
304
|
-
* @param {Array} array1
|
|
305
|
-
* @param {Array} array2
|
|
306
|
-
* @returns {Boolean}
|
|
307
|
-
*/
|
|
308
|
-
isEqual(array1, array2) {
|
|
309
|
-
// if length is not equal
|
|
310
|
-
if (array1.length != array2.length) {
|
|
311
|
-
return false
|
|
312
|
-
} else {
|
|
313
|
-
// comapring each element of array
|
|
314
|
-
for (let i = 0; i < array1.length; i++) {
|
|
315
|
-
if (array1[i] != array2[i]) {
|
|
316
|
-
return false
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
return true
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
</script>
|
|
325
|
-
<style scoped>
|
|
326
|
-
.quizZone,
|
|
327
|
-
.quizZoneActive {
|
|
328
|
-
height: 300px;
|
|
329
|
-
width: 300px;
|
|
330
|
-
border: solid 1px;
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
.quizZone {
|
|
334
|
-
border-color: black;
|
|
335
|
-
}
|
|
336
|
-
.quizZoneActive {
|
|
337
|
-
border-color: red;
|
|
338
|
-
}
|
|
339
|
-
</style>
|