glib-web 2.6.7 → 3.0.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 (110) hide show
  1. package/action.js +39 -17
  2. package/actions/analytics/logEvent.js +2 -2
  3. package/actions/auth/saveCsrfToken.js +6 -0
  4. package/actions/cables/push.js +4 -4
  5. package/actions/commands/enqueue.js +17 -0
  6. package/actions/fields/reset.js +2 -2
  7. package/actions/http/get.js +15 -27
  8. package/actions/panels/scrollTo.js +1 -1
  9. package/actions/panels/scrollToBottom.js +1 -1
  10. package/actions/popovers/close.js +5 -0
  11. package/actions/popovers/open.js +9 -0
  12. package/actions/windows/closeWithReload.js +1 -1
  13. package/actions/windows/refreshState.js +3 -1
  14. package/actions/ws/push.js +5 -3
  15. package/app.vue +59 -27
  16. package/components/_badge.vue +1 -6
  17. package/components/_button.vue +30 -30
  18. package/components/_chip.vue +27 -29
  19. package/components/_dropdownMenu.vue +10 -23
  20. package/components/_icon.vue +5 -5
  21. package/components/_responsive.vue +7 -21
  22. package/components/avatar.vue +11 -15
  23. package/components/banners/alert.vue +2 -7
  24. package/components/banners/select.vue +18 -30
  25. package/components/button.vue +4 -5
  26. package/components/component.vue +112 -133
  27. package/components/datetime.vue +2 -0
  28. package/components/fields/_patternText.vue +8 -19
  29. package/components/fields/_select.vue +9 -27
  30. package/components/fields/autocomplete.vue +8 -21
  31. package/components/fields/check.vue +5 -12
  32. package/components/fields/checkGroup.vue +3 -13
  33. package/components/fields/country/field.vue +9 -27
  34. package/components/fields/date.vue +5 -5
  35. package/components/fields/datetime.vue +6 -11
  36. package/components/fields/dynamicSelect.vue +8 -29
  37. package/components/fields/file.vue +10 -29
  38. package/components/fields/newRichText.vue +67 -54
  39. package/components/fields/otpField.vue +11 -31
  40. package/components/fields/phone/field.vue +60 -78
  41. package/components/fields/radio.vue +8 -44
  42. package/components/fields/radioGroup.vue +17 -19
  43. package/components/fields/rating.vue +9 -16
  44. package/components/fields/richText.vue +27 -45
  45. package/components/fields/select.vue +10 -7
  46. package/components/fields/stripe/stripeFields.vue +9 -2
  47. package/components/fields/stripe/stripeIndividualFields.vue +9 -7
  48. package/components/fields/stripeExternalAccount.vue +10 -24
  49. package/components/fields/text.vue +26 -50
  50. package/components/fields/textarea.vue +14 -27
  51. package/components/fields/timeZone.vue +9 -6
  52. package/components/fields/timer.vue +5 -11
  53. package/components/image.vue +12 -23
  54. package/components/label.vue +10 -18
  55. package/components/markdown.vue +45 -23
  56. package/components/mixins/events.js +24 -25
  57. package/components/mixins/generic.js +7 -4
  58. package/components/mixins/inputVariant.js +16 -0
  59. package/components/mixins/list/autoload.js +7 -5
  60. package/components/mixins/styles.js +16 -16
  61. package/components/mixins/table/autoload.js +6 -4
  62. package/components/mixins/ws/actionCable.js +6 -5
  63. package/components/mixins/ws/phoenixSocket.js +11 -9
  64. package/components/p.vue +10 -0
  65. package/components/panels/column.vue +8 -19
  66. package/components/panels/custom.vue +9 -13
  67. package/components/panels/flow.vue +19 -13
  68. package/components/panels/form.vue +26 -34
  69. package/components/panels/grid.vue +15 -9
  70. package/components/panels/horizontal.vue +58 -54
  71. package/components/panels/list.vue +37 -72
  72. package/components/panels/responsive.vue +2 -33
  73. package/components/panels/scroll.vue +3 -0
  74. package/components/panels/split.vue +2 -2
  75. package/components/panels/table.vue +32 -63
  76. package/components/panels/timeline.vue +20 -30
  77. package/components/panels/vertical.vue +8 -13
  78. package/components/popover.vue +39 -0
  79. package/components/progressCircle.vue +2 -8
  80. package/components/progressbar.vue +4 -14
  81. package/components/shareButton.vue +24 -30
  82. package/components/tabBar.vue +29 -28
  83. package/index.js +60 -94
  84. package/nav/appbar.vue +8 -6
  85. package/nav/dialog.vue +30 -49
  86. package/nav/drawer.vue +39 -51
  87. package/nav/drawerButton.vue +5 -7
  88. package/nav/drawerLabel.vue +2 -3
  89. package/nav/sheet.vue +21 -22
  90. package/nav/snackbar.vue +19 -30
  91. package/package.json +13 -16
  92. package/plugins/driverCustomBehavior.js +1 -1
  93. package/plugins/updatableComponent.js +2 -2
  94. package/plugins/vuetify.js +26 -0
  95. package/store.js +16 -0
  96. package/templates/comment.vue +42 -19
  97. package/templates/featured.vue +8 -9
  98. package/templates/thumbnail-old.vue +188 -0
  99. package/templates/thumbnail.vue +3 -208
  100. package/tsconfig.json +1 -1
  101. package/utils/component.js +18 -18
  102. package/utils/constant.js +4 -0
  103. package/utils/eventBus.js +9 -2
  104. package/utils/history.js +12 -8
  105. package/utils/http.js +29 -71
  106. package/utils/launch.js +89 -52
  107. package/utils/private/ws.js +5 -3
  108. package/utils/public.js +6 -0
  109. package/utils/queue.js +102 -0
  110. package/utils/settings.js +3 -9
@@ -1,45 +1,25 @@
1
1
  <template>
2
2
  <div>
3
3
  <div v-if="spec.type === 'text'">
4
- <input
5
- v-for="(digit, index) in digits"
6
- ref="input"
7
- :key="index"
8
- v-model="otp[index]"
9
- type="text"
10
- maxlength="1"
11
- class="otp-input"
12
- @input="handleInput($event, index)"
13
- @keydown="handleKeydown($event, index)"
14
- @paste="handlePaste($event, index)"
15
- @focus="handleFocus($event, index)"
16
- @blur="handleBlur($event, index)"
17
- @click="handleClick($event)"
18
- />
4
+ <input v-for="(digit, index) in digits" ref="input" :key="index" v-model="otp[index]" type="text" maxlength="1"
5
+ class="otp-input" @input="handleInput($event, index)" @keydown="handleKeydown($event, index)"
6
+ @paste="handlePaste($event, index)" @focus="handleFocus($event, index)" @blur="handleBlur($event, index)"
7
+ @click="handleClick($event)" />
19
8
  </div>
20
9
  <div v-else>
21
- <input
22
- v-for="(digit, index) in digits"
23
- ref="input"
24
- :key="index"
25
- v-model="otp[index]"
26
- type="number"
10
+ <input v-for="(digit, index) in digits" ref="input" :key="index" v-model="otp[index]" type="number"
27
11
  oninput="javascript: if (this.value.length > this.maxLength) this.value = this.value.slice(0, this.maxLength);"
28
- maxlength="1"
29
- class="otp-input"
30
- @input="handleInput($event, index)"
31
- @keydown="handleKeydown($event, index)"
32
- @paste="handlePaste($event, index)"
33
- @focus="handleFocus($event, index)"
34
- @blur="handleBlur($event, index)"
35
- @click="handleClick($event)"
36
- />
12
+ maxlength="1" class="otp-input" @input="handleInput($event, index)" @keydown="handleKeydown($event, index)"
13
+ @paste="handlePaste($event, index)" @focus="handleFocus($event, index)" @blur="handleBlur($event, index)"
14
+ @click="handleClick($event)" />
37
15
  </div>
38
16
  <input type="hidden" :name="spec.name" :value="otpValue" />
39
17
  </div>
40
18
  </template>
41
19
 
42
20
  <script>
21
+ import bus from '../../utils/eventBus'
22
+
43
23
  export default {
44
24
  props: {
45
25
  spec: { type: Object, required: true }
@@ -95,7 +75,7 @@ export default {
95
75
  },
96
76
  handleBlur(event, index) {
97
77
  if (this.otp.filter(digit => digit === "").length === 0) {
98
- this.$emit("complete", this.otp.join(""));
78
+ bus.$emit("complete", this.otp.join(""));
99
79
  }
100
80
  },
101
81
  focusNext(index) {
@@ -1,56 +1,26 @@
1
1
  <template>
2
2
  <div :style="$styles()" :class="classes()">
3
3
  <div class="country-code">
4
- <v-select
5
- v-model="countryCode"
6
- :items="sortedCountries"
7
- :disabled="spec.readOnly"
8
- :outlined="$classes().includes('outlined')"
9
- :rounded="$classes().includes('rounded')"
10
- :dense="$classes().includes('dense')"
11
- item-text="name"
12
- item-value="iso2"
13
- return-object
14
- @change="onChangeCountryCode"
15
- >
16
- <template v-slot:selection>
17
- <div :class="activeCountry.iso2.toLowerCase()" class="country_flag" />
18
- </template>
19
- <template v-slot:item="data">
20
- <span :class="data.item.iso2.toLowerCase()" class="country_flag" />
21
- <span>{{ data.item.name }} {{ `+${data.item.dialCode}` }}</span>
22
- </template>
4
+ <v-select v-model="countryCode" :items="sortedCountries" :disabled="spec.readOnly"
5
+ :outlined="$classes().includes('outlined') || null" :rounded="$classes().includes('rounded')"
6
+ :dense="$classes().includes('dense') || null" item-text="name" item-value="iso2" return-object
7
+ @change="onChangeCountryCode">
8
+ <!-- <template v-slot:selection> -->
9
+ <div :class="activeCountry.iso2.toLowerCase()" class="country_flag" />
10
+ <!-- </template> -->
11
+ <!-- <template v-slot:item="data"> -->
12
+ <span :class="data.item.iso2.toLowerCase()" class="country_flag" />
13
+ <span>{{ data.item.name }} {{ `+${data.item.dialCode}` }}</span>
14
+ <!-- </template> -->
23
15
  </v-select>
24
16
  </div>
25
- <v-text-field
26
- :id="inputId"
27
- ref="input"
28
- v-model="phone"
29
- class="tel"
30
- :label="spec.label"
31
- :name="fieldName"
32
- :value="spec.value"
33
- :hint="spec.hint"
34
- :placeholder="spec.placeholder"
35
- :maxlength="spec.maxLength || 25"
36
- :disabled="spec.readOnly"
37
- type="tel"
38
- :rules="hiddenDisplay() ? [] : rules"
39
- :prefix="spec.leftText"
40
- :suffix="spec.rightText"
41
- :outlined="$classes().includes('outlined')"
42
- :dense="$classes().includes('dense')"
43
- :rounded="$classes().includes('rounded')"
44
- :autofocus="spec.autoFocus || false"
45
- validate-on-blur
46
- >
17
+ <v-text-field :id="inputId" ref="input" v-model="phone" class="tel" :label="spec.label" :name="fieldName"
18
+ :hint="spec.hint" :placeholder="spec.placeholder" :maxlength="spec.maxLength || 25" :disabled="spec.readOnly"
19
+ type="tel" :rules="hiddenDisplay() ? [] : rules" :prefix="spec.leftText" :suffix="spec.rightText"
20
+ :outlined="$classes().includes('outlined') || null" :dense="$classes().includes('dense') || null"
21
+ :rounded="$classes().includes('rounded')" :autofocus="spec.autoFocus || false" validate-on="blur">
47
22
  </v-text-field>
48
- <input
49
- v-if="spec.readOnly"
50
- type="hidden"
51
- :name="fieldName"
52
- :value="phone"
53
- />
23
+ <input v-if="spec.readOnly" type="hidden" :name="fieldName" v-model="phone" />
54
24
  </div>
55
25
  </template>
56
26
 
@@ -60,8 +30,8 @@ import allCountries from "./countries";
60
30
 
61
31
  function getCountryByIp() {
62
32
  return fetch("https://ip2c.org/s")
63
- .then(response => response.text())
64
- .then(response => {
33
+ .then((response) => response.text())
34
+ .then((response) => {
65
35
  const result = (response || "").toString();
66
36
  if (!result || result[0] !== "1") {
67
37
  throw new Error("unable to fetch the country");
@@ -74,44 +44,44 @@ export default {
74
44
  props: {
75
45
  spec: {
76
46
  type: Object,
77
- required: true
47
+ required: true,
78
48
  },
79
49
  rules: {
80
50
  type: Array,
81
51
  default: () => [
82
- v =>
52
+ (v) =>
83
53
  !v ||
84
54
  /^\+[1-9]([0-9\(\)\-\ ]*)$/.test(v) ||
85
- "Must be a valid international phone number with prefix (e.g. +1 416 555 0134)"
86
- ]
55
+ "Must be a valid international phone number with prefix (e.g. +1 416 555 0134)",
56
+ ],
87
57
  },
88
58
  disableFetchingCountry: {
89
59
  type: Boolean,
90
- default: () => false
60
+ default: () => false,
91
61
  },
92
62
  mode: {
93
63
  type: String,
94
- default: () => ""
64
+ default: () => "",
95
65
  },
96
66
  allCountries: {
97
67
  type: Array,
98
- default: () => allCountries
68
+ default: () => allCountries,
99
69
  },
100
70
  preferredCountries: {
101
71
  type: Array,
102
- default: () => []
72
+ default: () => [],
103
73
  },
104
74
  inputId: {
105
75
  type: String,
106
- default: () => ""
107
- }
76
+ default: () => "",
77
+ },
108
78
  },
109
79
  data() {
110
80
  return {
111
81
  phone: "",
112
82
  activeCountry: { iso2: "" },
113
83
  selectedIndex: null,
114
- countryCode: null
84
+ countryCode: null,
115
85
  };
116
86
  },
117
87
  computed: {
@@ -130,9 +100,9 @@ export default {
130
100
  },
131
101
  sortedCountries() {
132
102
  // Sort by preferred countries
133
- const preferredCountries = this.getCountries(
134
- this.preferredCountries
135
- ).map(country => ({ ...country, preferred: true }));
103
+ const preferredCountries = this.getCountries(this.preferredCountries).map(
104
+ (country) => ({ ...country, preferred: true })
105
+ );
136
106
  return [...preferredCountries, ...this.allCountries];
137
107
  },
138
108
  phoneObject() {
@@ -142,14 +112,14 @@ export default {
142
112
  ).toJSON();
143
113
  Object.assign(result, {
144
114
  isValid: result.valid,
145
- country: this.activeCountry
115
+ country: this.activeCountry,
146
116
  });
147
117
  if (!this.phone) {
148
118
  return {
149
119
  ...result,
150
120
  number: {
151
- input: ""
152
- }
121
+ input: "",
122
+ },
153
123
  };
154
124
  }
155
125
  return result;
@@ -160,7 +130,7 @@ export default {
160
130
  key = this.parsedMode;
161
131
  }
162
132
  return this.phoneObject.number[key] || "";
163
- }
133
+ },
164
134
  },
165
135
  watch: {
166
136
  phone(val) {
@@ -172,7 +142,7 @@ export default {
172
142
  }
173
143
  }
174
144
  }
175
- }
145
+ },
176
146
  },
177
147
  mounted() {
178
148
  this.initializeCountry()
@@ -190,6 +160,9 @@ export default {
190
160
  }
191
161
  },
192
162
  methods: {
163
+ $ready() {
164
+ this.phone = this.spec.value;
165
+ },
193
166
  hiddenDisplay() {
194
167
  return this.$styles()["display"] == "none";
195
168
  },
@@ -197,7 +170,7 @@ export default {
197
170
  return this.$classes().concat(["g-text-field--hintless", "fields-phone"]);
198
171
  },
199
172
  initializeCountry() {
200
- return new Promise(resolve => {
173
+ return new Promise((resolve) => {
201
174
  // 1. If the phone included prefix (+12), try to get the country and set it
202
175
  if (this.phone && this.phone[0] === "+") {
203
176
  const activeCountry = PhoneNumber(this.phone).getRegionCode();
@@ -221,13 +194,13 @@ export default {
221
194
  // 3. Check if fetching country based on user's IP is allowed, set it as the default country
222
195
  if (!this.disableFetchingCountry) {
223
196
  getCountryByIp()
224
- .then(res => {
197
+ .then((res) => {
225
198
  if (this.phone === "") {
226
199
  this.activeCountry =
227
200
  this.findCountry(res) || this.activeCountry;
228
201
  }
229
202
  })
230
- .catch(error => {
203
+ .catch((error) => {
231
204
  console.warn(error);
232
205
  // 4. Use the first country from preferred list (if available) or all countries list
233
206
  this.choose(fallbackCountry);
@@ -245,24 +218,24 @@ export default {
245
218
  // Get ISO2 code from a list of countries
246
219
  getCountries(list = []) {
247
220
  return list
248
- .map(countryCode => this.findCountry(countryCode))
221
+ .map((countryCode) => this.findCountry(countryCode))
249
222
  .filter(Boolean);
250
223
  },
251
224
  findCountry(iso = "") {
252
225
  return this.allCountries.find(
253
- country => country.iso2 === iso.toUpperCase()
226
+ (country) => country.iso2 === iso.toUpperCase()
254
227
  );
255
228
  },
256
229
  getItemClass(index, iso2) {
257
230
  const highlighted = this.selectedIndex === index;
258
231
  const lastPreferred = index === this.preferredCountries.length - 1;
259
232
  const preferred = this.preferredCountries.some(
260
- c => c.toUpperCase() === iso2
233
+ (c) => c.toUpperCase() === iso2
261
234
  );
262
235
  return {
263
236
  highlighted,
264
237
  "last-preferred": lastPreferred,
265
- preferred
238
+ preferred,
266
239
  };
267
240
  },
268
241
  choose(country) {
@@ -292,13 +265,13 @@ export default {
292
265
  },
293
266
  reset() {
294
267
  this.selectedIndex = this.sortedCountries
295
- .map(c => c.iso2)
268
+ .map((c) => c.iso2)
296
269
  .indexOf(this.activeCountry.iso2);
297
270
  },
298
271
  onChangeCountryCode() {
299
272
  this.choose(this.countryCode, true);
300
- }
301
- }
273
+ },
274
+ },
302
275
  };
303
276
  </script>
304
277
 
@@ -309,6 +282,7 @@ export default {
309
282
  .v-text-field__details {
310
283
  min-height: 0;
311
284
  margin-bottom: 0;
285
+
312
286
  .v-messages__message {
313
287
  min-height: 0;
314
288
  line-height: 14px;
@@ -316,26 +290,33 @@ export default {
316
290
  }
317
291
  }
318
292
  }
293
+
319
294
  .country_flag {
320
295
  margin-right: 8px;
321
296
  }
297
+
322
298
  .fields-phone {
323
299
  display: flex;
324
300
  align-items: center;
301
+
325
302
  .country-code {
326
303
  width: 75px;
327
304
  }
305
+
328
306
  li.last-preferred {
329
307
  border-bottom: 1px solid #cacaca;
330
308
  }
309
+
331
310
  .v-text-field {
332
311
  .v-select__selections {
333
312
  position: relative;
313
+
334
314
  .country_flag {
335
315
  position: absolute;
336
316
  margin-left: 18px;
337
317
  }
338
318
  }
319
+
339
320
  &--outlined {
340
321
  .v-select__selections {
341
322
  .country_flag {
@@ -345,6 +326,7 @@ export default {
345
326
  }
346
327
  }
347
328
  }
329
+
348
330
  .fields-phone.outlined .country-code {
349
331
  margin-right: 6px;
350
332
  }
@@ -1,56 +1,20 @@
1
1
  <template>
2
- <common-tooltip :spec="spec">
3
- <template v-slot:activator="{ on }">
4
- <!-- <common-button :spec="spec" :disabled="$isBusy" :event-handlers="on" /> -->
5
-
6
- <div :class="$classes()">
7
- <!-- <v-tooltip
8
- :disabled="tooltip.disabled"
9
- :top="tooltipPositionMatches('top')"
10
- :right="tooltipPositionMatches('right')"
11
- :bottom="tooltipPositionMatches('bottom')"
12
- :left="tooltipPositionMatches('left')"
13
- >
14
- <template v-slot:activator="{ on }"> -->
15
- <v-radio
16
- :label="spec.label"
17
- :value="spec.value.presence() || vuetifyEmptyString"
18
- :disabled="spec.readOnly"
19
- :on-icon="spec.onIcon"
20
- :off-icon="spec.offIcon"
21
- v-on="on"
22
- @click="$onClick()"
23
- />
24
- <div v-if="spec.childViews" class="radio-childviews">
25
- <div v-for="(item, i) in spec.childViews" :key="i">
26
- <glib-component :spec="item" />
27
- </div>
28
- </div>
29
- <!-- </template>
30
- <span>{{ tooltip.text }}</span>
31
- </v-tooltip> -->
2
+ <div :class="$classes()" :style="$styles()">
3
+ <v-radio :label="spec.label" :value="spec.value.presence() || vuetifyEmptyString" :disabled="spec.readOnly"
4
+ :on-icon="spec.onIcon" :off-icon="spec.offIcon" @click="$onClick()" color="primary" />
5
+ <div v-if="spec.childViews" class="radio-childviews">
6
+ <div v-for="(item, i) in spec.childViews" :key="i">
7
+ <glib-component :spec="item" />
32
8
  </div>
33
- </template>
34
- </common-tooltip>
9
+ </div>
10
+ </div>
35
11
  </template>
36
12
 
37
13
  <script>
38
- // import TooltipMixins from "../mixins/tooltip";
39
14
 
40
15
  export default {
41
- // mixins: [TooltipMixins],
42
16
  props: {
43
17
  spec: { type: Object, required: true }
44
18
  }
45
- // data() {
46
- // return {
47
- // tooltip: {}
48
- // };
49
- // },
50
- // methods: {
51
- // $ready() {
52
- // this.tooltip = this.spec.tooltip || { disabled: true };
53
- // }
54
- // }
55
19
  };
56
20
  </script>
@@ -3,27 +3,13 @@
3
3
  the error can only be removed by submitting the form. But this is better than the alternative, which is radioGroup showing
4
4
  validation error on page load.
5
5
  -->
6
- <v-radio-group
7
- v-model="fieldModel"
8
- :name="fieldName"
9
- :disabled="spec.readOnly"
10
- :rules="$validation()"
11
- :row="spec.row"
12
- validate-on-blur
13
- @change="onChange"
14
- >
15
- <div v-for="(childView, index) in spec.childViews" :key="index">
16
- <div :class="activeClass(childView)" @click="updateValue(childView)">
17
- <glib-component :spec="childView" />
18
- </div>
6
+ <v-radio-group v-model="fieldModel" :name="fieldName" :disabled="spec.readOnly" :rules="$validation()" :row="spec.row"
7
+ validate-on="blur" @change="onChange" :class="$classes()" :style="$styles()">
8
+ <div v-for="(childView, index) in spec.childViews" :key="index" style="width: 100%;">
9
+ <glib-component :spec="childSpec(childView)" @click="updateValue(childView)" />
19
10
  </div>
20
11
 
21
- <input
22
- v-if="spec.readOnly"
23
- type="hidden"
24
- :name="fieldName"
25
- :value="fieldModel"
26
- />
12
+ <input v-if="spec.readOnly" type="hidden" :name="fieldName" :value="fieldModel" />
27
13
  </v-radio-group>
28
14
  </template>
29
15
 
@@ -43,6 +29,17 @@ export default {
43
29
  this.fieldModel = variable.value;
44
30
  }
45
31
  },
32
+ childSpec(childView) {
33
+ const cls = Object.assign({}, childView)
34
+ if (this.activeClass(cls)) {
35
+ if (!cls.styleClasses.includes('radio--active')) {
36
+ cls.styleClasses.push('radio--active')
37
+ }
38
+ } else {
39
+ cls.styleClasses = childView.styleClasses.filter((v) => v != 'radio--active')
40
+ }
41
+ return cls;
42
+ },
46
43
  activeClass(childView) {
47
44
  if (
48
45
  childView.view.includes("fields/radio") &&
@@ -68,6 +65,7 @@ div.v-input--radio-group {
68
65
  div.v-input--radio-group .v-messages {
69
66
  min-height: 0;
70
67
  }
68
+
71
69
  div.v-input--radio-group.v-input--selection-controls .v-input__slot {
72
70
  margin-bottom: 0;
73
71
  }
@@ -1,26 +1,19 @@
1
1
  <template>
2
2
  <div>
3
- <v-rating
4
- v-model="fieldModel"
5
- :name="fieldName"
6
- :value="spec.value"
7
- empty-icon="star_outline"
8
- full-icon="star"
9
- half-icon="star_half"
10
- :half-increments="spec.halfIncrements"
11
- hover
12
- length="5"
13
- :readonly="spec.readOnly"
14
- :color="spec.color"
15
- :background-color="spec.color"
16
- :size="spec.size"
17
- ></v-rating>
3
+ <v-rating v-model="fieldModel" :name="fieldName" empty-icon="star_outline" full-icon="star" half-icon="star_half"
4
+ :half-increments="spec.halfIncrements" hover length="5" :readonly="spec.readOnly" :color="spec.color"
5
+ :bg-color="spec.color" :size="spec.size"></v-rating>
18
6
  <input type="hidden" :name="fieldName" :value="fieldModel" />
19
7
  </div>
20
8
  </template>
21
9
 
22
10
  <script>
23
11
  export default {
24
- props: { spec: { type: Object, required: true } }
12
+ props: { spec: { type: Object, required: true } },
13
+ methos: {
14
+ $ready() {
15
+ this.fieldModel = this.spec.value;
16
+ },
17
+ },
25
18
  };
26
19
  </script>
@@ -8,36 +8,18 @@
8
8
  <v-progress-linear v-if="showProgress" v-model="progress.value" />
9
9
 
10
10
  <!-- Remove the editor to avoid circular updating between this editor and the raw field. -->
11
- <VueEditor
12
- v-if="!rawMode"
13
- id="rich-editor"
14
- v-model="richEditorValue"
15
- :editor-toolbar="customToolbar"
16
- use-custom-image-handler
17
- :editor-options="editorSettings"
18
- @text-change="onRichTextEditorChanged"
19
- @image-added="uploadImage"
20
- />
11
+ <!-- <VueEditor v-if="!rawMode" id="rich-editor" v-model="richEditorValue" :editor-toolbar="customToolbar"
12
+ use-custom-image-handler :editor-options="editorSettings" @text-change="onRichTextEditorChanged"
13
+ @image-added="uploadImage" /> -->
14
+ <QuillEditor v-if="!rawMode" ref="quilEditor" theme="snow" :toolbar="customToolbar" :content="richEditorValue"
15
+ contentType="html" :modules="modules" @textChange="onRichTextEditorChanged" />
21
16
  <!-- Hide these fields but don't remove them because these are the values that will get submitted. -->
22
17
  <div :style="{ display: rawMode ? 'block' : 'none' }">
23
- <v-textarea
24
- id="raw-editor"
25
- v-model="rawEditorValue"
26
- :style="$styles()"
27
- :class="$classes()"
28
- :outlined="$classes().includes('outlined')"
29
- @input="onRawTextEditorChanged"
30
- ></v-textarea>
31
- <v-text-field
32
- v-for="(imageKey, index) in imageKeys"
33
- :key="index"
34
- :label="`Image ${index + 1}`"
35
- :style="$styles()"
36
- :outlined="$classes().includes('outlined')"
37
- type="text"
38
- :name="imageUploader.name"
39
- :value="images[imageKey]"
40
- />
18
+ <v-textarea id="raw-editor" v-model="rawEditorValue" :style="$styles()" :class="$classes()"
19
+ :outlined="$classes().includes('outlined') || null" @input="onRawTextEditorChanged"></v-textarea>
20
+ <v-text-field v-for="(imageKey, index) in imageKeys" :key="index" :label="`Image ${index + 1}`" :style="$styles()"
21
+ :outlined="$classes().includes('outlined') || null" type="text" :name="imageUploader.name"
22
+ :value="images[imageKey]" />
41
23
  </div>
42
24
  <input type="hidden" :name="spec.name" :value="producedValue" />
43
25
  </div>
@@ -45,15 +27,14 @@
45
27
 
46
28
  <script>
47
29
  import Uploader from "../../utils/uploader";
48
- import { VueEditor, Quill } from "vue2-editor";
30
+ import { QuillEditor, Quill } from '@vueup/vue-quill'
31
+
49
32
  import TurndownService from "turndown";
50
33
  import { gfm } from "turndown-plugin-gfm";
51
34
  import eventFiltering from "../../utils/eventFiltering";
52
35
  import QuillImageDropAndPaste from "quill-image-drop-and-paste";
53
36
  import bus from "../../utils/eventBus";
54
37
 
55
- Quill.register("modules/imageDropAndPaste", QuillImageDropAndPaste);
56
-
57
38
  var ImageBlot = Quill.import("formats/image");
58
39
  ImageBlot.sanitize = function (url) {
59
40
  return url;
@@ -170,7 +151,7 @@ class TextEditor {
170
151
  }
171
152
 
172
153
  export default {
173
- components: { VueEditor },
154
+ components: { QuillEditor },
174
155
  props: {
175
156
  spec: { type: Object, required: true },
176
157
  },
@@ -179,21 +160,21 @@ export default {
179
160
  ["bold", "italic", "strike"],
180
161
  [{ header: [false, 1, 2, 3, 4, 5] }],
181
162
  [{ list: "ordered" }, { list: "bullet" }],
182
- ["image", "link"],
163
+ ["link"],
183
164
  ],
184
- editorSettings: {
185
- modules: {
186
- imageDropAndPaste: {
187
- // add an custom image handler
188
- handler: function (imageDataUrl, type, imageData) {
189
- bus.$emit("richText/dropOrPaste", {
190
- file: imageData.toFile(),
191
- editor: this.quill,
192
- cursorLocation: this.getIndex(),
193
- });
194
- },
165
+ modules: {
166
+ name: 'imageDropAndPaste',
167
+ module: QuillImageDropAndPaste,
168
+ options: {
169
+ // add an custom image handler
170
+ handler: function (imageDataUrl, type, imageData) {
171
+ bus.$emit("richText/dropOrPaste", {
172
+ file: imageData.toFile(),
173
+ editor: this.quill,
174
+ cursorLocation: this.getIndex(),
175
+ });
195
176
  },
196
- },
177
+ }
197
178
  },
198
179
  richEditorValue: "",
199
180
  rawEditorValue: "",
@@ -283,6 +264,7 @@ export default {
283
264
  );
284
265
  },
285
266
  onRichTextEditorChanged: eventFiltering.debounce(function () {
267
+ this.richEditorValue = this.$refs.quilEditor.getHTML()
286
268
  this.producedValue = this.textEditor.producedValue(
287
269
  this.richEditorValue,
288
270
  "html",