@windward/core 0.6.0 → 0.7.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 (158) hide show
  1. package/CHANGELOG.md +8 -1
  2. package/components/Content/Blocks/Accordion.vue +14 -0
  3. package/components/Content/Blocks/ClickableIcons.vue +9 -2
  4. package/components/Content/Blocks/Email.vue +11 -2
  5. package/components/Content/Blocks/GenerateAIQuestionButton.vue +14 -6
  6. package/components/Content/Blocks/HorizontalRule.vue +1 -4
  7. package/components/Content/Blocks/ScenarioChoice.vue +57 -32
  8. package/components/Content/Blocks/Tab.vue +5 -0
  9. package/components/Content/Blocks/UserUpload.vue +1 -8
  10. package/components/Content/Blocks/Video.vue +96 -8
  11. package/components/Settings/AccordionSettings.vue +61 -8
  12. package/components/Settings/BlockQuoteSettings.vue +20 -12
  13. package/components/Settings/ClickableIconsSettings.vue +48 -12
  14. package/components/Settings/EmailSettings.vue +20 -12
  15. package/components/Settings/FileDownloadSettings.vue +22 -16
  16. package/components/Settings/HorizontalRuleSettings.vue +0 -3
  17. package/components/Settings/ScenarioChoiceSettings.vue +29 -14
  18. package/components/Settings/TabSettings.vue +121 -78
  19. package/components/Settings/UserUploadSettings.vue +30 -32
  20. package/components/Settings/VideoSettings/SourcePicker.vue +222 -0
  21. package/components/Settings/VideoSettings.vue +139 -183
  22. package/components/utils/TinyMCEWrapper.vue +3 -2
  23. package/components/utils/assets/tinymce/content/global.scss +14 -0
  24. package/components/utils/glossary/CourseGlossary.vue +52 -27
  25. package/helpers/tinymce/WindwardPlugins.ts +59 -10
  26. package/i18n/en-US/components/content/blocks/generate_questions.ts +2 -1
  27. package/i18n/en-US/components/content/blocks/video.ts +2 -51
  28. package/i18n/en-US/components/settings/accordion.ts +1 -0
  29. package/i18n/en-US/components/settings/tab.ts +1 -0
  30. package/i18n/en-US/components/settings/user_upload.ts +1 -0
  31. package/i18n/en-US/components/settings/video.ts +51 -0
  32. package/i18n/en-US/components/utils/tiny_mce_wrapper.ts +9 -1
  33. package/i18n/es-ES/components/content/blocks/generate_questions.ts +2 -1
  34. package/i18n/es-ES/components/content/blocks/video.ts +3 -53
  35. package/i18n/es-ES/components/settings/accordion.ts +1 -0
  36. package/i18n/es-ES/components/settings/tab.ts +2 -0
  37. package/i18n/es-ES/components/settings/user_upload.ts +1 -0
  38. package/i18n/es-ES/components/settings/video.ts +53 -0
  39. package/i18n/es-ES/components/utils/tiny_mce_wrapper.ts +9 -0
  40. package/i18n/sv-SE/components/content/blocks/generate_questions.ts +2 -1
  41. package/i18n/sv-SE/components/content/blocks/video.ts +2 -51
  42. package/i18n/sv-SE/components/settings/accordion.ts +2 -0
  43. package/i18n/sv-SE/components/settings/tab.ts +1 -0
  44. package/i18n/sv-SE/components/settings/user_upload.ts +1 -0
  45. package/i18n/sv-SE/components/settings/video.ts +51 -0
  46. package/i18n/sv-SE/components/utils/tiny_mce_wrapper.ts +8 -0
  47. package/package.json +2 -1
  48. package/plugin.js +1 -1
  49. package/.idea/codeStyles/Project.xml +0 -58
  50. package/.idea/codeStyles/codeStyleConfig.xml +0 -5
  51. package/.idea/inspectionProfiles/Project_Default.xml +0 -6
  52. package/.idea/modules.xml +0 -8
  53. package/.idea/php-docker-settings.xml +0 -24
  54. package/.idea/php.xml +0 -19
  55. package/.idea/vcs.xml +0 -6
  56. package/.idea/watcherTasks.xml +0 -4
  57. package/.idea/windward-ui-plugin-core.iml +0 -8
  58. package/config/menu.config.json +0 -475
  59. package/coverage/clover.xml +0 -223
  60. package/coverage/coverage-final.json +0 -16
  61. package/coverage/lcov-report/base.css +0 -224
  62. package/coverage/lcov-report/block-navigation.js +0 -87
  63. package/coverage/lcov-report/components/Content/Blocks/Accordion.vue.html +0 -430
  64. package/coverage/lcov-report/components/Content/Blocks/Image.vue.html +0 -394
  65. package/coverage/lcov-report/components/Content/Blocks/Math.vue.html +0 -262
  66. package/coverage/lcov-report/components/Content/Blocks/RichText.vue.html +0 -295
  67. package/coverage/lcov-report/components/Content/Blocks/Tab.vue.html +0 -415
  68. package/coverage/lcov-report/components/Content/Blocks/Table.vue.html +0 -667
  69. package/coverage/lcov-report/components/Content/Blocks/Video.vue.html +0 -2275
  70. package/coverage/lcov-report/components/Content/Blocks/index.html +0 -206
  71. package/coverage/lcov-report/components/utils/ContentViewer.vue.html +0 -199
  72. package/coverage/lcov-report/components/utils/MathExpressionEditor.vue.html +0 -919
  73. package/coverage/lcov-report/components/utils/MathLiveWrapper.vue.html +0 -343
  74. package/coverage/lcov-report/components/utils/TinyMCEWrapper.vue.html +0 -271
  75. package/coverage/lcov-report/components/utils/index.html +0 -161
  76. package/coverage/lcov-report/config/index.html +0 -116
  77. package/coverage/lcov-report/config/tinymce.config.js.html +0 -493
  78. package/coverage/lcov-report/favicon.png +0 -0
  79. package/coverage/lcov-report/helpers/MathHelper.ts.html +0 -793
  80. package/coverage/lcov-report/helpers/index.html +0 -116
  81. package/coverage/lcov-report/helpers/tinymce/index.html +0 -116
  82. package/coverage/lcov-report/helpers/tinymce/plugin.ts.html +0 -334
  83. package/coverage/lcov-report/index.html +0 -191
  84. package/coverage/lcov-report/prettify.css +0 -1
  85. package/coverage/lcov-report/prettify.js +0 -2
  86. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  87. package/coverage/lcov-report/sorter.js +0 -196
  88. package/coverage/lcov-report/test/index.html +0 -116
  89. package/coverage/lcov-report/test/mocks.js.html +0 -457
  90. package/coverage/lcov.info +0 -403
  91. package/lib/helpers/GlossaryHelper.d.ts +0 -9
  92. package/lib/helpers/GlossaryHelper.js +0 -118
  93. package/lib/helpers/GlossaryTerm.d.ts +0 -10
  94. package/lib/helpers/GlossaryTerm.js +0 -22
  95. package/lib/helpers/MathHelper.d.ts +0 -99
  96. package/lib/helpers/MathHelper.js +0 -194
  97. package/lib/helpers/tinymce/plugin.d.ts +0 -2
  98. package/lib/helpers/tinymce/plugin.js +0 -86
  99. package/lib/i18n/en-US/components/content/blocks/image.d.ts +0 -6
  100. package/lib/i18n/en-US/components/content/blocks/image.js +0 -7
  101. package/lib/i18n/en-US/components/content/blocks/index.d.ts +0 -75
  102. package/lib/i18n/en-US/components/content/blocks/index.js +0 -14
  103. package/lib/i18n/en-US/components/content/blocks/tab.d.ts +0 -5
  104. package/lib/i18n/en-US/components/content/blocks/tab.js +0 -6
  105. package/lib/i18n/en-US/components/content/blocks/table.d.ts +0 -5
  106. package/lib/i18n/en-US/components/content/blocks/table.js +0 -6
  107. package/lib/i18n/en-US/components/content/blocks/user_upload.d.ts +0 -13
  108. package/lib/i18n/en-US/components/content/blocks/user_upload.js +0 -14
  109. package/lib/i18n/en-US/components/content/blocks/video.d.ts +0 -48
  110. package/lib/i18n/en-US/components/content/blocks/video.js +0 -49
  111. package/lib/i18n/en-US/components/content/index.d.ts +0 -77
  112. package/lib/i18n/en-US/components/content/index.js +0 -6
  113. package/lib/i18n/en-US/components/index.d.ts +0 -140
  114. package/lib/i18n/en-US/components/index.js +0 -12
  115. package/lib/i18n/en-US/components/navigation/image.d.ts +0 -5
  116. package/lib/i18n/en-US/components/navigation/image.js +0 -6
  117. package/lib/i18n/en-US/components/navigation/index.d.ts +0 -10
  118. package/lib/i18n/en-US/components/navigation/index.js +0 -8
  119. package/lib/i18n/en-US/components/navigation/user_upload.d.ts +0 -4
  120. package/lib/i18n/en-US/components/navigation/user_upload.js +0 -5
  121. package/lib/i18n/en-US/components/settings/clickable_icon.d.ts +0 -6
  122. package/lib/i18n/en-US/components/settings/clickable_icon.js +0 -7
  123. package/lib/i18n/en-US/components/settings/image.d.ts +0 -2
  124. package/lib/i18n/en-US/components/settings/image.js +0 -3
  125. package/lib/i18n/en-US/components/settings/index.d.ts +0 -39
  126. package/lib/i18n/en-US/components/settings/index.js +0 -14
  127. package/lib/i18n/en-US/components/settings/text_editor.d.ts +0 -8
  128. package/lib/i18n/en-US/components/settings/text_editor.js +0 -9
  129. package/lib/i18n/en-US/components/settings/user_upload.d.ts +0 -12
  130. package/lib/i18n/en-US/components/settings/user_upload.js +0 -13
  131. package/lib/i18n/en-US/components/settings/video.d.ts +0 -13
  132. package/lib/i18n/en-US/components/settings/video.js +0 -14
  133. package/lib/i18n/en-US/components/utils/index.d.ts +0 -15
  134. package/lib/i18n/en-US/components/utils/index.js +0 -6
  135. package/lib/i18n/en-US/components/utils/tiny_mce_wrapper.d.ts +0 -13
  136. package/lib/i18n/en-US/components/utils/tiny_mce_wrapper.js +0 -14
  137. package/lib/i18n/en-US/index.d.ts +0 -197
  138. package/lib/i18n/en-US/index.js +0 -16
  139. package/lib/i18n/en-US/modules/index.d.ts +0 -2
  140. package/lib/i18n/en-US/modules/index.js +0 -6
  141. package/lib/i18n/en-US/pages/glossary.d.ts +0 -8
  142. package/lib/i18n/en-US/pages/glossary.js +0 -9
  143. package/lib/i18n/en-US/pages/index.d.ts +0 -13
  144. package/lib/i18n/en-US/pages/index.js +0 -8
  145. package/lib/i18n/en-US/pages/user_upload.d.ts +0 -4
  146. package/lib/i18n/en-US/pages/user_upload.js +0 -5
  147. package/lib/i18n/en-US/shared/content_blocks.d.ts +0 -20
  148. package/lib/i18n/en-US/shared/content_blocks.js +0 -21
  149. package/lib/i18n/en-US/shared/index.d.ts +0 -39
  150. package/lib/i18n/en-US/shared/index.js +0 -10
  151. package/lib/i18n/en-US/shared/menu.d.ts +0 -4
  152. package/lib/i18n/en-US/shared/menu.js +0 -5
  153. package/lib/i18n/en-US/shared/settings.d.ts +0 -15
  154. package/lib/i18n/en-US/shared/settings.js +0 -16
  155. package/lib/i18n/en-US.d.ts +0 -197
  156. package/lib/i18n/en-US.js +0 -15
  157. package/lib/models/UserFileAsset.d.ts +0 -5
  158. package/lib/models/UserFileAsset.js +0 -37
package/CHANGELOG.md CHANGED
@@ -1,4 +1,11 @@
1
1
  # Changelog
2
2
 
3
- ### Release [0.6.0] created - 2024-07-30
3
+ ## Release [0.7.0] - 2024-08-29
4
+
5
+ * Version bump to 0.7.0
6
+
4
7
 
8
+ ### Release [0.7.0] created - 2024-08-29
9
+
10
+
11
+ ### Release [0.6.0] created - 2024-07-30
@@ -1,5 +1,16 @@
1
1
  <template>
2
2
  <div>
3
+ <v-container
4
+ class="pa-0"
5
+ v-if="
6
+ block.metadata.config.title ||
7
+ block.metadata.config.instructions
8
+ "
9
+ >
10
+ <h2>{{ block.metadata.config.title }}</h2>
11
+
12
+ <p>{{ block.metadata.config.instructions }}</p>
13
+ </v-container>
3
14
  <v-expansion-panels
4
15
  :value="selectedPanels"
5
16
  flat
@@ -91,6 +102,9 @@ export default {
91
102
  if (_.isEmpty(this.block.metadata.config)) {
92
103
  this.block.metadata.config = {}
93
104
  }
105
+ if (_.isEmpty(this.block.metadata.config.title)) {
106
+ this.block.metadata.config.title = ''
107
+ }
94
108
  if (_.isEmpty(this.block.metadata.config.items)) {
95
109
  const defaultObject = {
96
110
  header: '',
@@ -50,7 +50,7 @@
50
50
  </button>
51
51
  </v-col>
52
52
  <v-col cols="12" v-bind="bodyColumnAttrs">
53
- <v-container class="ml-4">
53
+ <v-container :class="bodyClass">
54
54
  <h4
55
55
  v-if="
56
56
  block.metadata.config.display.show_title ||
@@ -155,7 +155,7 @@ export default {
155
155
  } else {
156
156
  return {
157
157
  xl: '2',
158
- lg: '2',
158
+ lg: '3',
159
159
  md: '3',
160
160
  sm: '3',
161
161
  }
@@ -240,6 +240,13 @@ export default {
240
240
  }
241
241
  }
242
242
  },
243
+ bodyClass() {
244
+ if (window.innerWidth <= 665) {
245
+ return ''
246
+ } else {
247
+ return 'ml-4'
248
+ }
249
+ },
243
250
  },
244
251
  methods: {
245
252
  isIcon(str) {
@@ -25,7 +25,7 @@
25
25
  class="pa-0 primary container-subject d-flex justify-center align-center"
26
26
  >
27
27
  <v-row class="d-flex ma-5">
28
- <v-col cols="6">
28
+ <v-col cols="12">
29
29
  {{
30
30
  $t(
31
31
  'windward.core.components.content.blocks.email.email'
@@ -33,6 +33,7 @@
33
33
  }}
34
34
  </v-col>
35
35
  <v-col
36
+ v-if="false"
36
37
  cols="6"
37
38
  class="d-flex justify-end column-simulation"
38
39
  >
@@ -170,7 +171,11 @@
170
171
  >
171
172
  <v-row class="pt-4">
172
173
  <v-col cols="10" class="pa-0">
173
- <v-btn elevation="0" color="primary" text>
174
+ <v-btn
175
+ elevation="0"
176
+ color="primary"
177
+ text
178
+ >
174
179
  <v-icon>mdi-reply</v-icon>
175
180
  {{
176
181
  $t(
@@ -197,6 +202,7 @@
197
202
  </v-col>
198
203
  <v-col cols="2" class="pa-0 d-flex justify-end">
199
204
  <v-btn
205
+ v-show="false"
200
206
  elevation="0"
201
207
  color="primary"
202
208
  outlined
@@ -350,4 +356,7 @@ export default {
350
356
  .v-expansion-panels {
351
357
  z-index: 0 !important;
352
358
  }
359
+ .v-btn:before {
360
+ background-color: transparent !important;
361
+ }
353
362
  </style>
@@ -1,13 +1,17 @@
1
1
  <template>
2
2
  <v-btn
3
3
  elevation="0"
4
- color="primary"
5
- icon
4
+ color="secondary"
6
5
  @click="generateAIQuestion"
7
6
  :loading="isLoading"
8
7
  :disabled="isLoading"
9
8
  >
10
- <v-icon v-if="!isLoading">mdi-magic-staff</v-icon>
9
+ <v-icon class="pr-1" v-if="!isLoading">mdi-magic-staff</v-icon>
10
+ {{
11
+ this.$t(
12
+ 'windward.core.components.content.blocks.generate_questions.button_label'
13
+ )
14
+ }}
11
15
  <template v-slot:loader>
12
16
  <v-progress-circular indeterminate size="23"></v-progress-circular>
13
17
  </template>
@@ -42,7 +46,7 @@ export default {
42
46
  new Content(this.content),
43
47
  new Assessment({ id: this.block.id }),
44
48
  new AssessmentQuestion(),
45
- `suggest/${this.questionType}`
49
+ `suggest/${this.questionType}`
46
50
  ).get()
47
51
 
48
52
  if (response && response.length > 0) {
@@ -51,11 +55,15 @@ export default {
51
55
  }
52
56
  } catch (error) {
53
57
  console.error(error)
54
- this.$dialog.error(this.$t('windward.core.components.content.blocks.generate_questions.error'))
58
+ this.$dialog.error(
59
+ this.$t(
60
+ 'windward.core.components.content.blocks.generate_questions.error'
61
+ )
62
+ )
55
63
  } finally {
56
64
  this.isLoading = false
57
65
  }
58
66
  },
59
67
  },
60
68
  }
61
- </script>
69
+ </script>
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
  <div>
3
- <hr :class="isDashed" />
3
+ <hr :class="isDashed" class="mt-2 mb-2" />
4
4
  </div>
5
5
  </template>
6
6
  <script>
@@ -19,9 +19,6 @@ export default {
19
19
  if (_.isEmpty(this.block.metadata.config)) {
20
20
  this.block.metadata.config = {}
21
21
  }
22
- if (_.isEmpty(this.block.metadata.config)) {
23
- this.block.metadata.config = {}
24
- }
25
22
  if (_.isEmpty(this.block.metadata.config.dashed)) {
26
23
  this.block.metadata.config.dashed = false
27
24
  }
@@ -3,18 +3,16 @@
3
3
  <v-container class="pa-0">
4
4
  <h2>{{ block.metadata.config.title }}</h2>
5
5
  <p>{{ block.metadata.config.description }}</p>
6
- <p>
7
- {{
8
- $t(
9
- 'windward.core.components.content.blocks.scenario_choice.information'
10
- )
11
- }}
12
- </p>
13
6
  <div
14
7
  v-if="choiceIndex !== null && block.metadata.config.show_reset"
15
8
  class="text-right"
16
9
  >
17
- <v-btn elevation="0" color="primary" outlined @click="onClickReset">
10
+ <v-btn
11
+ elevation="0"
12
+ color="primary"
13
+ outlined
14
+ @click="onClickReset"
15
+ >
18
16
  {{
19
17
  $t(
20
18
  'windward.core.components.content.blocks.scenario_choice.try_again'
@@ -30,7 +28,7 @@
30
28
  no-gutters
31
29
  :class="rowClass(item, itemIndex)"
32
30
  >
33
- <v-col cols="2" class="text-center">
31
+ <v-col cols="12" v-bind="iconColumnAttrs" class="text-center">
34
32
  <div
35
33
  class="pt-8 pb-8 text-icon-container mb-4 mx-auto"
36
34
  role="button"
@@ -48,30 +46,34 @@
48
46
  }}
49
47
  </strong>
50
48
  </v-col>
51
- <v-col cols="10">
52
- <h4
53
- role="button"
54
- class="mt-4"
55
- @click="onClickItem(itemIndex)"
56
- >
57
- {{ item.title }}
58
- </h4>
49
+ <v-col cols="12" v-bind="bodyColumnAttrs">
50
+ <v-container :class="bodyClass">
51
+ <h4
52
+ role="button"
53
+ class="mt-4"
54
+ @click="onClickItem(itemIndex)"
55
+ >
56
+ {{ item.title }}
57
+ </h4>
59
58
 
60
- <v-expand-transition>
61
- <div v-if="choiceIndex !== null">
62
- <v-divider light class="my-4" />
63
- <TextViewer v-model="item.body"></TextViewer>
64
- <a
65
- v-if="linkedPage !== null"
66
- class="white--text text-decoration-underline"
67
- @click="
68
- onClickLink(linkedPage.course_content_id)
69
- "
70
- >
71
- {{ linkedPage.text }}
72
- </a>
73
- </div>
74
- </v-expand-transition>
59
+ <v-expand-transition>
60
+ <div v-if="choiceIndex !== null">
61
+ <v-divider light class="my-4" />
62
+ <TextViewer v-model="item.body"></TextViewer>
63
+ <a
64
+ v-if="linkedPage !== null"
65
+ class="white--text text-decoration-underline"
66
+ @click="
67
+ onClickLink(
68
+ linkedPage.course_content_id
69
+ )
70
+ "
71
+ >
72
+ {{ linkedPage.text }}
73
+ </a>
74
+ </div>
75
+ </v-expand-transition>
76
+ </v-container>
75
77
  </v-col>
76
78
  </v-row>
77
79
  </v-container>
@@ -199,6 +201,29 @@ export default {
199
201
  return null
200
202
  }
201
203
  },
204
+ iconColumnAttrs() {
205
+ return {
206
+ xl: '2',
207
+ lg: '3',
208
+ md: '3',
209
+ sm: '3',
210
+ }
211
+ },
212
+ bodyColumnAttrs() {
213
+ return {
214
+ xl: '10',
215
+ lg: '9',
216
+ md: '9',
217
+ sm: '9',
218
+ }
219
+ },
220
+ bodyClass() {
221
+ if (window.innerWidth <= 665) {
222
+ return ''
223
+ } else {
224
+ return 'ml-4'
225
+ }
226
+ },
202
227
  },
203
228
  beforeMount() {
204
229
  // Apply the default config
@@ -1,5 +1,10 @@
1
1
  <template>
2
2
  <div>
3
+ <v-container class="pa-0">
4
+ <h2>{{ block.metadata.config.title }}</h2>
5
+
6
+ <p>{{ block.metadata.config.instructions }}</p>
7
+ </v-container>
3
8
  <v-container class="pa-0">
4
9
  <v-tabs dark v-model="block.metadata.config.currentTab" show-arrows>
5
10
  <v-tabs-slider></v-tabs-slider>
@@ -6,14 +6,7 @@
6
6
  </h2>
7
7
  <v-row>
8
8
  <v-col cols="12">
9
- <TextViewer
10
- v-if="render || !block.__expandInstructions"
11
- v-model="block.metadata.config.instructions"
12
- ></TextViewer>
13
- <TextEditor
14
- v-if="!render && block.__expandInstructions"
15
- v-model="block.metadata.config.instructions"
16
- />
9
+ <p>{{ block.metadata.config.instructions }}</p>
17
10
  </v-col>
18
11
  <v-col v-if="!blockExists" cols="12">
19
12
  <v-alert color="warning">
@@ -5,14 +5,12 @@
5
5
  <v-icon class="mr-2">mdi-cloud-question</v-icon>
6
6
  {{
7
7
  $t(
8
- 'windward.core.components.content.blocks.video.video.not_configured_title'
8
+ 'windward.core.components.content.blocks.video.not_configured_title'
9
9
  )
10
10
  }}
11
11
  </v-card-title>
12
12
  <v-card-text>{{
13
- $t(
14
- 'windward.core.components.content.blocks.video.video.edit_prompt'
15
- )
13
+ $t('windward.core.components.content.blocks.video.edit_prompt')
16
14
  }}</v-card-text>
17
15
  </v-card>
18
16
 
@@ -60,6 +58,17 @@
60
58
  "
61
59
  :playbackrates="block.metadata.config.attributes.playbackrates"
62
60
  />
61
+ <!-- display first note in the playlist for now -->
62
+ <v-alert
63
+ v-if="notes.length > 0"
64
+ :color="
65
+ $vuetify.theme.isDark
66
+ ? 'v-navigation-drawer'
67
+ : 'blue-grey lighten-5'
68
+ "
69
+ >
70
+ <TextViewer v-model="notes[0]"></TextViewer>
71
+ </v-alert>
63
72
  </div>
64
73
  </template>
65
74
 
@@ -67,10 +76,13 @@
67
76
  import _ from 'lodash'
68
77
  import VuetifyPlayer from '@mindedge/vuetify-player'
69
78
  import BaseContentBlock from '~/components/Content/Blocks/BaseContentBlock'
79
+ import TextViewer from '~/components/Text/TextViewer'
80
+ import he from 'he'
70
81
 
71
82
  export default {
72
83
  name: 'ContentBlockVideo',
73
84
  components: {
85
+ TextViewer,
74
86
  VuetifyPlayer,
75
87
  },
76
88
  extends: BaseContentBlock,
@@ -96,12 +108,30 @@ export default {
96
108
  )
97
109
  return _.get(file, 'asset.public_url')
98
110
  },
111
+ notes() {
112
+ const playlist = this.block.metadata.config.playlist
113
+ let result = []
114
+ for (const index in playlist) {
115
+ for (const sourceIndex in playlist[index].sources) {
116
+ let file = this.resolveAsset(
117
+ playlist[index].sources[sourceIndex]
118
+ )
119
+ if (
120
+ !_.isEmpty(_.get(file, 'asset.metadata.notes')) &&
121
+ //check the file notes are actually text and not an empty div
122
+ this.hasWords(_.get(file, 'asset.metadata.notes'))
123
+ ) {
124
+ result.push(_.get(file, 'asset.metadata.notes'))
125
+ }
126
+ }
127
+ }
128
+ return result
129
+ },
99
130
  /**
100
131
  * Resolve assets to their playlist items
101
132
  */
102
133
  linkedPlaylist() {
103
134
  const playlist = _.cloneDeep(this.block.metadata.config.playlist)
104
-
105
135
  for (const index in playlist) {
106
136
  for (const sourceIndex in playlist[index].sources) {
107
137
  let file = this.resolveAsset(
@@ -112,6 +142,13 @@ export default {
112
142
  src: _.get(file, 'asset.public_url', ''),
113
143
  type: _.get(file, 'asset.metadata.mime', ''),
114
144
  }
145
+
146
+ // If there's linked captions and there's no hard-set captions
147
+ // Fallback to the linked captions
148
+ const linkedCaptions = this.getLinkedCaptions(file)
149
+ if (playlist[index].tracks.length === 0 && linkedCaptions) {
150
+ playlist[index].tracks.push(linkedCaptions)
151
+ }
115
152
  }
116
153
 
117
154
  for (const trackIndex in playlist[index].tracks) {
@@ -126,7 +163,6 @@ export default {
126
163
  default: true,
127
164
  }
128
165
  }
129
-
130
166
  for (const adIndex in playlist[index].ads) {
131
167
  for (const adSourceIndex in playlist[index].ads[adIndex]
132
168
  .sources) {
@@ -138,7 +174,20 @@ export default {
138
174
  src: _.get(file, 'asset.public_url', ''),
139
175
  type: _.get(file, 'asset.metadata.mime', ''),
140
176
  }
177
+
178
+ // If there's linked captions and there's no hard-set captions
179
+ // Fallback to the linked captions
180
+ const linkedCaptions = this.getLinkedCaptions(file)
181
+ if (
182
+ playlist[index].ads[adIndex].tracks.length === 0 &&
183
+ linkedCaptions
184
+ ) {
185
+ playlist[index].ads[adIndex].tracks.push(
186
+ linkedCaptions
187
+ )
188
+ }
141
189
  }
190
+
142
191
  for (const adTrackIndex in playlist[index].ads[adIndex]
143
192
  .tracks) {
144
193
  let file = this.resolveAsset(
@@ -154,7 +203,11 @@ export default {
154
203
  }
155
204
  }
156
205
  }
157
-
206
+ // reset adds to empty array as we aren't using these right now
207
+ // left code above in case we want to implement later
208
+ playlist.forEach((element) => {
209
+ element.ads = []
210
+ })
158
211
  return playlist
159
212
  },
160
213
  },
@@ -249,11 +302,46 @@ export default {
249
302
  this.$set(this.block, 'assets', [])
250
303
  }
251
304
  },
252
- mounted() {},
253
305
  methods: {
254
306
  async onBeforeSave() {
255
307
  this.block.body = 'video'
256
308
  },
309
+ getLinkedCaptions(file) {
310
+ // Check to see if the video source has a linked asset and it's a vtt file
311
+ const linkedCaption = _.find(
312
+ _.get(file, 'asset.linked_assets', []),
313
+ function (f) {
314
+ return _.get(f, 'asset.metadata.extension', '') === 'vtt'
315
+ }
316
+ )
317
+
318
+ if (linkedCaption) {
319
+ const foundAsset = this.block.assets.find((a) => {
320
+ return a.file_asset_id === linkedCaption.file_asset_id
321
+ })
322
+
323
+ // The linked captions aren't part of the block.assets
324
+ // Add it so the block knows how to properly load it
325
+ if (!foundAsset) {
326
+ this.block.assets.push(_.cloneDeep(linkedCaption))
327
+ }
328
+ }
329
+
330
+ return linkedCaption || null
331
+ },
332
+
333
+ /**
334
+ * Check if the given text has words, omitting HTML tags and HTML entities
335
+ * @param {string} text - The text to check
336
+ * @returns {boolean} - True if the text has words, false otherwise
337
+ */
338
+ hasWords(text) {
339
+ const strippedText = he
340
+ .decode(text)
341
+ .replace(/<\/?[^>]+(>|$)/g, '') // Remove HTML tags
342
+ .trim()
343
+ return /\b\w+\b/.test(strippedText) // Check if there are any words
344
+ },
257
345
  },
258
346
  }
259
347
  </script>
@@ -1,6 +1,30 @@
1
1
  <template>
2
2
  <div>
3
3
  <v-container class="pa-0">
4
+ <v-row class="pl-3 pr-3">
5
+ <v-text-field
6
+ v-model="block.metadata.config.title"
7
+ :autofocus="true"
8
+ :rules="validation.shortInputRules"
9
+ :counter="50"
10
+ outlined
11
+ id="title"
12
+ :label="
13
+ $t(
14
+ 'windward.core.components.settings.clickable_icon.title'
15
+ )
16
+ "
17
+ :disabled="render"
18
+ ></v-text-field>
19
+ <v-textarea
20
+ v-model="block.metadata.config.instructions"
21
+ :rules="validation.instructionRule"
22
+ :counter="255"
23
+ outlined
24
+ :label="$t('components.content.settings.base.instructions')"
25
+ :disabled="render"
26
+ ></v-textarea>
27
+ </v-row>
4
28
  <v-divider class="my-4 primary"></v-divider>
5
29
  <p>
6
30
  {{ $t('windward.core.components.settings.accordion.items') }}
@@ -23,7 +47,7 @@
23
47
  v-model="block.metadata.config.items[index].header"
24
48
  :autofocus="true"
25
49
  :counter="50"
26
- :rules="validation.titleRule"
50
+ :rules="validation.shortInputRules"
27
51
  outlined
28
52
  :label="
29
53
  $t('components.content.settings.base.title')
@@ -144,6 +168,7 @@ import Crypto from '~/helpers/Crypto'
144
168
  import BaseContentSettings from '~/components/Content/Settings/BaseContentSettings.js'
145
169
  import TextEditor from '~/components/Text/TextEditor'
146
170
  import SortableExpansionPanel from '~/components/Core/SortableExpansionPanel.vue'
171
+ import Uuid from '~/helpers/Uuid'
147
172
 
148
173
  export default {
149
174
  name: 'AccordionSettings',
@@ -162,6 +187,18 @@ export default {
162
187
  if (_.isEmpty(this.block.metadata.config)) {
163
188
  this.block.metadata.config = {}
164
189
  }
190
+ if (_.isEmpty(this.block.metadata.config.title)) {
191
+ this.block.metadata.config.title = ''
192
+ }
193
+ if (
194
+ _.isEmpty(this.block.metadata.config.instructions) &&
195
+ this.block.id &&
196
+ !Uuid.test(this.block.id)
197
+ ) {
198
+ this.block.metadata.config.instructions = this.$t(
199
+ 'windward.core.components.settings.accordion.instructions'
200
+ )
201
+ }
165
202
  if (_.isEmpty(this.block.metadata.config.editOnContentItem)) {
166
203
  this.block.metadata.config.editOnContentItem = false
167
204
  }
@@ -186,13 +223,29 @@ export default {
186
223
  expansionPanelKey: '0',
187
224
  loading: false,
188
225
  validation: {
189
- titleRule: [
190
- (v) =>
191
- v.length <= 50 ||
192
- this.$t(
193
- 'windward.core.shared.settings.errors.input_limitations',
194
- [50]
195
- ),
226
+ shortInputRules: [
227
+ (v) => {
228
+ if (v && v.length >= 50) {
229
+ return this.$t(
230
+ 'windward.core.shared.settings.errors.input_limitations',
231
+ [50]
232
+ )
233
+ } else {
234
+ return true
235
+ }
236
+ },
237
+ ],
238
+ instructionRule: [
239
+ (v) => {
240
+ if (v && v.length >= 255) {
241
+ return this.$t(
242
+ 'windward.core.shared.settings.errors.input_limitations',
243
+ [255]
244
+ )
245
+ } else {
246
+ return true
247
+ }
248
+ },
196
249
  ],
197
250
  },
198
251
  }
@@ -184,20 +184,28 @@ export default {
184
184
  ],
185
185
  validation: {
186
186
  shortInputRules: [
187
- (v) =>
188
- v.length <= 50 ||
189
- this.$t(
190
- 'windward.core.shared.settings.errors.input_limitations',
191
- [50]
192
- ),
187
+ (v) => {
188
+ if (v && v.length >= 50) {
189
+ return this.$t(
190
+ 'windward.core.shared.settings.errors.input_limitations',
191
+ [50]
192
+ )
193
+ } else {
194
+ return true
195
+ }
196
+ },
193
197
  ],
194
198
  longInputRules: [
195
- (v) =>
196
- v.length <= 255 ||
197
- this.$t(
198
- 'windward.core.shared.settings.errors.input_limitations',
199
- [255]
200
- ),
199
+ (v) => {
200
+ if (v && v.length >= 255) {
201
+ return this.$t(
202
+ 'windward.core.shared.settings.errors.input_limitations',
203
+ [255]
204
+ )
205
+ } else {
206
+ return true
207
+ }
208
+ },
201
209
  ],
202
210
  },
203
211
  }