@windward/core 0.8.0 → 0.9.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.
Files changed (34) hide show
  1. package/.eslintrc.js +5 -1
  2. package/.prettierrc +3 -2
  3. package/CHANGELOG.md +3 -0
  4. package/components/Content/Blocks/ClickableIcons.vue +3 -9
  5. package/components/Content/Blocks/GenerateAIQuestionButton.vue +85 -18
  6. package/components/Content/Blocks/Image.vue +7 -182
  7. package/components/Content/Blocks/Tab.vue +10 -0
  8. package/components/Navigation/Items/GlossaryNav.vue +25 -10
  9. package/components/Settings/ImageSettings.vue +12 -240
  10. package/components/Settings/TabSettings.vue +17 -1
  11. package/components/Settings/TextEditorSettings.vue +17 -15
  12. package/components/utils/ContentViewer.vue +0 -3
  13. package/components/utils/FillInBlank/FillInBlankInput.vue +29 -47
  14. package/components/utils/TinyMCEWrapper.vue +37 -79
  15. package/components/utils/glossary/CourseGlossary.vue +5 -3
  16. package/components/utils/glossary/GlossaryToolTip.vue +8 -1
  17. package/helpers/GlossaryHelper.ts +38 -18
  18. package/helpers/tinymce/WindwardPlugins.ts +166 -118
  19. package/i18n/en-US/components/content/blocks/generate_questions.ts +3 -2
  20. package/i18n/en-US/components/utils/FillInBlank/FillInBlankInput.ts +2 -0
  21. package/i18n/en-US/components/utils/tiny_mce_wrapper.ts +1 -0
  22. package/i18n/es-ES/components/content/blocks/generate_questions.ts +2 -1
  23. package/i18n/es-ES/components/utils/FillInBlank/FillInBlankInput.ts +2 -0
  24. package/i18n/es-ES/components/utils/tiny_mce_wrapper.ts +3 -2
  25. package/i18n/sv-SE/components/content/blocks/generate_questions.ts +2 -1
  26. package/i18n/sv-SE/components/utils/FillInBlank/FillInBlankInput.ts +2 -0
  27. package/i18n/sv-SE/components/utils/tiny_mce_wrapper.ts +2 -0
  28. package/package.json +2 -1
  29. package/pages/glossary.vue +1 -1
  30. package/stylelint.config.js +14 -0
  31. package/test/Components/Content/Blocks/OpenResponseCollate.spec.js +3 -3
  32. package/test/Components/Settings/TabSettings.spec.js +2 -2
  33. package/test/__mocks__/contentBlockMock.js +20 -0
  34. package/test/helpers/GlossaryHelper.spec.js +17 -0
@@ -1,176 +1,10 @@
1
1
  <template>
2
2
  <v-container>
3
- <ContentBlockAsset
4
- mimes="image/jpeg,image/png,image/gif"
5
- v-model="block.metadata.config.asset"
6
- class="mb-4"
7
- :label="
8
- $t(
9
- 'windward.core.components.settings.image.current_image_file'
10
- ) + ':'
11
- "
12
- :disabled="render"
3
+ <ImageAssetSettings
4
+ v-model="block.metadata.config"
13
5
  :assets.sync="block.assets"
14
- @click:file="onFileSelect"
15
6
  >
16
- <template #title>
17
- {{ $t('windward.core.components.settings.image.place_image') }}
18
- </template>
19
- </ContentBlockAsset>
20
-
21
- <v-switch
22
- v-model="block.metadata.config.hideBackground"
23
- :label="
24
- $t('windward.core.components.settings.image.hide_background')
25
- "
26
- :disabled="render"
27
- ></v-switch>
28
- <v-switch
29
- v-model="block.metadata.config.modal"
30
- :label="$t('windward.core.components.settings.image.modal')"
31
- :disabled="render"
32
- ></v-switch>
33
- <v-tooltip top color="primary">
34
- <template #activator="{ on, attrs }">
35
- <v-switch
36
- v-model="block.metadata.config.decorative"
37
- :disabled="render"
38
- @change="onDecorativeToggled($event)"
39
- >
40
- <template #label>
41
- <span v-bind="attrs" v-on="on">
42
- {{
43
- $t(
44
- 'windward.core.components.settings.image.decorative'
45
- )
46
- }}
47
- <v-icon x-small class="help-offset-icon">
48
- mdi-help
49
- </v-icon>
50
- </span>
51
- </template>
52
- </v-switch>
53
- </template>
54
- <span class="span-description">{{
55
- $t(
56
- 'windward.core.components.settings.image.decorative_toggle_description'
57
- )
58
- }}</span>
59
- </v-tooltip>
60
-
61
- <v-form v-if="!block.metadata.config.decorative">
62
- <v-tooltip top color="primary">
63
- <template #activator="{ on, attrs }">
64
- <v-switch
65
- v-model="block.metadata.config.inherit"
66
- :disabled="render"
67
- >
68
- <template #label>
69
- <span v-bind="attrs" v-on="on">
70
- {{
71
- $t(
72
- 'windward.core.components.settings.image.inherit'
73
- )
74
- }}
75
- <v-icon x-small class="help-offset-icon">
76
- mdi-help
77
- </v-icon>
78
- </span>
79
- </template>
80
- </v-switch>
81
- </template>
82
- <span class="span-description">{{
83
- $t(
84
- 'windward.core.components.settings.image.inherit_global_toggle_description'
85
- )
86
- }}</span>
87
- </v-tooltip>
88
-
89
- <v-alert
90
- v-if="block.metadata.config.inherit && !assetAltText"
91
- type="warning"
92
- >
93
- {{
94
- $t('windward.core.components.settings.image.inherit_no_alt')
95
- }}
96
- </v-alert>
97
-
98
- <v-text-field
99
- v-if="block.metadata.config.inherit && assetAltText"
100
- :value="assetAltText"
101
- :label="
102
- $t('windward.core.components.navigation.image.default_alt')
103
- "
104
- outlined
105
- counter
106
- maxlength="125"
107
- :rules="$Validation.getRule('exists')"
108
- disabled
109
- >
110
- </v-text-field>
111
-
112
- <v-text-field
113
- v-if="!block.metadata.config.inherit"
114
- v-model="block.metadata.config.alt"
115
- outlined
116
- counter
117
- maxlength="125"
118
- :label="
119
- $t('windward.core.components.navigation.image.default_alt')
120
- "
121
- :rules="$Validation.getRule('exists')"
122
- :disabled="render"
123
- >
124
- <template #append>
125
- <v-tooltip top color="primary">
126
- <template #activator="{ on }">
127
- <v-icon v-on="on" small>mdi-help</v-icon>
128
- </template>
129
- <span class="span-description">{{
130
- $t(
131
- 'windward.core.components.settings.image.alt_description'
132
- )
133
- }}</span>
134
- </v-tooltip>
135
- </template>
136
- </v-text-field>
137
- <h5 class="pb-2">
138
- {{ $t('windward.core.components.settings.image.screenreader') }}
139
- <v-tooltip top color="primary">
140
- <template #activator="{ on }">
141
- <v-icon v-on="on" small class="help-offset-icon">
142
- mdi-help
143
- </v-icon>
144
- </template>
145
- <span class="span-description">{{
146
- $t(
147
- 'windward.core.components.settings.image.screenreader_description'
148
- )
149
- }}</span>
150
- </v-tooltip>
151
- </h5>
152
- <TextEditor
153
- v-if="!block.metadata.config.inherit"
154
- v-model="block.metadata.config.ariaDescribedBy"
155
- menubar="bullist numlist"
156
- :disabled="render"
157
- ></TextEditor>
158
-
159
- <div v-if="block.metadata.config.inherit">
160
- <v-card v-if="assetDescribedByText">
161
- <v-card-text>
162
- <TextViewer v-model="assetDescribedByText"></TextViewer>
163
- </v-card-text>
164
- </v-card>
165
- <v-alert v-if="!assetDescribedByText" type="warning">
166
- {{
167
- $t(
168
- 'windward.core.components.settings.image.inherit_no_aria'
169
- )
170
- }}
171
- </v-alert>
172
- </div>
173
- </v-form>
7
+ </ImageAssetSettings>
174
8
  </v-container>
175
9
  </template>
176
10
 
@@ -180,35 +14,22 @@ import TextEditor from '~/components/Text/TextEditor'
180
14
  import TextViewer from '~/components/Text/TextViewer'
181
15
  import BaseContentSettings from '~/components/Content/Settings/BaseContentSettings.js'
182
16
  import ContentBlockAsset from '~/components/Content/ContentBlockAsset.vue'
17
+ import ImageAssetSettings from '~/components/Content/Settings/ImageAssetSettings.vue'
183
18
 
184
19
  export default {
185
20
  name: 'ImageSettings',
186
21
  extends: BaseContentSettings,
187
- components: { ContentBlockAsset, TextEditor, TextViewer },
22
+ components: {
23
+ ImageAssetSettings,
24
+ ContentBlockAsset,
25
+ TextEditor,
26
+ TextViewer,
27
+ },
188
28
  props: {
189
29
  settings: { type: Object, required: false, default: null },
190
30
  context: { type: String, required: false, default: 'block' },
191
31
  },
192
- computed: {
193
- assetAltText() {
194
- // Get the block aria info and fallback to the asset metadata
195
- return _.get(this.fileAsset, 'metadata.props.alt', null)
196
- },
197
- assetDescribedByText() {
198
- // Get the block aria info and fallback to the asset metadata
199
- return _.get(
200
- this.fileAsset,
201
- 'metadata.props.aria_describedby',
202
- null
203
- )
204
- },
205
- fileAsset() {
206
- return _.get(this.block, 'assets[0].asset', null)
207
- },
208
- fileAssetMap() {
209
- return _.get(this.block, 'metadata.config.asset', null)
210
- },
211
- },
32
+ computed: {},
212
33
  beforeMount() {
213
34
  if (_.isEmpty(this.block)) {
214
35
  this.block = {}
@@ -249,55 +70,6 @@ export default {
249
70
  },
250
71
  watch: {},
251
72
  mounted() {},
252
- methods: {
253
- onDecorativeToggled(evt) {
254
- if (evt) {
255
- this.block.metadata.config.ariaDescribedBy = ''
256
- this.block.metadata.config.alt = ''
257
- }
258
- },
259
- onFileSelect(file) {
260
- // Clear out the body since we're defining a proper file link now
261
- this.block.body = ''
262
-
263
- // file = null when you remove a file
264
- if (_.isEmpty(file)) {
265
- this.block.assets = []
266
- } else {
267
- this.block.assets = [file]
268
-
269
- //Assign height and width for skeleton loader
270
- if (!_.isEmpty(file.asset.metadata.props)) {
271
- this.block.metadata.config.height =
272
- file.asset.metadata.props['height']
273
- this.block.metadata.config.width =
274
- file.asset.metadata.props['width']
275
- }
276
- // Assign any alt text from the filemanager file
277
- this.block.metadata.config.alt = _.get(
278
- file,
279
- 'asset.metadata.props.alt',
280
- ''
281
- )
282
-
283
- this.block.metadata.config.ariaDescribedBy = _.get(
284
- file,
285
- 'asset.metadata.props.aria_describedby',
286
- ''
287
- )
288
- }
289
- },
290
- },
73
+ methods: {},
291
74
  }
292
75
  </script>
293
- <style>
294
- .span-description {
295
- display: flex;
296
- justify-content: center;
297
- width: 200px;
298
- }
299
- .help-offset-icon {
300
- position: relative;
301
- top: -8px;
302
- }
303
- </style>
@@ -74,6 +74,19 @@
74
74
  :key="textEditorUpdateKey"
75
75
  :disabled="render"
76
76
  ></TextEditor>
77
+
78
+ <v-card class="mt-2">
79
+ <v-card-text>
80
+ <ImageAssetSettings
81
+ v-model="
82
+ block.metadata.config.items[index]
83
+ .imageAsset
84
+ "
85
+ :assets.sync="block.assets"
86
+ >
87
+ </ImageAssetSettings>
88
+ </v-card-text>
89
+ </v-card>
77
90
  </v-container>
78
91
  </template>
79
92
  </SortableExpansionPanel>
@@ -103,13 +116,14 @@
103
116
  import _, { get } from 'lodash'
104
117
  import Crypto from '~/helpers/Crypto'
105
118
  import TextEditor from '~/components/Text/TextEditor'
119
+ import ImageAssetSettings from '~/components/Content/Settings/ImageAssetSettings.vue'
106
120
  import BaseContentSettings from '~/components/Content/Settings/BaseContentSettings.js'
107
121
  import SortableExpansionPanel from '~/components/Core/SortableExpansionPanel.vue'
108
122
  import Uuid from '~/helpers/Uuid'
109
123
 
110
124
  export default {
111
125
  name: 'TabSettings',
112
- components: { TextEditor, SortableExpansionPanel },
126
+ components: { TextEditor, ImageAssetSettings, SortableExpansionPanel },
113
127
  extends: BaseContentSettings,
114
128
  beforeMount() {
115
129
  if (_.isEmpty(this.block)) {
@@ -146,6 +160,7 @@ export default {
146
160
  tabHeader: '',
147
161
  expand: false,
148
162
  content: '',
163
+ imageAsset: null,
149
164
  }
150
165
  this.block.metadata.config.items = []
151
166
  this.block.metadata.config.items.push(defaultObject)
@@ -175,6 +190,7 @@ export default {
175
190
  tabHeader: '',
176
191
  expand: false,
177
192
  content: '',
193
+ imageAsset: null,
178
194
  }
179
195
  this.block.metadata.config.items.push(defaultObject)
180
196
  this.block.metadata.config.currentTab =
@@ -8,9 +8,9 @@
8
8
  <v-btn
9
9
  elevation="0"
10
10
  v-bind="attrs"
11
- v-on="on"
12
11
  text
13
12
  :disabled="render"
13
+ v-on="on"
14
14
  >
15
15
  <v-icon>mdi-comment-text-multiple</v-icon>
16
16
  {{
@@ -34,9 +34,9 @@
34
34
  <v-btn
35
35
  elevation="0"
36
36
  v-bind="attrs"
37
- v-on="on"
38
37
  text
39
38
  :disabled="render"
39
+ v-on="on"
40
40
  >
41
41
  <v-icon> mdi-text-long</v-icon>
42
42
  {{
@@ -55,14 +55,14 @@
55
55
  >
56
56
  </v-tooltip>
57
57
 
58
- <v-tooltip top v-if="settingSelector.includes(1)">
58
+ <v-tooltip v-if="settingSelector.includes(1)" top>
59
59
  <template #activator="{ on, attrs }">
60
60
  <v-btn
61
61
  v-bind="attrs"
62
- v-on="on"
63
62
  elevation="0"
64
63
  text
65
64
  :disabled="render"
65
+ v-on="on"
66
66
  @click="
67
67
  block.metadata.config.expand =
68
68
  !block.metadata.config.expand
@@ -94,7 +94,7 @@
94
94
  </v-card>
95
95
  <div v-show="settingSelector.includes(0)" class="pt-4">
96
96
  <br />
97
- <v-card elevation="0" outlined v-if="verifiedTerms.length > 0">
97
+ <v-card v-if="verifiedTerms.length > 0" elevation="0" outlined>
98
98
  <v-card-title outlined class="text-capitalize">
99
99
  {{
100
100
  $t(
@@ -113,11 +113,11 @@
113
113
  :disabled="render"
114
114
  @click:close="editTerm(verified)"
115
115
  >
116
- {{ verified.term }}
116
+ <TextViewer v-model="verified.term"></TextViewer>
117
117
  </v-chip>
118
118
  </v-card-text>
119
119
  </v-card>
120
- <v-card elevation="0" outlined v-if="unVerifiedTerms.length > 0">
120
+ <v-card v-if="unVerifiedTerms.length > 0" elevation="0" outlined>
121
121
  <v-card-title outlined class="text-capitalize">
122
122
  {{
123
123
  $t(
@@ -136,16 +136,16 @@
136
136
  :disabled="render"
137
137
  @click:close="addGlossaryTerm(unVerified)"
138
138
  >
139
- {{ unVerified.term }}
139
+ <TextViewer v-model="unVerified.term"></TextViewer>
140
140
  </v-chip>
141
141
  </v-card-text>
142
142
  </v-card>
143
143
  <v-card
144
- elevation="0"
145
- outlined
146
144
  v-if="
147
145
  verifiedTerms.length === 0 && unVerifiedTerms.length === 0
148
146
  "
147
+ elevation="0"
148
+ outlined
149
149
  ><v-card-text class="text-capitalize font-weight-bold">
150
150
  {{
151
151
  $t(
@@ -164,9 +164,9 @@
164
164
  allow-read
165
165
  ></TextEditor>
166
166
  <v-skeleton-loader
167
+ v-show="settingSelector.includes(1) && block.metadata.config.expand"
167
168
  v-bind="attrs"
168
169
  type=" table-row-divider, list-item, divider, list-item, divider, image,image"
169
- v-show="settingSelector.includes(1) && block.metadata.config.expand"
170
170
  ></v-skeleton-loader>
171
171
  <DialogBox
172
172
  v-model="dialog"
@@ -196,20 +196,22 @@
196
196
 
197
197
  <script>
198
198
  import { mapGetters, mapMutations } from 'vuex'
199
- import DialogBox from '~/components/Core/DialogBox.vue'
200
199
  import GlossaryHelper from '../../helpers/GlossaryHelper'
200
+ import CourseGlossaryForm from '../utils/glossary/CourseGlossaryForm.vue'
201
+ import DialogBox from '~/components/Core/DialogBox.vue'
201
202
  import Course from '~/models/Course'
202
203
  import BaseContentSettings from '~/components/Content/Settings/BaseContentSettings.js'
203
204
  import TextEditor from '~/components/Text/TextEditor'
204
- import CourseGlossaryForm from '../utils/glossary/CourseGlossaryForm.vue'
205
+ import TextViewer from '~/components/Text/TextViewer.vue'
205
206
  export default {
206
207
  name: 'TextEditorSettings',
207
- extends: BaseContentSettings,
208
208
  components: {
209
209
  DialogBox,
210
210
  TextEditor,
211
211
  CourseGlossaryForm,
212
+ TextViewer,
212
213
  },
214
+ extends: BaseContentSettings,
213
215
  data() {
214
216
  return {
215
217
  dialog: false,
@@ -255,7 +257,7 @@ export default {
255
257
  },
256
258
  methods: {
257
259
  async save() {
258
- let currentGlossary = _.cloneDeep(this.glossary)
260
+ const currentGlossary = _.cloneDeep(this.glossary)
259
261
  let currentItemIndex = -1
260
262
  currentGlossary.filter((item, index) => {
261
263
  if (item.term === this.selectedTerm.term) {
@@ -62,9 +62,6 @@ export default {
62
62
  </script>
63
63
 
64
64
  <style lang="scss">
65
- .text-viewer {
66
- min-height: 50px !important;
67
- }
68
65
  .text-viewer table tr td {
69
66
  padding: 10px !important;
70
67
  }
@@ -2,30 +2,24 @@
2
2
  <span class="fib">
3
3
  <v-dialog v-model="show" max-width="300">
4
4
  <v-card>
5
- <v-card-title class="text-h5">
6
- {{
7
- answerIsCorrect
8
- ? $t(
9
- 'windward.core.components.utils.fill_in_the_blank.fill_in_blank_input.correct'
10
- )
11
- : $t(
12
- 'windward.core.components.utils.fill_in_the_blank.fill_in_blank_input.incorrect'
13
- )
14
- }}
15
- </v-card-title>
16
- <v-card-text>
17
- <div v-if="answerIsCorrect || showAnswer">
5
+ <v-card-text class="pt-6">
6
+ <div>
18
7
  <p>
19
- <ContentViewer v-model="computedDescription" />
8
+ {{
9
+ $t(
10
+ 'windward.core.components.utils.fill_in_the_blank.fill_in_blank_input.user_input',
11
+ [userInput]
12
+ )
13
+ }}
14
+ </p>
15
+ <p class="pb-0 mb-0">
16
+ {{
17
+ $t(
18
+ 'windward.core.components.utils.fill_in_the_blank.fill_in_blank_input.correct_answer',
19
+ [answer]
20
+ )
21
+ }}
20
22
  </p>
21
- </div>
22
- <div v-else-if="!answerIsCorrect && userInput">
23
- {{
24
- $t(
25
- 'windward.core.components.utils.fill_in_the_blank.fill_in_blank_input.input_incorrect',
26
- [userInput]
27
- )
28
- }}
29
23
  </div>
30
24
  </v-card-text>
31
25
  <v-card-actions>
@@ -37,31 +31,14 @@
37
31
  elevation="0"
38
32
  outlined
39
33
  @click="show = false"
40
- >
41
- {{
42
- answerIsCorrect
43
- ? $t(
44
- 'windward.core.components.utils.fill_in_the_blank.fill_in_blank_input.close'
45
- )
46
- : $t(
47
- 'windward.core.components.utils.fill_in_the_blank.fill_in_blank_input.try_again'
48
- )
49
- }}
50
- </v-btn>
51
- <v-btn
52
- color="primary"
53
- outlined
54
- elevation="0"
55
- @click="displayAnswer"
56
- v-if="!answerIsCorrect"
57
34
  >
58
35
  {{
59
36
  $t(
60
- 'windward.core.components.utils.fill_in_the_blank.fill_in_blank_input.answer'
37
+ 'windward.core.components.utils.fill_in_the_blank.fill_in_blank_input.close'
61
38
  )
62
39
  }}
63
- </v-btn></v-row
64
- >
40
+ </v-btn>
41
+ </v-row>
65
42
  </v-container>
66
43
  </v-card-actions>
67
44
  </v-card>
@@ -142,8 +119,16 @@ export default {
142
119
  computed: {
143
120
  answerIsCorrect() {
144
121
  if (
145
- _.replace(_.trim(_.toLower(this.answer)),new RegExp(' ','g'), '', ) ===
146
- _.replace(_.trim(_.toLower(this.userInput)),new RegExp(' ','g'), '', )
122
+ _.replace(
123
+ _.trim(_.toLower(this.answer)),
124
+ new RegExp(' ', 'g'),
125
+ ''
126
+ ) ===
127
+ _.replace(
128
+ _.trim(_.toLower(this.userInput)),
129
+ new RegExp(' ', 'g'),
130
+ ''
131
+ )
147
132
  ) {
148
133
  return true
149
134
  }
@@ -158,9 +143,6 @@ export default {
158
143
  }
159
144
  return ''
160
145
  },
161
- computedDescription() {
162
- return atob(this.description)
163
- },
164
146
  },
165
147
  methods: {
166
148
  setFocusAction() {