@windward/core 0.3.0 → 0.4.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 (43) hide show
  1. package/components/Content/Blocks/Accordion.vue +37 -0
  2. package/components/Content/Blocks/ClickableIcons.vue +107 -20
  3. package/components/Content/Blocks/Email.vue +9 -0
  4. package/components/Content/Blocks/Image.vue +47 -19
  5. package/components/Content/Blocks/Video.vue +80 -9
  6. package/components/Settings/AccordionSettings.vue +53 -0
  7. package/components/Settings/ClickableIconsSettings.vue +84 -7
  8. package/components/Settings/EmailSettings.vue +0 -9
  9. package/components/Settings/ImageSettings.vue +142 -39
  10. package/components/Settings/OpenResponseSettings.vue +1 -2
  11. package/components/Settings/VideoSettings.vue +100 -63
  12. package/components/utils/ContentViewer.vue +6 -1
  13. package/components/utils/MathExpressionEditor.vue +10 -5
  14. package/components/utils/TinyMCEWrapper.vue +114 -18
  15. package/components/utils/assets/tinymce/content/dark/content.scss +4 -0
  16. package/components/utils/assets/tinymce/{css/content.scss → content/global.scss} +38 -37
  17. package/components/utils/assets/tinymce/content/light/content.scss +4 -0
  18. package/components/utils/assets/tinymce/ui/dark/content.scss +803 -0
  19. package/components/utils/assets/tinymce/ui/dark/skin.scss +4727 -0
  20. package/components/utils/assets/tinymce/ui/global.scss +19 -0
  21. package/components/utils/assets/tinymce/ui/light/content.scss +822 -0
  22. package/components/utils/assets/tinymce/ui/light/skin.scss +4731 -0
  23. package/components/utils/glossary/CourseGlossary.vue +1 -1
  24. package/config/tinymce.config.ts +22 -14
  25. package/helpers/FillInBlankHelper.ts +34 -28
  26. package/helpers/GlossaryHelper.ts +90 -73
  27. package/helpers/MathHelper.ts +49 -28
  28. package/helpers/tinymce/plugin.ts +9 -7
  29. package/i18n/en-US/components/settings/clickable_icon.ts +2 -0
  30. package/i18n/en-US/components/settings/image.ts +6 -1
  31. package/i18n/en-US/shared/settings.ts +3 -0
  32. package/i18n/es-ES/components/settings/clickable_icon.ts +2 -0
  33. package/i18n/es-ES/components/settings/image.ts +8 -1
  34. package/i18n/es-ES/shared/settings.ts +3 -0
  35. package/i18n/sv-SE/components/settings/clickable_icon.ts +2 -0
  36. package/i18n/sv-SE/components/settings/image.ts +6 -1
  37. package/i18n/sv-SE/shared/settings.ts +3 -0
  38. package/package.json +4 -3
  39. package/test/Components/Settings/AccordionSettings.spec.js +16 -2
  40. package/test/__mocks__/contentBlockMock.js +6 -0
  41. package/test/__mocks__/contentSettingsMock.js +6 -0
  42. package/test/helpers/MathHelper.spec.js +22 -3
  43. package/tsconfig.json +1 -0
@@ -60,6 +60,15 @@
60
60
  "
61
61
  :disabled="render"
62
62
  ></v-switch>
63
+ <v-switch
64
+ v-model="block.metadata.config.display.large_icon"
65
+ :label="
66
+ $t(
67
+ 'windward.core.components.settings.clickable_icon.display.large_icon'
68
+ )
69
+ "
70
+ :disabled="render"
71
+ ></v-switch>
63
72
  <v-switch
64
73
  v-model="block.metadata.config.display.autocolor"
65
74
  :label="
@@ -77,12 +86,25 @@
77
86
  @click:close="onRemoveElement"
78
87
  >
79
88
  <template #header="{ item }">
80
- <v-icon v-if="item.icon && isIcon(item.icon)">{{
81
- item.icon
82
- }}</v-icon>
83
- <span v-else-if="item.icon && !isIcon(item.icon)">{{
84
- item.icon
85
- }}</span>
89
+ <v-avatar v-if="item.iconImage && item.iconAsset">
90
+ <v-img :src="getImagePublicUrl(item.iconAsset)" />
91
+ </v-avatar>
92
+ <v-icon
93
+ v-else-if="
94
+ !item.iconImage &&
95
+ item.icon &&
96
+ isIcon(item.icon)
97
+ "
98
+ >{{ item.icon }}</v-icon
99
+ >
100
+ <span
101
+ v-else-if="
102
+ !item.iconImage &&
103
+ item.icon &&
104
+ !isIcon(item.icon)
105
+ "
106
+ >{{ item.icon }}</span
107
+ >
86
108
  <span v-else class="font-italic">
87
109
  {{
88
110
  $t(
@@ -93,7 +115,24 @@
93
115
  </template>
94
116
  <template #body="{ index }">
95
117
  <v-container>
118
+ <v-switch
119
+ v-model="
120
+ block.metadata.config.items[index].iconImage
121
+ "
122
+ :label="
123
+ $t(
124
+ 'windward.core.components.settings.clickable_icon.icon_image'
125
+ )
126
+ "
127
+ @click="onClickToggleIconImage(index)"
128
+ :disabled="render"
129
+ ></v-switch>
130
+
96
131
  <TextIconPicker
132
+ v-if="
133
+ !block.metadata.config.items[index]
134
+ .iconImage
135
+ "
97
136
  v-model="
98
137
  block.metadata.config.items[index].icon
99
138
  "
@@ -105,6 +144,20 @@
105
144
  "
106
145
  :disabled="render"
107
146
  ></TextIconPicker>
147
+
148
+ <ContentBlockAsset
149
+ v-if="
150
+ block.metadata.config.items[index].iconImage
151
+ "
152
+ v-model="
153
+ block.metadata.config.items[index].iconAsset
154
+ "
155
+ :assets.sync="block.assets"
156
+ class="mb-4"
157
+ mimes="image/jpeg,image/png,image/gif"
158
+ :disabled="render"
159
+ @click:file="onFileSelect($event, index)"
160
+ ></ContentBlockAsset>
108
161
  <v-text-field
109
162
  v-model="
110
163
  block.metadata.config.items[index].title
@@ -118,7 +171,6 @@
118
171
  "
119
172
  :disabled="render"
120
173
  ></v-text-field>
121
-
122
174
  <ColorPicker
123
175
  v-if="!block.metadata.config.display.autocolor"
124
176
  v-model="
@@ -164,6 +216,7 @@ import TextEditor from '~/components/Text/TextEditor'
164
216
  import TextIconPicker from '~/components/Core/TextIconPicker.vue'
165
217
  import ColorPicker from '~/components/Core/ColorPicker.vue'
166
218
  import SortableExpansionPanel from '~/components/Core/SortableExpansionPanel.vue'
219
+ import ContentBlockAsset from '~/components/Content/ContentBlockAsset.vue'
167
220
 
168
221
  export default {
169
222
  name: 'ClickableIconsSettings',
@@ -172,6 +225,7 @@ export default {
172
225
  TextEditor,
173
226
  TextIconPicker,
174
227
  ColorPicker,
228
+ ContentBlockAsset,
175
229
  },
176
230
  extends: BaseContentSettings,
177
231
 
@@ -202,6 +256,7 @@ export default {
202
256
  show_background: false,
203
257
  round_icon: false,
204
258
  italic_icon: false,
259
+ large_icon: false,
205
260
  autocolor: true,
206
261
  }
207
262
  }
@@ -218,6 +273,8 @@ export default {
218
273
  onAddElement() {
219
274
  const defaultObject = {
220
275
  icon: '',
276
+ iconAsset: null,
277
+ iconImage: false,
221
278
  title: '',
222
279
  body: '<p></p>',
223
280
  color: {
@@ -233,6 +290,26 @@ export default {
233
290
  isIcon(str) {
234
291
  return str && _.isString(str) && str.indexOf('mdi-') === 0
235
292
  },
293
+ getImagePublicUrl(fileAssetId) {
294
+ const foundAsset = this.resolveAsset(fileAssetId)
295
+
296
+ return _.get(foundAsset, 'asset.public_url', null)
297
+ },
298
+ onClickToggleIconImage(index) {
299
+ // We're switching between images / text. Clear the relevant fields
300
+ this.block.metadata.config.items[index].icon = ''
301
+ this.block.metadata.config.items[index].iconAsset = null
302
+ },
303
+ onFileSelect(file, index) {
304
+ // file = null when you remove a file
305
+ if (_.isEmpty(file)) {
306
+ this.block.metadata.config.items[index].icon = null
307
+ } else {
308
+ this.block.assets.push(file)
309
+ this.block.metadata.config.items[index].icon =
310
+ file.file_asset_id
311
+ }
312
+ },
236
313
  },
237
314
  }
238
315
  </script>
@@ -210,15 +210,6 @@ export default {
210
210
  this.block.metadata.config.selectedPanels = 0
211
211
  },
212
212
  methods: {
213
- onBeforeSave() {
214
- this.block.metadata.config.emails.forEach((element) => {
215
- if (element.from) {
216
- let matches = element.from.match(/\b(\w)/g)
217
- element.initials = matches.join('')
218
- }
219
- element.tinymce_expand = false
220
- })
221
- },
222
213
  onUpdatePanel($event) {
223
214
  if ($event !== this.block.metadata.config.selectedPanels) {
224
215
  //catch click event to open selected panel to edit
@@ -2,9 +2,10 @@
2
2
  <v-container>
3
3
  <ContentBlockAsset
4
4
  mimes="image/jpeg,image/png,image/gif"
5
- @click:file="onFileSelect"
5
+ v-model="block.metadata.config.asset"
6
6
  class="mb-4"
7
7
  :disabled="render"
8
+ @click:file="onFileSelect"
8
9
  >
9
10
  <template #title>
10
11
  {{ $t('windward.core.components.content.blocks.image.title') }}
@@ -19,7 +20,7 @@
19
20
  </ContentBlockAsset>
20
21
 
21
22
  <v-switch
22
- v-model="block.metadata.config.hide_background"
23
+ v-model="block.metadata.config.hideBackground"
23
24
  :label="
24
25
  $t('windward.core.components.settings.image.hide_background')
25
26
  "
@@ -31,30 +32,86 @@
31
32
  :disabled="render"
32
33
  ></v-switch>
33
34
  <v-tooltip top color="primary">
34
- <template v-slot:activator="{ on, attrs }">
35
- <div v-bind="attrs" v-on="on" class="d-flex justify-content">
36
- <v-switch
37
- v-model="block.metadata.config.decorative"
38
- @change="onDecorativeToggled($event)"
39
- :label="
40
- $t(
41
- 'windward.core.components.settings.image.decorative'
42
- )
43
- "
44
- :disabled="render"
45
- ></v-switch>
46
- <div class="d-flex align-center pb-4">
47
- <v-icon x-small>mdi-help</v-icon>
48
- </div>
49
- </div>
35
+ <template #activator="{ on, attrs }">
36
+ <v-switch
37
+ v-model="block.metadata.config.decorative"
38
+ :disabled="render"
39
+ @change="onDecorativeToggled($event)"
40
+ >
41
+ <template #label>
42
+ <span v-bind="attrs" v-on="on">
43
+ {{
44
+ $t(
45
+ 'windward.core.components.settings.image.decorative'
46
+ )
47
+ }}
48
+ <v-icon x-small class="help-offset-icon">
49
+ mdi-help
50
+ </v-icon>
51
+ </span>
52
+ </template>
53
+ </v-switch>
50
54
  </template>
51
55
  <span class="span-description">{{
52
- $t('windward.core.components.settings.image.toggle_description')
56
+ $t(
57
+ 'windward.core.components.settings.image.decorative_toggle_description'
58
+ )
53
59
  }}</span>
54
60
  </v-tooltip>
55
61
 
56
62
  <v-form v-if="!block.metadata.config.decorative">
63
+ <v-tooltip top color="primary">
64
+ <template #activator="{ on, attrs }">
65
+ <v-switch
66
+ v-model="block.metadata.config.inherit"
67
+ :disabled="render"
68
+ >
69
+ <template #label>
70
+ <span v-bind="attrs" v-on="on">
71
+ {{
72
+ $t(
73
+ 'windward.core.components.settings.image.inherit'
74
+ )
75
+ }}
76
+ <v-icon x-small class="help-offset-icon">
77
+ mdi-help
78
+ </v-icon>
79
+ </span>
80
+ </template>
81
+ </v-switch>
82
+ </template>
83
+ <span class="span-description">{{
84
+ $t(
85
+ 'windward.core.components.settings.image.inherit_global_toggle_description'
86
+ )
87
+ }}</span>
88
+ </v-tooltip>
89
+
90
+ <v-alert
91
+ v-if="block.metadata.config.inherit && !assetAltText"
92
+ type="warning"
93
+ >
94
+ {{
95
+ $t('windward.core.components.settings.image.inherit_no_alt')
96
+ }}
97
+ </v-alert>
98
+
99
+ <v-text-field
100
+ v-if="block.metadata.config.inherit && assetAltText"
101
+ :value="assetAltText"
102
+ :label="
103
+ $t('windward.core.components.navigation.image.default_alt')
104
+ "
105
+ outlined
106
+ counter
107
+ maxlength="125"
108
+ :rules="validation.textRules"
109
+ disabled
110
+ >
111
+ </v-text-field>
112
+
57
113
  <v-text-field
114
+ v-if="!block.metadata.config.inherit"
58
115
  v-model="block.metadata.config.alt"
59
116
  outlined
60
117
  counter
@@ -65,9 +122,9 @@
65
122
  :rules="validation.textRules"
66
123
  :disabled="render"
67
124
  >
68
- <template v-slot:append>
125
+ <template #append>
69
126
  <v-tooltip top color="primary">
70
- <template v-slot:activator="{ on }">
127
+ <template #activator="{ on }">
71
128
  <v-icon v-on="on" small>mdi-help</v-icon>
72
129
  </template>
73
130
  <span class="span-description">{{
@@ -81,8 +138,10 @@
81
138
  <h5 class="pb-2">
82
139
  {{ $t('windward.core.components.settings.image.screenreader') }}
83
140
  <v-tooltip top color="primary">
84
- <template v-slot:activator="{ on }">
85
- <v-icon v-on="on" small class="pb-3">mdi-help</v-icon>
141
+ <template #activator="{ on }">
142
+ <v-icon v-on="on" small class="help-offset-icon">
143
+ mdi-help
144
+ </v-icon>
86
145
  </template>
87
146
  <span class="span-description">{{
88
147
  $t(
@@ -92,10 +151,26 @@
92
151
  </v-tooltip>
93
152
  </h5>
94
153
  <TextEditor
95
- v-model="block.metadata.config.aria_describedby"
154
+ v-if="!block.metadata.config.inherit"
155
+ v-model="block.metadata.config.ariaDescribedBy"
96
156
  menubar="bullist numlist"
97
157
  :disabled="render"
98
158
  ></TextEditor>
159
+
160
+ <div v-if="block.metadata.config.inherit">
161
+ <v-card v-if="assetDescribedByText">
162
+ <v-card-text>
163
+ <TextViewer v-model="assetDescribedByText"></TextViewer>
164
+ </v-card-text>
165
+ </v-card>
166
+ <v-alert v-if="!assetDescribedByText" type="warning">
167
+ {{
168
+ $t(
169
+ 'windward.core.components.settings.image.inherit_no_aria'
170
+ )
171
+ }}
172
+ </v-alert>
173
+ </div>
99
174
  </v-form>
100
175
  </v-container>
101
176
  </template>
@@ -103,17 +178,38 @@
103
178
  <script>
104
179
  import _ from 'lodash'
105
180
  import TextEditor from '~/components/Text/TextEditor'
181
+ import TextViewer from '~/components/Text/TextViewer'
106
182
  import BaseContentSettings from '~/components/Content/Settings/BaseContentSettings.js'
107
183
  import ContentBlockAsset from '~/components/Content/ContentBlockAsset.vue'
108
184
 
109
185
  export default {
110
186
  name: 'ImageSettings',
111
187
  extends: BaseContentSettings,
112
- components: { ContentBlockAsset, TextEditor },
188
+ components: { ContentBlockAsset, TextEditor, TextViewer },
113
189
  props: {
114
190
  settings: { type: Object, required: false, default: null },
115
191
  context: { type: String, required: false, default: 'block' },
116
192
  },
193
+ computed: {
194
+ assetAltText() {
195
+ // Get the block aria info and fallback to the asset metadata
196
+ return _.get(this.fileAsset, 'metadata.props.alt', null)
197
+ },
198
+ assetDescribedByText() {
199
+ // Get the block aria info and fallback to the asset metadata
200
+ return _.get(
201
+ this.fileAsset,
202
+ 'metadata.props.aria_describedby',
203
+ null
204
+ )
205
+ },
206
+ fileAsset() {
207
+ return _.get(this.block, 'assets[0].asset', null)
208
+ },
209
+ fileAssetMap() {
210
+ return _.get(this.block, 'metadata.config.asset', null)
211
+ },
212
+ },
117
213
  beforeMount() {
118
214
  if (_.isEmpty(this.block)) {
119
215
  this.block = {}
@@ -127,11 +223,17 @@ export default {
127
223
  if (_.isEmpty(this.block.metadata.config)) {
128
224
  this.block.metadata.config = {}
129
225
  }
226
+ if (_.isEmpty(this.block.metadata.config.asset)) {
227
+ this.block.metadata.config.asset = null
228
+ }
130
229
  if (_.isEmpty(this.block.metadata.config.alt)) {
131
230
  this.block.metadata.config.alt = ''
132
231
  }
133
- if (!_.isBoolean(this.block.metadata.config.hide_background)) {
134
- this.block.metadata.config.hide_background = false
232
+ if (!_.isBoolean(this.block.metadata.config.hideBackground)) {
233
+ this.block.metadata.config.hideBackground = false
234
+ }
235
+ if (!_.isBoolean(this.block.metadata.config.inherit)) {
236
+ this.block.metadata.config.inherit = true
135
237
  }
136
238
  if (!_.isBoolean(this.block.metadata.config.modal)) {
137
239
  this.block.metadata.config.modal = false
@@ -139,18 +241,12 @@ export default {
139
241
  if (!_.isBoolean(this.block.metadata.config.decorative)) {
140
242
  this.block.metadata.config.decorative = false
141
243
  }
142
- if (_.isEmpty(this.block.metadata.config.aria_describedby)) {
143
- this.block.metadata.config.aria_describedby = ''
244
+ if (_.isEmpty(this.block.metadata.config.ariaDescribedBy)) {
245
+ this.block.metadata.config.ariaDescribedBy = ''
144
246
  }
145
247
  },
146
248
  data() {
147
249
  return {
148
- imageSettings: {
149
- // Default values
150
- alt_text: '',
151
- aria_described: '',
152
- release_results: 'submitted',
153
- },
154
250
  validation: {
155
251
  textRules: [
156
252
  (v) => !!v || this.$t('shared.forms.errors.required'),
@@ -163,16 +259,19 @@ export default {
163
259
  methods: {
164
260
  onDecorativeToggled(evt) {
165
261
  if (evt) {
166
- this.block.metadata.config.aria_describedby = ''
262
+ this.block.metadata.config.ariaDescribedBy = ''
167
263
  this.block.metadata.config.alt = ''
168
264
  }
169
265
  },
170
266
  onFileSelect(file) {
267
+ // Clear out the body since we're defining a proper file link now
268
+ this.block.body = ''
269
+
171
270
  // file = null when you remove a file
172
271
  if (_.isEmpty(file)) {
173
- this.block.body = ''
272
+ this.block.assets = []
174
273
  } else {
175
- this.block.body = file.asset.public_url
274
+ this.block.assets = [file]
176
275
 
177
276
  //Assign height and width for skeleton loader
178
277
  if (!_.isEmpty(file.asset.metadata.props)) {
@@ -188,7 +287,7 @@ export default {
188
287
  ''
189
288
  )
190
289
 
191
- this.block.metadata.config.aria_describedby = _.get(
290
+ this.block.metadata.config.ariaDescribedBy = _.get(
192
291
  file,
193
292
  'asset.metadata.props.aria_describedby',
194
293
  ''
@@ -204,4 +303,8 @@ export default {
204
303
  justify-content: center;
205
304
  width: 200px;
206
305
  }
306
+ .help-offset-icon {
307
+ position: relative;
308
+ top: -8px;
309
+ }
207
310
  </style>
@@ -45,12 +45,11 @@
45
45
  import _ from 'lodash'
46
46
  import TextEditor from '~/components/Text/TextEditor'
47
47
  import BaseContentSettings from '~/components/Content/Settings/BaseContentSettings.js'
48
- import ContentBlockAsset from '~/components/Content/ContentBlockAsset.vue'
49
48
 
50
49
  export default {
51
50
  name: 'ImageSettings',
52
51
  extends: BaseContentSettings,
53
- components: { ContentBlockAsset, TextEditor },
52
+ components: { TextEditor },
54
53
  props: {
55
54
  settings: { type: Object, required: false, default: null },
56
55
  context: { type: String, required: false, default: 'block' },