@windward/core 0.14.0 → 0.15.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 (48) hide show
  1. package/CHANGELOG.md +3 -0
  2. package/bitbucket-pipelines.yml +8 -0
  3. package/components/Content/Blocks/UserUpload/ManageDataTableUserFiles.vue +2 -11
  4. package/components/Content/Blocks/Video.vue +1 -1
  5. package/components/Glossary/GlossaryVerification.vue +240 -0
  6. package/components/Navigation/Items/GlossaryNav.vue +8 -2
  7. package/components/Navigation/Items/UserUploadNav.vue +10 -2
  8. package/components/Settings/AccordionSettings.vue +37 -27
  9. package/components/Settings/ClickableIconsSettings.vue +1 -0
  10. package/components/Settings/ImageSettings.vue +5 -12
  11. package/components/Settings/TabSettings.vue +33 -23
  12. package/components/Settings/TextEditorSettings.vue +16 -245
  13. package/components/Settings/VideoSettings.vue +1 -1
  14. package/components/utils/ContentViewer.vue +3 -3
  15. package/components/utils/TinyMCEWrapper.vue +24 -14
  16. package/components/utils/glossary/CourseGlossary.vue +66 -91
  17. package/components/utils/glossary/CourseGlossaryForm.vue +42 -13
  18. package/components/utils/glossary/GlossaryToolTip.vue +7 -11
  19. package/helpers/GlossaryHelper.ts +18 -16
  20. package/i18n/en-US/pages/glossary.ts +3 -1
  21. package/i18n/en-US/shared/notification.ts +5 -0
  22. package/i18n/en-US/shared/permission.ts +4 -0
  23. package/i18n/es-ES/pages/glossary.ts +3 -1
  24. package/i18n/es-ES/shared/notification.ts +5 -0
  25. package/i18n/es-ES/shared/permission.ts +8 -4
  26. package/i18n/sv-SE/pages/glossary.ts +3 -1
  27. package/i18n/sv-SE/shared/notification.ts +4 -0
  28. package/i18n/sv-SE/shared/permission.ts +8 -4
  29. package/jest.config.js +3 -0
  30. package/models/BaseModel.ts +16 -0
  31. package/models/CourseGlossaryTerm.ts +22 -0
  32. package/models/UserFileAsset.ts +1 -0
  33. package/package.json +4 -3
  34. package/pages/glossary.vue +11 -3
  35. package/pages/userUpload.vue +1 -1
  36. package/plugin.js +33 -11
  37. package/store/glossary.js +57 -0
  38. package/test/Components/Content/Blocks/Feedback.spec.js +3 -1
  39. package/test/Components/Content/Blocks/Video.spec.js +2 -2
  40. package/test/Components/Glossary/GlossaryVerification.spec.js +19 -0
  41. package/test/Components/utils/glossary/CourseGlossary.spec.js +19 -0
  42. package/test/Components/utils/glossary/CourseGlossaryForm.spec.js +28 -0
  43. package/test/__mocks__/helpersMock.js +0 -24
  44. package/test/__mocks__/modelMock.js +5 -0
  45. package/test/helpers/GlossaryHelper.spec.js +32 -14
  46. package/test/mocks.js +11 -0
  47. package/test/setup/before.js +15 -0
  48. package/helpers/GlossaryTerm.ts +0 -31
package/CHANGELOG.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # Changelog
2
2
 
3
+ ### Release [0.15.0] created - 2025-04-09
4
+
5
+
3
6
  ### Release [0.14.0] created - 2025-03-25
4
7
 
5
8
 
@@ -1,6 +1,14 @@
1
1
  image: atlassian/default-image:3
2
2
 
3
3
  pipelines:
4
+ pull-requests:
5
+ '**':
6
+ - step:
7
+ name: Build and test
8
+ image: node:16.20.2
9
+ script:
10
+ - npm install
11
+ - npm run test
4
12
  custom:
5
13
  create-release:
6
14
  import: infrastructure-automation:master:create-release
@@ -1,9 +1,9 @@
1
1
  <template>
2
- <div class="text-center">
2
+ <div>
3
3
  <DialogBox
4
4
  v-bind="$attrs"
5
5
  transition="dialog-bottom-transition"
6
- :color="color"
6
+ color="primary"
7
7
  v-if="value.file_assets && value.file_assets.length > 0"
8
8
  >
9
9
  <template #title>{{
@@ -45,15 +45,6 @@ export default {
45
45
  userUploads: {},
46
46
  }
47
47
  },
48
- computed: {
49
- color() {
50
- if (this.value.file_assets && this.value.file_assets.length > 0) {
51
- return 'success'
52
- } else {
53
- return ''
54
- }
55
- },
56
- },
57
48
  watch: {
58
49
  value(newVal) {
59
50
  this.userUploads = newVal
@@ -332,7 +332,7 @@ export default {
332
332
  captionsmenu: true, // Show the captions below the video
333
333
  playlistmenu: true, // Show the playlist menu if there's multiple videos
334
334
  playlistautoadvance: true, // Play the next source group
335
- playbackrates: [0.5, 1, 1.5, 2], // Default playback speeds
335
+ playbackrates: [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2], // Default playback speeds
336
336
  },
337
337
  playlist: [
338
338
  /*{
@@ -0,0 +1,240 @@
1
+ <template>
2
+ <div>
3
+ <v-card elevation="0">
4
+ <v-btn-toggle v-model="settingSelector" multiple borderless>
5
+ <v-tooltip top>
6
+ <template #activator="{ on, attrs }">
7
+ <v-btn
8
+ elevation="0"
9
+ v-bind="attrs"
10
+ text
11
+ :disabled="render"
12
+ v-on="on"
13
+ >
14
+ <v-icon>mdi-comment-text-multiple</v-icon>
15
+ {{
16
+ $t(
17
+ 'windward.core.components.settings.text_editor.glossary'
18
+ )
19
+ }}
20
+ </v-btn>
21
+ </template>
22
+ <span>
23
+ {{
24
+ $t(
25
+ 'windward.core.components.settings.text_editor.click_to_hide_glossary'
26
+ )
27
+ }}</span
28
+ >
29
+ </v-tooltip>
30
+
31
+ <slot name="actions-append"></slot>
32
+ </v-btn-toggle>
33
+ <br />
34
+ </v-card>
35
+ <div v-if="settingSelector.includes(0)" class="pt-4">
36
+ <br />
37
+ <v-card v-if="verifiedTerms.length > 0" elevation="0" outlined>
38
+ <v-card-title outlined class="text-capitalize">
39
+ {{
40
+ $t(
41
+ 'windward.core.components.settings.text_editor.verified_terms'
42
+ )
43
+ }}
44
+ </v-card-title>
45
+ <v-card-text>
46
+ <v-chip
47
+ v-for="(verified, index) in verifiedTerms"
48
+ :key="index"
49
+ class="ma-2"
50
+ :close="
51
+ $PermissionService.userHasAccessTo(
52
+ 'plugin.windward.core.organization.course.glossary',
53
+ 'writable'
54
+ )
55
+ "
56
+ color="success"
57
+ close-icon="mdi-pencil"
58
+ :disabled="render"
59
+ @click:close="editTerm(verified)"
60
+ >
61
+ <ContentViewer v-model="verified.term"></ContentViewer>
62
+ </v-chip>
63
+ </v-card-text>
64
+ </v-card>
65
+ <v-card v-if="unVerifiedTerms.length > 0" elevation="0" outlined>
66
+ <v-card-title outlined class="text-capitalize">
67
+ {{
68
+ $t(
69
+ 'windward.core.components.settings.text_editor.unverified_terms'
70
+ )
71
+ }}
72
+ </v-card-title>
73
+ <v-card-text>
74
+ <v-chip
75
+ v-for="(unVerified, index) in unVerifiedTerms"
76
+ :key="index"
77
+ class="ma-2"
78
+ close
79
+ color="error"
80
+ close-icon="mdi-content-save-plus-outline"
81
+ :disabled="render"
82
+ @click:close="addGlossaryTerm(unVerified)"
83
+ >
84
+ <ContentViewer
85
+ v-model="unVerified.term"
86
+ ></ContentViewer>
87
+ </v-chip>
88
+ </v-card-text>
89
+ </v-card>
90
+ <v-card
91
+ v-if="
92
+ verifiedTerms.length === 0 && unVerifiedTerms.length === 0
93
+ "
94
+ elevation="0"
95
+ outlined
96
+ ><v-card-text class="text-capitalize font-weight-bold">
97
+ {{
98
+ $t(
99
+ 'windward.core.components.settings.text_editor.no_glossary'
100
+ )
101
+ }}
102
+ </v-card-text></v-card
103
+ >
104
+ </div>
105
+ <DialogBox
106
+ v-model="dialog"
107
+ color="primary"
108
+ max-width="600px"
109
+ action-save
110
+ :trigger="false"
111
+ :disabled="
112
+ render ||
113
+ !$PermissionService.userHasAccessTo(
114
+ 'plugin.windward.core.organization.course.glossary',
115
+ 'writable'
116
+ )
117
+ "
118
+ @click:save="save"
119
+ @click:outside="close"
120
+ @click:close="close"
121
+ @keydown.esc="close"
122
+ >
123
+ <template #title> {{ formTitle }} </template>
124
+ <template #form="{ on, attrs }">
125
+ <CourseGlossaryForm
126
+ v-model="selectedTerm"
127
+ :glossary="glossaryTerms"
128
+ :edit-mode="glossaryEdit"
129
+ :disabled="
130
+ !$PermissionService.userHasAccessTo(
131
+ 'plugin.windward.core.organization.course.glossary',
132
+ 'writable'
133
+ )
134
+ "
135
+ v-bind="attrs"
136
+ v-on="on"
137
+ ></CourseGlossaryForm>
138
+ </template>
139
+ </DialogBox>
140
+ </div>
141
+ </template>
142
+ <script>
143
+ import _ from 'lodash'
144
+ import { mapGetters, mapMutations, mapActions } from 'vuex'
145
+ import DialogBox from '~/components/Core/DialogBox.vue'
146
+ import Course from '~/models/Course'
147
+ import CourseGlossaryTerm from '../../models/CourseGlossaryTerm'
148
+ import CourseGlossaryForm from '../utils/glossary/CourseGlossaryForm'
149
+ import ContentViewer from '../utils/ContentViewer.vue'
150
+ import GlossaryHelper from '../../helpers/GlossaryHelper'
151
+ export default {
152
+ name: 'GlossaryVerification',
153
+ components: {
154
+ ContentViewer,
155
+ DialogBox,
156
+ CourseGlossaryForm,
157
+ },
158
+ props: {
159
+ value: {
160
+ type: String,
161
+ required: false,
162
+ default: '',
163
+ },
164
+ render: {
165
+ type: Boolean,
166
+ required: false,
167
+ default: false,
168
+ },
169
+ },
170
+ data() {
171
+ return {
172
+ dialog: false,
173
+ selectedTerm: {},
174
+ glossaryEdit: false,
175
+ formTitle: '',
176
+ settingSelector: [0, 1],
177
+ }
178
+ },
179
+ computed: {
180
+ ...mapGetters({
181
+ course: 'course/get',
182
+ glossaryTerms: 'glossary/getTerms',
183
+ }),
184
+ ...mapMutations({
185
+ saveCourse: 'course/set',
186
+ }),
187
+ verifiedTerms() {
188
+ return GlossaryHelper.getContentVerifiedGlossaryTerms(
189
+ this.value,
190
+ this.glossaryTerms
191
+ )
192
+ },
193
+ unVerifiedTerms() {
194
+ return GlossaryHelper.getContentUnVerifiedGlossaryTerms(
195
+ this.value,
196
+ this.glossaryTerms
197
+ )
198
+ },
199
+ },
200
+ methods: {
201
+ ...mapActions({
202
+ reloadGlossary: 'glossary/load',
203
+ }),
204
+ async save() {
205
+ try {
206
+ // Save the term
207
+ await new CourseGlossaryTerm(_.cloneDeep(this.selectedTerm))
208
+ .for(new Course(this.course))
209
+ .save()
210
+
211
+ // And update our local list
212
+ this.reloadGlossary(this.course)
213
+
214
+ this.$toast.success(this.$t('shared.forms.saved'))
215
+ } catch (e) {
216
+ console.error('Could not save glossary term', e)
217
+ this.$toast.error(this.$t('shared.forms.errors.unknown'))
218
+ }
219
+ },
220
+ editTerm(term) {
221
+ this.selectedTerm = term
222
+
223
+ this.formTitle = this.$t('windward.core.pages.glossary.edit_term')
224
+ this.glossaryEdit = true
225
+ this.dialog = true
226
+ },
227
+ addGlossaryTerm(term) {
228
+ this.selectedTerm = term
229
+
230
+ this.formTitle = this.$t('windward.core.pages.glossary.add_term')
231
+ this.glossaryEdit = false
232
+ this.dialog = true
233
+ },
234
+ close() {
235
+ this.glossaryEdit = false
236
+ this.dialog = false
237
+ },
238
+ },
239
+ }
240
+ </script>
@@ -3,7 +3,13 @@
3
3
  <template #activator="{ on, attrs }">
4
4
  <v-list-item
5
5
  :class="color"
6
- :to="'/course/' + course.id + '/glossary'"
6
+ :to="
7
+ '/course/' +
8
+ course.id +
9
+ '/section/' +
10
+ enrollment.course_section_id +
11
+ '/glossary'
12
+ "
7
13
  v-bind="attrs"
8
14
  v-on="on"
9
15
  >
@@ -28,7 +34,6 @@ import { mapGetters } from 'vuex'
28
34
 
29
35
  export default {
30
36
  name: 'GlossaryNav',
31
- layout: 'course',
32
37
  middleware: ['auth'],
33
38
  props: {
34
39
  color: { type: String, required: false, default: '' },
@@ -39,6 +44,7 @@ export default {
39
44
  computed: {
40
45
  ...mapGetters({
41
46
  course: 'course/get',
47
+ enrollment: 'enrollment/get',
42
48
  }),
43
49
  },
44
50
  }
@@ -1,5 +1,13 @@
1
1
  <template>
2
- <v-list-item :to="'/course/' + course.id + '/user-uploads'">
2
+ <v-list-item
3
+ :to="
4
+ '/course/' +
5
+ course.id +
6
+ '/section/' +
7
+ enrollment.course_section_id +
8
+ '/user-uploads'
9
+ "
10
+ >
3
11
  <v-list-item-action>
4
12
  <v-icon>mdi-cloud-upload</v-icon>
5
13
  </v-list-item-action>
@@ -18,7 +26,6 @@ import { mapGetters } from 'vuex'
18
26
 
19
27
  export default {
20
28
  components: {},
21
- layout: 'course',
22
29
  middleware: ['auth'],
23
30
  data() {
24
31
  return {}
@@ -26,6 +33,7 @@ export default {
26
33
  computed: {
27
34
  ...mapGetters({
28
35
  course: 'course/get',
36
+ enrollment: 'enrollment/get',
29
37
  }),
30
38
  },
31
39
  created() {},
@@ -55,41 +55,51 @@
55
55
  "
56
56
  :disabled="render"
57
57
  ></v-text-field>
58
- <v-btn
59
- text
60
- elevation="0"
61
- class="mb-3"
62
- :disabled="render"
63
- @click="
64
- onToggleExpand(
65
- block.metadata.config.items[index]
66
- )
67
- "
68
- >
69
- <v-icon
70
- v-if="
71
- !block.metadata.config.items[index].expand
72
- "
73
- color="primary"
74
- >mdi-arrow-expand-all</v-icon
75
- >
76
- <v-icon
77
- v-if="block.metadata.config.items[index].expand"
78
- color="primary"
79
- >
80
- mdi-arrow-collapse-all
81
- </v-icon>
82
- </v-btn>
83
58
  <TextEditor
84
- v-show="!block.metadata.config.items[index].expand"
85
59
  v-model="block.metadata.config.items[index].content"
60
+ :hide-text-editor="
61
+ block.metadata.config.items[index].expand
62
+ "
86
63
  :label="
87
64
  $t(
88
65
  'windward.core.components.settings.accordion.label'
89
66
  )
90
67
  "
91
68
  :disabled="render"
92
- ></TextEditor>
69
+ show-glossary
70
+ >
71
+ <template #glossary-actions-append>
72
+ <v-btn
73
+ text
74
+ elevation="0"
75
+ class="mb-3"
76
+ :disabled="render"
77
+ @click="
78
+ onToggleExpand(
79
+ block.metadata.config.items[index]
80
+ )
81
+ "
82
+ >
83
+ <v-icon
84
+ v-if="
85
+ !block.metadata.config.items[index]
86
+ .expand
87
+ "
88
+ color="primary"
89
+ >mdi-arrow-expand-all</v-icon
90
+ >
91
+ <v-icon
92
+ v-if="
93
+ block.metadata.config.items[index]
94
+ .expand
95
+ "
96
+ color="primary"
97
+ >
98
+ mdi-arrow-collapse-all
99
+ </v-icon>
100
+ </v-btn>
101
+ </template>
102
+ </TextEditor>
93
103
  <v-container class="pa-0 pt-3">
94
104
  <h4>
95
105
  {{
@@ -173,6 +173,7 @@
173
173
  .fileConfig
174
174
  "
175
175
  :assets.sync="block.assets"
176
+ :disabled="render"
176
177
  hide-background
177
178
  hide-decorative
178
179
  hide-modal
@@ -3,6 +3,7 @@
3
3
  <ImageAssetSettings
4
4
  v-model="block.metadata.config"
5
5
  :assets.sync="block.assets"
6
+ :disabled="render"
6
7
  >
7
8
  </ImageAssetSettings>
8
9
  </v-container>
@@ -10,26 +11,22 @@
10
11
 
11
12
  <script>
12
13
  import _ from 'lodash'
13
- import TextEditor from '~/components/Text/TextEditor'
14
- import TextViewer from '~/components/Text/TextViewer'
15
14
  import BaseContentSettings from '~/components/Content/Settings/BaseContentSettings.js'
16
- import ContentBlockAsset from '~/components/Content/ContentBlockAsset.vue'
17
15
  import ImageAssetSettings from '~/components/Content/Settings/ImageAssetSettings.vue'
18
16
 
19
17
  export default {
20
18
  name: 'ImageSettings',
21
- extends: BaseContentSettings,
22
19
  components: {
23
20
  ImageAssetSettings,
24
- ContentBlockAsset,
25
- TextEditor,
26
- TextViewer,
27
21
  },
22
+ extends: BaseContentSettings,
28
23
  props: {
29
24
  settings: { type: Object, required: false, default: null },
30
25
  context: { type: String, required: false, default: 'block' },
31
26
  },
32
- computed: {},
27
+ data() {
28
+ return {}
29
+ },
33
30
  beforeMount() {
34
31
  if (_.isEmpty(this.block)) {
35
32
  this.block = {}
@@ -65,10 +62,6 @@ export default {
65
62
  this.block.metadata.config.ariaDescribedBy = ''
66
63
  }
67
64
  },
68
- data() {
69
- return {}
70
- },
71
- watch: {},
72
65
  mounted() {},
73
66
  methods: {},
74
67
  }
@@ -41,39 +41,49 @@
41
41
  {{ $t('windward.core.components.settings.tab.header') }}
42
42
  </p>
43
43
  <v-text-field
44
+ v-model="block.metadata.config.items[index].tabHeader"
44
45
  outlined
45
46
  :autofocus="true"
46
- v-model="block.metadata.config.items[index].tabHeader"
47
47
  :rules="$Validation.getRule('shortInput')"
48
48
  :counter="$Validation.getLimit('shortInput')"
49
49
  :label="'item ' + (index + 1)"
50
50
  :disabled="render"
51
51
  ></v-text-field>
52
- <v-btn
53
- @click="onToggleExpand(index)"
54
- text
55
- elevation="0"
56
- class="mb-3"
57
- :disabled="render"
58
- >
59
- <v-icon
60
- v-if="!block.metadata.config.items[index].expand"
61
- color="primary"
62
- >mdi-arrow-expand-all</v-icon
63
- >
64
- <v-icon
65
- v-if="block.metadata.config.items[index].expand"
66
- color="primary"
67
- >
68
- mdi-arrow-collapse-all
69
- </v-icon>
70
- </v-btn>
71
52
  <TextEditor
72
- v-model="block.metadata.config.items[index].content"
73
- v-if="!item.expand"
74
53
  :key="textEditorUpdateKey"
54
+ v-model="block.metadata.config.items[index].content"
75
55
  :disabled="render"
76
- ></TextEditor>
56
+ show-glossary
57
+ :hide-text-editor="item.expand"
58
+ >
59
+ <template #glossary-actions-append>
60
+ <v-btn
61
+ text
62
+ elevation="0"
63
+ class="mb-3"
64
+ :disabled="render"
65
+ @click="onToggleExpand(index)"
66
+ >
67
+ <v-icon
68
+ v-if="
69
+ !block.metadata.config.items[index]
70
+ .expand
71
+ "
72
+ color="primary"
73
+ >mdi-arrow-expand-all</v-icon
74
+ >
75
+ <v-icon
76
+ v-if="
77
+ block.metadata.config.items[index]
78
+ .expand
79
+ "
80
+ color="primary"
81
+ >
82
+ mdi-arrow-collapse-all
83
+ </v-icon>
84
+ </v-btn>
85
+ </template>
86
+ </TextEditor>
77
87
 
78
88
  <v-card class="mt-2">
79
89
  <v-card-text class="pa-0">