@windward/core 0.0.8 → 0.0.9

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 (175) hide show
  1. package/components/Content/Blocks/ClickableIcons.vue +128 -40
  2. package/components/Content/Blocks/Image.vue +2 -2
  3. package/components/Content/Blocks/ScenarioChoice.vue +262 -0
  4. package/components/Content/Blocks/Tab.vue +2 -7
  5. package/components/Settings/AccordionSettings.vue +97 -74
  6. package/components/Settings/ClickableIconsSettings.vue +101 -86
  7. package/components/Settings/ScenarioChoiceSettings.vue +329 -0
  8. package/components/Settings/TabSettings.vue +75 -61
  9. package/components/Settings/TextEditorSettings.vue +1 -3
  10. package/components/utils/FillInBlank/FillInBlankInput.vue +4 -1
  11. package/components/utils/TinyMCEWrapper.vue +1 -1
  12. package/helpers/FillInBlankHelper.ts +0 -2
  13. package/i18n/en-US/components/content/blocks/index.ts +2 -2
  14. package/i18n/en-US/components/content/blocks/scenario_choice.ts +5 -0
  15. package/i18n/en-US/components/settings/accordion.ts +5 -0
  16. package/i18n/en-US/components/settings/clickable_icon.ts +8 -0
  17. package/i18n/en-US/components/settings/index.ts +6 -0
  18. package/i18n/en-US/components/settings/scenario_choice.ts +19 -0
  19. package/i18n/en-US/components/settings/tab.ts +7 -0
  20. package/i18n/en-US/components/utils/FillInBlank/FillInBlankInput.ts +1 -1
  21. package/i18n/en-US/shared/content_blocks.ts +1 -0
  22. package/i18n/en-US/shared/settings.ts +2 -0
  23. package/i18n/es-ES/components/content/blocks/feedback.ts +2 -0
  24. package/i18n/es-ES/components/content/blocks/index.ts +2 -2
  25. package/i18n/es-ES/components/content/blocks/scenario_choice.ts +6 -0
  26. package/i18n/es-ES/components/navigation/index.ts +2 -0
  27. package/i18n/es-ES/components/settings/accordion.ts +5 -0
  28. package/i18n/es-ES/components/settings/clickable_icon.ts +8 -0
  29. package/i18n/es-ES/components/settings/index.ts +6 -0
  30. package/i18n/es-ES/components/settings/scenario_choice.ts +19 -0
  31. package/i18n/es-ES/components/{content/blocks → settings}/tab.ts +3 -0
  32. package/i18n/es-ES/components/utils/FillInBlank/FillInBlankInput.ts +13 -0
  33. package/i18n/es-ES/components/utils/FillInBlank/FillInTheBlanksManager.ts +11 -0
  34. package/i18n/es-ES/components/utils/FillInBlank/index.ts +6 -0
  35. package/i18n/es-ES/components/utils/index.ts +2 -0
  36. package/i18n/es-ES/components/utils/tiny_mce_wrapper.ts +1 -0
  37. package/i18n/es-ES/shared/content_blocks.ts +1 -0
  38. package/i18n/es-ES/shared/menu.ts +1 -0
  39. package/i18n/es-ES/shared/settings.ts +2 -0
  40. package/i18n/index.ts +11 -0
  41. package/i18n/sv-SE/components/content/blocks/feedback.ts +2 -0
  42. package/i18n/sv-SE/components/content/blocks/index.ts +2 -2
  43. package/i18n/sv-SE/components/content/blocks/scenario_choice.ts +5 -0
  44. package/i18n/sv-SE/components/navigation/index.ts +2 -0
  45. package/i18n/sv-SE/components/settings/accordion.ts +5 -0
  46. package/i18n/sv-SE/components/settings/clickable_icon.ts +8 -0
  47. package/i18n/sv-SE/components/settings/index.ts +6 -0
  48. package/i18n/sv-SE/components/settings/scenario_choice.ts +19 -0
  49. package/i18n/sv-SE/components/{content/blocks → settings}/tab.ts +3 -0
  50. package/i18n/sv-SE/components/utils/FillInBlank/FillInBlankInput.ts +13 -0
  51. package/i18n/sv-SE/components/utils/FillInBlank/FillInTheBlanksManager.ts +11 -0
  52. package/i18n/sv-SE/components/utils/FillInBlank/index.ts +6 -0
  53. package/i18n/sv-SE/components/utils/index.ts +2 -0
  54. package/i18n/sv-SE/components/utils/tiny_mce_wrapper.ts +1 -0
  55. package/i18n/sv-SE/shared/content_blocks.ts +1 -0
  56. package/i18n/sv-SE/shared/menu.ts +1 -0
  57. package/i18n/sv-SE/shared/settings.ts +2 -0
  58. package/package.json +2 -1
  59. package/plugin.js +24 -5
  60. package/test/Components/Content/Blocks/ScenarioChoice.spec.js +21 -0
  61. package/test/Components/Settings/ClickableIconsSettings.spec.js +1 -1
  62. package/test/Components/Settings/ScenarioChoiceSettings.spec.js +20 -0
  63. package/test/Feature/LocaleKeys.spec.js +9 -0
  64. package/test/__mocks__/componentsMock.js +24 -0
  65. package/test/locales.js +95 -0
  66. package/.idea/codeStyles/Project.xml +0 -58
  67. package/.idea/codeStyles/codeStyleConfig.xml +0 -5
  68. package/.idea/inspectionProfiles/Project_Default.xml +0 -6
  69. package/.idea/modules.xml +0 -8
  70. package/.idea/php-docker-settings.xml +0 -24
  71. package/.idea/php.xml +0 -19
  72. package/.idea/vcs.xml +0 -6
  73. package/.idea/watcherTasks.xml +0 -4
  74. package/.idea/windward-ui-plugin-core.iml +0 -8
  75. package/coverage/clover.xml +0 -223
  76. package/coverage/coverage-final.json +0 -16
  77. package/coverage/lcov-report/base.css +0 -224
  78. package/coverage/lcov-report/block-navigation.js +0 -87
  79. package/coverage/lcov-report/components/Content/Blocks/Accordion.vue.html +0 -430
  80. package/coverage/lcov-report/components/Content/Blocks/Image.vue.html +0 -394
  81. package/coverage/lcov-report/components/Content/Blocks/Math.vue.html +0 -262
  82. package/coverage/lcov-report/components/Content/Blocks/RichText.vue.html +0 -295
  83. package/coverage/lcov-report/components/Content/Blocks/Tab.vue.html +0 -415
  84. package/coverage/lcov-report/components/Content/Blocks/Table.vue.html +0 -667
  85. package/coverage/lcov-report/components/Content/Blocks/Video.vue.html +0 -2275
  86. package/coverage/lcov-report/components/Content/Blocks/index.html +0 -206
  87. package/coverage/lcov-report/components/utils/ContentViewer.vue.html +0 -199
  88. package/coverage/lcov-report/components/utils/MathExpressionEditor.vue.html +0 -919
  89. package/coverage/lcov-report/components/utils/MathLiveWrapper.vue.html +0 -343
  90. package/coverage/lcov-report/components/utils/TinyMCEWrapper.vue.html +0 -271
  91. package/coverage/lcov-report/components/utils/index.html +0 -161
  92. package/coverage/lcov-report/config/index.html +0 -116
  93. package/coverage/lcov-report/config/tinymce.config.js.html +0 -493
  94. package/coverage/lcov-report/favicon.png +0 -0
  95. package/coverage/lcov-report/helpers/MathHelper.ts.html +0 -793
  96. package/coverage/lcov-report/helpers/index.html +0 -116
  97. package/coverage/lcov-report/helpers/tinymce/index.html +0 -116
  98. package/coverage/lcov-report/helpers/tinymce/plugin.ts.html +0 -334
  99. package/coverage/lcov-report/index.html +0 -191
  100. package/coverage/lcov-report/prettify.css +0 -1
  101. package/coverage/lcov-report/prettify.js +0 -2
  102. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  103. package/coverage/lcov-report/sorter.js +0 -196
  104. package/coverage/lcov-report/test/index.html +0 -116
  105. package/coverage/lcov-report/test/mocks.js.html +0 -457
  106. package/coverage/lcov.info +0 -403
  107. package/i18n/en-US/components/content/blocks/tab.ts +0 -4
  108. package/lib/helpers/GlossaryHelper.d.ts +0 -9
  109. package/lib/helpers/GlossaryHelper.js +0 -118
  110. package/lib/helpers/GlossaryTerm.d.ts +0 -10
  111. package/lib/helpers/GlossaryTerm.js +0 -22
  112. package/lib/helpers/MathHelper.d.ts +0 -99
  113. package/lib/helpers/MathHelper.js +0 -194
  114. package/lib/helpers/tinymce/plugin.d.ts +0 -2
  115. package/lib/helpers/tinymce/plugin.js +0 -86
  116. package/lib/i18n/en-US/components/content/blocks/image.d.ts +0 -6
  117. package/lib/i18n/en-US/components/content/blocks/image.js +0 -7
  118. package/lib/i18n/en-US/components/content/blocks/index.d.ts +0 -75
  119. package/lib/i18n/en-US/components/content/blocks/index.js +0 -14
  120. package/lib/i18n/en-US/components/content/blocks/tab.d.ts +0 -5
  121. package/lib/i18n/en-US/components/content/blocks/tab.js +0 -6
  122. package/lib/i18n/en-US/components/content/blocks/table.d.ts +0 -5
  123. package/lib/i18n/en-US/components/content/blocks/table.js +0 -6
  124. package/lib/i18n/en-US/components/content/blocks/user_upload.d.ts +0 -13
  125. package/lib/i18n/en-US/components/content/blocks/user_upload.js +0 -14
  126. package/lib/i18n/en-US/components/content/blocks/video.d.ts +0 -48
  127. package/lib/i18n/en-US/components/content/blocks/video.js +0 -49
  128. package/lib/i18n/en-US/components/content/index.d.ts +0 -77
  129. package/lib/i18n/en-US/components/content/index.js +0 -6
  130. package/lib/i18n/en-US/components/index.d.ts +0 -140
  131. package/lib/i18n/en-US/components/index.js +0 -12
  132. package/lib/i18n/en-US/components/navigation/image.d.ts +0 -5
  133. package/lib/i18n/en-US/components/navigation/image.js +0 -6
  134. package/lib/i18n/en-US/components/navigation/index.d.ts +0 -10
  135. package/lib/i18n/en-US/components/navigation/index.js +0 -8
  136. package/lib/i18n/en-US/components/navigation/user_upload.d.ts +0 -4
  137. package/lib/i18n/en-US/components/navigation/user_upload.js +0 -5
  138. package/lib/i18n/en-US/components/settings/clickable_icon.d.ts +0 -6
  139. package/lib/i18n/en-US/components/settings/clickable_icon.js +0 -7
  140. package/lib/i18n/en-US/components/settings/image.d.ts +0 -2
  141. package/lib/i18n/en-US/components/settings/image.js +0 -3
  142. package/lib/i18n/en-US/components/settings/index.d.ts +0 -39
  143. package/lib/i18n/en-US/components/settings/index.js +0 -14
  144. package/lib/i18n/en-US/components/settings/text_editor.d.ts +0 -8
  145. package/lib/i18n/en-US/components/settings/text_editor.js +0 -9
  146. package/lib/i18n/en-US/components/settings/user_upload.d.ts +0 -12
  147. package/lib/i18n/en-US/components/settings/user_upload.js +0 -13
  148. package/lib/i18n/en-US/components/settings/video.d.ts +0 -13
  149. package/lib/i18n/en-US/components/settings/video.js +0 -14
  150. package/lib/i18n/en-US/components/utils/index.d.ts +0 -15
  151. package/lib/i18n/en-US/components/utils/index.js +0 -6
  152. package/lib/i18n/en-US/components/utils/tiny_mce_wrapper.d.ts +0 -13
  153. package/lib/i18n/en-US/components/utils/tiny_mce_wrapper.js +0 -14
  154. package/lib/i18n/en-US/index.d.ts +0 -197
  155. package/lib/i18n/en-US/index.js +0 -16
  156. package/lib/i18n/en-US/modules/index.d.ts +0 -2
  157. package/lib/i18n/en-US/modules/index.js +0 -6
  158. package/lib/i18n/en-US/pages/glossary.d.ts +0 -8
  159. package/lib/i18n/en-US/pages/glossary.js +0 -9
  160. package/lib/i18n/en-US/pages/index.d.ts +0 -13
  161. package/lib/i18n/en-US/pages/index.js +0 -8
  162. package/lib/i18n/en-US/pages/user_upload.d.ts +0 -4
  163. package/lib/i18n/en-US/pages/user_upload.js +0 -5
  164. package/lib/i18n/en-US/shared/content_blocks.d.ts +0 -20
  165. package/lib/i18n/en-US/shared/content_blocks.js +0 -21
  166. package/lib/i18n/en-US/shared/index.d.ts +0 -39
  167. package/lib/i18n/en-US/shared/index.js +0 -10
  168. package/lib/i18n/en-US/shared/menu.d.ts +0 -4
  169. package/lib/i18n/en-US/shared/menu.js +0 -5
  170. package/lib/i18n/en-US/shared/settings.d.ts +0 -15
  171. package/lib/i18n/en-US/shared/settings.js +0 -16
  172. package/lib/i18n/en-US.d.ts +0 -197
  173. package/lib/i18n/en-US.js +0 -15
  174. package/lib/models/UserFileAsset.d.ts +0 -5
  175. package/lib/models/UserFileAsset.js +0 -37
@@ -1,42 +1,60 @@
1
1
  <template>
2
2
  <div>
3
3
  <v-container>
4
- <v-row no-gutters>
5
- <h3>{{ block.metadata.config.title }}</h3>
6
- </v-row>
7
- <v-row no-gutters>
8
- <h4>{{ block.metadata.config.description }}</h4>
9
- </v-row>
10
- <v-row no-gutters>
11
- <p>
12
- {{
13
- $t(
14
- 'windward.core.components.settings.clickable_icon.information'
15
- )
16
- }}
17
- </p>
18
- </v-row>
4
+ <h3>{{ block.metadata.config.title }}</h3>
5
+
6
+ <h4>{{ block.metadata.config.description }}</h4>
7
+
8
+ <p>
9
+ {{
10
+ $t(
11
+ 'windward.core.components.settings.clickable_icon.information'
12
+ )
13
+ }}
14
+ </p>
19
15
  </v-container>
20
16
  <v-container>
21
17
  <v-row
22
18
  v-for="(item, itemIndex) in block.metadata.config.items"
23
19
  :key="itemIndex"
24
20
  no-gutters
21
+ :class="rowClass(itemIndex)"
25
22
  >
26
23
  <v-col cols="2">
27
24
  <v-btn
28
25
  class="pt-8 pb-8 outlined-button mb-4"
29
- :color="itemColor(item.color)"
26
+ :color="itemColor(itemIndex)"
27
+ :fab="block.metadata.config.display.round_icon"
30
28
  x-large
31
29
  outlined
32
30
  @click="item.active = !item.active"
33
31
  >
34
- <v-icon>{{ onHandleHtmlEntities(item.icon) }}</v-icon>
32
+ <v-icon v-if="isIcon(item.icon)" class="black--text">{{
33
+ item.icon
34
+ }}</v-icon>
35
+ <span v-else :class="iconClass + ' black--text'">{{
36
+ decode(item.icon)
37
+ }}</span>
35
38
  </v-btn>
36
39
  </v-col>
37
- <v-col cols="10" v-if="item.active">
38
- <h4>{{ item.title }}</h4>
39
- <TextViewer v-model="item.body"></TextViewer>
40
+ <v-col cols="10">
41
+ <h4
42
+ v-if="
43
+ block.metadata.config.display.show_title ||
44
+ item.active
45
+ "
46
+ class="mt-4"
47
+ role="button"
48
+ @click="item.active = !item.active"
49
+ >
50
+ {{ item.title }}
51
+ </h4>
52
+ <v-expand-transition>
53
+ <div v-if="item.active">
54
+ <v-divider light class="my-4" />
55
+ <TextViewer v-model="item.body"></TextViewer>
56
+ </div>
57
+ </v-expand-transition>
40
58
  </v-col>
41
59
  </v-row>
42
60
  </v-container>
@@ -44,6 +62,7 @@
44
62
  </template>
45
63
  <script>
46
64
  import _ from 'lodash'
65
+ import he from 'he'
47
66
  import BaseContentBlock from '~/components/Content/Blocks/BaseContentBlock'
48
67
  import TextViewer from '~/components/Text/TextViewer'
49
68
 
@@ -53,13 +72,77 @@ export default {
53
72
  TextViewer,
54
73
  },
55
74
  extends: BaseContentBlock,
75
+ data() {
76
+ return {}
77
+ },
56
78
  computed: {
79
+ decode() {
80
+ return (str) => {
81
+ return he.decode(str || '')
82
+ }
83
+ },
84
+ rowClass() {
85
+ return (itemIndex) => {
86
+ let classes = 'option-container mb-4 pa-1'
87
+ // If show background is enabled and the item has a color
88
+ // Otherwise we do NOT want to apply the `black--text` class since there's no color
89
+ // And things will look bad in dark mode
90
+ if (
91
+ _.get(
92
+ this.block,
93
+ 'metadata.config.display.show_background',
94
+ false
95
+ ) &&
96
+ this.itemColor(itemIndex)
97
+ ) {
98
+ classes += ' ' + this.itemColor(itemIndex) + ' black--text'
99
+ }
100
+ return classes
101
+ }
102
+ },
103
+ iconClass() {
104
+ let classes = 'text-icon'
105
+ if (
106
+ _.get(this.block, 'metadata.config.display.italic_icon', false)
107
+ ) {
108
+ classes += ' font-italic'
109
+ }
110
+ return classes
111
+ },
57
112
  itemColor() {
58
- return (v) => {
59
- if (_.isObject(v)) {
60
- return _.get(v, 'class', '')
113
+ return (itemIndex) => {
114
+ // If autocolor is enabled then calculate the color on the index
115
+ if (this.block.metadata.config.display.autocolor) {
116
+ const colors = [
117
+ 'light-blue lighten-4',
118
+ 'light-green lighten-4',
119
+ 'yellow lighten-4',
120
+ 'orange lighten-3',
121
+ 'red lighten-3',
122
+ 'deep-purple lighten-3',
123
+ ]
124
+ let colorIndex = itemIndex
125
+ // If we exceed the above list of colors loop back around to the beginning
126
+ if (colorIndex >= colors.length) {
127
+ colorIndex =
128
+ colorIndex -
129
+ Math.floor(colorIndex / colors.length) *
130
+ colors.length
131
+ }
132
+
133
+ return colors[colorIndex]
61
134
  } else {
62
- return v
135
+ // Otherwise get the predefined color
136
+ const color = _.get(
137
+ this.block,
138
+ 'metadata.config.items[' + itemIndex + '].color',
139
+ ''
140
+ )
141
+ if (_.isObject(color)) {
142
+ return _.get(color, 'class', '')
143
+ } else {
144
+ return color
145
+ }
63
146
  }
64
147
  }
65
148
  },
@@ -76,32 +159,37 @@ export default {
76
159
  if (_.isEmpty(this.block.metadata.config.description)) {
77
160
  this.block.metadata.config.description = ''
78
161
  }
79
- if (this.block.metadata.config.items) {
80
- this.block.metadata.config.items.forEach((element) => {
81
- element.active = false
82
- })
162
+ if (_.isEmpty(this.block.metadata.config.display)) {
163
+ this.block.metadata.config.display = {
164
+ show_title: false,
165
+ show_background: false,
166
+ round_icon: false,
167
+ italic_icon: false,
168
+ autocolor: true,
169
+ }
83
170
  }
84
- },
85
- data() {
86
- return {
87
- api_key: process.env.TINY_MCE_API_KEY,
88
- title: 'Title',
89
- displayText: false,
171
+ if (this.block.metadata.config.items.length) {
172
+ for (const index in this.block.metadata.config.items) {
173
+ this.block.metadata.config.items[index].active = false
174
+ }
90
175
  }
91
176
  },
92
177
  methods: {
93
- onHandleHtmlEntities(str) {
94
- let txt = document.createElement('textarea')
95
-
96
- txt.innerHTML = str
97
-
98
- return txt.value
178
+ isIcon(str) {
179
+ return str && _.isString(str) && str.indexOf('mdi-') === 0
99
180
  },
100
181
  },
101
182
  }
102
183
  </script>
103
184
  <style scoped>
185
+ .option-container {
186
+ border-radius: 1rem;
187
+ }
104
188
  .outlined-button {
105
189
  border-width: 4px;
190
+ background: #fff;
191
+ }
192
+ .text-icon {
193
+ font-size: 1.5rem;
106
194
  }
107
195
  </style>
@@ -25,7 +25,7 @@
25
25
  :src="block.body"
26
26
  contain
27
27
  >
28
- <template v-slot:placeholder>
28
+ <template #placeholder>
29
29
  <v-skeleton-loader
30
30
  type="image, image, list-item-avatar"
31
31
  height="100%"
@@ -121,7 +121,7 @@ export default {
121
121
  border-radius: 3px;
122
122
  }
123
123
  .img-holder {
124
- max-height: 300px;
124
+ height: 300px;
125
125
  }
126
126
  .img-white {
127
127
  background: #fff;
@@ -0,0 +1,262 @@
1
+ <template>
2
+ <div>
3
+ <v-container>
4
+ <h3>{{ block.metadata.config.title }}</h3>
5
+ <h4>{{ block.metadata.config.description }}</h4>
6
+ <p>
7
+ {{
8
+ $t(
9
+ 'windward.core.components.content.blocks.scenario_choice.information'
10
+ )
11
+ }}
12
+ </p>
13
+ <div
14
+ v-if="choiceIndex !== null && block.metadata.config.show_reset"
15
+ class="text-right"
16
+ >
17
+ <v-btn color="primary" outlined @click="onClickReset">
18
+ {{
19
+ $t(
20
+ 'windward.core.components.content.blocks.scenario_choice.try_again'
21
+ )
22
+ }}
23
+ </v-btn>
24
+ </div>
25
+ </v-container>
26
+ <v-container>
27
+ <v-row
28
+ v-for="(item, itemIndex) in block.metadata.config.items"
29
+ :key="itemIndex"
30
+ no-gutters
31
+ :class="rowClass(item, itemIndex)"
32
+ >
33
+ <v-col cols="2" class="text-center">
34
+ <div
35
+ class="pt-8 pb-8 text-icon-container mb-4 mx-auto"
36
+ role="button"
37
+ @click="onClickItem(itemIndex)"
38
+ >
39
+ <span :class="iconClass(itemIndex)">{{
40
+ itemIcon(itemIndex)
41
+ }}</span>
42
+ </div>
43
+ <strong v-if="choiceIndex === itemIndex">
44
+ {{
45
+ $t(
46
+ 'windward.core.components.content.blocks.scenario_choice.selected_choice'
47
+ )
48
+ }}
49
+ </strong>
50
+ </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>
59
+
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>
75
+ </v-col>
76
+ </v-row>
77
+ </v-container>
78
+ </div>
79
+ </template>
80
+ <script>
81
+ import _ from 'lodash'
82
+ import BaseContentBlock from '~/components/Content/Blocks/BaseContentBlock'
83
+ import TextViewer from '~/components/Text/TextViewer'
84
+
85
+ export default {
86
+ name: 'ClickableIcons',
87
+ components: {
88
+ TextViewer,
89
+ },
90
+ extends: BaseContentBlock,
91
+ data() {
92
+ return {
93
+ choiceIndex: null,
94
+ }
95
+ },
96
+ computed: {
97
+ rowClass() {
98
+ return (item, itemIndex) => {
99
+ let classes = 'option-container mb-4 pa-1 black--text '
100
+
101
+ // If an option was picked set the background to correct / incorrect
102
+ // Otherwise do the autocolor
103
+ if (this.choiceIndex !== null && item.correct) {
104
+ classes += 'success'
105
+ } else if (this.choiceIndex !== null && !item.correct) {
106
+ classes += 'error'
107
+ } else {
108
+ classes += this.itemColor(itemIndex)
109
+ }
110
+ return classes
111
+ }
112
+ },
113
+ iconClass() {
114
+ return (itemIndex) => {
115
+ let classes = 'text-icon '
116
+ // Add the appropriate color / modifiers to make the icon color
117
+ const color = this.itemColor(itemIndex).split(' ')
118
+ classes += color[0] + '--text text--' + color[1]
119
+
120
+ return classes
121
+ }
122
+ },
123
+ itemColor() {
124
+ return (itemIndex) => {
125
+ const colors = [
126
+ 'light-blue lighten-4',
127
+ 'light-green lighten-4',
128
+ 'yellow lighten-4',
129
+ 'orange lighten-3',
130
+ 'red lighten-3',
131
+ 'deep-purple lighten-3',
132
+ ]
133
+ let colorIndex = itemIndex
134
+ // If we exceed the above list of colors loop back around to the beginning
135
+ if (colorIndex >= colors.length) {
136
+ colorIndex =
137
+ colorIndex -
138
+ Math.floor(colorIndex / colors.length) * colors.length
139
+ }
140
+
141
+ return colors[colorIndex]
142
+ }
143
+ },
144
+ itemIcon() {
145
+ return (itemIndex) => {
146
+ if (isNaN(itemIndex) || itemIndex < 0) {
147
+ return 'ERR'
148
+ }
149
+ // Return a letter if the display style is letter (with super complicated logic)
150
+ // ... or return the index + 1 for number styles
151
+ if (this.block.metadata.config.display_style === 'letter') {
152
+ if (itemIndex <= 25) {
153
+ // 65 is where capitals start
154
+ return String.fromCharCode(65 + itemIndex)
155
+ } else {
156
+ // Calculate two character AA-ZZ or a max list length of 625 which we will never hit
157
+ // I'd be surprised if we ever get to AA tbh but I'm gonna support it just in case
158
+ const prependIndex = Math.floor(itemIndex / 26) - 1
159
+
160
+ return (
161
+ String.fromCharCode(65 + prependIndex) +
162
+ String.fromCharCode(
163
+ 65 + (itemIndex - 26 * (prependIndex + 1))
164
+ )
165
+ )
166
+ }
167
+ } else if (
168
+ this.block.metadata.config.display_style === 'number'
169
+ ) {
170
+ return itemIndex + 1
171
+ }
172
+ }
173
+ },
174
+ linkedPage() {
175
+ const isLinked =
176
+ !_.isEmpty(this.block.metadata.config.link_content_id) &&
177
+ !_.isEmpty(this.block.metadata.config.link_text)
178
+
179
+ if (isLinked) {
180
+ const flatTree = this.$ContentService.getFlatTree()
181
+ // Find the course_content_id that this content id is referencing
182
+ const pages = flatTree.filter((c) => {
183
+ return (
184
+ c.content_id ===
185
+ this.block.metadata.config.link_content_id
186
+ )
187
+ })
188
+
189
+ // We found it, so return it otherwise null
190
+ if (pages.length > 0) {
191
+ return {
192
+ text: this.block.metadata.config.link_text,
193
+ course_content_id: pages[0].id,
194
+ }
195
+ } else {
196
+ return null
197
+ }
198
+ } else {
199
+ return null
200
+ }
201
+ },
202
+ },
203
+ beforeMount() {
204
+ // Apply the default config
205
+ this.block.body = 'scenario choice'
206
+ if (_.isEmpty(this.block.metadata.config.items)) {
207
+ this.block.metadata.config.items = []
208
+ }
209
+ if (_.isEmpty(this.block.metadata.config.title)) {
210
+ this.block.metadata.config.title = ''
211
+ }
212
+ if (_.isEmpty(this.block.metadata.config.description)) {
213
+ this.block.metadata.config.description = ''
214
+ }
215
+ if (_.isEmpty(this.block.metadata.config.display_style)) {
216
+ this.block.metadata.config.display_style = 'letter'
217
+ }
218
+ if (_.isEmpty(this.block.metadata.config.link_content_id)) {
219
+ this.block.metadata.config.link_content_id = null
220
+ }
221
+ if (_.isEmpty(this.block.metadata.config.link_text)) {
222
+ this.block.metadata.config.link_text = null
223
+ }
224
+ if (!_.isBoolean(this.block.metadata.config.show_reset)) {
225
+ this.block.metadata.config.show_reset = false
226
+ }
227
+ },
228
+ methods: {
229
+ onClickReset() {
230
+ this.choiceIndex = null
231
+ },
232
+ onClickItem(itemIndex) {
233
+ // Only set the choice if it's null
234
+ if (this.choiceIndex === null) {
235
+ this.choiceIndex = itemIndex
236
+ }
237
+ },
238
+ onClickLink(id) {
239
+ this.$ContentService.set(id, { direct: true })
240
+ },
241
+ },
242
+ }
243
+ </script>
244
+ <style scoped>
245
+ .option-container {
246
+ border-radius: 1rem;
247
+ }
248
+ .text-icon-container {
249
+ background: #fff;
250
+ width: 5rem;
251
+ height: 5rem;
252
+ text-align: center;
253
+ line-height: 0;
254
+ margin: 1rem;
255
+ border-radius: 4rem;
256
+ }
257
+ .text-icon {
258
+ font-size: 4rem;
259
+ vertical-align: text-bottom;
260
+ filter: brightness(0.5);
261
+ }
262
+ </style>
@@ -5,7 +5,7 @@
5
5
  background-color="primary"
6
6
  v-model="block.metadata.config.tab"
7
7
  >
8
- <v-tabs-slider color="primary"></v-tabs-slider>
8
+ <v-tabs-slider></v-tabs-slider>
9
9
  <v-tab
10
10
  v-for="(tab, tabIndex) in block.metadata.config.items"
11
11
  :key="tabIndex"
@@ -24,12 +24,7 @@
24
24
  <v-container>
25
25
  <TextViewer
26
26
  v-if="!tabContent.expand"
27
- v-model="
28
- tabContent.content === '' ||
29
- tabContent.content === null
30
- ? 'Item ' + (tabContentIndex + 1)
31
- : tabContent.content
32
- "
27
+ v-model="tabContent.content"
33
28
  text-viewer
34
29
  ></TextViewer>
35
30
  <TextEditor