@windward/core 0.14.0 → 0.16.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.
Files changed (60) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/bitbucket-pipelines.yml +8 -0
  3. package/components/Content/Blocks/BlockQuote.vue +51 -47
  4. package/components/Content/Blocks/GenerateAIQuestionButton.vue +151 -37
  5. package/components/Content/Blocks/OpenResponse.vue +11 -3
  6. package/components/Content/Blocks/UserUpload/ManageDataTableUserFiles.vue +2 -11
  7. package/components/Content/Blocks/Video.vue +1 -1
  8. package/components/Glossary/GlossaryVerification.vue +240 -0
  9. package/components/Navigation/Items/GlossaryNav.vue +8 -2
  10. package/components/Navigation/Items/UserUploadNav.vue +32 -13
  11. package/components/Settings/AccordionSettings.vue +37 -27
  12. package/components/Settings/ClickableIconsSettings.vue +1 -0
  13. package/components/Settings/ImageSettings.vue +5 -12
  14. package/components/Settings/TabSettings.vue +33 -23
  15. package/components/Settings/TextEditorSettings.vue +16 -245
  16. package/components/Settings/VideoSettings.vue +1 -1
  17. package/components/utils/ContentViewer.vue +3 -3
  18. package/components/utils/TinyMCEWrapper.vue +24 -14
  19. package/components/utils/glossary/CourseGlossary.vue +75 -95
  20. package/components/utils/glossary/CourseGlossaryForm.vue +42 -13
  21. package/components/utils/glossary/GlossaryToolTip.vue +7 -11
  22. package/helpers/GlossaryHelper.ts +18 -16
  23. package/i18n/en-US/components/content/blocks/generate_questions.ts +26 -11
  24. package/i18n/en-US/pages/glossary.ts +3 -1
  25. package/i18n/en-US/shared/content_blocks.ts +1 -1
  26. package/i18n/en-US/shared/notification.ts +5 -0
  27. package/i18n/en-US/shared/permission.ts +4 -0
  28. package/i18n/en-US/shared/settings.ts +1 -1
  29. package/i18n/es-ES/components/content/blocks/generate_questions.ts +11 -1
  30. package/i18n/es-ES/pages/glossary.ts +3 -1
  31. package/i18n/es-ES/shared/content_blocks.ts +1 -1
  32. package/i18n/es-ES/shared/notification.ts +5 -0
  33. package/i18n/es-ES/shared/permission.ts +8 -4
  34. package/i18n/es-ES/shared/settings.ts +1 -2
  35. package/i18n/sv-SE/components/content/blocks/generate_questions.ts +11 -1
  36. package/i18n/sv-SE/pages/glossary.ts +3 -1
  37. package/i18n/sv-SE/shared/content_blocks.ts +1 -1
  38. package/i18n/sv-SE/shared/notification.ts +4 -0
  39. package/i18n/sv-SE/shared/permission.ts +8 -4
  40. package/i18n/sv-SE/shared/settings.ts +1 -1
  41. package/jest.config.js +3 -0
  42. package/models/BaseModel.ts +16 -0
  43. package/models/CourseGlossaryTerm.ts +22 -0
  44. package/models/UserFileAsset.ts +1 -0
  45. package/package.json +4 -3
  46. package/pages/glossary.vue +41 -4
  47. package/pages/userUpload.vue +70 -47
  48. package/plugin.js +34 -12
  49. package/store/glossary.js +57 -0
  50. package/test/Components/Content/Blocks/Feedback.spec.js +3 -1
  51. package/test/Components/Content/Blocks/Video.spec.js +2 -2
  52. package/test/Components/Glossary/GlossaryVerification.spec.js +19 -0
  53. package/test/Components/utils/glossary/CourseGlossary.spec.js +19 -0
  54. package/test/Components/utils/glossary/CourseGlossaryForm.spec.js +28 -0
  55. package/test/__mocks__/helpersMock.js +0 -24
  56. package/test/__mocks__/modelMock.js +5 -0
  57. package/test/helpers/GlossaryHelper.spec.js +32 -14
  58. package/test/mocks.js +11 -0
  59. package/test/setup/before.js +15 -0
  60. package/helpers/GlossaryTerm.ts +0 -31
@@ -1,61 +1,15 @@
1
1
  <template>
2
2
  <div>
3
- <br />
4
- <v-card elevation="0">
5
- <v-btn-toggle v-model="settingSelector" multiple borderless>
6
- <v-tooltip top>
7
- <template #activator="{ on, attrs }">
8
- <v-btn
9
- elevation="0"
10
- v-bind="attrs"
11
- text
12
- :disabled="render"
13
- v-on="on"
14
- >
15
- <v-icon>mdi-comment-text-multiple</v-icon>
16
- {{
17
- $t(
18
- 'windward.core.components.settings.text_editor.glossary'
19
- )
20
- }}
21
- </v-btn>
22
- </template>
23
- <span>
24
- {{
25
- $t(
26
- 'windward.core.components.settings.text_editor.click_to_hide_glossary'
27
- )
28
- }}</span
29
- >
30
- </v-tooltip>
31
-
3
+ <TextEditor
4
+ v-model="block.body"
5
+ autofill
6
+ :disabled="render"
7
+ allow-read
8
+ show-glossary
9
+ :hide-text-editor="hideTextEditor"
10
+ >
11
+ <template #glossary-actions-append>
32
12
  <v-tooltip top>
33
- <template #activator="{ on, attrs }">
34
- <v-btn
35
- elevation="0"
36
- v-bind="attrs"
37
- text
38
- :disabled="render"
39
- v-on="on"
40
- >
41
- <v-icon> mdi-text-long</v-icon>
42
- {{
43
- $t(
44
- 'windward.core.components.settings.text_editor.text_editor'
45
- )
46
- }}
47
- </v-btn>
48
- </template>
49
- <span>
50
- {{
51
- $t(
52
- 'windward.core.components.settings.text_editor.click_to_hide_editor'
53
- )
54
- }}</span
55
- >
56
- </v-tooltip>
57
-
58
- <v-tooltip v-if="settingSelector.includes(1)" top>
59
13
  <template #activator="{ on, attrs }">
60
14
  <v-btn
61
15
  v-bind="attrs"
@@ -63,10 +17,7 @@
63
17
  text
64
18
  :disabled="render"
65
19
  v-on="on"
66
- @click="
67
- block.metadata.config.expand =
68
- !block.metadata.config.expand
69
- "
20
+ @click="onExpand"
70
21
  >
71
22
  <v-icon
72
23
  v-if="!block.metadata.config.expand"
@@ -89,129 +40,23 @@
89
40
  }}</span
90
41
  >
91
42
  </v-tooltip>
92
- </v-btn-toggle>
93
- <br />
94
- </v-card>
95
- <div v-show="settingSelector.includes(0)" class="pt-4">
96
- <br />
97
- <v-card v-if="verifiedTerms.length > 0" elevation="0" outlined>
98
- <v-card-title outlined class="text-capitalize">
99
- {{
100
- $t(
101
- 'windward.core.components.settings.text_editor.verified_terms'
102
- )
103
- }}
104
- </v-card-title>
105
- <v-card-text>
106
- <v-chip
107
- v-for="(verified, index) in verifiedTerms"
108
- :key="index"
109
- class="ma-2"
110
- close
111
- color="success"
112
- close-icon="mdi-pencil"
113
- :disabled="render"
114
- @click:close="editTerm(verified)"
115
- >
116
- <ContentViewer v-model="verified.term"></ContentViewer>
117
- </v-chip>
118
- </v-card-text>
119
- </v-card>
120
- <v-card v-if="unVerifiedTerms.length > 0" elevation="0" outlined>
121
- <v-card-title outlined class="text-capitalize">
122
- {{
123
- $t(
124
- 'windward.core.components.settings.text_editor.unverified_terms'
125
- )
126
- }}
127
- </v-card-title>
128
- <v-card-text>
129
- <v-chip
130
- v-for="(unVerified, index) in unVerifiedTerms"
131
- :key="index"
132
- class="ma-2"
133
- close
134
- color="error"
135
- close-icon="mdi-content-save-plus-outline"
136
- :disabled="render"
137
- @click:close="addGlossaryTerm(unVerified)"
138
- >
139
- <ContentViewer
140
- v-model="unVerified.term"
141
- ></ContentViewer>
142
- </v-chip>
143
- </v-card-text>
144
- </v-card>
145
- <v-card
146
- v-if="
147
- verifiedTerms.length === 0 && unVerifiedTerms.length === 0
148
- "
149
- elevation="0"
150
- outlined
151
- ><v-card-text class="text-capitalize font-weight-bold">
152
- {{
153
- $t(
154
- 'windward.core.components.settings.text_editor.no_glossary'
155
- )
156
- }}
157
- </v-card-text></v-card
158
- >
159
- </div>
160
- <br />
161
- <TextEditor
162
- v-if="settingSelector.includes(1) && !block.metadata.config.expand"
163
- v-model="block.body"
164
- autofill
165
- :disabled="render"
166
- allow-read
167
- ></TextEditor>
43
+ </template>
44
+ </TextEditor>
168
45
  <v-skeleton-loader
169
46
  v-show="settingSelector.includes(1) && block.metadata.config.expand"
170
47
  v-bind="attrs"
171
48
  type=" table-row-divider, list-item, divider, list-item, divider, image,image"
172
49
  ></v-skeleton-loader>
173
- <DialogBox
174
- v-model="dialog"
175
- color="primary"
176
- max-width="600px"
177
- action-save
178
- :trigger="false"
179
- :disabled="render"
180
- @click:save="save"
181
- @click:outside="close"
182
- @click:close="close"
183
- @keydown.esc="close"
184
- >
185
- <template #title> {{ formTitle }} </template>
186
- <template #form="{ on, attrs }">
187
- <course-glossary-form
188
- v-model="selectedTerm"
189
- :glossary="glossary"
190
- :edit-mode="glossaryEdit"
191
- v-bind="attrs"
192
- v-on="on"
193
- />
194
- </template>
195
- </DialogBox>
196
50
  </div>
197
51
  </template>
198
52
 
199
53
  <script>
200
- import { mapGetters, mapMutations } from 'vuex'
201
- import GlossaryHelper from '../../helpers/GlossaryHelper'
202
- import CourseGlossaryForm from '../utils/glossary/CourseGlossaryForm.vue'
203
- import ContentViewer from '../utils/ContentViewer.vue'
204
- import DialogBox from '~/components/Core/DialogBox.vue'
205
- import Course from '~/models/Course'
206
54
  import BaseContentSettings from '~/components/Content/Settings/BaseContentSettings.js'
207
55
  import TextEditor from '~/components/Text/TextEditor'
208
56
  export default {
209
57
  name: 'TextEditorSettings',
210
58
  components: {
211
- DialogBox,
212
59
  TextEditor,
213
- CourseGlossaryForm,
214
- ContentViewer,
215
60
  },
216
61
  extends: BaseContentSettings,
217
62
  data() {
@@ -226,90 +71,16 @@ export default {
226
71
  boilerplate: true,
227
72
  elevation: 0,
228
73
  },
74
+ hideTextEditor: false,
229
75
  }
230
76
  },
231
- computed: {
232
- ...mapGetters({
233
- course: 'course/get',
234
- }),
235
- ...mapMutations({
236
- saveCourse: 'course/set',
237
- }),
238
- glossary() {
239
- return _.isObject(this.course.metadata) &&
240
- _.isArray(this.course.metadata.glossary)
241
- ? this.course.metadata.glossary
242
- : []
243
- },
244
- verifiedTerms() {
245
- return GlossaryHelper.getContentVerifiedGlossaryTerms(
246
- this.block.body,
247
- this.glossary
248
- )
249
- },
250
- unVerifiedTerms() {
251
- return GlossaryHelper.getContentUnVerifiedGlossaryTerms(
252
- this.block.body,
253
- this.glossary
254
- )
255
- },
256
- },
257
77
  mounted() {
258
78
  this.setConfig({ expand: false })
259
79
  },
260
80
  methods: {
261
- async save() {
262
- const currentGlossary = _.cloneDeep(this.glossary)
263
- let currentItemIndex = -1
264
- currentGlossary.filter((item, index) => {
265
- if (item.term === this.selectedTerm.term) {
266
- currentItemIndex = index
267
- return item
268
- }
269
- })
270
- if (currentItemIndex > -1) {
271
- currentGlossary[currentItemIndex] = this.selectedTerm
272
- } else {
273
- currentGlossary.push(this.selectedTerm)
274
- }
275
- const course = new Course(this.course)
276
-
277
- // If the course metadata is empty then init it
278
- if (_.isEmpty(course.metadata)) {
279
- course.metadata = {}
280
- course.metadata.glossary = {}
281
- }
282
-
283
- // Set the updated glossary
284
- course.metadata.glossary = currentGlossary
285
-
286
- const updatedCourse = await course.save()
287
- this.$store.commit('course/set', updatedCourse)
288
- this.$toast.success(this.$t('shared.forms.saved'))
289
- },
290
- editTerm(term) {
291
- this.selectedTerm = term
292
-
293
- this.formTitle =
294
- this.$t('shared.forms.edit') +
295
- ' ' +
296
- this.$t('pages.glossary.page_glossary.term')
297
- this.glossaryEdit = true
298
- this.dialog = true
299
- },
300
- addGlossaryTerm(term) {
301
- this.selectedTerm = term
302
-
303
- this.formTitle =
304
- this.$t('shared.forms.add') +
305
- ' ' +
306
- this.$t('pages.glossary.page_glossary.term')
307
- this.glossaryEdit = false
308
- this.dialog = true
309
- },
310
- close() {
311
- this.glossaryEdit = false
312
- this.dialog = false
81
+ onExpand() {
82
+ this.hideTextEditor = !this.hideTextEditor
83
+ this.block.metadata.config.expand = this.hideTextEditor
313
84
  },
314
85
  },
315
86
  }
@@ -412,7 +412,7 @@ export default {
412
412
  data() {
413
413
  return {
414
414
  fileTab: null,
415
- playbackRateOptions: [0.25, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4],
415
+ playbackRateOptions: [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2],
416
416
  playlistPaginator: 1,
417
417
  media: {
418
418
  source: null,
@@ -27,6 +27,7 @@ export default {
27
27
  computed: {
28
28
  ...mapGetters({
29
29
  course: 'course/get',
30
+ glossaryTerms: 'glossary/getTerms',
30
31
  }),
31
32
  convertedContent() {
32
33
  let content = ''
@@ -45,12 +46,11 @@ export default {
45
46
  }
46
47
  if (
47
48
  GlossaryHelper.containsGlossaryTerms(content) &&
48
- _.isObject(this.course.metadata) &&
49
- _.isArray(this.course.metadata.glossary)
49
+ this.glossaryTerms
50
50
  ) {
51
51
  content = GlossaryHelper.renderGlossaryWordsHtml(
52
52
  content,
53
- this.course.metadata.glossary
53
+ this.glossaryTerms
54
54
  )
55
55
  }
56
56
 
@@ -1,5 +1,14 @@
1
1
  <template>
2
2
  <div :class="'tinymce-included-' + seed">
3
+ <GlossaryVerification
4
+ v-if="showGlossary"
5
+ :render="render"
6
+ :value="text"
7
+ >
8
+ <template #actions-append>
9
+ <slot name="glossary-actions-append"></slot>
10
+ </template>
11
+ </GlossaryVerification>
3
12
  <div
4
13
  :class="
5
14
  'windward-tinymce-wrapper windward-tinymce-wrapper' +
@@ -11,8 +20,9 @@
11
20
  <label v-if="label" class="editor-label">{{ label }}</label>
12
21
  </slot>
13
22
  <Editor
14
- ref="editor"
23
+ v-if="!render && !hideTextEditor"
15
24
  :id="editorId"
25
+ ref="editor"
16
26
  :key="seed + (isDarkTheme ? '-theme-dark' : '-theme-light')"
17
27
  v-model="text"
18
28
  initial-value=""
@@ -26,28 +36,22 @@
26
36
  <label v-if="hint" class="editor-hint">{{ hint }}</label>
27
37
  </slot>
28
38
  </div>
29
-
30
39
  <v-btn-toggle dense multiple class="pt-1 d-flex justify-end">
31
40
  <slot name="actions-prepend" :render="render"></slot>
32
41
  <slot name="actions" :render="render">
33
- <v-btn-toggle v-if="allowRead" dense>
34
- <v-btn v-if="render" color="primary" outlined @click="read">
42
+ <v-btn-toggle v-if="allowRead && !render" dense>
43
+ <v-btn color="primary" outlined @click="read">
35
44
  <v-icon> mdi-play</v-icon>
36
45
  </v-btn>
37
- <v-btn
38
- v-if="render"
39
- color="primary"
40
- outlined
41
- @click="pause"
42
- >
46
+ <v-btn color="primary" outlined @click="pause">
43
47
  <v-icon> mdi-pause</v-icon>
44
48
  </v-btn>
45
- <v-btn v-if="render" color="primary" outlined @click="stop">
49
+ <v-btn color="primary" outlined @click="stop">
46
50
  <v-icon> mdi-stop</v-icon>
47
51
  </v-btn>
48
52
  </v-btn-toggle>
49
53
  </slot>
50
- <slot name="actions-append" :render="render"></slot>
54
+ <slot name="actions-append"></slot>
51
55
  </v-btn-toggle>
52
56
  </div>
53
57
  </template>
@@ -57,7 +61,7 @@ import _ from 'lodash'
57
61
  import 'tinymce'
58
62
  import Editor from '@tinymce/tinymce-vue'
59
63
  import { getTinymce } from '@tinymce/tinymce-vue/lib/cjs/main/ts/TinyMCE'
60
-
64
+ import GlossaryVerification from '../Glossary/GlossaryVerification.vue'
61
65
  /* Required TinyMCE components */
62
66
  import 'tinymce/icons/default/icons.min.js'
63
67
  import 'tinymce/themes/silver/theme.min.js'
@@ -118,6 +122,7 @@ export default {
118
122
  name: 'ContentEditorRichText',
119
123
  components: {
120
124
  Editor,
125
+ GlossaryVerification,
121
126
  },
122
127
  props: {
123
128
  value: { type: String, required: true, default: '' },
@@ -140,10 +145,12 @@ export default {
140
145
  hint: { type: String, required: false, default: '' },
141
146
  inline: { type: Boolean, required: false, default: false },
142
147
  allowRead: { type: Boolean, required: false, default: false },
148
+ showGlossary: { type: Boolean, required: false, default: false },
149
+ render: { type: Boolean, required: false, default: false },
150
+ hideTextEditor: { type: Boolean, required: false, default: false },
143
151
  },
144
152
  data() {
145
153
  return {
146
- render: true,
147
154
  text: '',
148
155
  seed: Crypto.id(),
149
156
  synthesizer: null,
@@ -245,6 +252,9 @@ export default {
245
252
  },
246
253
  font_size_formats:
247
254
  '8pt 10pt 12pt 14pt 16pt 18pt 24pt 36pt 48pt',
255
+ table_default_attributes: {
256
+ border: '1',
257
+ },
248
258
  table_class_list: [
249
259
  { title: 'None', value: ' ' },
250
260
  {