fcad-core-dragon 2.0.0-beta.0 → 2.0.0-beta.10
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 +6 -31
- package/.prettierrc +11 -0
- package/.vscode/extensions.json +8 -0
- package/.vscode/settings.json +16 -0
- package/CHANGELOG +153 -0
- package/README.md +28 -43
- package/documentation/.vitepress/config.js +114 -0
- package/documentation/api-examples.md +49 -0
- package/documentation/composants/app-base-button.md +58 -0
- package/documentation/composants/app-base-error-display.md +59 -0
- package/documentation/composants/app-base-popover.md +68 -0
- package/documentation/composants/app-comp-audio.md +75 -0
- package/documentation/composants/app-comp-branch-buttons.md +111 -0
- package/documentation/composants/app-comp-button-progress.md +53 -0
- package/documentation/composants/app-comp-carousel.md +53 -0
- package/documentation/composants/app-comp-container.md +53 -0
- package/documentation/composants/app-comp-input-checkbox-next.md +42 -0
- package/documentation/composants/app-comp-input-dropdown-next.md +34 -0
- package/documentation/composants/app-comp-input-radio-next.md +39 -0
- package/documentation/composants/app-comp-input-text-next.md +35 -0
- package/documentation/composants/app-comp-input-text-table-next.md +34 -0
- package/documentation/composants/app-comp-input-text-to-fill-dropdown-next.md +53 -0
- package/documentation/composants/app-comp-input-text-to-fill-next.md +31 -0
- package/documentation/composants/app-comp-jauge.md +31 -0
- package/documentation/composants/app-comp-menu-item.md +55 -0
- package/documentation/composants/app-comp-menu.md +29 -0
- package/documentation/composants/app-comp-navigation.md +41 -0
- package/documentation/composants/app-comp-note-call.md +53 -0
- package/documentation/composants/app-comp-note-credit.md +53 -0
- package/documentation/composants/app-comp-play-bar-next.md +53 -0
- package/documentation/composants/app-comp-pop-up-next.md +93 -0
- package/documentation/composants/app-comp-quiz-next.md +235 -0
- package/documentation/composants/app-comp-quiz-recall.md +53 -0
- package/documentation/composants/app-comp-svg-next.md +53 -0
- package/documentation/composants/app-comp-table-of-content.md +50 -0
- package/documentation/composants/app-comp-video-player.md +82 -0
- package/documentation/composants.md +46 -0
- package/documentation/composants_critiques/ModelPageComposant.md +53 -0
- package/documentation/composants_critiques/app-base-module.md +43 -0
- package/documentation/composants_critiques/app-base-page.md +48 -0
- package/documentation/composants_critiques/app-base.md +311 -0
- package/documentation/composants_critiques/main.md +15 -0
- package/documentation/demarrage.md +50 -0
- package/documentation/deploiement.md +58 -0
- package/documentation/index.md +33 -0
- package/documentation/markdown-examples.md +85 -0
- package/documentation/public/npm_version.png +0 -0
- package/documentation/public/vite.svg +15 -0
- package/documentation/public/vuejs.svg +2 -0
- package/documentation/public/vuetify.svg +6 -0
- package/eslint.config.js +60 -0
- package/package.json +43 -49
- package/src/$locales/en.json +94 -92
- package/src/$locales/fr.json +77 -113
- package/src/assets/data/onboardingMessages.json +1 -1
- package/src/components/AppBase.vue +971 -437
- package/src/components/AppBaseButton.test.js +21 -0
- package/src/components/AppBaseButton.vue +42 -10
- package/src/components/AppBaseErrorDisplay.vue +209 -162
- package/src/components/AppBaseFlipCard.vue +1 -0
- package/src/components/AppBaseModule.vue +1021 -976
- package/src/components/AppBasePage.vue +656 -128
- package/src/components/AppBasePopover.vue +41 -0
- package/src/components/AppBaseSkeleton.vue +66 -0
- package/src/components/AppCompAudio.vue +256 -0
- package/src/components/AppCompBranchButtons.vue +108 -181
- package/src/components/AppCompButtonProgress.vue +44 -70
- package/src/components/AppCompCarousel.vue +284 -233
- package/src/components/AppCompContainer.vue +29 -0
- package/src/components/AppCompInputCheckBoxNx.vue +323 -0
- package/src/components/AppCompInputDropdownNx.vue +299 -0
- package/src/components/AppCompInputRadioNx.vue +284 -0
- package/src/components/AppCompInputTextNx.vue +153 -0
- package/src/components/AppCompInputTextTableNx.vue +202 -0
- package/src/components/AppCompInputTextToFillDropdownNx.vue +340 -0
- package/src/components/AppCompInputTextToFillNx.vue +313 -0
- package/src/components/AppCompJauge.vue +36 -11
- package/src/components/AppCompMenu.vue +312 -92
- package/src/components/AppCompMenuItem.vue +129 -105
- package/src/components/AppCompNavigation.vue +972 -0
- package/src/components/AppCompNoteCall.vue +161 -0
- package/src/components/AppCompNoteCredit.vue +491 -0
- package/src/components/AppCompPlayBarNext.vue +2288 -0
- package/src/components/AppCompPopUpNext.vue +504 -0
- package/src/components/AppCompQuizNext.vue +510 -0
- package/src/components/AppCompQuizRecall.vue +350 -0
- package/src/components/AppCompSVGNext.vue +346 -0
- package/src/components/AppCompSettingsMenu.vue +18 -16
- package/src/components/AppCompTableOfContent.vue +340 -122
- package/src/components/AppCompVideoPlayer.vue +377 -0
- package/src/components/BaseModule.vue +24 -117
- package/src/components/tests__/AppBaseButton.spec.js +53 -0
- package/src/components/tests__/useTimer.spec.js +91 -0
- package/src/composables/useIdleDetector.js +56 -0
- package/src/composables/useQuiz.js +89 -0
- package/src/composables/useTimer.js +172 -0
- package/src/directives/nvdaFix.js +53 -0
- package/src/externalComps/ModuleView.vue +22 -0
- package/src/externalComps/SummaryView.vue +91 -0
- package/src/main.js +400 -142
- package/src/module/stores/appStore.js +947 -0
- package/src/module/xapi/ADL.js +241 -60
- package/src/module/xapi/Crypto/Hasher.js +8 -8
- package/src/module/xapi/Crypto/WordArray.js +6 -6
- package/src/module/xapi/Crypto/algorithms/BufferedBlockAlgorithm.js +4 -4
- package/src/module/xapi/Crypto/algorithms/C_algo.js +14 -18
- package/src/module/xapi/Crypto/algorithms/HMAC.js +1 -1
- package/src/module/xapi/Crypto/algorithms/SHA1.js +1 -1
- package/src/module/xapi/Crypto/encoders/Base.js +7 -7
- package/src/module/xapi/Crypto/encoders/Base64.js +3 -3
- package/src/module/xapi/Crypto/encoders/Hex.js +4 -3
- package/src/module/xapi/Crypto/encoders/Latin1.js +3 -3
- package/src/module/xapi/Crypto/encoders/Utf8.js +3 -3
- package/src/module/xapi/Statement/index.js +3 -3
- package/src/module/xapi/launch.js +10 -10
- package/src/module/xapi/utils.js +17 -17
- package/src/module/xapi/wrapper.js +223 -218
- package/src/module/xapi/xapiStatement.js +29 -29
- package/src/plugins/analytics.js +34 -0
- package/src/plugins/bus.js +7 -2
- package/src/plugins/gsap.js +9 -8
- package/src/plugins/helper.js +141 -43
- package/src/plugins/i18n.js +13 -18
- package/src/plugins/idb.js +46 -30
- package/src/plugins/save.js +1 -1
- package/src/plugins/scorm.js +15 -15
- package/src/plugins/xapi.js +2 -2
- package/src/public/index.html +23 -11
- package/src/router/index.js +57 -0
- package/src/router/routes.js +312 -0
- package/src/shared/generalfuncs.js +241 -10
- package/src/shared/validators.js +1018 -0
- package/vitest.config.js +19 -0
- package/.eslintignore +0 -29
- package/.eslintrc.js +0 -86
- 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/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/AppCompInputTextBox.vue +0 -91
- package/src/components/AppCompInputTextTable.vue +0 -155
- package/src/components/AppCompInputTextToFillDropdown.vue +0 -255
- package/src/components/AppCompInputTextToFillText.vue +0 -164
- package/src/components/AppCompMediaPlayer.vue +0 -365
- package/src/components/AppCompNavigationFull.vue +0 -1791
- package/src/components/AppCompPlayBar.vue +0 -1540
- package/src/components/AppCompPopUp.vue +0 -523
- package/src/components/AppCompQuiz.vue +0 -2998
- package/src/components/AppCompToolTip.vue +0 -94
- package/src/mixins/$pageMixins.js +0 -381
- package/src/mixins/$quizMixins.js +0 -456
- package/src/mixins/timerMixin.js +0 -132
- package/src/module/store.js +0 -874
- package/src/plugins/timeManager.js +0 -77
- package/src/routes.js +0 -734
- package/vue.config.js +0 -83
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<b-popover
|
|
3
|
-
ref="tooltip_1"
|
|
4
|
-
:show.sync="isShown"
|
|
5
|
-
:target="target"
|
|
6
|
-
:title="option.title"
|
|
7
|
-
triggers="manual"
|
|
8
|
-
placement="auto"
|
|
9
|
-
@hidden="onHidden()"
|
|
10
|
-
>
|
|
11
|
-
<div class="box-content-tooltip" v-html="option.content" />
|
|
12
|
-
<div>
|
|
13
|
-
<app-base-button
|
|
14
|
-
id="btn-cancel-tooltip"
|
|
15
|
-
:name-acces="'Annuler'"
|
|
16
|
-
class="btn-cancel"
|
|
17
|
-
:title="$t('button.cancel_pop')"
|
|
18
|
-
@click="$cancel(option.cb_$cancel)"
|
|
19
|
-
>
|
|
20
|
-
{{ $t('button.cancel_pop') }}
|
|
21
|
-
</app-base-button>
|
|
22
|
-
<app-base-button
|
|
23
|
-
id="btn-confirm-tooltip"
|
|
24
|
-
:name-acces="'Confirmer'"
|
|
25
|
-
class="btn-confirm"
|
|
26
|
-
:title="$t('button.confirm_pop')"
|
|
27
|
-
@click="$confirm(option.cb_$confirm)"
|
|
28
|
-
>
|
|
29
|
-
{{ $t('button.confirm_pop') }}
|
|
30
|
-
</app-base-button>
|
|
31
|
-
</div>
|
|
32
|
-
</b-popover>
|
|
33
|
-
</template>
|
|
34
|
-
|
|
35
|
-
<script>
|
|
36
|
-
//https://bootstrap-vue.org/docs/components/popover
|
|
37
|
-
export default {
|
|
38
|
-
name: 'AppCompToolTip',
|
|
39
|
-
props: {
|
|
40
|
-
target: { type: String, default: '' }
|
|
41
|
-
},
|
|
42
|
-
data() {
|
|
43
|
-
return {
|
|
44
|
-
option: {},
|
|
45
|
-
confirmFunction: false,
|
|
46
|
-
isShown: false
|
|
47
|
-
}
|
|
48
|
-
},
|
|
49
|
-
computed: {},
|
|
50
|
-
mounted() {
|
|
51
|
-
this.$bus.$on('tooltip-close', () => {
|
|
52
|
-
this.isShown = false
|
|
53
|
-
})
|
|
54
|
-
|
|
55
|
-
this.$bus.$on('tooltip-open', (e) => {
|
|
56
|
-
if (e) {
|
|
57
|
-
this.option = e
|
|
58
|
-
this.isShown = true
|
|
59
|
-
}
|
|
60
|
-
})
|
|
61
|
-
},
|
|
62
|
-
methods: {
|
|
63
|
-
/**
|
|
64
|
-
* @description - method for action confirm
|
|
65
|
-
* @param {Function} cb
|
|
66
|
-
*/
|
|
67
|
-
$confirm(cb) {
|
|
68
|
-
this.confirmFunction = cb
|
|
69
|
-
this.isShown = false
|
|
70
|
-
},
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* @description - method for action cancel
|
|
74
|
-
* @param {Function} cb
|
|
75
|
-
*/
|
|
76
|
-
$cancel(cb) {
|
|
77
|
-
this.confirmFunction = false
|
|
78
|
-
cb = cb || null
|
|
79
|
-
this.isShown = false
|
|
80
|
-
if (cb && typeof cb === 'function') cb()
|
|
81
|
-
},
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* @description action to do when tooltip is hidden
|
|
85
|
-
*/
|
|
86
|
-
onHidden() {
|
|
87
|
-
//check if closed with confirm
|
|
88
|
-
let cb = this.confirmFunction
|
|
89
|
-
//calls close
|
|
90
|
-
if (cb && typeof cb === 'function') cb()
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
</script>
|
|
@@ -1,381 +0,0 @@
|
|
|
1
|
-
import { mapGetters } from 'vuex'
|
|
2
|
-
/*
|
|
3
|
-
@ Description: Mixins to extends general fonctionnalities in a page of an activity.
|
|
4
|
-
@ Note: Must be used along component AppBasePage When creating page of an activity.
|
|
5
|
-
* some data and information will not be correctly tracked if this mixins not used
|
|
6
|
-
* when creating a page.
|
|
7
|
-
*/
|
|
8
|
-
const $extendsPage = {
|
|
9
|
-
// lazy laoding of components
|
|
10
|
-
components: {
|
|
11
|
-
AppCompMediaPlayer: () =>
|
|
12
|
-
import(
|
|
13
|
-
/* webpackChunkName: "MediaPlayerCompnent" */
|
|
14
|
-
'../components/AppCompMediaPlayer.vue'
|
|
15
|
-
),
|
|
16
|
-
AppCompMenuItem: () =>
|
|
17
|
-
import(
|
|
18
|
-
/* webpackChunkName: "MenuItemCompenent" */
|
|
19
|
-
'../components/AppCompMenuItem.vue'
|
|
20
|
-
),
|
|
21
|
-
AppCompQuiz: () =>
|
|
22
|
-
import(
|
|
23
|
-
/* webpackChunkName: "QuizComponent" */
|
|
24
|
-
'../components/AppCompQuiz.vue'
|
|
25
|
-
)
|
|
26
|
-
},
|
|
27
|
-
|
|
28
|
-
data: () => {
|
|
29
|
-
return {
|
|
30
|
-
userInteraction: {},
|
|
31
|
-
state: null,
|
|
32
|
-
anchorEnable: true,
|
|
33
|
-
anchorInfo: null,
|
|
34
|
-
error: null,
|
|
35
|
-
scrollLimit: null
|
|
36
|
-
}
|
|
37
|
-
},
|
|
38
|
-
watch: {
|
|
39
|
-
userInteraction: {
|
|
40
|
-
handler(newValue) {
|
|
41
|
-
/**
|
|
42
|
-
* Objserve changes in the number of poperties to dispatch updates in the userdata in the Store
|
|
43
|
-
*/
|
|
44
|
-
if (newValue && Object.entries(this.userInteraction).length) {
|
|
45
|
-
const { activityRef, id, userInteraction } = this.$data
|
|
46
|
-
this.$store.dispatch('updateUserMetaData', {
|
|
47
|
-
activityRef,
|
|
48
|
-
id,
|
|
49
|
-
userInteraction
|
|
50
|
-
})
|
|
51
|
-
}
|
|
52
|
-
},
|
|
53
|
-
immediate: true,
|
|
54
|
-
deep: true
|
|
55
|
-
}
|
|
56
|
-
},
|
|
57
|
-
mounted() {
|
|
58
|
-
this.userInteraction = this.getProgress() // Get the progress for the page
|
|
59
|
-
|
|
60
|
-
if (this.userInteraction && this.userInteraction.state)
|
|
61
|
-
// set the state of the page to existing record if any
|
|
62
|
-
this.state = this.userInteraction.state
|
|
63
|
-
else if (
|
|
64
|
-
this.type === 'pg_menu' &&
|
|
65
|
-
this.userInteraction.state !== 'completed'
|
|
66
|
-
) {
|
|
67
|
-
this.state = 'completed' // set menu page state to completed
|
|
68
|
-
} else this.state = 'started' // set the default state to started
|
|
69
|
-
|
|
70
|
-
this.$set(this.userInteraction, 'state', this.state) // add the state to the userInteraction
|
|
71
|
-
|
|
72
|
-
if (
|
|
73
|
-
document.documentElement.scrollHeight <=
|
|
74
|
-
document.documentElement.clientHeight + 20
|
|
75
|
-
) {
|
|
76
|
-
this.completePage()
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
window.addEventListener('scroll', this.onFirstScroll, { once: true }) //listener is removed when event fired
|
|
81
|
-
},
|
|
82
|
-
|
|
83
|
-
created() {
|
|
84
|
-
},
|
|
85
|
-
|
|
86
|
-
beforeDestroy() {
|
|
87
|
-
window.removeEventListener('scroll', this.onFirstScroll, { once: true }) //in case user did not scroll
|
|
88
|
-
window.removeEventListener('scroll', this.handleScroll)
|
|
89
|
-
},
|
|
90
|
-
|
|
91
|
-
methods: {
|
|
92
|
-
onFirstScroll() {
|
|
93
|
-
window.addEventListener('scroll', this.handleScroll)
|
|
94
|
-
},
|
|
95
|
-
/**
|
|
96
|
-
* @description to handle the complete state for the gauge
|
|
97
|
-
*/
|
|
98
|
-
handleScroll(event) {
|
|
99
|
-
event
|
|
100
|
-
|
|
101
|
-
/*
|
|
102
|
-
* DocumentElement properties does not alway work properly on all Browser. To Ensure reliable value of its properties on all * Broswer we will calculate the Document Height by taking the maximum of body and documentElement height poperties.
|
|
103
|
-
* ref:https://javascript.info/size-and-scroll-window
|
|
104
|
-
*/
|
|
105
|
-
let scrollHeight = Math.max(
|
|
106
|
-
document.body.scrollHeight,
|
|
107
|
-
document.documentElement.scrollHeight,
|
|
108
|
-
document.body.offsetHeight,
|
|
109
|
-
document.documentElement.offsetHeight,
|
|
110
|
-
document.body.clientHeight,
|
|
111
|
-
document.documentElement.clientHeight
|
|
112
|
-
)
|
|
113
|
-
|
|
114
|
-
//Set scroll limit reached at 200px above the document height.
|
|
115
|
-
let scrollLimit = scrollHeight - 200
|
|
116
|
-
let fullyScrolled = Math.round(
|
|
117
|
-
document.documentElement.clientHeight + window.pageYOffset
|
|
118
|
-
)
|
|
119
|
-
|
|
120
|
-
//consider page completed when scolled value has reached or passed set limit
|
|
121
|
-
if (fullyScrolled >= scrollLimit) {
|
|
122
|
-
this.completePage()
|
|
123
|
-
}
|
|
124
|
-
},
|
|
125
|
-
/**
|
|
126
|
-
* @description set the state of the page to complete
|
|
127
|
-
* @fires send-xapi-statement to AppBaseModule.vue
|
|
128
|
-
*/
|
|
129
|
-
completePage() {
|
|
130
|
-
//Set completion state of the page when not the menu page
|
|
131
|
-
if (this.type !== 'pg_menu')
|
|
132
|
-
this.$set(this.userInteraction, 'state', 'completed')
|
|
133
|
-
|
|
134
|
-
window.removeEventListener('scroll', this.handleScroll)
|
|
135
|
-
|
|
136
|
-
/*
|
|
137
|
-
* Send xapi statement to indicate the completion of an activity
|
|
138
|
-
* Send completion of activity when all pages in Activity are completed and the page is last page of activity
|
|
139
|
-
* Send completion statement for lesson if this is the last page of the last activity in lesson
|
|
140
|
-
*/
|
|
141
|
-
|
|
142
|
-
if (this.getModuleInfo.packageType !== 'xapi') return
|
|
143
|
-
if (!this.getConnectionInfo) return
|
|
144
|
-
if (!this.getConnectionInfo.remote || !this.getConnectionInfo.actor)
|
|
145
|
-
return
|
|
146
|
-
|
|
147
|
-
//Get the current acitivty reference from store
|
|
148
|
-
const currentActivity = this.getAllActivities.list.get(
|
|
149
|
-
this.getCurrentPage.activityRef
|
|
150
|
-
)
|
|
151
|
-
|
|
152
|
-
const activity_id = `${this.getConnectionInfo.activity_id}/${this.getCurrentPage.activityRef}`
|
|
153
|
-
|
|
154
|
-
const record = this.$xapi._getProgress(
|
|
155
|
-
this.getConnectionInfo.actor.mbox.replace('mailto:', ''),
|
|
156
|
-
activity_id,
|
|
157
|
-
'completed'
|
|
158
|
-
)
|
|
159
|
-
|
|
160
|
-
//Send a completion statement for the current activity
|
|
161
|
-
//When all pages of the activity are completed and the activity recorded is as completed
|
|
162
|
-
if (
|
|
163
|
-
this.getAllCompleted[this.getCurrentPage.activityRef] &&
|
|
164
|
-
this.getAllCompleted[this.getCurrentPage.activityRef].length ===
|
|
165
|
-
currentActivity.size &&
|
|
166
|
-
!record[this.getCurrentPage.activityRef]
|
|
167
|
-
) {
|
|
168
|
-
let aTitle
|
|
169
|
-
|
|
170
|
-
//Custom name of the activity
|
|
171
|
-
if (this.getCurrentPage.activityRef === 'A00')
|
|
172
|
-
aTitle = this.$t('text.introduction')
|
|
173
|
-
else
|
|
174
|
-
aTitle = `${this.$t('text.activity')} ${
|
|
175
|
-
this.getCurrentPage.activityRef
|
|
176
|
-
}`
|
|
177
|
-
|
|
178
|
-
//Custom text for description and definition
|
|
179
|
-
let text
|
|
180
|
-
this.$i18n.locale == 'fr'
|
|
181
|
-
? (text = `L'${aTitle} de ${this.getModuleInfo.id}`)
|
|
182
|
-
: (text = `The ${aTitle} of ${this.getModuleInfo.id}`)
|
|
183
|
-
|
|
184
|
-
// Retrive only user data in lessons front its interaction that we want to send to the LRS
|
|
185
|
-
const { isFistTime, userSettings, ...data } = this.getUserInteraction
|
|
186
|
-
|
|
187
|
-
//Dispatch a send statement event
|
|
188
|
-
this.$bus.$emit('send-xapi-statement', {
|
|
189
|
-
verb: (() => {
|
|
190
|
-
//set the verbe to complete if all the state of the pages of the activity are
|
|
191
|
-
if (
|
|
192
|
-
this.getAllCompleted[this.getCurrentPage.activityRef] &&
|
|
193
|
-
this.getAllCompleted[this.getCurrentPage.activityRef].length ===
|
|
194
|
-
currentActivity.size
|
|
195
|
-
)
|
|
196
|
-
return 'completed'
|
|
197
|
-
else return 'suspended'
|
|
198
|
-
})(),
|
|
199
|
-
id: this.getCurrentPage.activityRef,
|
|
200
|
-
definition: text,
|
|
201
|
-
description: text,
|
|
202
|
-
extension: [
|
|
203
|
-
{
|
|
204
|
-
id: 'user-data',
|
|
205
|
-
content: data
|
|
206
|
-
}
|
|
207
|
-
]
|
|
208
|
-
})
|
|
209
|
-
}
|
|
210
|
-
},
|
|
211
|
-
/**
|
|
212
|
-
* @description Get the user progress for the current page
|
|
213
|
-
* @return {oject} - the existing user data for the current page
|
|
214
|
-
*/
|
|
215
|
-
getProgress() {
|
|
216
|
-
const { id, activity_ref } = this.$route.meta
|
|
217
|
-
|
|
218
|
-
const record = this.$store.getters.getUserInteraction
|
|
219
|
-
if (
|
|
220
|
-
Object.entries(record).length &&
|
|
221
|
-
record[activity_ref] &&
|
|
222
|
-
record[activity_ref][id]
|
|
223
|
-
) {
|
|
224
|
-
const { userInteraction } = record[activity_ref][id]
|
|
225
|
-
return userInteraction
|
|
226
|
-
}
|
|
227
|
-
return {}
|
|
228
|
-
},
|
|
229
|
-
anchorProgress() {
|
|
230
|
-
const anchors = document.querySelectorAll('.anchor') // look for anchor
|
|
231
|
-
const options = {
|
|
232
|
-
root: null,
|
|
233
|
-
threshold: 0
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
let anchorsComplete
|
|
237
|
-
let indexStrt
|
|
238
|
-
let anchorString
|
|
239
|
-
let indexEnd
|
|
240
|
-
let anchorComplete
|
|
241
|
-
|
|
242
|
-
let target = document.querySelector('#App-base')
|
|
243
|
-
// get anchor already seen
|
|
244
|
-
anchorsComplete = this.getAnchorComplete()
|
|
245
|
-
|
|
246
|
-
const observer = new IntersectionObserver((entries) => {
|
|
247
|
-
// everytime the page passes a anchor
|
|
248
|
-
observer.observe(target)
|
|
249
|
-
|
|
250
|
-
entries.forEach((entry) => {
|
|
251
|
-
// when it's visable in the page
|
|
252
|
-
|
|
253
|
-
if (entry.isIntersecting) {
|
|
254
|
-
// get the target
|
|
255
|
-
|
|
256
|
-
this.anchorInfo = entry.target.classList
|
|
257
|
-
indexStrt = this.anchorInfo.value.indexOf('anchor-')
|
|
258
|
-
// work the string to get juste the anchor tag
|
|
259
|
-
// must be the same as the class
|
|
260
|
-
if (indexStrt == -1) {
|
|
261
|
-
return
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
anchorString = this.anchorInfo.value.substring(indexStrt)
|
|
265
|
-
|
|
266
|
-
indexEnd = anchorString.indexOf(' ')
|
|
267
|
-
if (indexEnd != -1) {
|
|
268
|
-
anchorComplete = anchorString.slice(0, indexEnd)
|
|
269
|
-
} else {
|
|
270
|
-
anchorComplete = anchorString
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
//get all the anchors of the current activity
|
|
274
|
-
const anchors_list = this.getAnchorsForActivity(this.activityRef)
|
|
275
|
-
|
|
276
|
-
//search for the current ancor
|
|
277
|
-
const anc = anchors_list.find((a) => a.anchorTag === anchorComplete)
|
|
278
|
-
//dispatch the current anchor to the store
|
|
279
|
-
if (anc) {
|
|
280
|
-
// update the store value for current section
|
|
281
|
-
this.$store.dispatch('updateCurrentSection', anc)
|
|
282
|
-
this.$bus.$emit('anchor-seen', anchorComplete)
|
|
283
|
-
} else {
|
|
284
|
-
if (process.env.NODE_ENV === 'development')
|
|
285
|
-
console.warn(
|
|
286
|
-
`%c WARNING!>>> Anchor handeling: 👉${anchorComplete}👈 doesn't exist. Please provide a valid anchor.`,
|
|
287
|
-
'background: orange; color: white; display: block; border-radius:5px; margin:5px;'
|
|
288
|
-
)
|
|
289
|
-
|
|
290
|
-
return
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
// if you didn't aldreay seen anchors
|
|
294
|
-
if (anchorsComplete != undefined) {
|
|
295
|
-
// look if you already saw this anchor
|
|
296
|
-
if (anc && !anchorsComplete.includes(anchorComplete)) {
|
|
297
|
-
// push it in the array them in the store
|
|
298
|
-
anchorsComplete.push(anchorComplete)
|
|
299
|
-
this.$set(this.userInteraction, 'anchors', anchorsComplete)
|
|
300
|
-
}
|
|
301
|
-
} else {
|
|
302
|
-
// if you never saw any anchor
|
|
303
|
-
// push it in the array them in the store
|
|
304
|
-
anchorsComplete = []
|
|
305
|
-
if (anc) anchorsComplete.push(anchorComplete)
|
|
306
|
-
this.$set(this.userInteraction, 'anchors', anchorsComplete)
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
})
|
|
310
|
-
}, options)
|
|
311
|
-
|
|
312
|
-
// observer call llok for each anchor in page
|
|
313
|
-
anchors.forEach((anchor) => {
|
|
314
|
-
observer.observe(anchor)
|
|
315
|
-
})
|
|
316
|
-
},
|
|
317
|
-
getAnchorComplete() {
|
|
318
|
-
const userInteraction = this.getUserInteraction
|
|
319
|
-
let completeAnchor
|
|
320
|
-
|
|
321
|
-
// Verify if the element existe
|
|
322
|
-
if (
|
|
323
|
-
userInteraction[this.activityRef] &&
|
|
324
|
-
userInteraction[this.activityRef][this.id] &&
|
|
325
|
-
userInteraction[this.activityRef][this.id].userInteraction.anchors
|
|
326
|
-
) {
|
|
327
|
-
// if you already saw anchors return them
|
|
328
|
-
completeAnchor =
|
|
329
|
-
userInteraction[this.activityRef][this.id].userInteraction.anchors
|
|
330
|
-
return completeAnchor
|
|
331
|
-
}
|
|
332
|
-
},
|
|
333
|
-
showChoiceBif(data) {
|
|
334
|
-
// check if you made a choice
|
|
335
|
-
if (
|
|
336
|
-
typeof this.getBifChoice === 'undefined' ||
|
|
337
|
-
Object.keys(this.getBifChoice).length === 0
|
|
338
|
-
) {
|
|
339
|
-
return data['A']
|
|
340
|
-
} else {
|
|
341
|
-
if (this.getBifChoice.choix) {
|
|
342
|
-
// get the choise from store
|
|
343
|
-
if (data.hasOwnProperty(this.getBifChoice.choix)) {
|
|
344
|
-
let choice = data[this.getBifChoice.choix]
|
|
345
|
-
//return choice
|
|
346
|
-
return choice
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
},
|
|
351
|
-
openPopup(data) {
|
|
352
|
-
this.$bus.$emit('open-popup', data)
|
|
353
|
-
}
|
|
354
|
-
},
|
|
355
|
-
computed: {
|
|
356
|
-
...mapGetters([
|
|
357
|
-
'getUserInteraction',
|
|
358
|
-
'getCurrentPage',
|
|
359
|
-
'getModuleInfo',
|
|
360
|
-
'getAllActivities',
|
|
361
|
-
'getAllCompleted',
|
|
362
|
-
'getConnectionInfo',
|
|
363
|
-
'getAnchorsForActivity',
|
|
364
|
-
'getBifChoice'
|
|
365
|
-
]),
|
|
366
|
-
|
|
367
|
-
pageMedia() {
|
|
368
|
-
return this.$store.getters.getCurrentPage
|
|
369
|
-
},
|
|
370
|
-
console() {
|
|
371
|
-
return console
|
|
372
|
-
},
|
|
373
|
-
window() {
|
|
374
|
-
return window
|
|
375
|
-
},
|
|
376
|
-
alert() {
|
|
377
|
-
return alert
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
export default $extendsPage
|