@windward/core 0.2.3 → 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 (173) hide show
  1. package/babel.config.js +1 -1
  2. package/components/Content/Blocks/Accordion.vue +37 -0
  3. package/components/Content/Blocks/ClickableIcons.vue +107 -20
  4. package/components/Content/Blocks/Email.vue +9 -0
  5. package/components/Content/Blocks/Image.vue +48 -20
  6. package/components/Content/Blocks/UserUpload/ManageDataTableUserFiles.vue +1 -1
  7. package/components/Content/Blocks/UserUpload.vue +1 -1
  8. package/components/Content/Blocks/Video.vue +80 -9
  9. package/components/Navigation/Items/AskTheExpert.vue +2 -1
  10. package/components/Navigation/Items/CourseGlossaryToolNav.vue +2 -1
  11. package/components/Settings/AccordionSettings.vue +64 -4
  12. package/components/Settings/BlockQuoteSettings.vue +9 -1
  13. package/components/Settings/ClickableIconsSettings.vue +104 -13
  14. package/components/Settings/EmailSettings.vue +13 -13
  15. package/components/Settings/FeedbackSettings.vue +2 -1
  16. package/components/Settings/HorizontalRuleSettings.vue +2 -1
  17. package/components/Settings/ImageSettings.vue +148 -39
  18. package/components/Settings/MathSettings.vue +6 -5
  19. package/components/Settings/OpenResponseCollateSettings.vue +5 -1
  20. package/components/Settings/OpenResponseSettings.vue +9 -4
  21. package/components/Settings/ScenarioChoiceSettings.vue +15 -4
  22. package/components/Settings/TabSettings.vue +12 -4
  23. package/components/Settings/TextEditorSettings.vue +14 -7
  24. package/components/Settings/UserUploadSettings.vue +11 -4
  25. package/components/Settings/VideoSettings.vue +121 -66
  26. package/components/utils/ContentViewer.vue +6 -1
  27. package/components/utils/MathExpressionEditor.vue +10 -5
  28. package/components/utils/TinyMCEWrapper.vue +120 -19
  29. package/components/utils/assets/tinymce/content/dark/content.scss +4 -0
  30. package/components/utils/assets/tinymce/{css/content.scss → content/global.scss} +38 -37
  31. package/components/utils/assets/tinymce/content/light/content.scss +4 -0
  32. package/components/utils/assets/tinymce/ui/dark/content.scss +803 -0
  33. package/components/utils/assets/tinymce/ui/dark/skin.scss +4727 -0
  34. package/components/utils/assets/tinymce/ui/global.scss +19 -0
  35. package/components/utils/assets/tinymce/ui/light/content.scss +822 -0
  36. package/components/utils/assets/tinymce/ui/light/skin.scss +4731 -0
  37. package/components/utils/glossary/CourseGlossary.vue +4 -3
  38. package/components/utils/glossary/CourseGlossaryForm.vue +1 -1
  39. package/config/tinymce.config.ts +22 -14
  40. package/helpers/FillInBlankHelper.ts +34 -28
  41. package/helpers/GlossaryHelper.ts +90 -73
  42. package/helpers/MathHelper.ts +49 -28
  43. package/helpers/tinymce/plugin.ts +9 -7
  44. package/i18n/en-US/components/content/blocks/image.ts +1 -1
  45. package/i18n/en-US/components/settings/clickable_icon.ts +2 -0
  46. package/i18n/en-US/components/settings/image.ts +6 -1
  47. package/i18n/en-US/shared/settings.ts +3 -0
  48. package/i18n/es-ES/components/content/blocks/image.ts +1 -1
  49. package/i18n/es-ES/components/settings/clickable_icon.ts +2 -0
  50. package/i18n/es-ES/components/settings/image.ts +8 -1
  51. package/i18n/es-ES/shared/settings.ts +3 -0
  52. package/i18n/sv-SE/components/content/blocks/image.ts +1 -1
  53. package/i18n/sv-SE/components/settings/clickable_icon.ts +2 -0
  54. package/i18n/sv-SE/components/settings/image.ts +6 -1
  55. package/i18n/sv-SE/shared/settings.ts +3 -0
  56. package/package.json +4 -3
  57. package/test/Components/Settings/AccordionSettings.spec.js +16 -2
  58. package/test/__mocks__/componentsMock.js +57 -97
  59. package/test/__mocks__/contentBlockMock.js +7 -1
  60. package/test/__mocks__/contentSettingsMock.js +8 -1
  61. package/test/__mocks__/helpersMock.js +9 -0
  62. package/test/__mocks__/modelMock.js +101 -31
  63. package/test/helpers/MathHelper.spec.js +22 -3
  64. package/tsconfig.json +1 -0
  65. package/.idea/codeStyles/Project.xml +0 -58
  66. package/.idea/codeStyles/codeStyleConfig.xml +0 -5
  67. package/.idea/inspectionProfiles/Project_Default.xml +0 -6
  68. package/.idea/modules.xml +0 -8
  69. package/.idea/php-docker-settings.xml +0 -24
  70. package/.idea/php.xml +0 -19
  71. package/.idea/vcs.xml +0 -6
  72. package/.idea/watcherTasks.xml +0 -4
  73. package/.idea/windward-ui-plugin-core.iml +0 -8
  74. package/coverage/clover.xml +0 -223
  75. package/coverage/coverage-final.json +0 -16
  76. package/coverage/lcov-report/base.css +0 -224
  77. package/coverage/lcov-report/block-navigation.js +0 -87
  78. package/coverage/lcov-report/components/Content/Blocks/Accordion.vue.html +0 -430
  79. package/coverage/lcov-report/components/Content/Blocks/Image.vue.html +0 -394
  80. package/coverage/lcov-report/components/Content/Blocks/Math.vue.html +0 -262
  81. package/coverage/lcov-report/components/Content/Blocks/RichText.vue.html +0 -295
  82. package/coverage/lcov-report/components/Content/Blocks/Tab.vue.html +0 -415
  83. package/coverage/lcov-report/components/Content/Blocks/Table.vue.html +0 -667
  84. package/coverage/lcov-report/components/Content/Blocks/Video.vue.html +0 -2275
  85. package/coverage/lcov-report/components/Content/Blocks/index.html +0 -206
  86. package/coverage/lcov-report/components/utils/ContentViewer.vue.html +0 -199
  87. package/coverage/lcov-report/components/utils/MathExpressionEditor.vue.html +0 -919
  88. package/coverage/lcov-report/components/utils/MathLiveWrapper.vue.html +0 -343
  89. package/coverage/lcov-report/components/utils/TinyMCEWrapper.vue.html +0 -271
  90. package/coverage/lcov-report/components/utils/index.html +0 -161
  91. package/coverage/lcov-report/config/index.html +0 -116
  92. package/coverage/lcov-report/config/tinymce.config.js.html +0 -493
  93. package/coverage/lcov-report/favicon.png +0 -0
  94. package/coverage/lcov-report/helpers/MathHelper.ts.html +0 -793
  95. package/coverage/lcov-report/helpers/index.html +0 -116
  96. package/coverage/lcov-report/helpers/tinymce/index.html +0 -116
  97. package/coverage/lcov-report/helpers/tinymce/plugin.ts.html +0 -334
  98. package/coverage/lcov-report/index.html +0 -191
  99. package/coverage/lcov-report/prettify.css +0 -1
  100. package/coverage/lcov-report/prettify.js +0 -2
  101. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  102. package/coverage/lcov-report/sorter.js +0 -196
  103. package/coverage/lcov-report/test/index.html +0 -116
  104. package/coverage/lcov-report/test/mocks.js.html +0 -457
  105. package/coverage/lcov.info +0 -403
  106. package/lib/helpers/GlossaryHelper.d.ts +0 -9
  107. package/lib/helpers/GlossaryHelper.js +0 -118
  108. package/lib/helpers/GlossaryTerm.d.ts +0 -10
  109. package/lib/helpers/GlossaryTerm.js +0 -22
  110. package/lib/helpers/MathHelper.d.ts +0 -99
  111. package/lib/helpers/MathHelper.js +0 -194
  112. package/lib/helpers/tinymce/plugin.d.ts +0 -2
  113. package/lib/helpers/tinymce/plugin.js +0 -86
  114. package/lib/i18n/en-US/components/content/blocks/image.d.ts +0 -6
  115. package/lib/i18n/en-US/components/content/blocks/image.js +0 -7
  116. package/lib/i18n/en-US/components/content/blocks/index.d.ts +0 -75
  117. package/lib/i18n/en-US/components/content/blocks/index.js +0 -14
  118. package/lib/i18n/en-US/components/content/blocks/tab.d.ts +0 -5
  119. package/lib/i18n/en-US/components/content/blocks/tab.js +0 -6
  120. package/lib/i18n/en-US/components/content/blocks/table.d.ts +0 -5
  121. package/lib/i18n/en-US/components/content/blocks/table.js +0 -6
  122. package/lib/i18n/en-US/components/content/blocks/user_upload.d.ts +0 -13
  123. package/lib/i18n/en-US/components/content/blocks/user_upload.js +0 -14
  124. package/lib/i18n/en-US/components/content/blocks/video.d.ts +0 -48
  125. package/lib/i18n/en-US/components/content/blocks/video.js +0 -49
  126. package/lib/i18n/en-US/components/content/index.d.ts +0 -77
  127. package/lib/i18n/en-US/components/content/index.js +0 -6
  128. package/lib/i18n/en-US/components/index.d.ts +0 -140
  129. package/lib/i18n/en-US/components/index.js +0 -12
  130. package/lib/i18n/en-US/components/navigation/image.d.ts +0 -5
  131. package/lib/i18n/en-US/components/navigation/image.js +0 -6
  132. package/lib/i18n/en-US/components/navigation/index.d.ts +0 -10
  133. package/lib/i18n/en-US/components/navigation/index.js +0 -8
  134. package/lib/i18n/en-US/components/navigation/user_upload.d.ts +0 -4
  135. package/lib/i18n/en-US/components/navigation/user_upload.js +0 -5
  136. package/lib/i18n/en-US/components/settings/clickable_icon.d.ts +0 -6
  137. package/lib/i18n/en-US/components/settings/clickable_icon.js +0 -7
  138. package/lib/i18n/en-US/components/settings/image.d.ts +0 -2
  139. package/lib/i18n/en-US/components/settings/image.js +0 -3
  140. package/lib/i18n/en-US/components/settings/index.d.ts +0 -39
  141. package/lib/i18n/en-US/components/settings/index.js +0 -14
  142. package/lib/i18n/en-US/components/settings/text_editor.d.ts +0 -8
  143. package/lib/i18n/en-US/components/settings/text_editor.js +0 -9
  144. package/lib/i18n/en-US/components/settings/user_upload.d.ts +0 -12
  145. package/lib/i18n/en-US/components/settings/user_upload.js +0 -13
  146. package/lib/i18n/en-US/components/settings/video.d.ts +0 -13
  147. package/lib/i18n/en-US/components/settings/video.js +0 -14
  148. package/lib/i18n/en-US/components/utils/index.d.ts +0 -15
  149. package/lib/i18n/en-US/components/utils/index.js +0 -6
  150. package/lib/i18n/en-US/components/utils/tiny_mce_wrapper.d.ts +0 -13
  151. package/lib/i18n/en-US/components/utils/tiny_mce_wrapper.js +0 -14
  152. package/lib/i18n/en-US/index.d.ts +0 -197
  153. package/lib/i18n/en-US/index.js +0 -16
  154. package/lib/i18n/en-US/modules/index.d.ts +0 -2
  155. package/lib/i18n/en-US/modules/index.js +0 -6
  156. package/lib/i18n/en-US/pages/glossary.d.ts +0 -8
  157. package/lib/i18n/en-US/pages/glossary.js +0 -9
  158. package/lib/i18n/en-US/pages/index.d.ts +0 -13
  159. package/lib/i18n/en-US/pages/index.js +0 -8
  160. package/lib/i18n/en-US/pages/user_upload.d.ts +0 -4
  161. package/lib/i18n/en-US/pages/user_upload.js +0 -5
  162. package/lib/i18n/en-US/shared/content_blocks.d.ts +0 -20
  163. package/lib/i18n/en-US/shared/content_blocks.js +0 -21
  164. package/lib/i18n/en-US/shared/index.d.ts +0 -39
  165. package/lib/i18n/en-US/shared/index.js +0 -10
  166. package/lib/i18n/en-US/shared/menu.d.ts +0 -4
  167. package/lib/i18n/en-US/shared/menu.js +0 -5
  168. package/lib/i18n/en-US/shared/settings.d.ts +0 -15
  169. package/lib/i18n/en-US/shared/settings.js +0 -16
  170. package/lib/i18n/en-US.d.ts +0 -197
  171. package/lib/i18n/en-US.js +0 -15
  172. package/lib/models/UserFileAsset.d.ts +0 -5
  173. package/lib/models/UserFileAsset.js +0 -37
package/babel.config.js CHANGED
@@ -1 +1 @@
1
- module.exports = {presets: ['@babel/preset-env']}
1
+ module.exports = { presets: ['@babel/preset-env'] }
@@ -38,6 +38,27 @@
38
38
  "
39
39
  ></TextEditor>
40
40
  </v-container>
41
+ <v-container>
42
+ <v-img
43
+ v-if="block.metadata.config.items[itemIndex].file"
44
+ :aria-describedby="
45
+ block.metadata.config.items[itemIndex]
46
+ .ariaDescribedBy
47
+ "
48
+ :alt="
49
+ getImageAlt(
50
+ block.metadata.config.items[itemIndex].file,
51
+ block.metadata.config.items[itemIndex]
52
+ .altText
53
+ )
54
+ "
55
+ :src="
56
+ getImagePublicUrl(
57
+ block.metadata.config.items[itemIndex].file
58
+ )
59
+ "
60
+ ></v-img>
61
+ </v-container>
41
62
  </v-expansion-panel-content>
42
63
  </v-expansion-panel>
43
64
  </v-expansion-panels>
@@ -73,6 +94,9 @@ export default {
73
94
  header: '',
74
95
  expand: false,
75
96
  content: '',
97
+ file: null,
98
+ altText: '',
99
+ ariaDescribedBy: '',
76
100
  }
77
101
  this.block.metadata.config.items = []
78
102
  this.block.metadata.config.items.push(defaultObject)
@@ -129,6 +153,19 @@ export default {
129
153
  },
130
154
  },
131
155
  methods: {
156
+ getImagePublicUrl(asset) {
157
+ const foundAsset = this.resolveAsset(asset)
158
+
159
+ return _.get(foundAsset, 'asset.public_url', null)
160
+ },
161
+ getImageAlt(asset, defaultText = '') {
162
+ // If a default / override was defined
163
+ if (defaultText) {
164
+ return defaultText
165
+ }
166
+ const foundAsset = this.resolveAsset(asset)
167
+ return _.get(foundAsset, 'asset.metadata.props.alt', null)
168
+ },
132
169
  async onBeforeSave() {
133
170
  this.block.metadata.config.items.forEach((element) => {
134
171
  element.expand = false
@@ -20,23 +20,34 @@
20
20
  no-gutters
21
21
  :class="rowClass(itemIndex)"
22
22
  >
23
- <v-col cols="12" xl="2" lg="3" md="3" sm="3">
24
- <v-btn
25
- class="button-icon pa-1 mb-4"
26
- :color="itemColor(itemIndex)"
27
- :fab="block.metadata.config.display.round_icon"
28
- outlined
23
+ <v-col cols="12" v-bind="iconColumnAttrs" class="pa-4">
24
+ <button
25
+ :class="activatorButtonClass(itemIndex)"
29
26
  @click="item.active = !item.active"
30
27
  >
31
- <v-icon v-if="isIcon(item.icon)" class="black--text">{{
32
- item.icon
33
- }}</v-icon>
28
+ <v-avatar
29
+ v-if="item.iconImage && item.icon"
30
+ class="clickable--image"
31
+ :rounded="
32
+ block.metadata.config.display.round_icon
33
+ ? '100%'
34
+ : '0'
35
+ "
36
+ size="100%"
37
+ >
38
+ <v-img :src="getImagePublicUrl(item.iconAsset)" />
39
+ </v-avatar>
40
+ <v-icon
41
+ v-else-if="isIcon(item.icon)"
42
+ class="clickable--icon black--text"
43
+ >{{ item.icon }}</v-icon
44
+ >
34
45
  <span v-else :class="iconClass + ' black--text'">{{
35
46
  decode(item.icon)
36
47
  }}</span>
37
- </v-btn>
48
+ </button>
38
49
  </v-col>
39
- <v-col cols="12" xl="10" lg="9" md="9" sm="9">
50
+ <v-col cols="12" v-bind="bodyColumnAttrs">
40
51
  <h4
41
52
  v-if="
42
53
  block.metadata.config.display.show_title ||
@@ -62,6 +73,7 @@
62
73
  <script>
63
74
  import _ from 'lodash'
64
75
  import he from 'he'
76
+ import Uuid from '~/helpers/Uuid'
65
77
  import BaseContentBlock from '~/components/Content/Blocks/BaseContentBlock'
66
78
  import TextViewer from '~/components/Text/TextViewer'
67
79
 
@@ -111,7 +123,7 @@ export default {
111
123
  },
112
124
  rowClass() {
113
125
  return (itemIndex) => {
114
- let classes = 'option-container mb-4 pa-1'
126
+ let classes = 'option-container pa-1'
115
127
  // If show background is enabled and the item has a color
116
128
  // Otherwise we do NOT want to apply the `black--text` class since there's no color
117
129
  // And things will look bad in dark mode
@@ -128,8 +140,42 @@ export default {
128
140
  return classes
129
141
  }
130
142
  },
143
+ iconColumnAttrs() {
144
+ if (this.block.metadata.config.display.large_icon) {
145
+ return {
146
+ xl: '3',
147
+ lg: '4',
148
+ md: '4',
149
+ sm: '4',
150
+ }
151
+ } else {
152
+ return {
153
+ xl: '2',
154
+ lg: '3',
155
+ md: '3',
156
+ sm: '3',
157
+ }
158
+ }
159
+ },
160
+ bodyColumnAttrs() {
161
+ if (this.block.metadata.config.display.large_icon) {
162
+ return {
163
+ xl: '9',
164
+ lg: '8',
165
+ md: '8',
166
+ sm: '8',
167
+ }
168
+ } else {
169
+ return {
170
+ xl: '10',
171
+ lg: '9',
172
+ md: '9',
173
+ sm: '9',
174
+ }
175
+ }
176
+ },
131
177
  iconClass() {
132
- let classes = 'text-icon'
178
+ let classes = 'clickable--text'
133
179
  if (
134
180
  _.get(this.block, 'metadata.config.display.italic_icon', false)
135
181
  ) {
@@ -137,6 +183,22 @@ export default {
137
183
  }
138
184
  return classes
139
185
  },
186
+ activatorButtonClass() {
187
+ return (itemIndex) => {
188
+ let classes =
189
+ 'button-icon button-icon--outline pa-1 ' +
190
+ this.itemColor(itemIndex)
191
+ if (this.block.metadata.config.display.large_icon) {
192
+ classes += ' button-icon--large'
193
+ } else {
194
+ classes += ' button-icon--normal'
195
+ }
196
+ if (this.block.metadata.config.display.round_icon) {
197
+ classes += ' button-icon--rounded'
198
+ }
199
+ return classes
200
+ }
201
+ },
140
202
  itemColor() {
141
203
  return (itemIndex) => {
142
204
  // If autocolor is enabled then calculate the color on the index
@@ -179,20 +241,45 @@ export default {
179
241
  isIcon(str) {
180
242
  return str && _.isString(str) && str.indexOf('mdi-') === 0
181
243
  },
244
+ getImagePublicUrl(asset) {
245
+ const foundAsset = this.resolveAsset(asset)
246
+
247
+ return _.get(foundAsset, 'asset.public_url', null)
248
+ },
182
249
  },
183
250
  }
184
251
  </script>
185
- <style scoped>
252
+ <style lang="scss" scoped>
186
253
  .option-container {
187
254
  border-radius: 1rem;
188
255
  }
189
- .button-icon {
256
+ button.button-icon {
257
+ border-width: 4px;
258
+ width: 100% !important;
259
+ height: auto !important;
260
+ aspect-ratio: 1 / 1;
261
+ }
262
+
263
+ button.button-icon.button-icon--outline {
264
+ background-color: #fff !important;
190
265
  border-width: 4px;
191
- background: #fff;
192
- height: 74px !important;
193
- width: 74px;
266
+ border-style: solid;
267
+ }
268
+
269
+ button.button-icon.button-icon--rounded {
270
+ border-radius: 100%;
271
+ }
272
+
273
+ .button-icon--normal {
274
+ .clickable--icon,
275
+ .clickable--text {
276
+ font-size: 1.5rem;
277
+ }
194
278
  }
195
- .text-icon {
196
- font-size: 1.5rem;
279
+ .button-icon--large {
280
+ .clickable--icon,
281
+ .clickable--text {
282
+ font-size: 2.5rem;
283
+ }
197
284
  }
198
285
  </style>
@@ -294,6 +294,15 @@ export default {
294
294
  onRemoveTags(body) {
295
295
  return body.replace(/(<([^>]+)>)/gi, '')
296
296
  },
297
+ async onBeforeSave() {
298
+ this.block.metadata.config.emails.forEach((element) => {
299
+ if (element.from) {
300
+ let matches = element.from.match(/\b(\w)/g)
301
+ element.initials = matches.join('')
302
+ }
303
+ element.tinymce_expand = false
304
+ })
305
+ },
297
306
  },
298
307
  }
299
308
  </script>
@@ -1,7 +1,7 @@
1
1
  <template>
2
2
  <div>
3
3
  <v-container class="pa-0 ma-0">
4
- <div v-if="!block.body" class="img-holder">
4
+ <div v-if="!imageUrl" class="img-holder">
5
5
  <v-skeleton-loader
6
6
  height="300px"
7
7
  :elevation="2"
@@ -19,11 +19,11 @@
19
19
  </div>
20
20
  <v-responsive :aspect-ratio="aspectRatio">
21
21
  <v-img
22
- v-if="block.body"
23
- :alt="block.metadata.config.alt"
24
- :aria-describedby="block.metadata.config.aria_described_by"
22
+ v-if="imageUrl"
23
+ :alt="altText"
24
+ :aria-describedby="describedByText"
25
25
  :class="imageClass"
26
- :src="block.body"
26
+ :src="imageUrl"
27
27
  contain
28
28
  @click="onHandleModal"
29
29
  >
@@ -52,13 +52,11 @@
52
52
  v-on="on"
53
53
  >
54
54
  <v-img
55
- v-if="block.body"
56
- :alt="block.metadata.config.alt"
57
- :aria-describedby="
58
- block.metadata.config.aria_described_by
59
- "
55
+ v-if="imageUrl"
56
+ :alt="altText"
57
+ :aria-describedby="describedByText"
60
58
  :class="imageClass"
61
- :src="block.body"
59
+ :src="imageUrl"
62
60
  contain
63
61
  @click="onHandleModal"
64
62
  >
@@ -78,7 +76,7 @@
78
76
 
79
77
  <script>
80
78
  import _ from 'lodash'
81
- import DialogBox from '~/components/DialogBox.vue'
79
+ import DialogBox from '~/components/Core/DialogBox.vue'
82
80
  import TextViewer from '~/components/Text/TextViewer'
83
81
  import Crypto from '~/helpers/Crypto'
84
82
  import BaseContentBlock from '~/components/Content/Blocks/BaseContentBlock'
@@ -104,27 +102,57 @@ export default {
104
102
  if (_.isEmpty(this.block.metadata.config.alt)) {
105
103
  this.block.metadata.config.alt = ''
106
104
  }
107
- if (!_.isBoolean(this.block.metadata.config.hide_background)) {
108
- this.block.metadata.config.hide_background = false
105
+ if (!_.isBoolean(this.block.metadata.config.hideBackground)) {
106
+ this.block.metadata.config.hideBackground = false
109
107
  }
110
108
  if (!_.isBoolean(this.block.metadata.config.modal)) {
111
109
  this.block.metadata.config.modal = false
112
110
  }
113
- if (_.isEmpty(this.block.metadata.config.aria_describedby)) {
114
- this.block.metadata.config.aria_describedby = ''
111
+ if (_.isEmpty(this.block.metadata.config.ariaDescribedBy)) {
112
+ this.block.metadata.config.ariaDescribedBy = ''
115
113
  }
116
114
  },
117
115
  computed: {
118
116
  describedById() {
119
117
  // If there's a described by
120
- if (_.get(this.block.metadata, 'config.aria_describedby', null)) {
118
+ if (this.describedByText) {
121
119
  return this.id
122
120
  } else {
123
121
  return null
124
122
  }
125
123
  },
124
+ altText() {
125
+ // Get the asset info first and fallback to the block metadata if inherit is set to false
126
+ if (_.get(this.block.metadata, 'config.inherit', true)) {
127
+ return _.get(this.fileAsset, 'metadata.props.alt', null)
128
+ } else {
129
+ return _.get(this.block.metadata, 'config.alt', null)
130
+ }
131
+ },
126
132
  describedByText() {
127
- return _.get(this.block.metadata, 'config.aria_describedby', null)
133
+ // Get the asset info first and fallback to the block metadata if inherit is set to false
134
+ if (_.get(this.block.metadata, 'config.inherit', true)) {
135
+ return _.get(
136
+ this.fileAsset,
137
+ 'metadata.props.aria_describedby',
138
+ null
139
+ )
140
+ } else {
141
+ return _.get(
142
+ this.block.metadata,
143
+ 'config.ariaDescribedBy',
144
+ null
145
+ )
146
+ }
147
+ },
148
+ fileAsset() {
149
+ return this.resolveAsset(
150
+ _.get(this.block, 'metadata.config.asset', null)
151
+ )
152
+ },
153
+ imageUrl() {
154
+ // Get the image public url and fallback to the block body
155
+ return _.get(this.fileAsset, 'asset.public_url', this.block.body)
128
156
  },
129
157
  imageClass() {
130
158
  let imageClass = ''
@@ -133,7 +161,7 @@ export default {
133
161
  imageClass += ' container-pointer'
134
162
  }
135
163
  // If NOT hide background, inclide the extra class
136
- if (!_.get(this.block.metadata, 'config.hide_background', false)) {
164
+ if (!_.get(this.block.metadata, 'config.hideBackground', false)) {
137
165
  imageClass += ' img-white'
138
166
  }
139
167
  return 'img-display' + imageClass
@@ -164,7 +192,7 @@ export default {
164
192
  }
165
193
  </script>
166
194
 
167
- <style scoped>
195
+ <style lang="scss" scoped>
168
196
  .img-display {
169
197
  border-radius: 3px;
170
198
  }
@@ -29,7 +29,7 @@
29
29
 
30
30
  <script>
31
31
  import _ from 'lodash'
32
- import DialogBox from '~/components/DialogBox'
32
+ import DialogBox from '~/components/Core/DialogBox'
33
33
 
34
34
  import DisplayUserFilesTable from './DisplayUserFilesTable.vue'
35
35
 
@@ -101,7 +101,7 @@ import UserFileAsset from '../../../models/UserFileAsset'
101
101
  import Enrollment from '~/models/Enrollment'
102
102
  import ContentBlock from '~/models/ContentBlock'
103
103
  import BaseContentBlock from '~/components/Content/Blocks/BaseContentBlock'
104
- import FileDropZone from '~/components/FileDropZone.vue'
104
+ import FileDropZone from '~/components/Core/FileDropZone.vue'
105
105
 
106
106
  import DisplayUserFilesTable from './UserUpload/DisplayUserFilesTable.vue'
107
107
 
@@ -28,7 +28,7 @@
28
28
  v-if="hasSource"
29
29
  :language="$i18n && $i18n.locale ? $i18n.locale : 'en-US'"
30
30
  :type="block.metadata.config.type"
31
- :playlist="block.metadata.config.playlist"
31
+ :playlist="linkedPlaylist"
32
32
  :autoplay="block.metadata.config.attributes.autoplay"
33
33
  :autopictureinpicture="
34
34
  block.metadata.config.attributes.autopictureinpicture
@@ -48,7 +48,7 @@
48
48
  :loop="block.metadata.config.attributes.loop"
49
49
  :muted="block.metadata.config.attributes.muted"
50
50
  :playsinline="block.metadata.config.attributes.playsinline"
51
- :poster="block.metadata.config.attributes.poster"
51
+ :poster="linkedPosterPublicUrl"
52
52
  :preload="block.metadata.config.attributes.preload"
53
53
  :captionsmenu="block.metadata.config.attributes.captionsmenu"
54
54
  :playlistmenu="block.metadata.config.attributes.playlistmenu"
@@ -63,14 +63,12 @@
63
63
  <script>
64
64
  import _ from 'lodash'
65
65
  import VuetifyPlayer from '@mindedge/vuetify-player'
66
- import ContentBlockAsset from '~/components/Content/ContentBlockAsset.vue'
67
66
  import BaseContentBlock from '~/components/Content/Blocks/BaseContentBlock'
68
67
 
69
68
  export default {
70
69
  name: 'ContentBlockVideo',
71
70
  components: {
72
71
  VuetifyPlayer,
73
- ContentBlockAsset,
74
72
  },
75
73
  extends: BaseContentBlock,
76
74
  computed: {
@@ -89,6 +87,73 @@ export default {
89
87
  )
90
88
  )
91
89
  },
90
+ linkedPosterPublicUrl() {
91
+ const file = this.resolveAsset(
92
+ _.get(this.block, 'metadata.config.attributes.poster', null)
93
+ )
94
+ return _.get(file, 'asset.public_url')
95
+ },
96
+ /**
97
+ * Resolve assets to their playlist items
98
+ */
99
+ linkedPlaylist() {
100
+ const playlist = _.cloneDeep(this.block.metadata.config.playlist)
101
+
102
+ for (const index in playlist) {
103
+ for (const sourceIndex in playlist[index].sources) {
104
+ let file = this.resolveAsset(
105
+ playlist[index].sources[sourceIndex]
106
+ )
107
+
108
+ playlist[index].sources[sourceIndex] = {
109
+ src: _.get(file, 'asset.public_url', ''),
110
+ type: _.get(file, 'asset.metadata.mime', ''),
111
+ }
112
+ }
113
+
114
+ for (const trackIndex in playlist[index].tracks) {
115
+ let file = this.resolveAsset(
116
+ playlist[index].tracks[trackIndex]
117
+ )
118
+
119
+ playlist[index].tracks[trackIndex] = {
120
+ src: _.get(file, 'asset.public_url', ''),
121
+ kind: 'captions',
122
+ srclang: 'en-US',
123
+ default: true,
124
+ }
125
+ }
126
+
127
+ for (const adIndex in playlist[index].ads) {
128
+ for (const adSourceIndex in playlist[index].ads[adIndex]
129
+ .sources) {
130
+ let file = this.resolveAsset(
131
+ playlist[index].ads[adIndex].sources[adSourceIndex]
132
+ )
133
+
134
+ playlist[index].ads[adIndex].sources[adSourceIndex] = {
135
+ src: _.get(file, 'asset.public_url', ''),
136
+ type: _.get(file, 'asset.metadata.mime', ''),
137
+ }
138
+ }
139
+ for (const adTrackIndex in playlist[index].ads[adIndex]
140
+ .tracks) {
141
+ let file = this.resolveAsset(
142
+ playlist[index].ads[adIndex].tracks[adTrackIndex]
143
+ )
144
+
145
+ playlist[index].ads[adIndex].tracks[adTrackIndex] = {
146
+ src: _.get(file, 'asset.public_url', ''),
147
+ kind: 'captions',
148
+ srclang: 'en-US',
149
+ default: true,
150
+ }
151
+ }
152
+ }
153
+ }
154
+
155
+ return playlist
156
+ },
92
157
  },
93
158
  data() {
94
159
  return {
@@ -170,13 +235,19 @@ export default {
170
235
  if (_.isEmpty(this.block.metadata.config)) {
171
236
  this.block.metadata.config = this.defaultConfig
172
237
  }
238
+ // If no playback rates were set then re-init it as an array with the rate 1 or normal only
239
+ if (
240
+ _.isEmpty(
241
+ _.get(this.block, 'metadata.config.attributes.playbackrates')
242
+ )
243
+ ) {
244
+ this.block.metadata.config.attributes.playbackrates = [1]
245
+ }
246
+ if (_.isEmpty(this.block.assets)) {
247
+ this.$set(this.block, 'assets', [])
248
+ }
173
249
  },
174
250
  mounted() {
175
- // TODO Check privs
176
- //const hasPrivs = true
177
- //if (hasPrivs) {
178
- //this.blockSettings = this.initEditorSettings(this.settings)
179
- //}
180
251
  this.saveKey = this.settingsKey()
181
252
  },
182
253
  methods: {
@@ -111,12 +111,13 @@
111
111
 
112
112
  <script>
113
113
  import { mapGetters } from 'vuex'
114
+ import DialogBox from '~/components/Core/DialogBox.vue'
114
115
  import AuthUserRepository from '~/models/repositories/AuthUserRepository'
115
116
  import AskTheExpert from '~/models/AskTheExpert'
116
117
 
117
118
  export default {
118
119
  name: 'NavigationItemAskTheExpert',
119
- components: {},
120
+ components: { DialogBox },
120
121
  props: {
121
122
  config: { type: Object, required: true },
122
123
  },
@@ -18,10 +18,11 @@
18
18
  </template>
19
19
 
20
20
  <script>
21
+ import DialogBox from '~/components/Core/DialogBox.vue'
21
22
  import CourseGlossary from '../../utils/glossary/CourseGlossary.vue'
22
23
  export default {
23
24
  name: 'NavigationItemCourseGlossary',
24
- components: { CourseGlossary },
25
+ components: { DialogBox, CourseGlossary },
25
26
  props: {
26
27
  config: { type: Object, required: true },
27
28
  },