@windward/core 0.23.0 → 0.25.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 +74 -59
- package/components/Content/Blocks/Email.vue +12 -3
- package/components/Settings/AccordionSettings.vue +0 -1
- package/components/Settings/ClickableIconsSettings.vue +7 -3
- package/components/Settings/OpenResponseSettings.vue +55 -6
- package/components/Settings/TabSettings.vue +0 -1
- package/components/Settings/TextEditorSettings.vue +4 -0
- package/components/utils/TinyMCEWrapper.vue +253 -3
- package/helpers/tinymce/WindwardPlugins.ts +65 -1
- package/i18n/en-US/components/utils/tiny_mce_wrapper.ts +7 -0
- package/i18n/es-ES/components/utils/tiny_mce_wrapper.ts +8 -0
- package/i18n/sv-SE/components/utils/tiny_mce_wrapper.ts +8 -0
- package/package.json +1 -1
- package/plugin.js +0 -43
- package/test/mocks.js +6 -2
- package/components/Navigation/Items/GlossaryNav.vue +0 -53
- package/components/Navigation/Items/UserUploadNav.vue +0 -58
package/CHANGELOG.md
CHANGED
|
@@ -1,77 +1,92 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## Release [0.
|
|
3
|
+
## Release [0.25.0] - 2025-10-29
|
|
4
4
|
|
|
5
|
-
* Merged in
|
|
6
|
-
* Merged in
|
|
7
|
-
*
|
|
8
|
-
* Merged in
|
|
9
|
-
* Merged in
|
|
10
|
-
* Merged in
|
|
11
|
-
* Merged in bugfix/LE-2052-clickable-icon-text-color-should (pull request #426)
|
|
12
|
-
* Merged in bugfix/LE-2088-open-response-block-remove-edito (pull request #430)
|
|
13
|
-
* Merged release/0.23.0 into bugfix/LE-2071-vimeo-videos-not-working
|
|
14
|
-
* Merged release/0.22.0 into bugfix/LE-2052-clickable-icon-text-color-should
|
|
5
|
+
* Merged in bugfix/LE-2067-scorm-provider (pull request #451)
|
|
6
|
+
* Merged in feature/LE-2108/revise-text (pull request #445)
|
|
7
|
+
* Merge remote-tracking branch 'origin/release/0.24.0' into release/0.25.0
|
|
8
|
+
* Merged in feature/LE-2123/open-res-gen (pull request #446)
|
|
9
|
+
* Merged in feature/LE-2127-increase-clickable-icon-item-tit (pull request #450)
|
|
10
|
+
* Merged in feature/LE-2157-remove-user-uploads-and-glossary (pull request #449)
|
|
15
11
|
|
|
16
12
|
|
|
17
|
-
## Release [0.
|
|
13
|
+
## Release [0.24.0] - 2025-10-06
|
|
18
14
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
* Merged in bugfix/LE-2057-save-button-disappeared-again-on (pull request #419)
|
|
27
|
-
* Merged release/0.22.0 into bugfix/LE-1960-video-using-urls-as-a-source
|
|
28
|
-
* Merged in feature/LE-2036/word-jumble-gen (pull request #420)
|
|
29
|
-
* Merged in feature/LE-1997/scenario-gen (pull request #416)
|
|
30
|
-
* Merged in bugfix/LE-1928-user-upload-allowed-file-types (pull request #415)
|
|
31
|
-
* Merged in release/0.21.0 (pull request #401)
|
|
32
|
-
* Merged release/0.21.0 into bugfix/LE-1960-video-using-urls-as-a-source
|
|
33
|
-
* Merged release/0.21.0 into bugfix/LE-1928-user-upload-allowed-file-types
|
|
15
|
+
- Merged in feature/LE-2123/open-res-gen (pull request #446)
|
|
16
|
+
- Merged in bugfix/LE-2134-email-block-show-hide-title (pull request #444)
|
|
17
|
+
- Merged in feature/LE-2097-tabs-and-accordions-hide-backgro (pull request #436)
|
|
18
|
+
- Merged release/0.24.0 into feature/LE-2097-tabs-and-accordions-hide-backgro
|
|
19
|
+
- Merged in bugfix/LE-1841-all-blocks-save-or-cancel-change (pull request #440)
|
|
20
|
+
- Merged release/0.24.0 into bugfix/LE-1841-all-blocks-save-or-cancel-change
|
|
21
|
+
- Merged in feature/LE-2100-edit-in-text-area-update-text-fi (pull request #435)
|
|
34
22
|
|
|
23
|
+
## Release [0.23.0] - 2025-09-18
|
|
35
24
|
|
|
36
|
-
|
|
25
|
+
- Merged in feature/LE-2099-track-engagement-on-videos-from- (pull request #439)
|
|
26
|
+
- Merged in bugfix/LE-2071-vimeo-videos-not-working (pull request #438)
|
|
27
|
+
- Merged in bugfix/LE-2071-vimeo-videos-not-working (pull request #437)
|
|
28
|
+
- Merged in bugfix/LE-2088-open-response-block-remove-edito (pull request #434)
|
|
29
|
+
- Merged in bugfix/MIND-6075-decouple-generateaiquestionbut (pull request #432)
|
|
30
|
+
- Merged in bugfix/LE-2071-vimeo-videos-not-working (pull request #433)
|
|
31
|
+
- Merged in bugfix/LE-2052-clickable-icon-text-color-should (pull request #426)
|
|
32
|
+
- Merged in bugfix/LE-2088-open-response-block-remove-edito (pull request #430)
|
|
33
|
+
- Merged release/0.23.0 into bugfix/LE-2071-vimeo-videos-not-working
|
|
34
|
+
- Merged release/0.22.0 into bugfix/LE-2052-clickable-icon-text-color-should
|
|
35
|
+
|
|
36
|
+
## Release [0.22.0] - 2025-08-28
|
|
37
37
|
|
|
38
|
+
- Merge branch 'master' into release/0.22.0
|
|
39
|
+
- Merged in bugfix/LE-2075-the-panel-of-the-text-block-isnt (pull request #427)
|
|
40
|
+
- Merged in bug-fix/LE-2060/llm-character-limit-validation (pull request #421)
|
|
41
|
+
- Merged in bugfix/LE-2031-open-response-download-collate-q (pull request #422)
|
|
42
|
+
- Merged in bugfix/LE-1960-video-using-urls-as-a-source (pull request #423)
|
|
43
|
+
- Merged in hotfix/0.21.1 (pull request #425)
|
|
44
|
+
- Merged release/0.22.0 into bugfix/LE-1960-video-using-urls-as-a-source
|
|
45
|
+
- Merged in bugfix/LE-2057-save-button-disappeared-again-on (pull request #419)
|
|
46
|
+
- Merged release/0.22.0 into bugfix/LE-1960-video-using-urls-as-a-source
|
|
47
|
+
- Merged in feature/LE-2036/word-jumble-gen (pull request #420)
|
|
48
|
+
- Merged in feature/LE-1997/scenario-gen (pull request #416)
|
|
49
|
+
- Merged in bugfix/LE-1928-user-upload-allowed-file-types (pull request #415)
|
|
50
|
+
- Merged in release/0.21.0 (pull request #401)
|
|
51
|
+
- Merged release/0.21.0 into bugfix/LE-1960-video-using-urls-as-a-source
|
|
52
|
+
- Merged release/0.21.0 into bugfix/LE-1928-user-upload-allowed-file-types
|
|
38
53
|
|
|
39
|
-
##
|
|
54
|
+
## Hotfix [0.21.1] created - 2025-08-20
|
|
40
55
|
|
|
41
|
-
|
|
42
|
-
* Merged in feature/LE-2009-organizations-custom-color-palle (pull request #410)
|
|
43
|
-
* Merged in feature/LE-2011-open-response-download-field-to- (pull request #411)
|
|
44
|
-
* Merged in feature/LE-1912/sorting-game-gen-2 (pull request #413)
|
|
45
|
-
* Merged in feature/LE-2029-open-response-block-design (pull request #412)
|
|
46
|
-
* Merged in feature/LE-1912/sorting-game-gen (pull request #409)
|
|
47
|
-
* Merged in feature/LE-2011-open-response-download-field-to- (pull request #408)
|
|
48
|
-
* Merged in feature/LE-1924-clickable-icons-ux (pull request #407)
|
|
49
|
-
* Merged in feature/LE-1913/matching-block (pull request #405)
|
|
50
|
-
* Merged in feature/LE-1924-clickable-icons-ux (pull request #404)
|
|
51
|
-
* Merged in feature/LE-2011-open-response-download-field-to- (pull request #406)
|
|
52
|
-
* Merged in bugfix/LE-1928-user-upload-allowed-file-types (pull request #398)
|
|
53
|
-
* Merged release/0.21.0 into feature/LE-2011-open-response-download-field-to-
|
|
54
|
-
* Merge branch 'release/0.21.0' into feature/LE-1913/matching-block
|
|
55
|
-
* Merged in bugfix/LE-1990-video-black-line-on-left-and-rig (pull request #403)
|
|
56
|
-
* Merged in feature/LE-1900-fill-in-the-blank-formatting-sho (pull request #402)
|
|
57
|
-
* Merged release/0.21.0 into feature/LE-1924-clickable-icons-ux
|
|
58
|
-
* Merge branch 'release/0.20.0' into feature/LE-1913/matching-block
|
|
56
|
+
## Release [0.21.0] - 2025-08-01
|
|
59
57
|
|
|
58
|
+
- Merged in feature/LE-2045/lableing-fixes (pull request #414)
|
|
59
|
+
- Merged in feature/LE-2009-organizations-custom-color-palle (pull request #410)
|
|
60
|
+
- Merged in feature/LE-2011-open-response-download-field-to- (pull request #411)
|
|
61
|
+
- Merged in feature/LE-1912/sorting-game-gen-2 (pull request #413)
|
|
62
|
+
- Merged in feature/LE-2029-open-response-block-design (pull request #412)
|
|
63
|
+
- Merged in feature/LE-1912/sorting-game-gen (pull request #409)
|
|
64
|
+
- Merged in feature/LE-2011-open-response-download-field-to- (pull request #408)
|
|
65
|
+
- Merged in feature/LE-1924-clickable-icons-ux (pull request #407)
|
|
66
|
+
- Merged in feature/LE-1913/matching-block (pull request #405)
|
|
67
|
+
- Merged in feature/LE-1924-clickable-icons-ux (pull request #404)
|
|
68
|
+
- Merged in feature/LE-2011-open-response-download-field-to- (pull request #406)
|
|
69
|
+
- Merged in bugfix/LE-1928-user-upload-allowed-file-types (pull request #398)
|
|
70
|
+
- Merged release/0.21.0 into feature/LE-2011-open-response-download-field-to-
|
|
71
|
+
- Merge branch 'release/0.21.0' into feature/LE-1913/matching-block
|
|
72
|
+
- Merged in bugfix/LE-1990-video-black-line-on-left-and-rig (pull request #403)
|
|
73
|
+
- Merged in feature/LE-1900-fill-in-the-blank-formatting-sho (pull request #402)
|
|
74
|
+
- Merged release/0.21.0 into feature/LE-1924-clickable-icons-ux
|
|
75
|
+
- Merge branch 'release/0.20.0' into feature/LE-1913/matching-block
|
|
60
76
|
|
|
61
77
|
## Release [0.20.0] - 2025-07-01
|
|
62
78
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
79
|
+
- Merge remote-tracking branch 'origin/release/0.20.0' into release/0.20.0
|
|
80
|
+
- Merge remote-tracking branch 'origin/release/0.20.0' into release/0.20.0
|
|
81
|
+
- Merged in feature/LE-1948/empty-bucket-localization-fix (pull request #397)
|
|
82
|
+
- Merged in LE-1911-email-block-to-cc-and-subject-te (pull request #395)
|
|
83
|
+
- Merged in bugfix/LE-1928-user-upload-allowed-file-types (pull request #391)
|
|
84
|
+
- Merged in bugfix/LE-1941-divider-dashed-line-renders-soli (pull request #396)
|
|
85
|
+
- Merged in feature/LE-1948/empty-bucket (pull request #393)
|
|
86
|
+
- Merged in feature/LE-1906-ai-assistant-button-text (pull request #394)
|
|
87
|
+
- Merged in bugfix/LE-1739-email-block-to-cc-and-subject-te (pull request #392)
|
|
88
|
+
- Merged in bugfix/LE-1917-student-experience-cleanup (pull request #386)
|
|
89
|
+
- Merged release/0.19.0 into bugfix/LE-1917-student-experience-cleanup
|
|
75
90
|
|
|
76
91
|
### Release [0.19.0] created - 2025-05-30
|
|
77
92
|
|
|
@@ -7,7 +7,13 @@
|
|
|
7
7
|
"
|
|
8
8
|
>
|
|
9
9
|
<v-col cols="12" class="pa-0">
|
|
10
|
-
<h2
|
|
10
|
+
<h2
|
|
11
|
+
v-if="
|
|
12
|
+
block.metadata.config.title &&
|
|
13
|
+
block.metadata.config.display_title
|
|
14
|
+
"
|
|
15
|
+
tabindex="0"
|
|
16
|
+
>
|
|
11
17
|
{{ block.metadata.config.title }}
|
|
12
18
|
</h2>
|
|
13
19
|
<p
|
|
@@ -141,7 +147,10 @@
|
|
|
141
147
|
)
|
|
142
148
|
}}: {{ item.cc }}
|
|
143
149
|
</div>
|
|
144
|
-
<div
|
|
150
|
+
<div
|
|
151
|
+
v-if="item.subject"
|
|
152
|
+
class="div-details-subject"
|
|
153
|
+
>
|
|
145
154
|
{{
|
|
146
155
|
$t(
|
|
147
156
|
'windward.core.components.content.blocks.email.subject'
|
|
@@ -317,7 +326,7 @@ export default {
|
|
|
317
326
|
methods: {
|
|
318
327
|
onRemoveTags(body) {
|
|
319
328
|
if (typeof body !== 'string') {
|
|
320
|
-
|
|
329
|
+
return ''
|
|
321
330
|
}
|
|
322
331
|
let text = body.replace(/ /g, ' ')
|
|
323
332
|
text = text.replace(/\u00A0/g, ' ')
|
|
@@ -163,13 +163,17 @@
|
|
|
163
163
|
hide-modal
|
|
164
164
|
></ImageAssetSettings>
|
|
165
165
|
<v-text-field
|
|
166
|
+
:id="'item-' + index + '-title'"
|
|
166
167
|
v-model="
|
|
167
168
|
block.metadata.config.items[index].title
|
|
168
169
|
"
|
|
169
|
-
:id="'item-' + index + '-title'"
|
|
170
170
|
outlined
|
|
171
|
-
:rules="
|
|
172
|
-
|
|
171
|
+
:rules="
|
|
172
|
+
$Validation.getRule('clickableIconInput')
|
|
173
|
+
"
|
|
174
|
+
:counter="
|
|
175
|
+
$Validation.getLimit('clickableIconInput')
|
|
176
|
+
"
|
|
173
177
|
:label="
|
|
174
178
|
$t(
|
|
175
179
|
'windward.core.components.settings.clickable_icon.item_title'
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<v-container>
|
|
2
|
+
<v-container class="pb-6">
|
|
3
3
|
<v-row>
|
|
4
4
|
<BaseContentBlockSettings
|
|
5
5
|
v-model="block.metadata.config"
|
|
6
6
|
:disabled="render"
|
|
7
7
|
></BaseContentBlockSettings>
|
|
8
8
|
</v-row>
|
|
9
|
-
<p>
|
|
10
|
-
{{
|
|
9
|
+
<p class="pt-4 mb-2">
|
|
10
|
+
{{
|
|
11
|
+
$t('windward.core.components.settings.open_response.question')
|
|
12
|
+
}}
|
|
11
13
|
</p>
|
|
12
14
|
<TextEditor
|
|
13
15
|
id="block-settings-body"
|
|
@@ -41,18 +43,36 @@
|
|
|
41
43
|
:height="200"
|
|
42
44
|
:disabled="render"
|
|
43
45
|
></TextEditor>
|
|
46
|
+
<v-row class="pt-6">
|
|
47
|
+
<v-col cols="12">
|
|
48
|
+
<PluginRef
|
|
49
|
+
target="contentBlockSettingTool"
|
|
50
|
+
:attrs="{
|
|
51
|
+
value: block,
|
|
52
|
+
course,
|
|
53
|
+
content: currentContent,
|
|
54
|
+
}"
|
|
55
|
+
:on="{
|
|
56
|
+
input: onApplyGeneratedBlock,
|
|
57
|
+
append: onApplyGeneratedBlock,
|
|
58
|
+
}"
|
|
59
|
+
></PluginRef>
|
|
60
|
+
</v-col>
|
|
61
|
+
</v-row>
|
|
44
62
|
</v-container>
|
|
45
63
|
</template>
|
|
46
64
|
|
|
47
65
|
<script>
|
|
48
66
|
import _ from 'lodash'
|
|
67
|
+
import { mapGetters } from 'vuex'
|
|
49
68
|
import BaseContentSettings from '~/components/Content/Settings/BaseContentSettings.js'
|
|
50
69
|
import BaseContentBlockSettings from '~/components/Content/Settings/BaseContentBlockSettings.vue'
|
|
70
|
+
import PluginRef from '~/components/Core/PluginRef.vue'
|
|
51
71
|
import TextEditor from '~/components/Text/TextEditor'
|
|
52
72
|
|
|
53
73
|
export default {
|
|
54
|
-
name: '
|
|
55
|
-
components: { TextEditor, BaseContentBlockSettings },
|
|
74
|
+
name: 'OpenResponseSettings',
|
|
75
|
+
components: { TextEditor, BaseContentBlockSettings, PluginRef },
|
|
56
76
|
extends: BaseContentSettings,
|
|
57
77
|
props: {
|
|
58
78
|
settings: { type: Object, required: false, default: null },
|
|
@@ -61,6 +81,12 @@ export default {
|
|
|
61
81
|
data() {
|
|
62
82
|
return {}
|
|
63
83
|
},
|
|
84
|
+
computed: {
|
|
85
|
+
...mapGetters({
|
|
86
|
+
course: 'course/get',
|
|
87
|
+
currentContent: 'content/get',
|
|
88
|
+
}),
|
|
89
|
+
},
|
|
64
90
|
beforeMount() {
|
|
65
91
|
if (_.isEmpty(this.block)) {
|
|
66
92
|
this.block = {}
|
|
@@ -91,6 +117,29 @@ export default {
|
|
|
91
117
|
}
|
|
92
118
|
},
|
|
93
119
|
mounted() {},
|
|
94
|
-
methods: {
|
|
120
|
+
methods: {
|
|
121
|
+
onApplyGeneratedBlock(payload = {}) {
|
|
122
|
+
if (_.isEmpty(payload)) {
|
|
123
|
+
return
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const generatedBlock = _.cloneDeep(payload)
|
|
127
|
+
const config = _.get(generatedBlock, 'metadata.config', {})
|
|
128
|
+
|
|
129
|
+
this.block.body = _.get(generatedBlock, 'body', '') ?? ''
|
|
130
|
+
this.block.metadata.config.title =
|
|
131
|
+
_.get(config, 'title', '') ?? ''
|
|
132
|
+
this.block.metadata.config.instructions =
|
|
133
|
+
_.get(config, 'instructions', '') ?? ''
|
|
134
|
+
this.block.metadata.config.sample_response =
|
|
135
|
+
_.get(config, 'sample_response', '') ?? ''
|
|
136
|
+
this.block.metadata.config.starting_text =
|
|
137
|
+
_.get(config, 'starting_text', '') ?? ''
|
|
138
|
+
|
|
139
|
+
if (_.has(config, 'display_title')) {
|
|
140
|
+
this.block.metadata.config.display_title = config.display_title
|
|
141
|
+
}
|
|
142
|
+
},
|
|
143
|
+
},
|
|
95
144
|
}
|
|
96
145
|
</script>
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
autofill
|
|
6
6
|
:disabled="render"
|
|
7
7
|
allow-read
|
|
8
|
+
:key="updateKey"
|
|
8
9
|
root-block="p"
|
|
9
10
|
show-glossary
|
|
10
11
|
:hide-text-editor="hideTextEditor"
|
|
@@ -52,6 +53,7 @@
|
|
|
52
53
|
</template>
|
|
53
54
|
|
|
54
55
|
<script>
|
|
56
|
+
import Crypto from '~/helpers/Crypto'
|
|
55
57
|
import BaseContentSettings from '~/components/Content/Settings/BaseContentSettings.js'
|
|
56
58
|
import TextEditor from '~/components/Text/TextEditor'
|
|
57
59
|
export default {
|
|
@@ -73,6 +75,7 @@ export default {
|
|
|
73
75
|
elevation: 0,
|
|
74
76
|
},
|
|
75
77
|
hideTextEditor: false,
|
|
78
|
+
updateKey: Crypto.id(),
|
|
76
79
|
}
|
|
77
80
|
},
|
|
78
81
|
mounted() {
|
|
@@ -82,6 +85,7 @@ export default {
|
|
|
82
85
|
onExpand() {
|
|
83
86
|
this.hideTextEditor = !this.hideTextEditor
|
|
84
87
|
this.block.metadata.config.expand = this.hideTextEditor
|
|
88
|
+
this.updateKey = Crypto.id()
|
|
85
89
|
},
|
|
86
90
|
},
|
|
87
91
|
}
|
|
@@ -66,6 +66,7 @@ import _ from 'lodash'
|
|
|
66
66
|
import 'tinymce'
|
|
67
67
|
import Editor from '@tinymce/tinymce-vue'
|
|
68
68
|
import { getTinymce } from '@tinymce/tinymce-vue/lib/cjs/main/ts/TinyMCE'
|
|
69
|
+
import { mapGetters } from 'vuex'
|
|
69
70
|
/* Required TinyMCE components */
|
|
70
71
|
import 'tinymce/icons/default/icons.min.js'
|
|
71
72
|
import 'tinymce/themes/silver/theme.min.js'
|
|
@@ -119,6 +120,8 @@ import Crypto from '~/helpers/Crypto'
|
|
|
119
120
|
import GlossaryVerification from '../Glossary/GlossaryVerification.vue'
|
|
120
121
|
import MathHelper from '../../helpers/MathHelper'
|
|
121
122
|
import { WindwardPlugins } from '../../helpers/tinymce/WindwardPlugins'
|
|
123
|
+
import Course from '~/models/Course'
|
|
124
|
+
import Organization from '~/models/Organization'
|
|
122
125
|
|
|
123
126
|
import ContentCss from '!raw-loader!sass-loader!./assets/tinymce/content/global.scss'
|
|
124
127
|
import EditorCss from '!raw-loader!sass-loader!./assets/tinymce/ui/global.scss'
|
|
@@ -143,7 +146,7 @@ export default {
|
|
|
143
146
|
type: String,
|
|
144
147
|
required: false,
|
|
145
148
|
default:
|
|
146
|
-
'styles | bold italic underline strikethrough removeformat | alignleft aligncenter alignright | table tablerowprops tablecellprops |bullist numlist outdent indent |glossaryButton fibFormatButton mathButton a11yButton | undo redo',
|
|
149
|
+
'styles | bold italic underline strikethrough removeformat | alignleft aligncenter alignright | table tablerowprops tablecellprops |bullist numlist outdent indent |glossaryButton fibFormatButton mathButton a11yButton reviseText | undo redo',
|
|
147
150
|
},
|
|
148
151
|
rootBlock: { type: String, required: false, default: 'div' },
|
|
149
152
|
label: { type: String, required: false, default: '' },
|
|
@@ -160,10 +163,17 @@ export default {
|
|
|
160
163
|
seed: Crypto.id(),
|
|
161
164
|
synthesizer: null,
|
|
162
165
|
paused: false,
|
|
166
|
+
isRevising: false,
|
|
167
|
+
rephraseToneIndex: 0,
|
|
168
|
+
toneSequence: ['neutral', 'conversational', 'formal', 'succinct', 'encouraging'],
|
|
163
169
|
}
|
|
164
170
|
},
|
|
165
171
|
|
|
166
172
|
computed: {
|
|
173
|
+
...mapGetters({
|
|
174
|
+
organization: 'organization/get',
|
|
175
|
+
course: 'course/get',
|
|
176
|
+
}),
|
|
167
177
|
hasActions() {
|
|
168
178
|
if (this.allowRead && !this.render) {
|
|
169
179
|
return true
|
|
@@ -346,12 +356,14 @@ export default {
|
|
|
346
356
|
value: 'windward-table-subject-report',
|
|
347
357
|
},
|
|
348
358
|
],
|
|
349
|
-
setup(
|
|
359
|
+
setup: () => {
|
|
350
360
|
// Here we can add plugin
|
|
351
361
|
getTinymce().PluginManager.add(
|
|
352
362
|
'WindwardToolKit',
|
|
353
363
|
(editor) => {
|
|
354
|
-
new WindwardPlugins(editor
|
|
364
|
+
new WindwardPlugins(editor, {
|
|
365
|
+
onRevise: this.handleRevision,
|
|
366
|
+
})
|
|
355
367
|
}
|
|
356
368
|
)
|
|
357
369
|
},
|
|
@@ -519,6 +531,244 @@ export default {
|
|
|
519
531
|
return true
|
|
520
532
|
}
|
|
521
533
|
},
|
|
534
|
+
getRevisionContext() {
|
|
535
|
+
return {
|
|
536
|
+
organizationId: this.organization?.id ?? null,
|
|
537
|
+
courseId: this.course?.id ?? null,
|
|
538
|
+
}
|
|
539
|
+
},
|
|
540
|
+
selectionContainsProtected(node) {
|
|
541
|
+
if (!node) {
|
|
542
|
+
return false
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
if (typeof Node === 'undefined') {
|
|
546
|
+
return false
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
const editor = this.getEditor()
|
|
550
|
+
const body = editor ? editor.getBody() : null
|
|
551
|
+
const protectedClasses = [
|
|
552
|
+
'windward-math-content',
|
|
553
|
+
'windward-fill-blank',
|
|
554
|
+
'glossary-word',
|
|
555
|
+
]
|
|
556
|
+
|
|
557
|
+
let current = node
|
|
558
|
+
|
|
559
|
+
while (current && current !== body) {
|
|
560
|
+
if (current.nodeType === Node.ELEMENT_NODE) {
|
|
561
|
+
const classList = current.classList || []
|
|
562
|
+
if (
|
|
563
|
+
protectedClasses.some((className) =>
|
|
564
|
+
classList.contains(className)
|
|
565
|
+
)
|
|
566
|
+
) {
|
|
567
|
+
return true
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
current = current.parentNode
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
return false
|
|
574
|
+
},
|
|
575
|
+
nextTone(operation) {
|
|
576
|
+
if (operation !== 'rephrase') {
|
|
577
|
+
this.rephraseToneIndex = 0
|
|
578
|
+
|
|
579
|
+
return null
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
const tone = this.toneSequence[
|
|
583
|
+
this.rephraseToneIndex % this.toneSequence.length
|
|
584
|
+
]
|
|
585
|
+
this.rephraseToneIndex =
|
|
586
|
+
(this.rephraseToneIndex + 1) % this.toneSequence.length
|
|
587
|
+
|
|
588
|
+
return tone
|
|
589
|
+
},
|
|
590
|
+
async handleRevision(operation) {
|
|
591
|
+
const editor = this.getEditor()
|
|
592
|
+
if (!editor || this.isRevising) {
|
|
593
|
+
return
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
const selection = editor.selection
|
|
597
|
+
const selectionHtml = selection
|
|
598
|
+
? selection.getContent({ format: 'html' })
|
|
599
|
+
: ''
|
|
600
|
+
const useSelection =
|
|
601
|
+
selection &&
|
|
602
|
+
!selection.isCollapsed() &&
|
|
603
|
+
selectionHtml.trim().length > 0
|
|
604
|
+
|
|
605
|
+
const targetHtml = useSelection
|
|
606
|
+
? selectionHtml
|
|
607
|
+
: editor.getContent({ format: 'html' })
|
|
608
|
+
|
|
609
|
+
if (!targetHtml || targetHtml.trim().length === 0) {
|
|
610
|
+
return
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
if (useSelection) {
|
|
614
|
+
const range = selection.getRng()
|
|
615
|
+
if (
|
|
616
|
+
this.selectionContainsProtected(range.startContainer) ||
|
|
617
|
+
this.selectionContainsProtected(range.endContainer)
|
|
618
|
+
) {
|
|
619
|
+
if (this.$toast) {
|
|
620
|
+
this.$toast.error(
|
|
621
|
+
this.$t(
|
|
622
|
+
'windward.core.components.utils.tiny_mce_wrapper.revision_protected_error'
|
|
623
|
+
)
|
|
624
|
+
)
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
return
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
const { organizationId, courseId } = this.getRevisionContext()
|
|
632
|
+
|
|
633
|
+
if (!organizationId || !courseId) {
|
|
634
|
+
if (this.$toast) {
|
|
635
|
+
this.$toast.error(
|
|
636
|
+
this.$t(
|
|
637
|
+
'windward.core.components.utils.tiny_mce_wrapper.revision_error'
|
|
638
|
+
)
|
|
639
|
+
)
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
return
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
const tone = this.nextTone(operation)
|
|
646
|
+
const payload = {
|
|
647
|
+
operation,
|
|
648
|
+
html: targetHtml,
|
|
649
|
+
language: this.$i18n.locale,
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
if (tone) {
|
|
653
|
+
payload.tone = tone
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
const revisionRequest = new Course()
|
|
657
|
+
revisionRequest.custom(
|
|
658
|
+
new Organization({ id: organizationId }),
|
|
659
|
+
new Course({ id: courseId }),
|
|
660
|
+
'llm-revise'
|
|
661
|
+
)
|
|
662
|
+
|
|
663
|
+
const resourcePath = revisionRequest._customResource
|
|
664
|
+
|
|
665
|
+
if (!resourcePath) {
|
|
666
|
+
if (this.$toast) {
|
|
667
|
+
this.$toast.error(
|
|
668
|
+
this.$t(
|
|
669
|
+
'windward.core.components.utils.tiny_mce_wrapper.revision_error'
|
|
670
|
+
)
|
|
671
|
+
)
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
this.isRevising = false
|
|
675
|
+
editor.setProgressState(false)
|
|
676
|
+
|
|
677
|
+
return
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
this.isRevising = true
|
|
681
|
+
editor.setProgressState(true)
|
|
682
|
+
let bookmark = null
|
|
683
|
+
if (!useSelection && selection) {
|
|
684
|
+
bookmark = selection.getBookmark(2, true)
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
try {
|
|
688
|
+
const requestConfig = revisionRequest._reqConfig(
|
|
689
|
+
{
|
|
690
|
+
method: 'POST',
|
|
691
|
+
url: `${revisionRequest.baseURL()}/${resourcePath}`,
|
|
692
|
+
data: payload,
|
|
693
|
+
},
|
|
694
|
+
{ forceMethod: true }
|
|
695
|
+
)
|
|
696
|
+
|
|
697
|
+
const response = await revisionRequest.request(requestConfig)
|
|
698
|
+
const responseData = response?.data || response
|
|
699
|
+
|
|
700
|
+
if (!responseData || !responseData.html) {
|
|
701
|
+
throw new Error('missing_html')
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
editor.undoManager.transact(() => {
|
|
705
|
+
if (useSelection) {
|
|
706
|
+
const range = selection.getRng()
|
|
707
|
+
const fragment = editor.dom.createFragment(
|
|
708
|
+
responseData.html
|
|
709
|
+
)
|
|
710
|
+
|
|
711
|
+
if (!fragment.hasChildNodes()) {
|
|
712
|
+
return
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
const firstNode = fragment.firstChild
|
|
716
|
+
const lastNode = fragment.lastChild
|
|
717
|
+
|
|
718
|
+
if (!firstNode || !lastNode) {
|
|
719
|
+
return
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
range.deleteContents()
|
|
723
|
+
range.insertNode(fragment)
|
|
724
|
+
|
|
725
|
+
const newRange = editor.dom.createRng()
|
|
726
|
+
|
|
727
|
+
if (firstNode.nodeType === Node.TEXT_NODE) {
|
|
728
|
+
newRange.setStart(firstNode, 0)
|
|
729
|
+
} else {
|
|
730
|
+
newRange.setStartBefore(firstNode)
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
if (lastNode.nodeType === Node.TEXT_NODE) {
|
|
734
|
+
newRange.setEnd(
|
|
735
|
+
lastNode,
|
|
736
|
+
lastNode.textContent ? lastNode.textContent.length : 0
|
|
737
|
+
)
|
|
738
|
+
} else {
|
|
739
|
+
newRange.setEndAfter(lastNode)
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
editor.selection.setRng(newRange)
|
|
743
|
+
} else {
|
|
744
|
+
editor.setContent(responseData.html)
|
|
745
|
+
}
|
|
746
|
+
})
|
|
747
|
+
|
|
748
|
+
editor.fire('change')
|
|
749
|
+
|
|
750
|
+
if (!useSelection && bookmark) {
|
|
751
|
+
try {
|
|
752
|
+
editor.selection.moveToBookmark(bookmark)
|
|
753
|
+
} catch (_error) {
|
|
754
|
+
editor.selection.select(editor.getBody(), true)
|
|
755
|
+
editor.selection.collapse(false)
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
} catch (error) {
|
|
759
|
+
console.error('TinyMCE revision failed', error)
|
|
760
|
+
if (this.$toast) {
|
|
761
|
+
this.$toast.error(
|
|
762
|
+
this.$t(
|
|
763
|
+
'windward.core.components.utils.tiny_mce_wrapper.revision_error'
|
|
764
|
+
)
|
|
765
|
+
)
|
|
766
|
+
}
|
|
767
|
+
} finally {
|
|
768
|
+
this.isRevising = false
|
|
769
|
+
editor.setProgressState(false)
|
|
770
|
+
}
|
|
771
|
+
},
|
|
522
772
|
},
|
|
523
773
|
}
|
|
524
774
|
</script>
|
|
@@ -5,17 +5,29 @@ import local from '../../i18n/index'
|
|
|
5
5
|
/**
|
|
6
6
|
* Class representing the WindwardPlugins.
|
|
7
7
|
*/
|
|
8
|
+
type RevisionOptions = {
|
|
9
|
+
onRevise?: (operation: string) => void
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
type RevisionMenuItem = {
|
|
13
|
+
type: 'menuitem'
|
|
14
|
+
text: string
|
|
15
|
+
onAction: () => void
|
|
16
|
+
}
|
|
17
|
+
|
|
8
18
|
export class WindwardPlugins {
|
|
9
19
|
editor: any
|
|
10
20
|
formula: any
|
|
11
21
|
fillInBlank: any
|
|
12
22
|
private window: any
|
|
23
|
+
private options: RevisionOptions
|
|
13
24
|
|
|
14
|
-
constructor(editor: any) {
|
|
25
|
+
constructor(editor: any, options: RevisionOptions = {}) {
|
|
15
26
|
this.editor = editor
|
|
16
27
|
this.formula = undefined
|
|
17
28
|
this.fillInBlank = undefined
|
|
18
29
|
this.window = window
|
|
30
|
+
this.options = options
|
|
19
31
|
this.register()
|
|
20
32
|
}
|
|
21
33
|
|
|
@@ -70,6 +82,10 @@ export class WindwardPlugins {
|
|
|
70
82
|
'glossaryIcon',
|
|
71
83
|
'<svg viewBox="0 0 24 24" width="20px" height="20px" ><path d="M3,15H1V3A2,2 0 0,1 3,1H19V3H3V15M12,23A1,1 0 0,1 11,22V19H7A2,2 0 0,1 5,17V7A2,2 0 0,1 7,5H21A2,2 0 0,1 23,7V17A2,2 0 0,1 21,19H16.9L13.2,22.71C13,22.89 12.76,23 12.5,23H12M9,9V11H19V9H9M9,13V15H17V13H9Z"></path></svg>'
|
|
72
84
|
)
|
|
85
|
+
this.registerIcon(
|
|
86
|
+
'reviseIcon',
|
|
87
|
+
'<svg viewBox="0 0 24 24" width="20" height="20"><path d="M20.71,4.63L19.37,3.29C19,2.9 18.35,2.9 17.96,3.29L11,10.25L10.75,12.75L13.25,12.5L20.21,5.54C20.61,5.15 20.61,4.5 20.21,4.11M17,8L7,18L2,20L4,15L14,5L17,8Z"></path></svg>'
|
|
88
|
+
)
|
|
73
89
|
}
|
|
74
90
|
|
|
75
91
|
/**
|
|
@@ -188,6 +204,53 @@ export class WindwardPlugins {
|
|
|
188
204
|
)
|
|
189
205
|
}
|
|
190
206
|
|
|
207
|
+
private registerRevisionControls() {
|
|
208
|
+
const reviseLabel = this.$t(
|
|
209
|
+
'windward.core.components.utils.tiny_mce_wrapper.revise_text'
|
|
210
|
+
)
|
|
211
|
+
|
|
212
|
+
const items = [
|
|
213
|
+
{
|
|
214
|
+
text: this.$t(
|
|
215
|
+
'windward.core.components.utils.tiny_mce_wrapper.shorten'
|
|
216
|
+
),
|
|
217
|
+
value: 'shorten',
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
text: this.$t(
|
|
221
|
+
'windward.core.components.utils.tiny_mce_wrapper.rephrase'
|
|
222
|
+
),
|
|
223
|
+
value: 'rephrase',
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
text: this.$t(
|
|
227
|
+
'windward.core.components.utils.tiny_mce_wrapper.proofread'
|
|
228
|
+
),
|
|
229
|
+
value: 'proofread',
|
|
230
|
+
},
|
|
231
|
+
]
|
|
232
|
+
|
|
233
|
+
this.editor.ui.registry.addMenuButton('reviseText', {
|
|
234
|
+
icon: 'reviseIcon',
|
|
235
|
+
tooltip: reviseLabel,
|
|
236
|
+
fetch: (callback: (menuItems: RevisionMenuItem[]) => void) => {
|
|
237
|
+
callback(
|
|
238
|
+
items.map((item) => ({
|
|
239
|
+
type: 'menuitem',
|
|
240
|
+
text: item.text,
|
|
241
|
+
onAction: () => this.handleRevision(item.value),
|
|
242
|
+
}))
|
|
243
|
+
)
|
|
244
|
+
},
|
|
245
|
+
})
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
private handleRevision(operation: string) {
|
|
249
|
+
if (this.options.onRevise) {
|
|
250
|
+
this.options.onRevise(operation)
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
191
254
|
/**
|
|
192
255
|
* Add a button to the editor's UI registry
|
|
193
256
|
* @param {string} name Name of the button
|
|
@@ -470,6 +533,7 @@ export class WindwardPlugins {
|
|
|
470
533
|
private register() {
|
|
471
534
|
this.addIcons()
|
|
472
535
|
this.addButtons()
|
|
536
|
+
this.registerRevisionControls()
|
|
473
537
|
this.addMenuItems()
|
|
474
538
|
this.setContent()
|
|
475
539
|
this.setInputEvents()
|
|
@@ -21,6 +21,13 @@ export default {
|
|
|
21
21
|
math: 'Math',
|
|
22
22
|
minimize: 'Minimize',
|
|
23
23
|
read_text_aloud: 'Read Text aloud',
|
|
24
|
+
revise_text: 'Revise text',
|
|
25
|
+
shorten: 'Shorten',
|
|
26
|
+
rephrase: 'Rephrase',
|
|
27
|
+
proofread: 'Proofread',
|
|
28
|
+
revision_error: 'Unable to revise text. Try selecting a smaller portion or edit manually.',
|
|
29
|
+
revision_protected_error:
|
|
30
|
+
'Select text outside of math, fill-in-the-blank, or glossary items before revising.',
|
|
24
31
|
heading_order_incorrect:
|
|
25
32
|
'Headings must be applied in sequential order: H2 should be followed by H3, H4, and so on',
|
|
26
33
|
wcag_guidelines: '(WCAG {0} guidelines)',
|
|
@@ -22,6 +22,14 @@ export default {
|
|
|
22
22
|
math: 'Matemáticas',
|
|
23
23
|
minimize: 'Minimizar',
|
|
24
24
|
read_text_aloud: 'Leer texto',
|
|
25
|
+
revise_text: 'Revisar texto',
|
|
26
|
+
shorten: 'Acortar',
|
|
27
|
+
rephrase: 'Reformular',
|
|
28
|
+
proofread: 'Corregir',
|
|
29
|
+
revision_error:
|
|
30
|
+
'No se pudo revisar el texto. Intenta seleccionar un fragmento más pequeño o edita manualmente.',
|
|
31
|
+
revision_protected_error:
|
|
32
|
+
'Selecciona texto fuera de elementos de matemáticas, rellenado o glosario antes de revisar.',
|
|
25
33
|
heading_order_incorrect:
|
|
26
34
|
'Los títulos deben aplicarse en orden secuencial: H2 debe ir seguido de H3, H4, etc.',
|
|
27
35
|
wcag_guidelines: '(Directrices WCAG {0})',
|
|
@@ -22,6 +22,14 @@ export default {
|
|
|
22
22
|
math: 'Matematik',
|
|
23
23
|
minimize: 'Minimera',
|
|
24
24
|
read_text_aloud: 'Läs texten högt',
|
|
25
|
+
revise_text: 'Revidera text',
|
|
26
|
+
shorten: 'Förkorta',
|
|
27
|
+
rephrase: 'Omformulera',
|
|
28
|
+
proofread: 'Korrekturläs',
|
|
29
|
+
revision_error:
|
|
30
|
+
'Det gick inte att revidera texten. Försök markera ett mindre avsnitt eller redigera manuellt.',
|
|
31
|
+
revision_protected_error:
|
|
32
|
+
'Markera text utanför matematik, lucktexter eller ordlistor innan du reviderar.',
|
|
25
33
|
heading_order_incorrect:
|
|
26
34
|
'Rubriker måste tillämpas i sekventiell ordning: H2 ska följas av H3, H4, och så vidare',
|
|
27
35
|
wcag_guidelines: '(WCAG {0} riktlinjer)',
|
package/package.json
CHANGED
package/plugin.js
CHANGED
|
@@ -12,19 +12,15 @@ import Email from './components/Content/Blocks/Email'
|
|
|
12
12
|
import BlockQuote from './components/Content/Blocks/BlockQuote.vue'
|
|
13
13
|
import HorizontalRule from './components/Content/Blocks/HorizontalRule.vue'
|
|
14
14
|
|
|
15
|
-
import UserUploadNav from './components/Navigation/Items/UserUploadNav.vue'
|
|
16
|
-
|
|
17
15
|
import OpenResponse from './components/Content/Blocks/OpenResponse'
|
|
18
16
|
import OpenResponseCollate from './components/Content/Blocks/OpenResponseCollate'
|
|
19
17
|
import Image from './components/Content/Blocks/Image'
|
|
20
18
|
import UserUpload from './components/Content/Blocks/UserUpload'
|
|
21
19
|
import FileDownload from './components/Content/Blocks/FileDownload'
|
|
22
20
|
|
|
23
|
-
import GlossaryPage from './pages/glossary.vue'
|
|
24
21
|
import TinymcePlugin from './pages/plugins/tinymce/_plugin.vue'
|
|
25
22
|
|
|
26
23
|
import CourseGlossaryToolNav from './components/Navigation/Items/CourseGlossaryToolNav.vue'
|
|
27
|
-
import GlossaryNav from './components/Navigation/Items/GlossaryNav.vue'
|
|
28
24
|
import AskTheExpert from './components/Navigation/Items/AskTheExpert.vue'
|
|
29
25
|
|
|
30
26
|
// Entrypoint for npm
|
|
@@ -43,7 +39,6 @@ import EmailSettings from './components/Settings/EmailSettings.vue'
|
|
|
43
39
|
import BlockQuoteSettigns from './components/Settings/BlockQuoteSettings.vue'
|
|
44
40
|
import HorizontalRuleSettings from './components/Settings/HorizontalRuleSettings.vue'
|
|
45
41
|
|
|
46
|
-
import UserUploadPage from './pages/userUpload.vue'
|
|
47
42
|
import GlossaryToolTip from './components/utils/glossary/GlossaryToolTip.vue'
|
|
48
43
|
import TextEditorSettings from './components/Settings/TextEditorSettings.vue'
|
|
49
44
|
import FillInTheBlanks from './components/utils/FillInBlank/FillInTheBlanksManager.vue'
|
|
@@ -74,22 +69,6 @@ export default {
|
|
|
74
69
|
},
|
|
75
70
|
i18n: locales.messages,
|
|
76
71
|
pages: [
|
|
77
|
-
{
|
|
78
|
-
page: 'user-uploads',
|
|
79
|
-
path: '/course/:course/section/:section/user-uploads',
|
|
80
|
-
i18n: 'menu.user-upload',
|
|
81
|
-
icon: 'mdi-cloud-upload',
|
|
82
|
-
name: 'PluginUserUploadPage',
|
|
83
|
-
template: UserUploadPage,
|
|
84
|
-
},
|
|
85
|
-
{
|
|
86
|
-
page: 'glossary',
|
|
87
|
-
path: '/course/:course/section/:section/glossary',
|
|
88
|
-
i18n: 'windward.core.shared.menu.course_glossary',
|
|
89
|
-
icon: 'mdi-comment-text-multiple',
|
|
90
|
-
name: 'CourseGlossaryPage',
|
|
91
|
-
template: GlossaryPage,
|
|
92
|
-
},
|
|
93
72
|
{
|
|
94
73
|
page: 'tinymce-plugin',
|
|
95
74
|
path: '/plugins/tinymce/:plugin',
|
|
@@ -119,28 +98,6 @@ export default {
|
|
|
119
98
|
},
|
|
120
99
|
],
|
|
121
100
|
menu: [
|
|
122
|
-
{
|
|
123
|
-
tag: 'core-user-upload-nav',
|
|
124
|
-
template: UserUploadNav,
|
|
125
|
-
context: ['course'],
|
|
126
|
-
display: ['menu'],
|
|
127
|
-
permissions: {
|
|
128
|
-
'windward.organization.course.file': {
|
|
129
|
-
writable: true,
|
|
130
|
-
},
|
|
131
|
-
},
|
|
132
|
-
},
|
|
133
|
-
{
|
|
134
|
-
tag: 'core-user-glossary-nav',
|
|
135
|
-
template: GlossaryNav,
|
|
136
|
-
context: ['course'],
|
|
137
|
-
display: ['menu'],
|
|
138
|
-
permissions: {
|
|
139
|
-
'windward.organization.course.content': {
|
|
140
|
-
readable: true,
|
|
141
|
-
},
|
|
142
|
-
},
|
|
143
|
-
},
|
|
144
101
|
{
|
|
145
102
|
tag: 'core-ask-the-expert',
|
|
146
103
|
i18n: 'windward.core.shared.menu.ask_the_expert',
|
package/test/mocks.js
CHANGED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<v-tooltip right>
|
|
3
|
-
<template #activator="{ on, attrs }">
|
|
4
|
-
<v-list-item
|
|
5
|
-
:class="color"
|
|
6
|
-
:to="
|
|
7
|
-
'/course/' +
|
|
8
|
-
course.id +
|
|
9
|
-
'/section/' +
|
|
10
|
-
enrollment.course_section_id +
|
|
11
|
-
'/glossary'
|
|
12
|
-
"
|
|
13
|
-
v-bind="attrs"
|
|
14
|
-
v-on="on"
|
|
15
|
-
>
|
|
16
|
-
<v-list-item-action>
|
|
17
|
-
<v-icon v-bind="attrs" v-on="on"
|
|
18
|
-
>mdi-comment-text-multiple</v-icon
|
|
19
|
-
>
|
|
20
|
-
</v-list-item-action>
|
|
21
|
-
<v-list-item-content>
|
|
22
|
-
<v-list-item-title
|
|
23
|
-
>{{ $t('windward.core.shared.menu.course_glossary') }}
|
|
24
|
-
</v-list-item-title>
|
|
25
|
-
</v-list-item-content>
|
|
26
|
-
</v-list-item>
|
|
27
|
-
</template>
|
|
28
|
-
<span>{{ $t('windward.core.shared.menu.course_glossary') }}</span>
|
|
29
|
-
</v-tooltip>
|
|
30
|
-
</template>
|
|
31
|
-
|
|
32
|
-
<script>
|
|
33
|
-
import { mapGetters } from 'vuex'
|
|
34
|
-
|
|
35
|
-
export default {
|
|
36
|
-
name: 'GlossaryNav',
|
|
37
|
-
middleware: ['auth'],
|
|
38
|
-
props: {
|
|
39
|
-
color: { type: String, required: false, default: '' },
|
|
40
|
-
},
|
|
41
|
-
data() {
|
|
42
|
-
return {}
|
|
43
|
-
},
|
|
44
|
-
computed: {
|
|
45
|
-
...mapGetters({
|
|
46
|
-
course: 'course/get',
|
|
47
|
-
enrollment: 'enrollment/get',
|
|
48
|
-
}),
|
|
49
|
-
},
|
|
50
|
-
}
|
|
51
|
-
</script>
|
|
52
|
-
|
|
53
|
-
<style scoped></style>
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<v-tooltip right>
|
|
3
|
-
<template #activator="{ on, attrs }">
|
|
4
|
-
<v-list-item
|
|
5
|
-
:class="color"
|
|
6
|
-
:to="
|
|
7
|
-
'/course/' +
|
|
8
|
-
course.id +
|
|
9
|
-
'/section/' +
|
|
10
|
-
enrollment.course_section_id +
|
|
11
|
-
'/user-uploads'
|
|
12
|
-
"
|
|
13
|
-
v-bind="attrs"
|
|
14
|
-
v-on="on"
|
|
15
|
-
>
|
|
16
|
-
<v-list-item-action>
|
|
17
|
-
<v-icon>mdi-cloud-upload</v-icon>
|
|
18
|
-
</v-list-item-action>
|
|
19
|
-
<v-list-item-content>
|
|
20
|
-
<v-list-item-title
|
|
21
|
-
>{{
|
|
22
|
-
$t(
|
|
23
|
-
'windward.core.components.navigation.user_upload.title'
|
|
24
|
-
)
|
|
25
|
-
}}
|
|
26
|
-
</v-list-item-title>
|
|
27
|
-
</v-list-item-content>
|
|
28
|
-
</v-list-item>
|
|
29
|
-
</template>
|
|
30
|
-
<span>{{
|
|
31
|
-
$t('windward.core.components.navigation.user_upload.title')
|
|
32
|
-
}}</span>
|
|
33
|
-
</v-tooltip>
|
|
34
|
-
</template>
|
|
35
|
-
|
|
36
|
-
<script>
|
|
37
|
-
import { mapGetters } from 'vuex'
|
|
38
|
-
|
|
39
|
-
export default {
|
|
40
|
-
components: {},
|
|
41
|
-
middleware: ['auth'],
|
|
42
|
-
props: {
|
|
43
|
-
color: { type: String, required: false, default: '' },
|
|
44
|
-
},
|
|
45
|
-
data() {
|
|
46
|
-
return {}
|
|
47
|
-
},
|
|
48
|
-
computed: {
|
|
49
|
-
...mapGetters({
|
|
50
|
-
course: 'course/get',
|
|
51
|
-
enrollment: 'enrollment/get',
|
|
52
|
-
}),
|
|
53
|
-
},
|
|
54
|
-
created() {},
|
|
55
|
-
mounted() {},
|
|
56
|
-
methods: {},
|
|
57
|
-
}
|
|
58
|
-
</script>
|