@windward/core 0.16.0 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/components/Content/Blocks/Accordion.vue +49 -39
- package/components/Content/Blocks/BlockQuote.vue +10 -1
- package/components/Content/Blocks/ClickableIcons.vue +55 -39
- package/components/Content/Blocks/Email.vue +11 -2
- package/components/Content/Blocks/FileDownload.vue +9 -1
- package/components/Content/Blocks/OpenResponse.vue +25 -12
- package/components/Content/Blocks/ScenarioChoice.vue +14 -5
- package/components/Content/Blocks/Tab.vue +15 -2
- package/components/Content/Blocks/UserUpload.vue +10 -1
- package/components/Content/Blocks/Video.vue +13 -4
- package/components/Navigation/Items/UserUploadNav.vue +4 -0
- package/components/Settings/AccordionSettings.vue +16 -30
- package/components/Settings/BlockQuoteSettings.vue +35 -48
- package/components/Settings/ClickableIconsSettings.vue +14 -27
- package/components/Settings/EmailSettings.vue +18 -28
- package/components/Settings/FileDownloadSettings.vue +14 -21
- package/components/Settings/OpenResponseSettings.vue +13 -27
- package/components/Settings/ScenarioChoiceSettings.vue +19 -29
- package/components/Settings/TabSettings.vue +22 -30
- package/components/Settings/TextEditorSettings.vue +1 -0
- package/components/Settings/UserUploadSettings.vue +12 -22
- package/components/Settings/VideoSettings.vue +12 -19
- package/components/utils/ContentViewer.vue +3 -0
- package/components/utils/FillInBlank/FillInBlankInput.vue +32 -28
- package/components/{Content/Blocks → utils}/GenerateAIQuestionButton.vue +117 -25
- package/components/utils/TinyMCEWrapper.vue +14 -57
- package/helpers/tinymce/WindwardPlugins.ts +36 -3
- package/models/Activity.ts +9 -0
- package/package.json +1 -1
- package/test/__mocks__/componentsMock.js +1 -0
- package/utils/index.js +1 -1
|
@@ -1,27 +1,10 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div>
|
|
3
3
|
<v-row class="pl-3 pr-3">
|
|
4
|
-
<
|
|
5
|
-
|
|
6
|
-
v-model="block.metadata.config.title"
|
|
7
|
-
:autofocus="true"
|
|
8
|
-
:rules="$Validation.getRule('block.title')"
|
|
9
|
-
:counter="$Validation.getLimit('block.title')"
|
|
10
|
-
outlined
|
|
11
|
-
:label="
|
|
12
|
-
$t('windward.core.components.settings.clickable_icon.title')
|
|
13
|
-
"
|
|
4
|
+
<BaseContentBlockSettings
|
|
5
|
+
v-model="block.metadata.config"
|
|
14
6
|
:disabled="render"
|
|
15
|
-
></
|
|
16
|
-
<v-textarea
|
|
17
|
-
id="block-settings-instructions"
|
|
18
|
-
v-model="block.metadata.config.instructions"
|
|
19
|
-
:rules="$Validation.getRule('block.instructions')"
|
|
20
|
-
:counter="$Validation.getLimit('block.instructions')"
|
|
21
|
-
outlined
|
|
22
|
-
:label="$t('components.content.settings.base.instructions')"
|
|
23
|
-
:disabled="render"
|
|
24
|
-
></v-textarea>
|
|
7
|
+
></BaseContentBlockSettings>
|
|
25
8
|
</v-row>
|
|
26
9
|
<v-divider class="my-4 primary"></v-divider>
|
|
27
10
|
<p>{{ $t('windward.core.components.settings.tab.tabs') }}</p>
|
|
@@ -130,16 +113,30 @@
|
|
|
130
113
|
<script>
|
|
131
114
|
import _, { get } from 'lodash'
|
|
132
115
|
import Crypto from '~/helpers/Crypto'
|
|
133
|
-
import TextEditor from '~/components/Text/TextEditor'
|
|
134
116
|
import ImageAssetSettings from '~/components/Content/Settings/ImageAssetSettings.vue'
|
|
135
117
|
import BaseContentSettings from '~/components/Content/Settings/BaseContentSettings.js'
|
|
136
118
|
import SortableExpansionPanel from '~/components/Core/SortableExpansionPanel.vue'
|
|
137
119
|
import Uuid from '~/helpers/Uuid'
|
|
120
|
+
import BaseContentBlockSettings from '~/components/Content/Settings/BaseContentBlockSettings.vue'
|
|
121
|
+
import TextEditor from '~/components/Text/TextEditor'
|
|
138
122
|
|
|
139
123
|
export default {
|
|
140
124
|
name: 'TabSettings',
|
|
141
|
-
components: {
|
|
125
|
+
components: {
|
|
126
|
+
TextEditor,
|
|
127
|
+
ImageAssetSettings,
|
|
128
|
+
SortableExpansionPanel,
|
|
129
|
+
BaseContentBlockSettings,
|
|
130
|
+
},
|
|
142
131
|
extends: BaseContentSettings,
|
|
132
|
+
data() {
|
|
133
|
+
return {
|
|
134
|
+
expansionPanelKey: '0',
|
|
135
|
+
textEditorUpdateKey: Crypto.id(),
|
|
136
|
+
valid: true,
|
|
137
|
+
loading: false,
|
|
138
|
+
}
|
|
139
|
+
},
|
|
143
140
|
beforeMount() {
|
|
144
141
|
if (_.isEmpty(this.block)) {
|
|
145
142
|
this.block = {}
|
|
@@ -158,6 +155,9 @@ export default {
|
|
|
158
155
|
if (_.isEmpty(this.block.metadata.config.title)) {
|
|
159
156
|
this.block.metadata.config.title = ''
|
|
160
157
|
}
|
|
158
|
+
if (!_.isBoolean(this.block.metadata.config.display_title)) {
|
|
159
|
+
this.$set(this.block.metadata.config, 'display_title', true)
|
|
160
|
+
}
|
|
161
161
|
if (
|
|
162
162
|
_.isEmpty(this.block.metadata.config.instructions) &&
|
|
163
163
|
this.block.id &&
|
|
@@ -188,14 +188,6 @@ export default {
|
|
|
188
188
|
this.block.metadata.config.items.push(defaultObject)
|
|
189
189
|
}
|
|
190
190
|
},
|
|
191
|
-
data() {
|
|
192
|
-
return {
|
|
193
|
-
expansionPanelKey: '0',
|
|
194
|
-
textEditorUpdateKey: Crypto.id(),
|
|
195
|
-
valid: true,
|
|
196
|
-
loading: false,
|
|
197
|
-
}
|
|
198
|
-
},
|
|
199
191
|
mounted() {
|
|
200
192
|
if (this.block.metadata.config.items.length <= 0) {
|
|
201
193
|
this.onAddElement()
|
|
@@ -1,24 +1,11 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div>
|
|
3
|
-
<v-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
:autofocus="true"
|
|
10
|
-
:label="$t('components.content.settings.base.title')"
|
|
11
|
-
:disabled="render"
|
|
12
|
-
></v-text-field>
|
|
13
|
-
<v-textarea
|
|
14
|
-
id="block-settings-instructions"
|
|
15
|
-
v-model="block.metadata.config.instructions"
|
|
16
|
-
:rules="$Validation.getRule('block.instructions')"
|
|
17
|
-
:counter="$Validation.getLimit('block.instructions')"
|
|
18
|
-
outlined
|
|
19
|
-
:label="$t('components.content.settings.base.instructions')"
|
|
20
|
-
:disabled="render"
|
|
21
|
-
></v-textarea>
|
|
3
|
+
<v-container>
|
|
4
|
+
<BaseContentBlockSettings
|
|
5
|
+
v-model="block.metadata.config"
|
|
6
|
+
:disabled="render"
|
|
7
|
+
></BaseContentBlockSettings>
|
|
8
|
+
</v-container>
|
|
22
9
|
<v-switch
|
|
23
10
|
v-model="block.metadata.config.uploadSettings.multiple"
|
|
24
11
|
:label="
|
|
@@ -45,15 +32,15 @@
|
|
|
45
32
|
</template>
|
|
46
33
|
<script>
|
|
47
34
|
import BaseContentSettings from '~/components/Content/Settings/BaseContentSettings.js'
|
|
48
|
-
import Crypto from '~/helpers/Crypto'
|
|
49
|
-
import TextEditor from '~/components/Text/TextEditor'
|
|
50
35
|
import _ from 'lodash'
|
|
51
36
|
import Uuid from '~/helpers/Uuid'
|
|
37
|
+
import BaseContentBlockSettings from '~/components/Content/Settings/BaseContentBlockSettings.vue'
|
|
38
|
+
import TextEditor from '~/components/Text/TextEditor'
|
|
52
39
|
|
|
53
40
|
export default {
|
|
54
41
|
name: 'UserUploadSettings',
|
|
42
|
+
components: { TextEditor, BaseContentBlockSettings },
|
|
55
43
|
extends: BaseContentSettings,
|
|
56
|
-
components: { TextEditor },
|
|
57
44
|
beforeMount() {
|
|
58
45
|
if (_.isEmpty(this.block)) {
|
|
59
46
|
this.block = {}
|
|
@@ -73,6 +60,9 @@ export default {
|
|
|
73
60
|
if (_.isEmpty(this.block.metadata.config.title)) {
|
|
74
61
|
this.block.metadata.config.title = ''
|
|
75
62
|
}
|
|
63
|
+
if (!_.isBoolean(this.block.metadata.config.display_title)) {
|
|
64
|
+
this.$set(this.block.metadata.config, 'display_title', true)
|
|
65
|
+
}
|
|
76
66
|
if (
|
|
77
67
|
_.isEmpty(this.block.metadata.config.instructions) &&
|
|
78
68
|
this.block.id &&
|
|
@@ -2,29 +2,18 @@
|
|
|
2
2
|
<div>
|
|
3
3
|
<v-row>
|
|
4
4
|
<v-col cols="12">
|
|
5
|
-
<
|
|
6
|
-
|
|
7
|
-
v-model="block.metadata.config.title"
|
|
8
|
-
:rules="$Validation.getRule('block.title')"
|
|
9
|
-
:counter="$Validation.getLimit('block.title')"
|
|
10
|
-
outlined
|
|
11
|
-
:label="$t('windward.core.components.settings.video.title')"
|
|
5
|
+
<BaseContentBlockSettings
|
|
6
|
+
v-model="block.metadata.config"
|
|
12
7
|
:disabled="render"
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
outlined
|
|
18
|
-
auto-grow
|
|
19
|
-
:rules="$Validation.getRule('block.instructions')"
|
|
20
|
-
:counter="$Validation.getLimit('block.instructions')"
|
|
21
|
-
:label="
|
|
8
|
+
:title-label="
|
|
9
|
+
$t('windward.core.components.settings.video.title')
|
|
10
|
+
"
|
|
11
|
+
:instructions-label="
|
|
22
12
|
$t(
|
|
23
13
|
'components.content.settings.base.description_optional'
|
|
24
14
|
)
|
|
25
15
|
"
|
|
26
|
-
|
|
27
|
-
></v-textarea>
|
|
16
|
+
></BaseContentBlockSettings>
|
|
28
17
|
|
|
29
18
|
<h4 class="mb-3">
|
|
30
19
|
{{ $t('windward.core.components.settings.video.sources') }}
|
|
@@ -404,11 +393,12 @@ import _ from 'lodash'
|
|
|
404
393
|
import BaseContentSettings from '~/components/Content/Settings/BaseContentSettings.js'
|
|
405
394
|
import ContentBlockAsset from '~/components/Content/ContentBlockAsset.vue'
|
|
406
395
|
import SourcePicker from './VideoSettings/SourcePicker.vue'
|
|
396
|
+
import BaseContentBlockSettings from '~/components/Content/Settings/BaseContentBlockSettings.vue'
|
|
407
397
|
|
|
408
398
|
export default {
|
|
409
399
|
name: 'VideoSettings',
|
|
400
|
+
components: { ContentBlockAsset, SourcePicker, BaseContentBlockSettings },
|
|
410
401
|
extends: BaseContentSettings,
|
|
411
|
-
components: { ContentBlockAsset, SourcePicker },
|
|
412
402
|
data() {
|
|
413
403
|
return {
|
|
414
404
|
fileTab: null,
|
|
@@ -450,6 +440,9 @@ export default {
|
|
|
450
440
|
this.onAddPlaylistItem()
|
|
451
441
|
this.playlistPaginator = 1
|
|
452
442
|
}
|
|
443
|
+
if (!_.isBoolean(this.block.metadata.config.display_title)) {
|
|
444
|
+
this.$set(this.block.metadata.config, 'display_title', true)
|
|
445
|
+
}
|
|
453
446
|
},
|
|
454
447
|
mounted() {
|
|
455
448
|
this.reloadMedia()
|
|
@@ -30,7 +30,8 @@
|
|
|
30
30
|
color="primary"
|
|
31
31
|
elevation="0"
|
|
32
32
|
outlined
|
|
33
|
-
@click="
|
|
33
|
+
@click="close"
|
|
34
|
+
@keydown.esc="close"
|
|
34
35
|
>
|
|
35
36
|
{{
|
|
36
37
|
$t(
|
|
@@ -46,12 +47,11 @@
|
|
|
46
47
|
|
|
47
48
|
<div class="fib">
|
|
48
49
|
<v-text-field
|
|
50
|
+
v-model="userInput"
|
|
49
51
|
:disabled="false"
|
|
50
52
|
outlined
|
|
51
53
|
dense
|
|
52
|
-
v-model="userInput"
|
|
53
54
|
clear-icon="mdi-close-circle-outline"
|
|
54
|
-
@click:append-outer="toggleToolTip"
|
|
55
55
|
clearable
|
|
56
56
|
:background-color="feedback"
|
|
57
57
|
:placeholder="
|
|
@@ -59,18 +59,19 @@
|
|
|
59
59
|
'windward.core.components.utils.fill_in_the_blank.fill_in_blank_input.add_answer'
|
|
60
60
|
)
|
|
61
61
|
"
|
|
62
|
-
@input="showAnswer = false"
|
|
63
|
-
@keydown="onPressEnter"
|
|
64
62
|
:aria-label="
|
|
65
63
|
$t(
|
|
66
64
|
'windward.core.components.utils.tiny_mce_wrapper.fill_in_blank'
|
|
67
65
|
)
|
|
68
66
|
"
|
|
67
|
+
@click:append-outer="toggleToolTip"
|
|
68
|
+
@input="showAnswer = false"
|
|
69
|
+
@keydown="onPressEnter"
|
|
69
70
|
></v-text-field>
|
|
70
71
|
|
|
71
72
|
<v-btn
|
|
72
73
|
v-if="userInput && userInput.length > 0"
|
|
73
|
-
|
|
74
|
+
ref="btnCheck"
|
|
74
75
|
elevation="0"
|
|
75
76
|
color="primary"
|
|
76
77
|
outlined
|
|
@@ -79,25 +80,22 @@
|
|
|
79
80
|
'windward.core.components.utils.fill_in_the_blank.fill_in_blank_input.check_answer'
|
|
80
81
|
)
|
|
81
82
|
"
|
|
83
|
+
@click="toggleToolTip"
|
|
82
84
|
>{{
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
)
|
|
87
|
-
: $t(
|
|
88
|
-
'windward.core.components.utils.fill_in_the_blank.fill_in_blank_input.check'
|
|
89
|
-
)
|
|
85
|
+
$t(
|
|
86
|
+
'windward.core.components.utils.fill_in_the_blank.fill_in_blank_input.check'
|
|
87
|
+
)
|
|
90
88
|
}}</v-btn
|
|
91
89
|
>
|
|
92
90
|
</div>
|
|
93
91
|
</span>
|
|
94
92
|
</template>
|
|
95
93
|
<script>
|
|
96
|
-
import ContentViewer from '../ContentViewer.vue'
|
|
97
94
|
import _ from 'lodash'
|
|
95
|
+
|
|
98
96
|
export default {
|
|
99
97
|
name: 'FillInBlankInput',
|
|
100
|
-
components: {
|
|
98
|
+
components: {},
|
|
101
99
|
props: {
|
|
102
100
|
answer: { type: String, required: true },
|
|
103
101
|
description: {
|
|
@@ -144,6 +142,20 @@ export default {
|
|
|
144
142
|
return ''
|
|
145
143
|
},
|
|
146
144
|
},
|
|
145
|
+
watch: {
|
|
146
|
+
// set focus on the action button when dialog loaded for accessibility
|
|
147
|
+
show: function (newValue) {
|
|
148
|
+
if (newValue) {
|
|
149
|
+
this.timerId = setTimeout(() => {
|
|
150
|
+
this.setFocusAction()
|
|
151
|
+
}, 100)
|
|
152
|
+
} else {
|
|
153
|
+
if (this.timerId !== '') {
|
|
154
|
+
clearTimeout(this.timeout)
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
},
|
|
158
|
+
},
|
|
147
159
|
methods: {
|
|
148
160
|
setFocusAction() {
|
|
149
161
|
this.$refs.action_button_1.$el.focus()
|
|
@@ -171,19 +183,11 @@ export default {
|
|
|
171
183
|
|
|
172
184
|
this.show = !this.show
|
|
173
185
|
},
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
this.timerId = setTimeout(() => {
|
|
180
|
-
this.setFocusAction()
|
|
181
|
-
}, 100)
|
|
182
|
-
} else {
|
|
183
|
-
if (this.timerId !== '') {
|
|
184
|
-
clearTimeout(this.timeout)
|
|
185
|
-
}
|
|
186
|
-
}
|
|
186
|
+
close() {
|
|
187
|
+
this.show = false
|
|
188
|
+
this.$nextTick(() => {
|
|
189
|
+
this.$refs.btnCheck.$el.focus()
|
|
190
|
+
})
|
|
187
191
|
},
|
|
188
192
|
},
|
|
189
193
|
}
|
|
@@ -40,6 +40,25 @@
|
|
|
40
40
|
return-object
|
|
41
41
|
></v-select>
|
|
42
42
|
</v-col>
|
|
43
|
+
<v-col
|
|
44
|
+
cols="auto"
|
|
45
|
+
class="d-flex align-center"
|
|
46
|
+
v-if="isFlashcardType"
|
|
47
|
+
>
|
|
48
|
+
<v-switch
|
|
49
|
+
v-model="replaceExisting"
|
|
50
|
+
hide-details
|
|
51
|
+
dense
|
|
52
|
+
color="secondary"
|
|
53
|
+
class="mt-0 pt-0"
|
|
54
|
+
:label="
|
|
55
|
+
$t(
|
|
56
|
+
'windward.games.components.settings.flashcard.form.replace_existing'
|
|
57
|
+
)
|
|
58
|
+
"
|
|
59
|
+
:disabled="isLoading"
|
|
60
|
+
></v-switch>
|
|
61
|
+
</v-col>
|
|
43
62
|
<v-col>
|
|
44
63
|
<v-btn
|
|
45
64
|
elevation="0"
|
|
@@ -76,7 +95,7 @@ import AssessmentQuestion from '~/models/AssessmentQuestion'
|
|
|
76
95
|
import Course from '~/models/Course'
|
|
77
96
|
import Assessment from '~/models/Assessment'
|
|
78
97
|
import Content from '~/models/Content'
|
|
79
|
-
import
|
|
98
|
+
import Activity from '../../models/Activity'
|
|
80
99
|
|
|
81
100
|
export default {
|
|
82
101
|
name: 'GenerateAIQuestionButton',
|
|
@@ -85,6 +104,7 @@ export default {
|
|
|
85
104
|
content: { type: Object, required: true },
|
|
86
105
|
block: { type: Object, required: true },
|
|
87
106
|
questionType: { type: String, required: true },
|
|
107
|
+
replaceExistingMode: { type: Boolean, default: false },
|
|
88
108
|
},
|
|
89
109
|
data() {
|
|
90
110
|
return {
|
|
@@ -96,12 +116,16 @@ export default {
|
|
|
96
116
|
'windward.core.components.content.blocks.generate_questions.blooms.none'
|
|
97
117
|
),
|
|
98
118
|
},
|
|
119
|
+
replaceExisting: this.replaceExistingMode,
|
|
99
120
|
}
|
|
100
121
|
},
|
|
101
122
|
computed: {
|
|
102
123
|
...mapGetters({
|
|
103
124
|
contentTree: 'content/getTree',
|
|
104
125
|
}),
|
|
126
|
+
isFlashcardType() {
|
|
127
|
+
return this.questionType === 'flashcard'
|
|
128
|
+
},
|
|
105
129
|
flattenedContent() {
|
|
106
130
|
let cloneContentTree = _.cloneDeep(this.contentTree)
|
|
107
131
|
const homepage = this.$ContentService.getHomepage()
|
|
@@ -131,6 +155,7 @@ export default {
|
|
|
131
155
|
return fullTree
|
|
132
156
|
},
|
|
133
157
|
taxonomyLevels() {
|
|
158
|
+
// Basic Bloom's taxonomy levels available to all question types
|
|
134
159
|
let basicBloomTaxonomy = [
|
|
135
160
|
{
|
|
136
161
|
value: 'None',
|
|
@@ -158,10 +183,13 @@ export default {
|
|
|
158
183
|
},
|
|
159
184
|
]
|
|
160
185
|
|
|
186
|
+
// Only add higher-level Bloom's taxonomy for supported question types
|
|
187
|
+
// Flashcards use only basic levels
|
|
161
188
|
if (
|
|
162
|
-
this.
|
|
163
|
-
this.questionType === '
|
|
164
|
-
|
|
189
|
+
!this.isFlashcardType &&
|
|
190
|
+
(this.questionType === 'multi_choice_single_answer' ||
|
|
191
|
+
this.questionType === 'ordering' ||
|
|
192
|
+
this.questionType === 'multi_choice_multi_answer')
|
|
165
193
|
) {
|
|
166
194
|
const multiBlooms = [
|
|
167
195
|
{
|
|
@@ -185,32 +213,96 @@ export default {
|
|
|
185
213
|
methods: {
|
|
186
214
|
async generateAIQuestion() {
|
|
187
215
|
this.isLoading = true
|
|
188
|
-
let bloomsRequest = ''
|
|
189
|
-
if (
|
|
190
|
-
this.selectedDifficulty.text !==
|
|
191
|
-
this.$t(
|
|
192
|
-
'windward.core.components.content.blocks.generate_questions.blooms.none'
|
|
193
|
-
)
|
|
194
|
-
) {
|
|
195
|
-
// send value to api call so its not changing with language
|
|
196
|
-
bloomsRequest = `?blooms_level=${this.selectedDifficulty.value}`
|
|
197
|
-
}
|
|
198
216
|
try {
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
)
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
217
|
+
let bloomsRequest = ''
|
|
218
|
+
if (
|
|
219
|
+
this.selectedDifficulty.text !==
|
|
220
|
+
this.$t(
|
|
221
|
+
'windward.core.components.content.blocks.generate_questions.blooms.none'
|
|
222
|
+
)
|
|
223
|
+
) {
|
|
224
|
+
bloomsRequest = `?blooms_level=${this.selectedDifficulty.value}`
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
const course = new Course(this.course)
|
|
228
|
+
const content = new Content(
|
|
229
|
+
this.selectedContent || this.content
|
|
230
|
+
)
|
|
231
|
+
|
|
232
|
+
let response
|
|
233
|
+
if (this.questionType === 'flashcard') {
|
|
234
|
+
// FLASHCARD GENERATION
|
|
235
|
+
const activity = new Activity()
|
|
236
|
+
|
|
237
|
+
const endpoint = `suggest/flashcard${bloomsRequest}`
|
|
238
|
+
|
|
239
|
+
// Call the endpoint exactly like FlashCardSlidesManager does
|
|
240
|
+
response = await Activity.custom(
|
|
241
|
+
course,
|
|
242
|
+
content,
|
|
243
|
+
activity,
|
|
244
|
+
endpoint
|
|
245
|
+
).get()
|
|
246
|
+
|
|
247
|
+
let activityData = null
|
|
248
|
+
|
|
249
|
+
if (response && response.activity) {
|
|
250
|
+
activityData = response.activity
|
|
251
|
+
} else if (
|
|
252
|
+
response &&
|
|
253
|
+
response.length > 0 &&
|
|
254
|
+
response[0] &&
|
|
255
|
+
response[0].activity
|
|
256
|
+
) {
|
|
257
|
+
activityData = response[0].activity
|
|
258
|
+
} else if (Array.isArray(response) && response.length > 0) {
|
|
259
|
+
activityData = response[0]
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
if (
|
|
263
|
+
activityData &&
|
|
264
|
+
activityData.metadata &&
|
|
265
|
+
activityData.metadata.config &&
|
|
266
|
+
activityData.metadata.config.cards &&
|
|
267
|
+
Array.isArray(activityData.metadata.config.cards)
|
|
268
|
+
) {
|
|
269
|
+
// We pass the activity data and the replace flag to the parent component
|
|
270
|
+
this.$emit(
|
|
271
|
+
'click:generate',
|
|
272
|
+
activityData,
|
|
273
|
+
this.replaceExisting
|
|
274
|
+
)
|
|
275
|
+
} else {
|
|
276
|
+
throw new Error(
|
|
277
|
+
'Invalid response from flashcard generation'
|
|
278
|
+
)
|
|
279
|
+
}
|
|
280
|
+
} else {
|
|
281
|
+
// ASSESSMENT QUESTION GENERATION
|
|
282
|
+
const assessment = new Assessment({ id: this.block.id })
|
|
283
|
+
const question = new AssessmentQuestion()
|
|
284
|
+
|
|
285
|
+
response = await AssessmentQuestion.custom(
|
|
286
|
+
course,
|
|
287
|
+
content,
|
|
288
|
+
assessment,
|
|
289
|
+
question,
|
|
290
|
+
`suggest/${this.questionType}${bloomsRequest}`
|
|
291
|
+
).get()
|
|
292
|
+
|
|
293
|
+
if (response && response.length > 0) {
|
|
294
|
+
const generatedQuestion = response[0]
|
|
295
|
+
this.$emit('click:generate', generatedQuestion)
|
|
296
|
+
} else {
|
|
297
|
+
throw new Error(
|
|
298
|
+
'Invalid response from question generation'
|
|
299
|
+
)
|
|
300
|
+
}
|
|
210
301
|
}
|
|
211
302
|
} catch (error) {
|
|
212
303
|
const errorMessage =
|
|
213
304
|
error.response?.data?.error?.message ||
|
|
305
|
+
error.message ||
|
|
214
306
|
'assessment.error.technical'
|
|
215
307
|
const errorType = errorMessage.split('.').pop()
|
|
216
308
|
const basePath =
|
|
@@ -138,7 +138,7 @@ export default {
|
|
|
138
138
|
type: String,
|
|
139
139
|
required: false,
|
|
140
140
|
default:
|
|
141
|
-
'
|
|
141
|
+
'styles | bold italic underline strikethrough removeformat | alignleft aligncenter alignright | table tablerowprops tablecellprops |bullist numlist outdent indent |glossaryButton fibFormatButton mathButton a11yButton | undo redo',
|
|
142
142
|
},
|
|
143
143
|
rootBlock: { type: String, required: false, default: 'div' },
|
|
144
144
|
label: { type: String, required: false, default: '' },
|
|
@@ -212,7 +212,7 @@ export default {
|
|
|
212
212
|
},
|
|
213
213
|
format: {
|
|
214
214
|
title: 'Format',
|
|
215
|
-
items: ' bold italic underline strikethrough superscript subscript codeformat | formats align | language | removeformat',
|
|
215
|
+
items: ' bold italic underline strikethrough superscript subscript codeformat | formats align | language | removeformat | glossary',
|
|
216
216
|
},
|
|
217
217
|
},
|
|
218
218
|
autoresize_min_height: 100,
|
|
@@ -337,6 +337,9 @@ export default {
|
|
|
337
337
|
},
|
|
338
338
|
formats: {
|
|
339
339
|
glossary: {
|
|
340
|
+
title: this.$t(
|
|
341
|
+
'windward.core.components.utils.tiny_mce_wrapper.glossary'
|
|
342
|
+
),
|
|
340
343
|
inline: 'span',
|
|
341
344
|
attributes: {
|
|
342
345
|
'aria-label': this.$t(
|
|
@@ -378,67 +381,22 @@ export default {
|
|
|
378
381
|
],
|
|
379
382
|
},
|
|
380
383
|
style_formats: [
|
|
381
|
-
{
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
{ title: 'Heading 6', format: 'h6' },
|
|
389
|
-
],
|
|
390
|
-
},
|
|
391
|
-
{
|
|
392
|
-
title: 'Inline',
|
|
393
|
-
items: [
|
|
394
|
-
{ title: 'Bold', format: 'bold' },
|
|
395
|
-
{ title: 'Italic', format: 'italic' },
|
|
396
|
-
{ title: 'Underline', format: 'underline' },
|
|
397
|
-
{ title: 'Strikethrough', format: 'strikethrough' },
|
|
398
|
-
{ title: 'Superscript', format: 'superscript' },
|
|
399
|
-
{ title: 'Subscript', format: 'subscript' },
|
|
400
|
-
{ title: 'Code', format: 'code' },
|
|
401
|
-
],
|
|
402
|
-
},
|
|
403
|
-
{
|
|
404
|
-
title: 'Blocks',
|
|
405
|
-
items: [{ title: 'Paragraph', format: 'p' }],
|
|
406
|
-
},
|
|
407
|
-
{
|
|
408
|
-
title: 'Align',
|
|
409
|
-
items: [
|
|
410
|
-
{ title: 'Left', format: 'alignleft' },
|
|
411
|
-
{ title: 'Center', format: 'aligncenter' },
|
|
412
|
-
{ title: 'Right', format: 'alignright' },
|
|
413
|
-
{ title: 'Justify', format: 'alignjustify' },
|
|
414
|
-
],
|
|
415
|
-
},
|
|
416
|
-
{
|
|
417
|
-
title: 'LearningEdge',
|
|
418
|
-
items: [
|
|
419
|
-
{
|
|
420
|
-
title: this.$t(
|
|
421
|
-
'windward.core.components.utils.tiny_mce_wrapper.term'
|
|
422
|
-
),
|
|
423
|
-
format: 'glossary',
|
|
424
|
-
},
|
|
425
|
-
{
|
|
426
|
-
title: this.$t(
|
|
427
|
-
'windward.core.components.utils.tiny_mce_wrapper.fill_blank'
|
|
428
|
-
),
|
|
429
|
-
format: 'fib',
|
|
430
|
-
},
|
|
431
|
-
],
|
|
432
|
-
},
|
|
384
|
+
{ title: 'Normal Text', format: 'div' },
|
|
385
|
+
{ title: 'Paragraph', format: 'p' },
|
|
386
|
+
{ title: 'Heading 2', format: 'h2' },
|
|
387
|
+
{ title: 'Heading 3', format: 'h3' },
|
|
388
|
+
{ title: 'Heading 4', format: 'h4' },
|
|
389
|
+
{ title: 'Heading 5', format: 'h5' },
|
|
390
|
+
{ title: 'Heading 6', format: 'h6' },
|
|
433
391
|
],
|
|
434
392
|
placeholder: this.label
|
|
435
393
|
? this.label
|
|
436
394
|
: this.$t('components.content.settings.base.placeholder'),
|
|
437
|
-
//required as it will be displayed as inline style in tinymce renderer
|
|
395
|
+
// required as it will be displayed as inline style in tinymce renderer
|
|
438
396
|
skin: false,
|
|
439
397
|
content_css: this.$vuetify.theme.isDark ? 'dark' : 'default',
|
|
440
398
|
|
|
441
|
-
//we need to inject the glossary style directly
|
|
399
|
+
// we need to inject the glossary style directly
|
|
442
400
|
content_style:
|
|
443
401
|
ContentCss +
|
|
444
402
|
EditorCss +
|
|
@@ -477,7 +435,6 @@ export default {
|
|
|
477
435
|
this.text = this.value
|
|
478
436
|
}
|
|
479
437
|
},
|
|
480
|
-
|
|
481
438
|
methods: {
|
|
482
439
|
getEditor() {
|
|
483
440
|
if (this.$refs.editor && this.$refs.editor.editor) {
|