@vcmap/ui 5.0.0-rc.14 → 5.0.0-rc.16

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 (132) hide show
  1. package/README.md +33 -31
  2. package/build/build.js +9 -0
  3. package/build/buildHelpers.js +12 -10
  4. package/build/commonViteConfig.js +3 -10
  5. package/config/base.config.json +30 -24
  6. package/config/dev.config.json +13 -1
  7. package/config/www.config.json +104 -17
  8. package/dist/assets/cesium.430460.js +137226 -0
  9. package/dist/assets/cesium.js +1 -1
  10. package/dist/assets/core.5089ba.js +16024 -0
  11. package/dist/assets/core.js +1 -1
  12. package/dist/assets/index.854f8e2b.js +1 -0
  13. package/dist/assets/ol.9be53a.js +44279 -0
  14. package/dist/assets/ol.js +1 -1
  15. package/dist/assets/{ui.15ef6a.css → ui.49010a.css} +1 -1
  16. package/dist/assets/ui.49010a.js +16776 -0
  17. package/dist/assets/ui.js +1 -1
  18. package/dist/assets/vue.247c1c.js +4675 -0
  19. package/dist/assets/vue.js +5 -2
  20. package/dist/assets/{vuetify.202322.css → vuetify.735e58.css} +1 -1
  21. package/dist/assets/vuetify.735e58.js +21019 -0
  22. package/dist/assets/vuetify.js +5 -2
  23. package/dist/index.html +1 -1
  24. package/index.html +77 -0
  25. package/index.js +8 -1
  26. package/package.json +12 -10
  27. package/plugins/@vcmap/create-link/fallbackCreateLink.vue +4 -1
  28. package/plugins/@vcmap/create-link/index.js +4 -1
  29. package/plugins/@vcmap/pluginExample/exampleActions.js +45 -0
  30. package/plugins/@vcmap/pluginExample/index.js +38 -1
  31. package/plugins/@vcmap/pluginExample/pluginExampleComponent.vue +152 -98
  32. package/plugins/@vcmap/project-selector/ContextsListComponent.vue +8 -1
  33. package/plugins/@vcmap/project-selector/ProjectSelectorComponent.vue +27 -1
  34. package/plugins/@vcmap/search-nominatim/LICENSE.md +14 -0
  35. package/plugins/@vcmap/search-nominatim/README.md +2 -0
  36. package/plugins/@vcmap/search-nominatim/config.json +4 -0
  37. package/plugins/@vcmap/search-nominatim/index.js +26 -0
  38. package/plugins/@vcmap/search-nominatim/nominatim.js +170 -0
  39. package/plugins/@vcmap/search-nominatim/package.json +43 -0
  40. package/plugins/@vcmap/theme-changer/ThemeChangerComponent.vue +26 -0
  41. package/plugins/buttonExamples/ButtonExamples.vue +28 -1
  42. package/plugins/categoryTest/Categories.vue +16 -0
  43. package/plugins/categoryTest/Category.vue +30 -4
  44. package/plugins/example/mySuperComponent.vue +12 -1
  45. package/plugins/notifier/index.js +31 -0
  46. package/plugins/notifier/notifierTester.vue +88 -0
  47. package/plugins/package.json +2 -1
  48. package/plugins/simple-graph/SimpleGraphComponent.vue +5 -11
  49. package/plugins/test/allIconsComponent.vue +16 -0
  50. package/plugins/test/editor.vue +3 -0
  51. package/plugins/test/emptyComponent.vue +3 -0
  52. package/plugins/test/index.js +22 -0
  53. package/plugins/test/myCustomHeader.vue +9 -1
  54. package/plugins/test/testList.vue +287 -0
  55. package/plugins/test/vcsContent.vue +3 -0
  56. package/plugins/test/windowManagerExample.vue +3 -0
  57. package/plugins/wizardExample/index.js +41 -0
  58. package/plugins/wizardExample/wizardExample.vue +77 -0
  59. package/src/actions/actionHelper.js +103 -2
  60. package/src/actions/styleSelector.vue +9 -0
  61. package/src/application/VcsApp.vue +95 -17
  62. package/src/application/VcsAttributions.vue +63 -0
  63. package/src/application/VcsAttributionsFooter.vue +87 -0
  64. package/src/application/{Navbar.vue → VcsNavbar.vue} +35 -2
  65. package/src/application/VcsSettings.vue +4 -0
  66. package/src/application/attributionsHelper.js +150 -0
  67. package/src/application/vcsAppWrapper.vue +5 -1
  68. package/src/components/buttons/VcsActionButtonList.vue +8 -1
  69. package/src/components/buttons/VcsButton.vue +7 -1
  70. package/src/components/form-inputs-controls/VcsCheckbox.vue +7 -2
  71. package/src/components/form-inputs-controls/VcsColorPicker.vue +4 -0
  72. package/src/components/form-inputs-controls/VcsFormSection.vue +55 -9
  73. package/src/components/form-inputs-controls/VcsRadio.vue +7 -1
  74. package/src/components/form-inputs-controls/VcsSelect.vue +38 -2
  75. package/src/components/form-inputs-controls/VcsTextArea.vue +2 -0
  76. package/src/components/form-inputs-controls/VcsTextField.vue +16 -4
  77. package/src/components/form-inputs-controls/VcsWizard.vue +133 -0
  78. package/src/components/imageElementInjector.vue +22 -0
  79. package/src/components/lists/VcsActionList.vue +12 -1
  80. package/src/components/lists/VcsList.vue +466 -0
  81. package/src/components/lists/VcsTreeview.vue +7 -3
  82. package/src/components/lists/VcsTreeviewLeaf.vue +23 -51
  83. package/src/components/lists/VcsTreeviewSearchbar.vue +6 -23
  84. package/src/components/notification/VcsTooltip.vue +14 -9
  85. package/src/components/tables/VcsTable.vue +129 -38
  86. package/src/contentTree/LayerTree.vue +1 -1
  87. package/src/contentTree/contentTreeItem.js +13 -13
  88. package/src/contentTree/subContentTreeItem.js +1 -1
  89. package/src/contentTree/vcsObjectContentTreeItem.js +1 -1
  90. package/src/featureInfo/AddressBalloonComponent.vue +17 -1
  91. package/src/featureInfo/BalloonComponent.vue +63 -27
  92. package/src/featureInfo/balloonFeatureInfoView.js +14 -14
  93. package/src/featureInfo/balloonHelper.js +4 -0
  94. package/src/featureInfo/featureInfo.js +23 -2
  95. package/src/featureInfo/featureInfoInteraction.js +1 -1
  96. package/src/i18n/de.js +22 -0
  97. package/src/i18n/en.js +22 -0
  98. package/src/icons/+all.js +4 -0
  99. package/src/icons/WandIcon.vue +63 -0
  100. package/src/legend/legendHelper.js +18 -12
  101. package/src/legend/styleLegendItem.vue +20 -1
  102. package/src/legend/vcsLegend.vue +29 -3
  103. package/src/manager/toolbox/GroupToolboxComponent.vue +13 -1
  104. package/src/manager/toolbox/SelectToolboxComponent.vue +13 -1
  105. package/src/manager/toolbox/ToolboxManager.vue +3 -0
  106. package/src/manager/window/WindowComponent.vue +15 -2
  107. package/src/manager/window/WindowComponentHeader.vue +38 -7
  108. package/src/manager/window/WindowManager.vue +1 -0
  109. package/src/manager/window/windowManager.js +11 -1
  110. package/src/navigation/mapNavigation.vue +15 -36
  111. package/src/navigation/orientationToolsButton.vue +6 -1
  112. package/src/navigation/overviewMap.js +19 -47
  113. package/src/navigation/tiltSlider.vue +3 -0
  114. package/src/navigation/vcsCompass.vue +2 -0
  115. package/src/notifier/notifier.js +121 -0
  116. package/src/notifier/notifierComponent.vue +84 -0
  117. package/src/search/resultItem.vue +89 -0
  118. package/src/search/resultsComponent.vue +98 -0
  119. package/src/search/search.js +326 -0
  120. package/src/search/searchComponent.vue +90 -0
  121. package/src/styles/_typography.scss +3 -0
  122. package/src/styles/utils/_cursor.scss +4 -0
  123. package/src/styles/variables.scss +23 -4
  124. package/src/vcsUiApp.js +35 -1
  125. package/src/vuePlugins/vuetify.js +2 -0
  126. package/dist/assets/cesium.9489f8.js +0 -8699
  127. package/dist/assets/core.aa346a.js +0 -4
  128. package/dist/assets/index.3cd4fffa.js +0 -1
  129. package/dist/assets/ol.39651b.js +0 -439
  130. package/dist/assets/ui.15ef6a.js +0 -71
  131. package/dist/assets/vue.cbe9d8.js +0 -9
  132. package/dist/assets/vuetify.202322.js +0 -148
@@ -0,0 +1,466 @@
1
+ <template>
2
+ <div
3
+ class="d-contents"
4
+ >
5
+ <vcs-treeview-searchbar
6
+ v-if="searchable"
7
+ :placeholder="searchbarPlaceholder"
8
+ v-model="query"
9
+ />
10
+ <v-list
11
+ dense
12
+ >
13
+ <v-list-item
14
+ v-if="showTitle"
15
+ class="font-weight-bold"
16
+ >
17
+ <v-list-item-action
18
+ v-if="selectable"
19
+ >
20
+ <v-icon
21
+ v-if="selected.length === renderingItems.length"
22
+ @click="clear"
23
+ >
24
+ mdi-check-circle-outline
25
+ </v-icon>
26
+ <v-icon
27
+ v-else
28
+ @click="selectAll()"
29
+ >
30
+ mdi-circle-outline
31
+ </v-icon>
32
+ </v-list-item-action>
33
+
34
+ <v-list-item-content
35
+ :title="$t(tooltip || title)"
36
+ >
37
+ <v-icon v-if="icon">
38
+ {{ icon }}
39
+ </v-icon>
40
+
41
+ <v-list-item-title>
42
+ {{ $t(title) }}
43
+ </v-list-item-title>
44
+
45
+ <vcs-action-button-list
46
+ v-if="actions?.length > 0"
47
+ :actions="actions"
48
+ :block-overflow="true"
49
+ :overflow-count="actionButtonListOverflowCount"
50
+ small
51
+ right
52
+ />
53
+ </v-list-item-content>
54
+ </v-list-item>
55
+ <v-list-item
56
+ v-for="(item, index) in renderingItems"
57
+ :key="`item-${index}`"
58
+ :input-value="selected.includes(item)"
59
+ :disabled="item.disabled"
60
+ @mousedown.shift="$event.preventDefault()"
61
+ @mouseover="hovering = index"
62
+ @mouseout="hovering = null"
63
+ >
64
+ <v-list-item-action
65
+ v-if="selectable"
66
+ >
67
+ <v-icon
68
+ v-if="selected.includes(item)"
69
+ @click="remove(item)"
70
+ >
71
+ mdi-check-circle-outline
72
+ </v-icon>
73
+ <v-icon
74
+ v-else-if="hovering === index || (!singleSelect && selected.length > 0)"
75
+ @click="singleSelect ? select(item, $event) : add(item)"
76
+ >
77
+ mdi-circle-outline
78
+ </v-icon>
79
+ <v-icon
80
+ v-else
81
+ @click="select(item, $event)"
82
+ >
83
+ mdi-circle-small
84
+ </v-icon>
85
+ </v-list-item-action>
86
+
87
+ <v-list-item-content
88
+ :title="$t(item.tooltip || item.title)"
89
+ :class="[selectable ? 'cursor-pointer' : '']"
90
+ @click="select(item, $event)"
91
+ >
92
+ <v-icon v-if="item.icon">
93
+ {{ item.icon }}
94
+ </v-icon>
95
+
96
+ <v-list-item-title>
97
+ {{ $t(item.title) }}
98
+ </v-list-item-title>
99
+
100
+ <vcs-action-button-list
101
+ v-if="item.actions?.length > 0"
102
+ :actions="item.actions"
103
+ :block-overflow="true"
104
+ :overflow-count="actionButtonListOverflowCount"
105
+ small
106
+ right
107
+ />
108
+ </v-list-item-content>
109
+ </v-list-item>
110
+ </v-list>
111
+ </div>
112
+ </template>
113
+
114
+ <script>
115
+ import { computed, getCurrentInstance, inject, ref, watch } from 'vue';
116
+ import {
117
+ VList,
118
+ VListItem,
119
+ VListItemContent,
120
+ VListItemAction,
121
+ VIcon,
122
+ VListItemTitle,
123
+ } from 'vuetify/lib';
124
+ import VcsActionButtonList from '../buttons/VcsActionButtonList.vue';
125
+ import VcsTreeviewSearchbar from './VcsTreeviewSearchbar.vue';
126
+
127
+ /**
128
+ * @typedef {Object} VcsListItem
129
+ * @property {string} name
130
+ * @property {boolean} [visible] - Whether to display this item or not.
131
+ * @property {boolean} [disabled] - Whether this item should be displayed as disabled.
132
+ * @property {string} title - The title to be displayed
133
+ * @property {string} [tooltip]
134
+ * @property {string|HTMLCanvasElement|HTMLImageElement|undefined} [icon] - An optional icon to display with this item. Can be an URL or HTMLElement.
135
+ * @property {Array<VcsAction>} [actions]
136
+ * @property {function(boolean):void} [selectionChanged] - A callback called if the selection changes with the current selection status. called before value update
137
+ */
138
+
139
+ /**
140
+ * The VCS list is intended to render items. Items can be selectable (by default, more then one) or only a single item can
141
+ * be selected. If items are disabled they cannot selected. Items which are not visible are not rendered. This items can
142
+ * no longer be selected or deselected either. Making a selected item invisible can lead to undefined behavior
143
+ * in the selection state.
144
+ * Clicking an unselected item selects it.
145
+ * Clicking a selected item which is not part of a set or range, deselects it.
146
+ * Clicking a selected item of a list or range will deselect the other items in the range or set
147
+ * Clicking with CTRL adds or removes to a selection set.
148
+ * Clicking with SHIFT will create a selection range, starting or ending with the first item in the list
149
+ * or the last normally selected item (not the last item clicked with CTRL for instance).
150
+ * @vue-prop {Array<VcsListItem>} items
151
+ * @vue-prop {boolean} [selectable=false]
152
+ * @vue-prop {boolean} [singleSelect=false]
153
+ * @vue-prop {Array<VcsListItem>} [value=[]] - the initial items to be selected.
154
+ * @vue-prop {boolean} [searchable=false] - if this list can have its items searched. you can provide your own predicate function by providing "filterPredicate" which is of type function(VcsListItem, string):boolean
155
+ * @vue-prop {string} [searchbarPlaceholder] - placeholder to render inside the search field
156
+ * @vue-prop {boolean} [showTitle=true] - show the title component
157
+ * @vue-prop {number} [actionButtonListOverflowCount] - overflow count to use for action lists in the title and items
158
+ * @vue-prop {string} [title] - the lists title
159
+ * @vue-prop {string} [icon] - icon to prepend to the list title
160
+ * @vue-prop {string} [tooltip] - tooltip to render on the list title
161
+ * @vue-prop {Array<VcsAction>} [actions] - actions to render in the list title
162
+ */
163
+ export default {
164
+ name: 'VcsList',
165
+ components: {
166
+ VcsTreeviewSearchbar,
167
+ VcsActionButtonList,
168
+ VList,
169
+ VListItem,
170
+ VListItemContent,
171
+ VListItemAction,
172
+ VIcon,
173
+ VListItemTitle,
174
+ },
175
+ props: {
176
+ /** @type {Array<VcsListItem>} */
177
+ items: {
178
+ type: Array,
179
+ required: true,
180
+ },
181
+ selectable: {
182
+ type: Boolean,
183
+ default: false,
184
+ },
185
+ singleSelect: {
186
+ type: Boolean,
187
+ default: false,
188
+ },
189
+ /** @type {Array<VcsListItem>} */
190
+ value: {
191
+ type: Array,
192
+ default: () => [],
193
+ },
194
+ searchable: {
195
+ type: Boolean,
196
+ default: false,
197
+ },
198
+ searchbarPlaceholder: {
199
+ type: String,
200
+ default: undefined,
201
+ },
202
+ showTitle: {
203
+ type: Boolean,
204
+ default: true,
205
+ },
206
+ actionButtonListOverflowCount: {
207
+ type: Number,
208
+ required: false,
209
+ default: undefined,
210
+ },
211
+ title: {
212
+ type: String,
213
+ required: false,
214
+ default: '',
215
+ },
216
+ icon: {
217
+ type: String,
218
+ required: false,
219
+ default: undefined,
220
+ },
221
+ tooltip: {
222
+ type: String,
223
+ required: false,
224
+ default: '',
225
+ },
226
+ actions: {
227
+ type: Array,
228
+ required: false,
229
+ default: undefined,
230
+ },
231
+ },
232
+ setup(props, { emit }) {
233
+ /** @type {import("vue").Ref<Array<VcsListItem>>} */
234
+ const selected = ref(props.value);
235
+ /** @type {import("vue").Ref<string>} */
236
+ const query = ref('');
237
+ const hovering = ref(null);
238
+ let firstSelected = null;
239
+
240
+ watch(props, () => {
241
+ if (selected.value !== props.value) {
242
+ selected.value = props.value;
243
+ }
244
+ if (props.singleSelect && selected.value.length > 1) {
245
+ selected.value
246
+ .filter((i, index) => index && i.selectionChanged)
247
+ .forEach(i => i.selectionChanged(false));
248
+ selected.value = [selected.value[0]];
249
+ emit('input', selected);
250
+ }
251
+ if (!props.selectable && selected.value.length > 0) {
252
+ selected.value
253
+ .filter(i => i.selectionChanged)
254
+ .forEach(i => i.selectionChanged(false));
255
+ selected.value = [];
256
+ emit('input', selected);
257
+ }
258
+ if (!props.searchable) {
259
+ query.value = '';
260
+ }
261
+ }, { immediate: true, deep: false });
262
+
263
+ const vm = getCurrentInstance().proxy;
264
+ /** @type {function(VcsListItem, string):boolean} */
265
+ const filterPredicate = inject('filterPredicate', (item, queryString = '') => {
266
+ const translatedTitle = vm.$t(item.title);
267
+ return translatedTitle.toLocaleLowerCase().includes(queryString.toLocaleLowerCase());
268
+ });
269
+
270
+ return {
271
+ query,
272
+ hovering,
273
+ /**
274
+ * @type {import("vue").ComputedRef<Array<VcsListItem>>}
275
+ */
276
+ renderingItems: computed(() => {
277
+ let items = props.items.filter(i => i.visible !== false);
278
+ if (query.value) {
279
+ items = items.filter(i => filterPredicate(i, query.value));
280
+ }
281
+ return items;
282
+ }),
283
+ /** @type {import("vue").Ref<Array<VcsListItem>>} */
284
+ selected,
285
+ /**
286
+ * @param {VcsListItem} item
287
+ * @param {PointerEvent} event
288
+ */
289
+ select(item, event) {
290
+ if (!props.selectable || item.disabled) {
291
+ return;
292
+ }
293
+ if (props.singleSelect) {
294
+ if (selected.value[0] === item) {
295
+ item.selectionChanged?.(false);
296
+ selected.value = [];
297
+ firstSelected = null;
298
+ } else {
299
+ selected.value[0]?.selectionChanged?.(false);
300
+ item.selectionChanged?.(true);
301
+ selected.value = [item];
302
+ firstSelected = item;
303
+ }
304
+ } else if (event.shiftKey) {
305
+ let firstIndex = 0;
306
+ if (firstSelected) {
307
+ firstIndex = this.renderingItems.indexOf(firstSelected);
308
+ }
309
+ const currentIndex = this.renderingItems.indexOf(item);
310
+ if (firstIndex > -1 && currentIndex > -1) {
311
+ const currentSelection = [...selected.value];
312
+ selected.value = this.renderingItems.slice(
313
+ Math.min(firstIndex, currentIndex),
314
+ Math.max(firstIndex, currentIndex) + 1,
315
+ );
316
+ currentSelection.forEach((oldItem) => {
317
+ if (oldItem.selectionChanged && !selected.value.includes(oldItem)) {
318
+ oldItem.selectionChanged(false);
319
+ }
320
+ });
321
+ selected.value.forEach((newItem) => {
322
+ if (newItem.selectionChanged && !currentSelection.includes(newItem)) {
323
+ newItem.selectionChanged(true);
324
+ }
325
+ });
326
+ } else {
327
+ selected.value
328
+ .filter(i => i !== item && i.selectionChanged)
329
+ .forEach(i => i.selectionChanged(false));
330
+ selected.value = [];
331
+ firstSelected = null;
332
+ }
333
+ } else if (selected.value.includes(item)) {
334
+ if (event.ctrlKey) {
335
+ item.selectionChanged?.(false);
336
+ selected.value = selected.value.filter(i => i !== item);
337
+ } else if (selected.value.length > 1) {
338
+ selected.value
339
+ .filter(i => i !== item && i.selectionChanged)
340
+ .forEach(i => i.selectionChanged(false));
341
+ selected.value = [item];
342
+ firstSelected = item;
343
+ } else {
344
+ item.selectionChanged?.(false);
345
+ selected.value = [];
346
+ firstSelected = null;
347
+ }
348
+ } else if (event.ctrlKey) {
349
+ item.selectionChanged?.(true);
350
+ selected.value = [...selected.value, item];
351
+ if (selected.value.length === 1) {
352
+ firstSelected = item;
353
+ }
354
+ } else {
355
+ selected.value
356
+ .filter(i => i !== item && i.selectionChanged)
357
+ .forEach(i => i.selectionChanged(false));
358
+ item.selectionChanged?.(true);
359
+ selected.value = [item];
360
+ firstSelected = item;
361
+ }
362
+
363
+ emit('input', selected.value);
364
+ },
365
+ /**
366
+ * @param {VcsListItem} item
367
+ */
368
+ add(item) {
369
+ if (!selected.value.includes(item) && !item.disabled) {
370
+ item.selectionChanged?.(true);
371
+ selected.value = [...selected.value, item];
372
+ emit('input', selected.value);
373
+ }
374
+ },
375
+ /**
376
+ * @param {VcsListItem} item
377
+ */
378
+ remove(item) {
379
+ if (selected.value.includes(item) && !item.disabled) {
380
+ item.selectionChanged?.(false);
381
+ selected.value = selected.value.filter(i => i !== item);
382
+ emit('input', selected.value);
383
+ }
384
+ },
385
+ clear() {
386
+ selected.value
387
+ .filter(i => i.selectionChanged)
388
+ .forEach(i => i.selectionChanged(false));
389
+ selected.value = [];
390
+ firstSelected = null;
391
+ },
392
+ selectAll() {
393
+ const currentSelection = [...selected.value];
394
+ selected.value = this.renderingItems.slice(0);
395
+ selected.value.forEach((item) => {
396
+ if (item.selectionChanged && currentSelection.includes(item)) {
397
+ item.selectionChanged(true);
398
+ }
399
+ });
400
+ },
401
+ };
402
+ },
403
+ };
404
+ </script>
405
+
406
+ <style lang="scss" scoped>
407
+ ::v-deep {
408
+ .v-list{
409
+ .v-list-item {
410
+ padding: 4px 8px 4px 16px;
411
+ display: grid;
412
+ grid-template-columns: auto 1fr;
413
+ &:after{
414
+ display: none;
415
+ }
416
+ &.font-weight-bold{
417
+ .v-list-item__title{
418
+ font-weight: 700;
419
+ }
420
+ }
421
+ &.v-list-item--active{
422
+ padding: 4px 8px 3px 16px;
423
+ &.theme--light{
424
+ background-color: var(--v-primary-base);
425
+ border-bottom: 1px solid var(--v-primary-darken1);
426
+ }
427
+ }
428
+ &.v-list-item.theme--dark{
429
+ &.v-list-item--active{
430
+ background-color: var(--v-primary-darken1);
431
+ border-bottom: 1px solid var(--v-primary-darken2);
432
+ &:nth-child(even){
433
+ background-color: var(--v-primary-darken1);
434
+ }
435
+ }
436
+ &:nth-child(even){
437
+ background-color: rgba(255, 255, 255, 0.15);
438
+ }
439
+ }
440
+ &:nth-child(even) {
441
+ background-color: var(--v-accent-base);
442
+ }
443
+ .v-list-item__action {
444
+ .v-icon {
445
+ font-size: 16px;
446
+ }
447
+ }
448
+ .v-list-item__content {
449
+ flex-wrap: nowrap;
450
+ column-gap: 4px;
451
+ .v-icon,
452
+ .action-btn-wrap {
453
+ flex: 1 1 auto;
454
+ }
455
+ .v-icon{
456
+ font-size: 16px;
457
+ .v-icon__component{
458
+ width: 16px;
459
+ height: 16px;
460
+ }
461
+ }
462
+ }
463
+ }
464
+ }
465
+ }
466
+ </style>
@@ -13,13 +13,12 @@
13
13
  item-key="name"
14
14
  :search="search"
15
15
  :filter="handleFilter"
16
- :activatable="false"
17
16
  >
18
17
  <template #label="{ item }">
19
18
  <VcsTreeviewLeaf
20
19
  :item="item"
21
20
  :class="[item.clickable ? 'cursor-pointer' : '']"
22
- @click.native="item.clickable && item.clicked()"
21
+ @click.native="item.clickable && item.clicked($event)"
23
22
  />
24
23
  </template>
25
24
  </v-treeview>
@@ -56,6 +55,7 @@
56
55
 
57
56
  <script>
58
57
  import { getCurrentInstance, ref } from 'vue';
58
+ import { VTreeview } from 'vuetify/lib';
59
59
  import VcsTreeviewLeaf from './VcsTreeviewLeaf.vue';
60
60
  import VcsTreeviewSearchbar from './VcsTreeviewSearchbar.vue';
61
61
 
@@ -68,7 +68,11 @@
68
68
  */
69
69
  export default {
70
70
  name: 'VcsTreeview',
71
- components: { VcsTreeviewSearchbar, VcsTreeviewLeaf },
71
+ components: {
72
+ VcsTreeviewSearchbar,
73
+ VcsTreeviewLeaf,
74
+ VTreeview,
75
+ },
72
76
  props: {
73
77
  showSearchbar: {
74
78
  type: Boolean,
@@ -3,21 +3,22 @@
3
3
  class="d-flex flex-row align-center"
4
4
  v-if="item"
5
5
  >
6
- <span v-if="item.icon" class="d-flex align-center">
7
- <v-icon
8
- v-if="iconType === iconTypes.string"
9
- v-text="item.icon"
10
- :size="16"
11
- class="mr-1"
12
- />
13
- <span ref="imgContainer" />
14
- </span>
15
-
16
6
  <div
17
- class="position-relative col-8 pa-0 d-flex align-center treeview-label"
7
+ class="position-relative col-8 pa-0 d-flex align-center vcs-treeview-leaf"
18
8
  :title="$t(item.tooltip || item.title)"
19
9
  >
20
- <span>{{ $t(item.title) }}</span>
10
+ <span
11
+ v-if="item.icon"
12
+ >
13
+ <v-icon
14
+ v-if="isStringIcon"
15
+ v-text="item.icon"
16
+ :size="16"
17
+ class="mr-1"
18
+ />
19
+ <ImageElementInjector :element="item.icon" v-else />
20
+ </span>
21
+ <span class="vcs-treeview-item-title">{{ $t(item.title) }}</span>
21
22
  </div>
22
23
  <VcsActionButtonList
23
24
  v-if="item.actions.length > 0"
@@ -31,7 +32,7 @@
31
32
  </div>
32
33
  </template>
33
34
  <style lang="css" scoped>
34
- .treeview-label span{
35
+ .vcs-treeview-leaf .vcs-treeview-item-title{
35
36
  white-space: nowrap;
36
37
  overflow: hidden;
37
38
  text-overflow: ellipsis;
@@ -39,21 +40,10 @@
39
40
  </style>
40
41
 
41
42
  <script>
42
- import
43
- {
44
- computed,
45
- onMounted,
46
- ref,
47
- } from 'vue';
48
-
43
+ import { computed } from 'vue';
44
+ import { VIcon } from 'vuetify/lib';
49
45
  import VcsActionButtonList from '../buttons/VcsActionButtonList.vue';
50
-
51
-
52
- const iconTypes = {
53
- image: 'HTMLImageElement',
54
- canvas: 'HTMLCanvasElement',
55
- string: 'StringIcon',
56
- };
46
+ import ImageElementInjector from '../imageElementInjector.vue';
57
47
 
58
48
  /**
59
49
  * @description
@@ -62,7 +52,11 @@
62
52
  * @vue-computed {boolean} leaf - Whether the item is a leaf item or not
63
53
  */
64
54
  export default {
65
- components: { VcsActionButtonList },
55
+ components: {
56
+ VcsActionButtonList,
57
+ VIcon,
58
+ ImageElementInjector,
59
+ },
66
60
  props: {
67
61
  item: {
68
62
  type: Object,
@@ -70,32 +64,10 @@
70
64
  },
71
65
  },
72
66
  setup(props) {
73
- const iconType = ref();
74
- const imgContainer = ref();
75
-
76
67
  const leaf = computed(() => props.item?.children?.length === 0);
77
68
 
78
- onMounted(() => { // TODO make icon reactive
79
- const { icon } = props.item;
80
- if (icon) {
81
- if (icon instanceof HTMLImageElement) {
82
- imgContainer.value.appendChild(icon);
83
- iconType.value = iconTypes.image;
84
- }
85
- if (icon instanceof HTMLCanvasElement) {
86
- imgContainer.value.appendChild(icon);
87
- iconType.value = iconTypes.canvas;
88
- }
89
- if (typeof icon === 'string') {
90
- iconType.value = iconTypes.string;
91
- }
92
- }
93
- });
94
-
95
69
  return {
96
- iconTypes,
97
- iconType,
98
- imgContainer,
70
+ isStringIcon: computed(() => typeof props.item.icon === 'string'),
99
71
  leaf,
100
72
  };
101
73
  },
@@ -17,7 +17,7 @@
17
17
  class="searchbar outlined rounded-xl align-center d-flex justify-center white pa-1 pl-6"
18
18
  :placeholder="$t(placeholder)"
19
19
  :value="value"
20
- @input="$event => handleInput($event)"
20
+ v-on="$listeners"
21
21
  clearable
22
22
  />
23
23
  </slot>
@@ -104,11 +104,7 @@
104
104
 
105
105
 
106
106
  <script>
107
- import { onMounted, onUnmounted } from 'vue';
108
-
109
- import { Subject } from 'rxjs';
110
- import { debounceTime } from 'rxjs/operators';
111
-
107
+ import { VIcon, VTextField } from 'vuetify/lib';
112
108
 
113
109
  /**
114
110
  * @description Stylized wrapper around vuetify divider
@@ -117,6 +113,10 @@
117
113
  */
118
114
  export default {
119
115
  name: 'VcsTreeviewSearchbar',
116
+ components: {
117
+ VIcon,
118
+ VTextField,
119
+ },
120
120
  props: {
121
121
  placeholder: {
122
122
  type: String,
@@ -135,22 +135,5 @@
135
135
  default: false,
136
136
  },
137
137
  },
138
- setup(props, context) {
139
- const sub = new Subject();
140
- onMounted(() => {
141
- sub.pipe(debounceTime(330)).subscribe(
142
- (value) => {
143
- context.emit('input', value);
144
- },
145
- );
146
- });
147
- onUnmounted(() => sub.unsubscribe());
148
-
149
- return {
150
- handleInput: (val) => {
151
- sub.next(val);
152
- },
153
- };
154
- },
155
138
  };
156
139
  </script>
@@ -110,15 +110,17 @@
110
110
  </style>
111
111
  <script>
112
112
 
113
- /**
114
- * @enum {string} TooltipPositions
115
- * @property {string} bottom
116
- * @property {string} left
117
- * @property {string} top
118
- * @property {string} right
119
- * @readonly
120
- * @module VcsTooltip
121
- */
113
+ import { VTooltip } from 'vuetify/lib';
114
+
115
+ /**
116
+ * @enum {string} TooltipPositions
117
+ * @property {string} bottom
118
+ * @property {string} left
119
+ * @property {string} top
120
+ * @property {string} right
121
+ * @readonly
122
+ * @module VcsTooltip
123
+ */
122
124
  const TooltipPositions = {
123
125
  bottom: 'arrow-top',
124
126
  top: 'arrow-bottom',
@@ -134,6 +136,9 @@
134
136
  */
135
137
  export default {
136
138
  name: 'VcsTooltip',
139
+ components: {
140
+ VTooltip,
141
+ },
137
142
  props: {
138
143
  tooltip: {
139
144
  type: String,