@windward/core 0.20.0 → 0.21.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/CHANGELOG.md +25 -0
- package/components/Content/Blocks/ClickableIcons.vue +113 -116
- package/components/Content/Blocks/OpenResponseCollate.vue +30 -15
- package/components/Content/Blocks/Video.vue +67 -40
- package/components/Settings/OpenResponseCollateSettings.vue +48 -16
- package/components/Settings/UserUploadSettings.vue +77 -17
- package/components/utils/FillInBlank/FillInBlankInput.vue +24 -1
- package/components/utils/FillInBlank/FillInTheBlanksManager.vue +5 -0
- package/components/utils/GenerateAIQuestionButton.vue +152 -12
- package/components/utils/TinyMCEWrapper.vue +22 -2
- package/i18n/en-US/components/content/blocks/generate_questions.ts +10 -0
- package/i18n/en-US/components/settings/open_response_collate.ts +2 -2
- package/i18n/en-US/components/settings/user_upload.ts +6 -4
- package/i18n/en-US/components/utils/FillInBlank/FillInBlankInput.ts +1 -0
- package/i18n/en-US/components/utils/FillInBlank/FillInTheBlanksManager.ts +1 -0
- package/i18n/en-US/shared/settings.ts +2 -0
- package/i18n/es-ES/components/content/blocks/generate_questions.ts +10 -0
- package/i18n/es-ES/components/settings/open_response_collate.ts +1 -0
- package/i18n/es-ES/components/settings/user_upload.ts +6 -4
- package/i18n/es-ES/components/utils/FillInBlank/FillInBlankInput.ts +4 -3
- package/i18n/es-ES/components/utils/FillInBlank/FillInTheBlanksManager.ts +2 -1
- package/i18n/es-ES/shared/settings.ts +2 -0
- package/i18n/sv-SE/components/content/blocks/generate_questions.ts +10 -0
- package/i18n/sv-SE/components/settings/open_response_collate.ts +2 -0
- package/i18n/sv-SE/components/settings/user_upload.ts +7 -5
- package/i18n/sv-SE/components/utils/FillInBlank/FillInBlankInput.ts +6 -5
- package/i18n/sv-SE/components/utils/FillInBlank/FillInTheBlanksManager.ts +5 -4
- package/i18n/sv-SE/shared/settings.ts +2 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## Hotfix [0.21.1] created - 2025-08-20
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
## Release [0.21.0] - 2025-08-01
|
|
7
|
+
|
|
8
|
+
* Merged in feature/LE-2045/lableing-fixes (pull request #414)
|
|
9
|
+
* Merged in feature/LE-2009-organizations-custom-color-palle (pull request #410)
|
|
10
|
+
* Merged in feature/LE-2011-open-response-download-field-to- (pull request #411)
|
|
11
|
+
* Merged in feature/LE-1912/sorting-game-gen-2 (pull request #413)
|
|
12
|
+
* Merged in feature/LE-2029-open-response-block-design (pull request #412)
|
|
13
|
+
* Merged in feature/LE-1912/sorting-game-gen (pull request #409)
|
|
14
|
+
* Merged in feature/LE-2011-open-response-download-field-to- (pull request #408)
|
|
15
|
+
* Merged in feature/LE-1924-clickable-icons-ux (pull request #407)
|
|
16
|
+
* Merged in feature/LE-1913/matching-block (pull request #405)
|
|
17
|
+
* Merged in feature/LE-1924-clickable-icons-ux (pull request #404)
|
|
18
|
+
* Merged in feature/LE-2011-open-response-download-field-to- (pull request #406)
|
|
19
|
+
* Merged in bugfix/LE-1928-user-upload-allowed-file-types (pull request #398)
|
|
20
|
+
* Merged release/0.21.0 into feature/LE-2011-open-response-download-field-to-
|
|
21
|
+
* Merge branch 'release/0.21.0' into feature/LE-1913/matching-block
|
|
22
|
+
* Merged in bugfix/LE-1990-video-black-line-on-left-and-rig (pull request #403)
|
|
23
|
+
* Merged in feature/LE-1900-fill-in-the-blank-formatting-sho (pull request #402)
|
|
24
|
+
* Merged release/0.21.0 into feature/LE-1924-clickable-icons-ux
|
|
25
|
+
* Merge branch 'release/0.20.0' into feature/LE-1913/matching-block
|
|
26
|
+
|
|
27
|
+
|
|
3
28
|
## Release [0.20.0] - 2025-07-01
|
|
4
29
|
|
|
5
30
|
* Merge remote-tracking branch 'origin/release/0.20.0' into release/0.20.0
|
|
@@ -19,71 +19,87 @@
|
|
|
19
19
|
</p>
|
|
20
20
|
</v-container>
|
|
21
21
|
<v-container class="pa-0">
|
|
22
|
-
<v-
|
|
22
|
+
<v-container
|
|
23
23
|
v-for="(item, itemIndex) in block.metadata.config.items"
|
|
24
24
|
:key="itemIndex"
|
|
25
25
|
no-gutters
|
|
26
|
+
role="button"
|
|
27
|
+
class="flex-nowrap mb-3"
|
|
26
28
|
:class="rowClass(itemIndex)"
|
|
27
|
-
|
|
29
|
+
@click="item.active = !item.active"
|
|
28
30
|
>
|
|
29
|
-
<v-
|
|
30
|
-
<
|
|
31
|
-
class="
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
block.metadata.config.display.round_icon
|
|
40
|
-
? '100%'
|
|
41
|
-
: '0'
|
|
42
|
-
"
|
|
43
|
-
size="100%"
|
|
44
|
-
>
|
|
45
|
-
<ImageAssetViewer
|
|
46
|
-
v-if="
|
|
47
|
-
item.fileConfig.asset &&
|
|
48
|
-
item.fileConfig.asset.file_asset_id
|
|
31
|
+
<v-row class="mb-0 pb-0" no-gutters>
|
|
32
|
+
<v-col cols="auto" class="flex-shrink-0 ma-2 mr-0">
|
|
33
|
+
<button :class="activatorButtonClass(itemIndex)">
|
|
34
|
+
<v-avatar
|
|
35
|
+
v-if="item.iconImage && item.fileConfig"
|
|
36
|
+
class="clickable--image"
|
|
37
|
+
:rounded="
|
|
38
|
+
block.metadata.config.display.round_icon
|
|
39
|
+
? '100%'
|
|
40
|
+
: '0'
|
|
49
41
|
"
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
42
|
+
size="100%"
|
|
43
|
+
>
|
|
44
|
+
<ImageAssetViewer
|
|
45
|
+
v-if="
|
|
46
|
+
item.fileConfig.asset &&
|
|
47
|
+
item.fileConfig.asset.file_asset_id
|
|
48
|
+
"
|
|
49
|
+
v-model="item.fileConfig"
|
|
50
|
+
:assets="block.assets"
|
|
51
|
+
class="image-asset-viewer"
|
|
52
|
+
:inherit-sizing="true"
|
|
53
|
+
></ImageAssetViewer>
|
|
54
|
+
</v-avatar>
|
|
55
|
+
<v-icon
|
|
56
|
+
v-else-if="isIcon(item.icon)"
|
|
57
|
+
class="clickable--icon black--text"
|
|
58
|
+
>{{ item.icon }}</v-icon
|
|
59
|
+
>
|
|
60
|
+
<span v-else :class="iconClass + ' black--text'">{{
|
|
61
|
+
decode(item.icon)
|
|
62
|
+
}}</span>
|
|
63
|
+
</button>
|
|
64
|
+
</v-col>
|
|
65
|
+
<v-col style="min-width: 0" class="ma-3 mt-5">
|
|
66
|
+
<v-row :class="clickableContainerClass">
|
|
67
|
+
<v-col style="min-width: 0">
|
|
68
|
+
<h3
|
|
69
|
+
v-if="
|
|
70
|
+
block.metadata.config.display
|
|
71
|
+
.show_title || item.active
|
|
72
|
+
"
|
|
73
|
+
class="wrap-text"
|
|
74
|
+
>
|
|
75
|
+
{{ item.title }}
|
|
76
|
+
</h3>
|
|
77
|
+
</v-col>
|
|
78
|
+
<v-col cols="auto" class="d-flex justify-end">
|
|
79
|
+
<v-icon v-if="!item.active" class="icon-chevron"
|
|
80
|
+
>mdi-chevron-down</v-icon
|
|
81
|
+
>
|
|
82
|
+
<v-icon v-else class="icon-chevron"
|
|
83
|
+
>mdi-chevron-up</v-icon
|
|
84
|
+
>
|
|
85
|
+
</v-col>
|
|
86
|
+
</v-row>
|
|
87
|
+
<div v-if="item.active && !isMobile" class="pr-8">
|
|
88
|
+
<TextViewer
|
|
89
|
+
v-model="item.body"
|
|
90
|
+
class="content-body"
|
|
91
|
+
/>
|
|
92
|
+
</div>
|
|
93
|
+
</v-col>
|
|
94
|
+
</v-row>
|
|
95
|
+
<v-row
|
|
96
|
+
v-if="isMobile && item.active"
|
|
97
|
+
cols="12"
|
|
98
|
+
class="px-6 pb-4"
|
|
99
|
+
>
|
|
100
|
+
<TextViewer v-model="item.body" class="content-body" />
|
|
101
|
+
</v-row>
|
|
102
|
+
</v-container>
|
|
87
103
|
</v-container>
|
|
88
104
|
</div>
|
|
89
105
|
</template>
|
|
@@ -128,46 +144,9 @@ export default {
|
|
|
128
144
|
) {
|
|
129
145
|
classes += ' ' + this.itemColor(itemIndex) + ' black--text'
|
|
130
146
|
}
|
|
131
|
-
if (window.innerWidth <= 600) {
|
|
132
|
-
classes += 'd-flex justify-center '
|
|
133
|
-
}
|
|
134
147
|
return classes
|
|
135
148
|
}
|
|
136
149
|
},
|
|
137
|
-
iconColumnAttrs() {
|
|
138
|
-
if (this.block.metadata.config.display.large_icon) {
|
|
139
|
-
return {
|
|
140
|
-
xl: '3',
|
|
141
|
-
lg: '3',
|
|
142
|
-
md: '4',
|
|
143
|
-
sm: '4',
|
|
144
|
-
}
|
|
145
|
-
} else {
|
|
146
|
-
return {
|
|
147
|
-
xl: '2',
|
|
148
|
-
lg: '3',
|
|
149
|
-
md: '3',
|
|
150
|
-
sm: '3',
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
},
|
|
154
|
-
bodyColumnAttrs() {
|
|
155
|
-
if (this.block.metadata.config.display.large_icon) {
|
|
156
|
-
return {
|
|
157
|
-
xl: '9',
|
|
158
|
-
lg: '8',
|
|
159
|
-
md: '8',
|
|
160
|
-
sm: '8',
|
|
161
|
-
}
|
|
162
|
-
} else {
|
|
163
|
-
return {
|
|
164
|
-
xl: '10',
|
|
165
|
-
lg: '9',
|
|
166
|
-
md: '9',
|
|
167
|
-
sm: '9',
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
},
|
|
171
150
|
iconClass() {
|
|
172
151
|
let classes = 'clickable--text'
|
|
173
152
|
if (
|
|
@@ -198,12 +177,12 @@ export default {
|
|
|
198
177
|
// If autocolor is enabled then calculate the color on the index
|
|
199
178
|
if (this.block.metadata.config.display.autocolor) {
|
|
200
179
|
const colors = [
|
|
201
|
-
'
|
|
202
|
-
'
|
|
203
|
-
'
|
|
204
|
-
'
|
|
205
|
-
'
|
|
206
|
-
'
|
|
180
|
+
'extended-system-9',
|
|
181
|
+
'extended-system-7',
|
|
182
|
+
'extended-system-6',
|
|
183
|
+
'extended-system-5',
|
|
184
|
+
'extended-system-4',
|
|
185
|
+
'extended-system-10',
|
|
207
186
|
]
|
|
208
187
|
let colorIndex = itemIndex
|
|
209
188
|
// If we exceed the above list of colors loop back around to the beginning
|
|
@@ -230,12 +209,15 @@ export default {
|
|
|
230
209
|
}
|
|
231
210
|
}
|
|
232
211
|
},
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
212
|
+
isMobile() {
|
|
213
|
+
return window.innerWidth <= 400
|
|
214
|
+
},
|
|
215
|
+
clickableContainerClass() {
|
|
216
|
+
let classList = 'align-start'
|
|
217
|
+
if (window.innerWidth > 400) {
|
|
218
|
+
classList += ' mb-3'
|
|
238
219
|
}
|
|
220
|
+
return classList
|
|
239
221
|
},
|
|
240
222
|
},
|
|
241
223
|
beforeMount() {
|
|
@@ -277,11 +259,6 @@ export default {
|
|
|
277
259
|
isIcon(str) {
|
|
278
260
|
return str && _.isString(str) && str.indexOf('mdi-') === 0
|
|
279
261
|
},
|
|
280
|
-
getImagePublicUrl(asset) {
|
|
281
|
-
const foundAsset = this.resolveAsset(asset)
|
|
282
|
-
|
|
283
|
-
return _.get(foundAsset, 'asset.public_url', null)
|
|
284
|
-
},
|
|
285
262
|
},
|
|
286
263
|
}
|
|
287
264
|
</script>
|
|
@@ -291,9 +268,8 @@ export default {
|
|
|
291
268
|
}
|
|
292
269
|
button.button-icon {
|
|
293
270
|
border-width: 4px;
|
|
294
|
-
width: 100% !important;
|
|
295
|
-
height: auto !important;
|
|
296
271
|
aspect-ratio: 1 / 1;
|
|
272
|
+
border-radius: 16px;
|
|
297
273
|
}
|
|
298
274
|
|
|
299
275
|
button.button-icon.button-icon--outline {
|
|
@@ -307,16 +283,20 @@ button.button-icon.button-icon--rounded {
|
|
|
307
283
|
}
|
|
308
284
|
|
|
309
285
|
.button-icon--normal {
|
|
286
|
+
width: 5rem;
|
|
287
|
+
height: 5rem;
|
|
310
288
|
.clickable--icon {
|
|
311
|
-
font-size:
|
|
289
|
+
font-size: 3rem;
|
|
312
290
|
}
|
|
313
291
|
.clickable--text {
|
|
314
292
|
font-size: 1.5rem;
|
|
315
293
|
}
|
|
316
294
|
}
|
|
317
295
|
.button-icon--large {
|
|
296
|
+
width: 7rem;
|
|
297
|
+
height: 7rem;
|
|
318
298
|
.clickable--icon {
|
|
319
|
-
font-size:
|
|
299
|
+
font-size: 5rem;
|
|
320
300
|
}
|
|
321
301
|
.clickable--text {
|
|
322
302
|
font-size: 2.5rem;
|
|
@@ -326,4 +306,21 @@ button.button-icon.button-icon--rounded {
|
|
|
326
306
|
height: inherit;
|
|
327
307
|
width: inherit;
|
|
328
308
|
}
|
|
309
|
+
|
|
310
|
+
.content-body {
|
|
311
|
+
overflow-wrap: break-word;
|
|
312
|
+
word-break: break-word;
|
|
313
|
+
}
|
|
314
|
+
.icon-chevron {
|
|
315
|
+
color: inherit;
|
|
316
|
+
}
|
|
317
|
+
h3 {
|
|
318
|
+
font-size: 1.2rem;
|
|
319
|
+
font-weight: 500;
|
|
320
|
+
}
|
|
321
|
+
.wrap-text {
|
|
322
|
+
word-wrap: break-word;
|
|
323
|
+
overflow-wrap: break-word;
|
|
324
|
+
white-space: normal;
|
|
325
|
+
}
|
|
329
326
|
</style>
|
|
@@ -34,13 +34,21 @@ import UserContentBlockState from '~/models/UserContentBlockState'
|
|
|
34
34
|
|
|
35
35
|
export default {
|
|
36
36
|
name: 'ContentBlockOpenResponseCollate',
|
|
37
|
-
extends: BaseContentBlock,
|
|
38
37
|
components: {},
|
|
38
|
+
extends: BaseContentBlock,
|
|
39
39
|
data() {
|
|
40
40
|
return {
|
|
41
41
|
saveState: false, // Override the base block to disable state saving
|
|
42
42
|
}
|
|
43
43
|
},
|
|
44
|
+
computed: {
|
|
45
|
+
...mapGetters({
|
|
46
|
+
organization: 'organization/get',
|
|
47
|
+
course: 'course/get',
|
|
48
|
+
enrollment: 'enrollment/get',
|
|
49
|
+
content: 'content/get',
|
|
50
|
+
}),
|
|
51
|
+
},
|
|
44
52
|
beforeMount() {
|
|
45
53
|
if (_.isEmpty(this.block.body)) {
|
|
46
54
|
this.block.body = ''
|
|
@@ -59,20 +67,10 @@ export default {
|
|
|
59
67
|
this.block.metadata.config.include_prompts = false
|
|
60
68
|
}
|
|
61
69
|
},
|
|
62
|
-
computed: {
|
|
63
|
-
...mapGetters({
|
|
64
|
-
organization: 'organization/get',
|
|
65
|
-
course: 'course/get',
|
|
66
|
-
enrollment: 'enrollment/get',
|
|
67
|
-
content: 'content/get',
|
|
68
|
-
}),
|
|
69
|
-
},
|
|
70
|
-
watch: {},
|
|
71
|
-
mounted() {},
|
|
72
70
|
methods: {
|
|
73
71
|
async onCollate() {
|
|
74
72
|
try {
|
|
75
|
-
|
|
73
|
+
const userState = await UserContentBlockState.where({
|
|
76
74
|
'metadata->block->tag': 'plugin-core-open-response',
|
|
77
75
|
course_user_id: this.enrollment.id,
|
|
78
76
|
})
|
|
@@ -98,14 +96,14 @@ export default {
|
|
|
98
96
|
'</strong><hr />'
|
|
99
97
|
}
|
|
100
98
|
if (!_.isEmpty(state.metadata.response)) {
|
|
101
|
-
collated += '\n' + state.metadata.response
|
|
99
|
+
collated += '\n' + state.metadata.response + '<br>'
|
|
102
100
|
} else {
|
|
103
101
|
collated +=
|
|
104
102
|
'\n<p>' +
|
|
105
103
|
this.$t(
|
|
106
104
|
'windward.core.components.content.blocks.open_response_collate.no_response'
|
|
107
105
|
) +
|
|
108
|
-
'</p>'
|
|
106
|
+
'</p><br>'
|
|
109
107
|
}
|
|
110
108
|
})
|
|
111
109
|
let filename = this.block.metadata.config.filename
|
|
@@ -123,7 +121,24 @@ export default {
|
|
|
123
121
|
filename = filename.replaceAll(/\s+/gi, '_')
|
|
124
122
|
filename = filename.replaceAll(/[^a-z0-9\-\_]/gi, '')
|
|
125
123
|
}
|
|
126
|
-
|
|
124
|
+
if (!_.isEmpty(this.block.metadata.config.additional_text)) {
|
|
125
|
+
if (
|
|
126
|
+
this.block.metadata.config.additional_text_alignment ===
|
|
127
|
+
'top'
|
|
128
|
+
) {
|
|
129
|
+
collated =
|
|
130
|
+
this.block.metadata.config.additional_text +
|
|
131
|
+
'<br><br><br>' +
|
|
132
|
+
collated
|
|
133
|
+
} else if (
|
|
134
|
+
this.block.metadata.config.additional_text_alignment ===
|
|
135
|
+
'bottom'
|
|
136
|
+
) {
|
|
137
|
+
collated +=
|
|
138
|
+
'<br><br><br>' +
|
|
139
|
+
this.block.metadata.config.additional_text
|
|
140
|
+
}
|
|
141
|
+
}
|
|
127
142
|
this.generateDocument(collated, filename)
|
|
128
143
|
} catch (e) {
|
|
129
144
|
// eslint-disable-next-line no-console
|
|
@@ -13,46 +13,48 @@
|
|
|
13
13
|
{{ block.metadata.config.instructions }}
|
|
14
14
|
</p>
|
|
15
15
|
|
|
16
|
-
<
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
block.metadata.config.attributes.
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
block.metadata.config.attributes.
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
block.metadata.config.attributes.
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
16
|
+
<div class="video-wrapper">
|
|
17
|
+
<VuetifyPlayer
|
|
18
|
+
class="no-border-player"
|
|
19
|
+
:language="$i18n && $i18n.locale ? $i18n.locale : 'en-US'"
|
|
20
|
+
type="auto"
|
|
21
|
+
:playlist="linkedPlaylist"
|
|
22
|
+
:autoplay="block.metadata.config.attributes.autoplay"
|
|
23
|
+
:autopictureinpicture="
|
|
24
|
+
block.metadata.config.attributes.autopictureinpicture
|
|
25
|
+
"
|
|
26
|
+
:controls="block.metadata.config.attributes.controls"
|
|
27
|
+
:controlslist="block.metadata.config.attributes.controlslist"
|
|
28
|
+
:crossorigin="block.metadata.config.attributes.crossorigin"
|
|
29
|
+
:disablepictureinpicture="
|
|
30
|
+
block.metadata.config.attributes.disablepictureinpicture
|
|
31
|
+
"
|
|
32
|
+
:disableremoteplayback="
|
|
33
|
+
block.metadata.config.attributes.disableremoteplayback
|
|
34
|
+
"
|
|
35
|
+
:height="block.metadata.config.attributes.height"
|
|
36
|
+
:width="block.metadata.config.attributes.width"
|
|
37
|
+
:rewind="block.metadata.config.attributes.rewind"
|
|
38
|
+
:loop="block.metadata.config.attributes.loop"
|
|
39
|
+
:muted="block.metadata.config.attributes.muted"
|
|
40
|
+
:volume.sync="volume"
|
|
41
|
+
:cc.sync="ccVisible"
|
|
42
|
+
:playsinline="block.metadata.config.attributes.playsinline"
|
|
43
|
+
:poster="linkedPosterPublicUrl"
|
|
44
|
+
:preload="block.metadata.config.attributes.preload"
|
|
45
|
+
:captionsmenu="block.metadata.config.attributes.captionsmenu"
|
|
46
|
+
:playlistmenu="block.metadata.config.attributes.playlistmenu"
|
|
47
|
+
:playlistautoadvance="
|
|
48
|
+
block.metadata.config.attributes.playlistautoadvance
|
|
49
|
+
"
|
|
50
|
+
:playbackrates="block.metadata.config.attributes.playbackrates"
|
|
51
|
+
:captions-autoscroll.sync="captionsAutoscroll"
|
|
52
|
+
:captions-paragraph-view.sync="captionsParagraphView"
|
|
53
|
+
:captions-visible.sync="captionsVisible"
|
|
54
|
+
flat
|
|
55
|
+
@seeking="onSeeking"
|
|
56
|
+
@timeupdate="onTimeupdate"
|
|
57
|
+
>
|
|
56
58
|
<template #no-source>
|
|
57
59
|
<v-card>
|
|
58
60
|
<v-card-title class="justify-center">
|
|
@@ -71,6 +73,7 @@
|
|
|
71
73
|
</v-card>
|
|
72
74
|
</template>
|
|
73
75
|
</VuetifyPlayer>
|
|
76
|
+
</div>
|
|
74
77
|
<!-- display first note in the playlist for now -->
|
|
75
78
|
<v-alert
|
|
76
79
|
v-if="notes.length > 0"
|
|
@@ -475,3 +478,27 @@ export default {
|
|
|
475
478
|
overflow: hidden;
|
|
476
479
|
}
|
|
477
480
|
</style>
|
|
481
|
+
|
|
482
|
+
<style>
|
|
483
|
+
/* Remove black backgrounds from video player containers */
|
|
484
|
+
.no-border-player,
|
|
485
|
+
.no-border-player > div:not(.vjs-control-bar),
|
|
486
|
+
.no-border-player .video-js:not(.vjs-control-bar) {
|
|
487
|
+
background: transparent !important;
|
|
488
|
+
background-color: transparent !important;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
/* Ensure video element has transparent background */
|
|
492
|
+
.no-border-player video {
|
|
493
|
+
background: transparent !important;
|
|
494
|
+
background-color: transparent !important;
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
/* Make video player larger */
|
|
498
|
+
.video-wrapper {
|
|
499
|
+
margin-left: -15px;
|
|
500
|
+
margin-right: -15px;
|
|
501
|
+
padding-left: 0;
|
|
502
|
+
padding-right: 0;
|
|
503
|
+
}
|
|
504
|
+
</style>
|
|
@@ -60,6 +60,30 @@
|
|
|
60
60
|
</v-list-item>
|
|
61
61
|
</v-list-item-group>
|
|
62
62
|
</v-list>
|
|
63
|
+
<v-container class="pa-0">
|
|
64
|
+
<p>
|
|
65
|
+
{{
|
|
66
|
+
$t(
|
|
67
|
+
'windward.core.components.settings.open_response_collate.additional_text'
|
|
68
|
+
)
|
|
69
|
+
}}
|
|
70
|
+
</p>
|
|
71
|
+
<TextEditor
|
|
72
|
+
v-model="block.metadata.config.additional_text"
|
|
73
|
+
:disabled="render"
|
|
74
|
+
></TextEditor>
|
|
75
|
+
<v-btn-toggle
|
|
76
|
+
v-model="block.metadata.config.additional_text_alignment"
|
|
77
|
+
class="pt-2"
|
|
78
|
+
>
|
|
79
|
+
<v-btn value="top" :disabled="render">{{
|
|
80
|
+
$t('windward.core.shared.settings.top')
|
|
81
|
+
}}</v-btn>
|
|
82
|
+
<v-btn value="bottom" :disabled="render">{{
|
|
83
|
+
$t('windward.core.shared.settings.bottom')
|
|
84
|
+
}}</v-btn>
|
|
85
|
+
</v-btn-toggle>
|
|
86
|
+
</v-container>
|
|
63
87
|
</v-form>
|
|
64
88
|
</v-container>
|
|
65
89
|
</template>
|
|
@@ -67,16 +91,15 @@
|
|
|
67
91
|
<script>
|
|
68
92
|
import _ from 'lodash'
|
|
69
93
|
import { mapGetters } from 'vuex'
|
|
70
|
-
import draggable from 'vuedraggable'
|
|
71
|
-
import TextEditor from '~/components/Text/TextEditor'
|
|
72
94
|
import BaseContentSettings from '~/components/Content/Settings/BaseContentSettings.js'
|
|
73
95
|
import ContentBlock from '~/models/ContentBlock'
|
|
74
96
|
import Course from '~/models/Course'
|
|
97
|
+
import TextEditor from '~/components/Text/TextEditor'
|
|
75
98
|
|
|
76
99
|
export default {
|
|
77
100
|
name: 'OpenResponseCollateSettings',
|
|
101
|
+
components: { TextEditor },
|
|
78
102
|
extends: BaseContentSettings,
|
|
79
|
-
components: { draggable, TextEditor },
|
|
80
103
|
props: {
|
|
81
104
|
settings: { type: Object, required: false, default: null },
|
|
82
105
|
context: { type: String, required: false, default: 'block' },
|
|
@@ -87,6 +110,16 @@ export default {
|
|
|
87
110
|
linked: [],
|
|
88
111
|
}
|
|
89
112
|
},
|
|
113
|
+
async fetch() {
|
|
114
|
+
this.contentBlocks = await ContentBlock.where(
|
|
115
|
+
'tag',
|
|
116
|
+
'plugin-core-open-response'
|
|
117
|
+
)
|
|
118
|
+
.for(new Course({ id: this.course.id }))
|
|
119
|
+
.get()
|
|
120
|
+
|
|
121
|
+
this.sortContentBlocks(this.contentBlocks)
|
|
122
|
+
},
|
|
90
123
|
computed: {
|
|
91
124
|
...mapGetters({
|
|
92
125
|
organization: 'organization/get',
|
|
@@ -100,16 +133,6 @@ export default {
|
|
|
100
133
|
}
|
|
101
134
|
},
|
|
102
135
|
},
|
|
103
|
-
async fetch() {
|
|
104
|
-
this.contentBlocks = await ContentBlock.where(
|
|
105
|
-
'tag',
|
|
106
|
-
'plugin-core-open-response'
|
|
107
|
-
)
|
|
108
|
-
.for(new Course({ id: this.course.id }))
|
|
109
|
-
.get()
|
|
110
|
-
|
|
111
|
-
this.sortContentBlocks(this.contentBlocks)
|
|
112
|
-
},
|
|
113
136
|
beforeMount() {
|
|
114
137
|
if (_.isEmpty(this.block)) {
|
|
115
138
|
this.block = {}
|
|
@@ -129,21 +152,30 @@ export default {
|
|
|
129
152
|
if (_.isEmpty(this.block.metadata.config.filename)) {
|
|
130
153
|
this.block.metadata.config.filename = ''
|
|
131
154
|
}
|
|
155
|
+
if (_.isEmpty(this.block.metadata.config.additional_text)) {
|
|
156
|
+
this.block.metadata.config.additional_text = ''
|
|
157
|
+
}
|
|
158
|
+
if (_.isEmpty(this.block.metadata.config.additional_text_alignment)) {
|
|
159
|
+
this.block.metadata.config.additional_text_alignment = 'top'
|
|
160
|
+
}
|
|
132
161
|
// _.isEmpty(true) returns false. use isBoolean to check if this prop exists
|
|
133
162
|
if (!_.isBoolean(this.block.metadata.config.include_prompts)) {
|
|
134
163
|
this.block.metadata.config.include_prompts = false
|
|
135
164
|
}
|
|
136
165
|
this.linked = this.block.metadata.config.linked
|
|
137
166
|
},
|
|
138
|
-
watch: {},
|
|
139
167
|
mounted() {},
|
|
140
168
|
methods: {
|
|
141
169
|
sortContentBlocks(contentBlocks) {
|
|
142
|
-
|
|
170
|
+
const contentBlocksByPage = []
|
|
143
171
|
const blockMap = []
|
|
144
172
|
// getting page order
|
|
145
173
|
const contentBlockTree = this.$ContentService.getFlatTree()
|
|
146
|
-
|
|
174
|
+
const homePage = this.$ContentService.getHomepage()
|
|
175
|
+
if (homePage !== null) {
|
|
176
|
+
contentBlockTree.unshift(homePage)
|
|
177
|
+
}
|
|
178
|
+
contentBlockTree.forEach(function (page) {
|
|
147
179
|
contentBlocks.forEach((block) => {
|
|
148
180
|
// If the block is on this page and it wasn't already used on a different page
|
|
149
181
|
if (
|