fcad-core-dragon 2.1.0-beta.4 → 2.1.1
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 +8 -33
- package/.prettierrc +11 -0
- package/.vscode/extensions.json +8 -0
- package/.vscode/settings.json +16 -0
- package/CHANGELOG +20 -0
- package/eslint.config.js +60 -0
- package/package.json +9 -9
- package/src/$locales/en.json +3 -3
- package/src/$locales/fr.json +3 -3
- package/src/assets/data/onboardingMessages.json +47 -47
- package/src/components/AppBase.vue +5 -6
- package/src/components/AppBaseErrorDisplay.vue +438 -438
- package/src/components/AppBaseFlipCard.vue +84 -84
- package/src/components/AppBaseModule.vue +15 -17
- package/src/components/AppBasePage.vue +91 -8
- package/src/components/AppBasePopover.vue +41 -41
- package/src/components/AppBaseSkeleton.vue +24 -3
- package/src/components/AppCompAudio.vue +12 -2
- package/src/components/AppCompInputCheckBoxNx.vue +1 -2
- package/src/components/AppCompInputRadioNx.vue +8 -2
- package/src/components/AppCompInputTextToFillDropdownNx.vue +45 -0
- package/src/components/AppCompMenu.vue +423 -423
- package/src/components/AppCompNavigation.vue +2 -2
- package/src/components/AppCompPlayBarNext.vue +123 -94
- package/src/components/AppCompPopUpNext.vue +2 -2
- package/src/components/AppCompQuizNext.vue +12 -2
- package/src/components/AppCompQuizRecall.vue +10 -4
- package/src/components/AppCompSettingsMenu.vue +172 -172
- package/src/components/AppCompTableOfContent.vue +1 -4
- package/src/components/AppCompVideoPlayer.vue +7 -0
- package/src/components/AppCompViewDisplay.vue +6 -6
- package/src/composables/useTimer.js +17 -20
- package/src/externalComps/ModuleView.vue +22 -22
- package/src/externalComps/SummaryView.vue +91 -91
- package/src/main.js +5 -5
- package/src/module/stores/appStore.js +0 -1
- package/src/module/xapi/Crypto/Hasher.js +241 -241
- package/src/module/xapi/Crypto/WordArray.js +278 -278
- package/src/module/xapi/Crypto/algorithms/BufferedBlockAlgorithm.js +103 -103
- package/src/module/xapi/Crypto/algorithms/C_algo.js +315 -315
- package/src/module/xapi/Crypto/algorithms/HMAC.js +9 -9
- package/src/module/xapi/Crypto/algorithms/SHA1.js +9 -9
- package/src/module/xapi/Crypto/encoders/Base.js +105 -105
- package/src/module/xapi/Crypto/encoders/Base64.js +99 -99
- package/src/module/xapi/Crypto/encoders/Hex.js +61 -61
- package/src/module/xapi/Crypto/encoders/Latin1.js +61 -61
- package/src/module/xapi/Crypto/encoders/Utf8.js +45 -45
- package/src/module/xapi/Crypto/index.js +53 -53
- package/src/module/xapi/Statement/activity.js +47 -47
- package/src/module/xapi/Statement/agent.js +55 -55
- package/src/module/xapi/Statement/group.js +26 -26
- package/src/module/xapi/Statement/index.js +259 -259
- package/src/module/xapi/Statement/statement.js +253 -253
- package/src/module/xapi/Statement/statementRef.js +23 -23
- package/src/module/xapi/Statement/substatement.js +22 -22
- package/src/module/xapi/Statement/verb.js +36 -36
- package/src/module/xapi/activitytypes.js +17 -17
- package/src/module/xapi/utils.js +167 -167
- package/src/module/xapi/verbs.js +294 -294
- package/src/module/xapi/xapiStatement.js +444 -444
- package/src/plugins/analytics.js +4 -4
- package/src/plugins/bus.js +8 -8
- package/src/plugins/gsap.js +4 -2
- package/src/plugins/helper.js +8 -4
- 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 +1 -1
- package/src/shared/validators.js +22 -6
- package/.eslintignore +0 -29
- package/.eslintrc.cjs +0 -81
- package/bk.scss +0 -117
|
@@ -432,7 +432,8 @@ mediaMixins is used for all the methods/data shared between audio and video. In
|
|
|
432
432
|
</div>
|
|
433
433
|
<div v-if="appDebugMode" class="timer">
|
|
434
434
|
<!-- <div class="timer"> -->
|
|
435
|
-
|
|
435
|
+
<p></p>
|
|
436
|
+
<p>Timer : {{ timer.getElapsedTime() }}</p>
|
|
436
437
|
</div>
|
|
437
438
|
</div>
|
|
438
439
|
</div>
|
|
@@ -712,6 +713,12 @@ export default {
|
|
|
712
713
|
}
|
|
713
714
|
},
|
|
714
715
|
watch: {
|
|
716
|
+
viewedThresholdReached: {
|
|
717
|
+
handler() {
|
|
718
|
+
//send a "viewed" event for this media
|
|
719
|
+
this.trackEvent('end')
|
|
720
|
+
}
|
|
721
|
+
},
|
|
715
722
|
getUserInteraction: {
|
|
716
723
|
handler() {
|
|
717
724
|
const activityID = this.$route.meta.activity_ref
|
|
@@ -791,6 +798,96 @@ export default {
|
|
|
791
798
|
'setMediaMuted',
|
|
792
799
|
'setMediaPlaybarValues'
|
|
793
800
|
]),
|
|
801
|
+
trackEvent(action) {
|
|
802
|
+
const expectedActions = ['play', 'viewed']
|
|
803
|
+
if (!action || !expectedActions.includes(action)) return
|
|
804
|
+
const media = this.mediaRawData
|
|
805
|
+
if (!media || !media.mSources || !media.mSources.length) return
|
|
806
|
+
const { mTitle, mSources } = media
|
|
807
|
+
const { mType } = this.mediaToPlay
|
|
808
|
+
const URIBase = `media/${mType}/`
|
|
809
|
+
|
|
810
|
+
//send statement
|
|
811
|
+
const stmt = {
|
|
812
|
+
id: (() => `${URIBase}${mSources[0].src.split('/').toReversed()[0]}`)(),
|
|
813
|
+
verb: null,
|
|
814
|
+
definition: mTitle || mSources[0].src,
|
|
815
|
+
description: null,
|
|
816
|
+
type: `https://w3id.org/xapi/${mType}/activity-type/${mType}`,
|
|
817
|
+
context: {
|
|
818
|
+
contextActivities: {
|
|
819
|
+
category: [{ id: `https://w3id.org/xapi/${mType}` }]
|
|
820
|
+
},
|
|
821
|
+
extensions: {
|
|
822
|
+
'https://w3id.org/xapi/video/extensions/session-id':
|
|
823
|
+
this.getModuleInfo.id
|
|
824
|
+
}
|
|
825
|
+
},
|
|
826
|
+
result: null
|
|
827
|
+
}
|
|
828
|
+
switch (action) {
|
|
829
|
+
case 'play': {
|
|
830
|
+
stmt.verb = 'played'
|
|
831
|
+
stmt.description = `${mType} ${stmt.id.replace(URIBase, '')}`
|
|
832
|
+
stmt.result = {
|
|
833
|
+
extensions: {
|
|
834
|
+
'https://w3id.org/xapi/video/extensions/time': Math.round(
|
|
835
|
+
this.startedTime
|
|
836
|
+
),
|
|
837
|
+
'https://w3id.org/xapi/video/extensions/progress': Math.round(
|
|
838
|
+
(this.startedTime / this.mediaDuration) * 100
|
|
839
|
+
)
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
break
|
|
843
|
+
}
|
|
844
|
+
case 'viewed': {
|
|
845
|
+
const expectedViewTime = Number(
|
|
846
|
+
this.timer.getElapsedTime() / Math.trunc(this.mediaDuration)
|
|
847
|
+
)
|
|
848
|
+
stmt.verb = 'completed'
|
|
849
|
+
stmt.description = `${mType} ${stmt.id.replace(URIBase, '')}`
|
|
850
|
+
stmt.result = {
|
|
851
|
+
extensions: {
|
|
852
|
+
'https://w3id.org/xapi/video/extensions/progress':
|
|
853
|
+
expectedViewTime * 100,
|
|
854
|
+
'https://w3id.org/xapi/video/extensions/time-from': Math.round(
|
|
855
|
+
this.startedTime
|
|
856
|
+
),
|
|
857
|
+
'https://w3id.org/xapi/video/extensions/time-to': this.currentTime
|
|
858
|
+
},
|
|
859
|
+
completion:
|
|
860
|
+
expectedViewTime >= this.viewedThreshold &&
|
|
861
|
+
this.viewedThresholdReached
|
|
862
|
+
}
|
|
863
|
+
stmt.duration = this.timer.ISOTimeParser(
|
|
864
|
+
expectedViewTime * this.mediaDuration
|
|
865
|
+
)
|
|
866
|
+
break
|
|
867
|
+
}
|
|
868
|
+
}
|
|
869
|
+
this.$bus.$emit('send-xapi-statement', stmt)
|
|
870
|
+
//send Analytics Event
|
|
871
|
+
const analyticsEventName = `fcad_${mType}_${action}`
|
|
872
|
+
this.trackWithGA(analyticsEventName)
|
|
873
|
+
},
|
|
874
|
+
trackWithGA(eventName) {
|
|
875
|
+
if (
|
|
876
|
+
!eventName ||
|
|
877
|
+
!this.mediaRawData ||
|
|
878
|
+
!this.mediaRawData.mSources ||
|
|
879
|
+
!this.mediaRawData.mSources.length
|
|
880
|
+
)
|
|
881
|
+
return
|
|
882
|
+
const { mTitle, mSources } = this.mediaRawData
|
|
883
|
+
|
|
884
|
+
const eventParams = {
|
|
885
|
+
title: mTitle || mSources[0].src,
|
|
886
|
+
url: mSources[0].src
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
this.$analytics.sendEvent(eventName, eventParams)
|
|
890
|
+
},
|
|
794
891
|
|
|
795
892
|
//======================================================================
|
|
796
893
|
/**
|
|
@@ -882,7 +979,8 @@ export default {
|
|
|
882
979
|
!this.isPlaying ? this.timer.start() : this.timer.pause()
|
|
883
980
|
|
|
884
981
|
if (!this.playStmtSent) {
|
|
885
|
-
this.sendMediaStatement(
|
|
982
|
+
//this.sendMediaStatement("play", this.startedTime, null);
|
|
983
|
+
this.trackEvent('play')
|
|
886
984
|
this.playStmtSent = true
|
|
887
985
|
}
|
|
888
986
|
//Data
|
|
@@ -918,14 +1016,10 @@ export default {
|
|
|
918
1016
|
if (this.mediaElement && this.isPlaying) {
|
|
919
1017
|
this.mediaElement.pause()
|
|
920
1018
|
this.isPlaying = false
|
|
921
|
-
|
|
922
|
-
const expectedViewTime = Number(
|
|
923
|
-
this.timer.getElapsedTime() / Math.trunc(this.mediaDuration)
|
|
924
|
-
) //relation view time to media duration
|
|
925
|
-
|
|
926
1019
|
this.timer.stop()
|
|
927
1020
|
|
|
928
|
-
this.sendMediaStatement(
|
|
1021
|
+
//this.sendMediaStatement("end", this.startedTime, expectedViewTime);
|
|
1022
|
+
this.trackEvent('viewed')
|
|
929
1023
|
this.playStmtSent = false //reset the play statement for next play
|
|
930
1024
|
}
|
|
931
1025
|
this.$bus.$emit('media-viewed', this.mediaToPlay.id)
|
|
@@ -1174,7 +1268,10 @@ export default {
|
|
|
1174
1268
|
this.currentTime = e.target.currentTime
|
|
1175
1269
|
|
|
1176
1270
|
//Set viewedThresholdReached to true when the threshold is reached
|
|
1177
|
-
if (
|
|
1271
|
+
if (
|
|
1272
|
+
this.timer.getElapsedTime() / Math.trunc(this.mediaDuration) >=
|
|
1273
|
+
this.viewedThreshold
|
|
1274
|
+
)
|
|
1178
1275
|
this.viewedThresholdReached = true
|
|
1179
1276
|
|
|
1180
1277
|
//Update strings
|
|
@@ -1529,6 +1626,7 @@ export default {
|
|
|
1529
1626
|
*/
|
|
1530
1627
|
toggleFullScreen() {
|
|
1531
1628
|
const fullscreenElement = this.mediaContainer
|
|
1629
|
+
console.log(fullscreenElement)
|
|
1532
1630
|
|
|
1533
1631
|
if (document.fullscreenElement) {
|
|
1534
1632
|
// exitFullscreen is only available on the Document object.
|
|
@@ -1682,7 +1780,7 @@ export default {
|
|
|
1682
1780
|
this.hideTimer = setTimeout(() => {
|
|
1683
1781
|
this.showControlsValue = false
|
|
1684
1782
|
}, this.delayUntilHide)
|
|
1685
|
-
}
|
|
1783
|
+
}
|
|
1686
1784
|
|
|
1687
1785
|
/**
|
|
1688
1786
|
* @description - Send xAPI statement for media play and end
|
|
@@ -1690,87 +1788,6 @@ export default {
|
|
|
1690
1788
|
* @param {Number} startTime - time in seconds when the media start to be played
|
|
1691
1789
|
* @param {Number} endTime - time in seconds when the media stop to be played
|
|
1692
1790
|
*/
|
|
1693
|
-
async sendMediaStatement(action, startTime = null, endTime = null) {
|
|
1694
|
-
const expectedActions = ['play', 'end']
|
|
1695
|
-
if (!action || !expectedActions.includes(action)) return
|
|
1696
|
-
|
|
1697
|
-
// const { audiosData, videosData } = this.getCurrentPage
|
|
1698
|
-
const media = this.mediaRawData
|
|
1699
|
-
// this.mediaToPlay.mType == 'video'
|
|
1700
|
-
// ? videosData.find((el) => el.id == this.mediaToPlay.id)
|
|
1701
|
-
// : audiosData.find((el) => el.id == this.mediaToPlay.id)
|
|
1702
|
-
|
|
1703
|
-
if (!media || !media.mSources || !media.mSources.length) return
|
|
1704
|
-
|
|
1705
|
-
const { mTitle, mSources } = media
|
|
1706
|
-
const { mType } = this.mediaToPlay
|
|
1707
|
-
|
|
1708
|
-
const URIBase = `media/${mType}/`
|
|
1709
|
-
|
|
1710
|
-
const stmt = {
|
|
1711
|
-
id: (() => `${URIBase}${mSources[0].src.split('/').toReversed()[0]}`)(),
|
|
1712
|
-
verb: null,
|
|
1713
|
-
definition: mTitle || mSources[0].src,
|
|
1714
|
-
description: null,
|
|
1715
|
-
type: `https://w3id.org/xapi/${mType}/activity-type/${mType}`,
|
|
1716
|
-
context: {
|
|
1717
|
-
contextActivities: {
|
|
1718
|
-
category: [{ id: `https://w3id.org/xapi/${mType}` }]
|
|
1719
|
-
},
|
|
1720
|
-
extensions: {
|
|
1721
|
-
'https://w3id.org/xapi/video/extensions/session-id':
|
|
1722
|
-
this.getModuleInfo.id
|
|
1723
|
-
}
|
|
1724
|
-
},
|
|
1725
|
-
result: null
|
|
1726
|
-
}
|
|
1727
|
-
|
|
1728
|
-
switch (action) {
|
|
1729
|
-
case 'play': {
|
|
1730
|
-
stmt.verb = 'played'
|
|
1731
|
-
stmt.description = `${mType} ${stmt.id.replace(URIBase, '')}`
|
|
1732
|
-
stmt.result = {
|
|
1733
|
-
extensions: {
|
|
1734
|
-
'https://w3id.org/xapi/video/extensions/time':
|
|
1735
|
-
Math.round(startTime),
|
|
1736
|
-
'https://w3id.org/xapi/video/extensions/progress': Math.round(
|
|
1737
|
-
(startTime / this.mediaDuration) * 100
|
|
1738
|
-
)
|
|
1739
|
-
}
|
|
1740
|
-
}
|
|
1741
|
-
break
|
|
1742
|
-
}
|
|
1743
|
-
|
|
1744
|
-
case 'end': {
|
|
1745
|
-
stmt.verb = 'completed'
|
|
1746
|
-
stmt.description = `${mType} ${stmt.id.replace(URIBase, '')}`
|
|
1747
|
-
stmt.result = {
|
|
1748
|
-
extensions: {
|
|
1749
|
-
'https://w3id.org/xapi/video/extensions/progress': endTime * 100,
|
|
1750
|
-
'https://w3id.org/xapi/video/extensions/time-from':
|
|
1751
|
-
Math.round(startTime),
|
|
1752
|
-
'https://w3id.org/xapi/video/extensions/time-to': this.currentTime
|
|
1753
|
-
},
|
|
1754
|
-
completion:
|
|
1755
|
-
endTime >= this.viewedThreshold && this.viewedThresholdReached
|
|
1756
|
-
}
|
|
1757
|
-
stmt.duration = this.timer.ISOTimeParser(endTime * this.mediaDuration)
|
|
1758
|
-
break
|
|
1759
|
-
}
|
|
1760
|
-
}
|
|
1761
|
-
|
|
1762
|
-
/* send play/end events to Google Analytics */
|
|
1763
|
-
const analyticsEventName = `fcad_${mType}_${action}`
|
|
1764
|
-
const analyticsEventParams = {
|
|
1765
|
-
title: stmt.definition,
|
|
1766
|
-
url: mSources[0].src
|
|
1767
|
-
}
|
|
1768
|
-
if (action === 'end') {
|
|
1769
|
-
analyticsEventParams.viewed = this.viewedThresholdReached
|
|
1770
|
-
}
|
|
1771
|
-
this.$analytics.sendEvent(analyticsEventName, analyticsEventParams)
|
|
1772
|
-
this.$bus.$emit('send-xapi-statement', stmt)
|
|
1773
|
-
}
|
|
1774
1791
|
}
|
|
1775
1792
|
}
|
|
1776
1793
|
</script>
|
|
@@ -1781,19 +1798,21 @@ export default {
|
|
|
1781
1798
|
width: 100%;
|
|
1782
1799
|
justify-content: center;
|
|
1783
1800
|
display: flex;
|
|
1801
|
+
margin-bottom: 78px;
|
|
1784
1802
|
}
|
|
1785
1803
|
|
|
1786
1804
|
.playback-button {
|
|
1787
1805
|
position: absolute;
|
|
1788
|
-
|
|
1806
|
+
bottom: 0;
|
|
1789
1807
|
left: 0;
|
|
1790
1808
|
width: 100%;
|
|
1791
|
-
height:
|
|
1809
|
+
height: 94%;
|
|
1792
1810
|
display: flex;
|
|
1793
1811
|
flex-flow: column wrap;
|
|
1794
1812
|
justify-content: center;
|
|
1795
1813
|
align-items: center;
|
|
1796
1814
|
background-color: transparent;
|
|
1815
|
+
|
|
1797
1816
|
.playback-wrapper {
|
|
1798
1817
|
height: 64px;
|
|
1799
1818
|
width: 64px;
|
|
@@ -1817,9 +1836,10 @@ export default {
|
|
|
1817
1836
|
display: flex;
|
|
1818
1837
|
flex-direction: column;
|
|
1819
1838
|
position: absolute;
|
|
1820
|
-
bottom:
|
|
1839
|
+
bottom: -78px;
|
|
1821
1840
|
opacity: 0;
|
|
1822
1841
|
z-index: 2;
|
|
1842
|
+
|
|
1823
1843
|
&.show-controls {
|
|
1824
1844
|
opacity: 1;
|
|
1825
1845
|
transition: opacity 0.35s ease-in-out;
|
|
@@ -2158,6 +2178,7 @@ export default {
|
|
|
2158
2178
|
min-width: 50px;
|
|
2159
2179
|
margin: 0 auto;
|
|
2160
2180
|
}
|
|
2181
|
+
|
|
2161
2182
|
.progress-area {
|
|
2162
2183
|
justify-content: center;
|
|
2163
2184
|
}
|
|
@@ -2235,6 +2256,14 @@ export default {
|
|
|
2235
2256
|
}
|
|
2236
2257
|
}
|
|
2237
2258
|
|
|
2259
|
+
.FS {
|
|
2260
|
+
&:fullscreen {
|
|
2261
|
+
.pb-wrapper {
|
|
2262
|
+
bottom: -45px;
|
|
2263
|
+
}
|
|
2264
|
+
}
|
|
2265
|
+
}
|
|
2266
|
+
|
|
2238
2267
|
@keyframes handlePlayBack {
|
|
2239
2268
|
0% {
|
|
2240
2269
|
opacity: 0;
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
<div class="pop-containt">
|
|
62
62
|
<div class="pop-box">
|
|
63
63
|
<div id="popHeader">
|
|
64
|
-
<
|
|
64
|
+
<div id="dialogTitle" class="p-title" v-html="pTitle"></div>
|
|
65
65
|
</div>
|
|
66
66
|
<div class="box-content-popUp"></div>
|
|
67
67
|
<div
|
|
@@ -103,7 +103,7 @@
|
|
|
103
103
|
<div class="pop-containt">
|
|
104
104
|
<div class="pop-box">
|
|
105
105
|
<div id="popHeader">
|
|
106
|
-
<
|
|
106
|
+
<p id="dialogTitle" class="p-title" v-html="pTitle"></p>
|
|
107
107
|
</div>
|
|
108
108
|
<div class="box-content-popUp">
|
|
109
109
|
<template v-if="contentLength > 0">
|
|
@@ -22,7 +22,11 @@
|
|
|
22
22
|
>
|
|
23
23
|
<!--Show skeleton while quiz data is not ready-->
|
|
24
24
|
<template v-if="!isReady">
|
|
25
|
-
<app-base-skeleton
|
|
25
|
+
<app-base-skeleton
|
|
26
|
+
:skeleton-text="''"
|
|
27
|
+
:skeleton-type="skeletonType(quizData.type_question)"
|
|
28
|
+
/>
|
|
29
|
+
{{ quizData.type_question }}
|
|
26
30
|
</template>
|
|
27
31
|
<!--Show when quiz data is ready-->
|
|
28
32
|
<template v-else>
|
|
@@ -185,7 +189,6 @@ export default {
|
|
|
185
189
|
|
|
186
190
|
return quiz
|
|
187
191
|
},
|
|
188
|
-
|
|
189
192
|
retroAriaLabel() {
|
|
190
193
|
let label = ''
|
|
191
194
|
switch (this.retroType) {
|
|
@@ -489,6 +492,13 @@ export default {
|
|
|
489
492
|
if (el.id !== this.quizData.id) return
|
|
490
493
|
|
|
491
494
|
this.showRetro = value
|
|
495
|
+
},
|
|
496
|
+
skeletonType(type) {
|
|
497
|
+
if (type == 'reponse_ouverte') {
|
|
498
|
+
return `quiz-texte`
|
|
499
|
+
} else {
|
|
500
|
+
return `quiz-choix`
|
|
501
|
+
}
|
|
492
502
|
}
|
|
493
503
|
}
|
|
494
504
|
}
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
<!--Optionnal title, out of quiz-answer-conditionning, default tag H4, but can be change by user-->
|
|
11
11
|
<!--Show skeleton while app data is not ready-->
|
|
12
12
|
<template v-if="!isReady">
|
|
13
|
-
<app-base-skeleton :skeleton-
|
|
13
|
+
<app-base-skeleton :skeleton-text="''" :skeleton-type="`quiz-recall`" />
|
|
14
14
|
</template>
|
|
15
15
|
<!--Show app data when ready-->
|
|
16
16
|
<template v-else>
|
|
@@ -140,10 +140,17 @@ export default {
|
|
|
140
140
|
for (let property in searchObject) {
|
|
141
141
|
//Should only check for not null poperties
|
|
142
142
|
if (!searchObject[property]) continue
|
|
143
|
+
|
|
143
144
|
// Should only check for Object or Array property
|
|
144
145
|
if (
|
|
145
|
-
searchObject[property].constructor !==
|
|
146
|
-
searchObject[property].constructor !==
|
|
146
|
+
searchObject[property].constructor !== Object &&
|
|
147
|
+
searchObject[property].constructor !== Array
|
|
148
|
+
)
|
|
149
|
+
continue
|
|
150
|
+
|
|
151
|
+
if (
|
|
152
|
+
searchObject[property].constructor == Array &&
|
|
153
|
+
searchObject[property][0].constructor !== Object
|
|
147
154
|
)
|
|
148
155
|
continue
|
|
149
156
|
|
|
@@ -152,7 +159,6 @@ export default {
|
|
|
152
159
|
searchObject[property].constructor === Object
|
|
153
160
|
? [searchObject[property]]
|
|
154
161
|
: searchObject[property]
|
|
155
|
-
|
|
156
162
|
//Only Search for quiz:
|
|
157
163
|
//Search Array is a list of quiz if one of its element has at least the property 'type_question'
|
|
158
164
|
return searchArray[0]['type_question']
|