@vcmap/ui 6.1.0-rc.1 → 6.1.0-rc.3

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 (128) hide show
  1. package/config/base.config.json +6 -0
  2. package/config/clipping.config.json +384 -0
  3. package/config/cluster.config.json +106 -0
  4. package/config/concepts-show-case.config.json +4 -0
  5. package/config/projects.config.json +5 -2
  6. package/dist/assets/{cesium-11e5bbc6.js → cesium-87d5e72d.js} +438 -432
  7. package/dist/assets/cesium.js +1 -1
  8. package/dist/assets/{core-9d0cfec3.js → core-72f9f393.js} +4907 -4514
  9. package/dist/assets/core.js +1 -1
  10. package/dist/assets/{ol-0d0ebb27.js → ol-e468ba43.js} +23518 -22404
  11. package/dist/assets/ol.js +1 -1
  12. package/dist/assets/ui-73257b15.css +1 -0
  13. package/dist/assets/{ui-08446666.js → ui-73257b15.js} +13703 -12977
  14. package/dist/assets/ui.js +1 -1
  15. package/dist/assets/vue.js +1 -1
  16. package/dist/assets/{vuetify-67025c41.css → vuetify-2437380c.css} +2 -2
  17. package/dist/assets/{vuetify-67025c41.js → vuetify-2437380c.js} +8024 -7634
  18. package/dist/assets/vuetify.js +1 -1
  19. package/index.d.ts +40 -19
  20. package/index.js +36 -6
  21. package/lib/olLib.js +25 -3
  22. package/package.json +6 -6
  23. package/plugins/@vcmap-show-case/callback-tester/README.md +3 -0
  24. package/plugins/@vcmap-show-case/callback-tester/package.json +5 -0
  25. package/plugins/@vcmap-show-case/callback-tester/src/CallbackTester.vue +62 -0
  26. package/plugins/@vcmap-show-case/callback-tester/src/index.js +48 -0
  27. package/plugins/@vcmap-show-case/form-inputs-example/src/FormInputsExample.vue +1 -0
  28. package/src/actions/actionHelper.d.ts +1 -0
  29. package/src/actions/actionHelper.js +70 -19
  30. package/src/application/VcsApp.vue +83 -50
  31. package/src/application/VcsApp.vue.d.ts +28 -2
  32. package/src/application/VcsContainer.vue +5 -3
  33. package/src/application/VcsContainer.vue.d.ts +14 -0
  34. package/src/application/VcsNavbar.vue +10 -6
  35. package/src/application/VcsNavbar.vue.d.ts +2 -0
  36. package/src/application/VcsObliqueFooter.vue +9 -3
  37. package/src/application/VcsSplashScreen.vue +37 -0
  38. package/src/application/VcsSplashScreen.vue.d.ts +6 -0
  39. package/src/application/positionDisplayInteraction.js +1 -1
  40. package/src/callback/activateClippingPolygonCallback.d.ts +29 -0
  41. package/src/callback/activateClippingPolygonCallback.js +54 -0
  42. package/src/callback/closeSplashScreenCallback.d.ts +8 -0
  43. package/src/callback/closeSplashScreenCallback.js +33 -0
  44. package/src/callback/deactivateClippingPolygonCallback.d.ts +29 -0
  45. package/src/callback/deactivateClippingPolygonCallback.js +54 -0
  46. package/src/callback/openSplashScreenCallback.d.ts +8 -0
  47. package/src/callback/openSplashScreenCallback.js +35 -0
  48. package/src/callback/toggleNavbarButtonCallback.d.ts +36 -0
  49. package/src/callback/toggleNavbarButtonCallback.js +62 -0
  50. package/src/components/buttons/VcsActionButtonList.vue +6 -4
  51. package/src/components/buttons/VcsToolButton.vue +0 -1
  52. package/src/components/form-inputs-controls/VcsDatePicker.vue +7 -1
  53. package/src/components/form-inputs-controls/VcsDatePicker.vue.d.ts +9 -0
  54. package/src/components/form-inputs-controls/VcsSelect.vue +1 -1
  55. package/src/components/form-inputs-controls/VcsTextArea.vue +13 -8
  56. package/src/components/form-output/markdownHelper.d.ts +0 -25
  57. package/src/components/form-output/markdownHelper.js +1 -386
  58. package/src/components/import/VcsImportComponent.vue +2 -0
  59. package/src/components/lists/VcsGroupedList.vue +178 -0
  60. package/src/components/lists/VcsGroupedList.vue.d.ts +17 -0
  61. package/src/components/lists/VcsList.vue +144 -394
  62. package/src/components/lists/VcsList.vue.d.ts +38 -159
  63. package/src/components/lists/VcsTreeNode.vue +18 -11
  64. package/src/components/lists/VcsTreeview.vue +27 -20
  65. package/src/components/lists/VcsTreeview.vue.d.ts +18 -1
  66. package/src/components/lists/listHelper.d.ts +87 -0
  67. package/src/components/lists/listHelper.js +348 -0
  68. package/src/components/section/VcsFormSection.vue +7 -2
  69. package/src/components/section/VcsFormSection.vue.d.ts +9 -0
  70. package/src/components/tables/VcsDataTable.vue +14 -3
  71. package/src/components/tables/VcsDataTable.vue.d.ts +9 -0
  72. package/src/components/vector-properties/VcsVectorPropertiesComponent.vue.d.ts +1 -1
  73. package/src/contentTree/LayerTree.vue +2 -1
  74. package/src/contentTree/LayerTree.vue.d.ts +2 -0
  75. package/src/contentTree/contentTreeCollection.d.ts +1 -0
  76. package/src/contentTree/contentTreeCollection.js +7 -3
  77. package/src/contentTree/contentTreeItem.js +4 -2
  78. package/src/contentTree/groupContentTreeItem.js +5 -3
  79. package/src/featureInfo/ClusterFeatureComponent.vue +58 -0
  80. package/src/featureInfo/ClusterFeatureComponent.vue.d.ts +6 -0
  81. package/src/featureInfo/abstractFeatureInfoView.js +1 -2
  82. package/src/featureInfo/featureInfo.d.ts +87 -1
  83. package/src/featureInfo/featureInfo.js +342 -34
  84. package/src/featureInfo/featureInfoInteraction.js +18 -3
  85. package/src/featureInfo/iframeFeatureInfoView.js +1 -1
  86. package/src/featureInfo/markdownBalloonFeatureInfoView.js +2 -4
  87. package/src/featureInfo/markdownFeatureInfoView.js +1 -1
  88. package/src/i18n/de.d.ts +17 -4
  89. package/src/i18n/de.js +7 -0
  90. package/src/i18n/en.d.ts +17 -4
  91. package/src/i18n/en.js +7 -0
  92. package/src/legend/VcsLegend.vue +1 -1
  93. package/src/legend/legendHelper.d.ts +1 -1
  94. package/src/legend/legendHelper.js +52 -9
  95. package/src/localStorage.d.ts +21 -0
  96. package/src/localStorage.js +51 -0
  97. package/src/manager/collectionManager/CollectionComponent.vue +1 -1
  98. package/src/manager/collectionManager/CollectionComponentContent.vue +2 -3
  99. package/src/manager/collectionManager/CollectionComponentList.vue +2 -3
  100. package/src/manager/collectionManager/CollectionComponentStandalone.vue +1 -1
  101. package/src/manager/navbarManager.js +9 -4
  102. package/src/manager/toolbox/ToolboxManagerComponent.vue +14 -12
  103. package/src/manager/toolbox/ToolboxManagerComponent.vue.d.ts +13 -2
  104. package/src/manager/toolbox/toolboxManager.d.ts +5 -0
  105. package/src/manager/toolbox/toolboxManager.js +7 -1
  106. package/src/manager/window/WindowComponent.vue +10 -0
  107. package/src/manager/window/WindowComponent.vue.d.ts +1 -0
  108. package/src/manager/window/WindowManager.vue +14 -4
  109. package/src/manager/window/WindowManager.vue.d.ts +1 -0
  110. package/src/manager/window/windowHelper.d.ts +7 -3
  111. package/src/manager/window/windowHelper.js +30 -10
  112. package/src/navigation/MapNavigation.vue +5 -5
  113. package/src/navigation/MapNavigation.vue.d.ts +1 -1
  114. package/src/navigation/overviewMap.d.ts +7 -0
  115. package/src/navigation/overviewMap.js +18 -4
  116. package/src/pluginHelper.d.ts +7 -0
  117. package/src/pluginHelper.js +18 -4
  118. package/src/search/ResultItem.vue.d.ts +1 -1
  119. package/src/search/markText.d.ts +1 -1
  120. package/src/search/markText.js +4 -4
  121. package/src/search/search.js +1 -1
  122. package/src/state.d.ts +4 -2
  123. package/src/state.js +54 -31
  124. package/src/uiConfig.d.ts +36 -0
  125. package/src/uiConfig.js +17 -1
  126. package/src/vcsUiApp.js +7 -11
  127. package/dist/assets/ui-08446666.css +0 -1
  128. /package/dist/assets/{vue-2f81c7f8.js → vue-ff37ea23.js} +0 -0
@@ -0,0 +1,348 @@
1
+ import { computed, isReactive, reactive, ref, shallowRef, watch } from 'vue';
2
+
3
+ /**
4
+ * @param {import("vue").Ref<import("./VcsListItemComponent.vue").VcsListItem[]>} items
5
+ * @param {import("vue").ShallowRef<import("./VcsListItemComponent.vue").VcsListItem[]>} selected
6
+ * @param {(event: 'update:modelValue', value: import("./VcsListItemComponent.vue").VcsListItem[]) => void} emit
7
+ * @returns {Array<import("../../actions/actionHelper.js").VcsAction>}
8
+ */
9
+ export function createSelectionActions(items, selected, emit) {
10
+ const selectAllAction = reactive({
11
+ name: 'list.selectAll',
12
+ tooltip: 'list.selectAll',
13
+ disabled: computed(() => items.value.length - selected.value.length < 1),
14
+ callback() {
15
+ const currentSelection = [...selected.value];
16
+ selected.value = items.value.filter((item) => !item.disabled);
17
+
18
+ selected.value.forEach((item) => {
19
+ if (item.selectionChanged && !currentSelection.includes(item)) {
20
+ item.selectionChanged(true);
21
+ }
22
+ });
23
+ emit('update:modelValue', selected.value);
24
+ },
25
+ });
26
+
27
+ const clearSelectionAction = reactive({
28
+ name: 'list.clearSelection',
29
+ tooltip: 'list.clearSelection',
30
+ disabled: computed(() => selected.value.length < 1),
31
+ callback() {
32
+ [...selected.value].forEach((item) => {
33
+ if (item.selectionChanged) {
34
+ item.selectionChanged(false);
35
+ }
36
+ });
37
+ selected.value = [];
38
+ emit('update:modelValue', selected.value);
39
+ },
40
+ });
41
+
42
+ return [selectAllAction, clearSelectionAction];
43
+ }
44
+
45
+ /**
46
+ * @typedef {Object & {
47
+ * selectable?: boolean,
48
+ * singleSelect?: boolean,
49
+ * selectFunction?: (item: import("vue").UnwrapNestedRefs<import("./VcsListItemComponent.vue").VcsListItem>, event: PointerEvent) => void,
50
+ * modelValue?: Array<import("./VcsListItemComponent.vue").VcsListItem> }
51
+ * } SelectableListProps
52
+ * @property {boolean?} selectable
53
+ * @property {boolean?} singleSelect
54
+ * @property {(item: import("vue").UnwrapNestedRefs<import("./VcsListItemComponent.vue").VcsListItem>, event: PointerEvent) => void} selectFunction
55
+ * @property {Array<import("./VcsListItemComponent.vue").VcsListItem>?} modelValue
56
+ */
57
+
58
+ /**
59
+ * @typedef {{
60
+ * selected: import("vue").ShallowRef<Array<import("./VcsListItemComponent.vue").VcsListItem>>,
61
+ * select: (item: import("vue").UnwrapNestedRefs<import("./VcsListItemComponent.vue").VcsListItem>, event: PointerEvent) => void,
62
+ * selectionActions:Array<import("../../actions/actionHelper.js").VcsAction>
63
+ * }} SelectableListSetup
64
+ */
65
+
66
+ /**
67
+ * Function setting up selection logic for lists. Use only in setup function of components!
68
+ * This requires VcsListItems with unique keys (name property).
69
+ * @param {Object & SelectableListProps} props
70
+ * @param {import("vue").ComputedRef<Array<import("./VcsListItemComponent.vue").VcsListItem>>} renderingItems
71
+ * @param {(event: 'update:modelValue', value: import("./VcsListItemComponent.vue").VcsListItem[]) => void} emit
72
+ * @returns {SelectableListSetup}
73
+ */
74
+ export function setupSelectableList(props, renderingItems, emit) {
75
+ /** @type {import("vue").ShallowRef<Array<import("./VcsListItemComponent.vue").VcsListItem>>} */
76
+ const selected = shallowRef([]);
77
+
78
+ watch(
79
+ props,
80
+ () => {
81
+ if (selected.value !== props.modelValue) {
82
+ selected.value = props.modelValue;
83
+ }
84
+ if (props.singleSelect && selected.value.length > 1) {
85
+ selected.value
86
+ .filter((i, index) => index && i.selectionChanged)
87
+ .forEach((i) => i.selectionChanged(false));
88
+ selected.value = [selected.value[0]];
89
+ emit('update:modelValue', selected);
90
+ }
91
+ if (!props.selectable && selected.value.length > 0) {
92
+ selected.value
93
+ .filter((i) => i.selectionChanged)
94
+ .forEach((i) => i.selectionChanged(false));
95
+ selected.value = [];
96
+ emit('update:modelValue', selected);
97
+ }
98
+ },
99
+ { immediate: true, deep: false },
100
+ );
101
+
102
+ const selectionActions = createSelectionActions(
103
+ renderingItems,
104
+ selected,
105
+ emit,
106
+ );
107
+
108
+ let firstSelected;
109
+
110
+ return {
111
+ selected,
112
+ select:
113
+ props.selectFunction ||
114
+ ((item, event) => {
115
+ if (!props.selectable || item.disabled) {
116
+ return;
117
+ }
118
+ if (!isReactive(item)) {
119
+ throw new Error('Trying to select an unreactive item');
120
+ }
121
+ if (Array.isArray(item.clickedCallbacks)) {
122
+ item.clickedCallbacks.forEach((cb) => cb(event));
123
+ }
124
+ if (props.singleSelect) {
125
+ if (selected.value[0] === item) {
126
+ item.selectionChanged?.(false);
127
+ selected.value = [];
128
+ firstSelected = null;
129
+ } else {
130
+ selected.value[0]?.selectionChanged?.(false);
131
+ item.selectionChanged?.(true);
132
+ selected.value = [item];
133
+ firstSelected = item;
134
+ }
135
+ } else if (event.shiftKey) {
136
+ let firstIndex = 0;
137
+ if (firstSelected) {
138
+ firstIndex = renderingItems.value.indexOf(firstSelected);
139
+ }
140
+ const currentIndex = renderingItems.value.indexOf(item);
141
+ if (firstIndex > -1 && currentIndex > -1) {
142
+ const currentSelection = [...selected.value];
143
+ selected.value = renderingItems.value.slice(
144
+ Math.min(firstIndex, currentIndex),
145
+ Math.max(firstIndex, currentIndex) + 1,
146
+ );
147
+ currentSelection.forEach((oldItem) => {
148
+ if (
149
+ oldItem.selectionChanged &&
150
+ !selected.value.includes(oldItem)
151
+ ) {
152
+ oldItem.selectionChanged(false);
153
+ }
154
+ });
155
+ selected.value.forEach((newItem) => {
156
+ if (
157
+ newItem.selectionChanged &&
158
+ !currentSelection.includes(newItem)
159
+ ) {
160
+ newItem.selectionChanged(true);
161
+ }
162
+ });
163
+ } else {
164
+ selected.value
165
+ .filter((i) => i !== item && i.selectionChanged)
166
+ .forEach((i) => i.selectionChanged(false));
167
+ selected.value = [];
168
+ firstSelected = null;
169
+ }
170
+ } else if (selected.value.includes(item)) {
171
+ if (event.ctrlKey) {
172
+ item.selectionChanged?.(false);
173
+ selected.value = selected.value.filter((i) => i !== item);
174
+ } else if (selected.value.length > 1) {
175
+ selected.value
176
+ .filter((i) => i !== item && i.selectionChanged)
177
+ .forEach((i) => {
178
+ i.selectionChanged(false);
179
+ });
180
+ selected.value = [item];
181
+ firstSelected = item;
182
+ } else {
183
+ item.selectionChanged?.(false);
184
+ selected.value = [];
185
+ firstSelected = null;
186
+ }
187
+ } else if (event.ctrlKey) {
188
+ item.selectionChanged?.(true);
189
+ selected.value = [...selected.value, item];
190
+ if (selected.value.length === 1) {
191
+ firstSelected = item;
192
+ }
193
+ } else {
194
+ selected.value
195
+ .filter((i) => i !== item && i.selectionChanged)
196
+ .forEach((i) => i.selectionChanged(false));
197
+ item.selectionChanged?.(true);
198
+ selected.value = [item];
199
+ firstSelected = item;
200
+ }
201
+
202
+ emit('update:modelValue', selected.value);
203
+ }),
204
+ selectionActions,
205
+ };
206
+ }
207
+
208
+ /**
209
+ * @typedef {{
210
+ * hovering: import("vue").Ref<number|undefined>,
211
+ * dragging: import("vue").Ref<number|undefined>,
212
+ * isDraggable: import("vue").ComputedRef<boolean>,
213
+ * borderBottom: (index: number) => boolean,
214
+ * borderTop: (index: number) => boolean,
215
+ * dragStart: (
216
+ * e: MouseEvent,
217
+ * item: import('./VcsListItemComponent.vue').VcsListItem,
218
+ * index: number,
219
+ * ) => void;
220
+ * dragOver: (e: MouseEvent, index: number) => void;
221
+ * dragLeave: (e: MouseEvent) => void;
222
+ * dragEnd: (e: MouseEvent) => void;
223
+ * drop: (e: MouseEvent, targetIndex: number) => void;
224
+ * }} DraggableListSetup
225
+ */
226
+
227
+ /**
228
+ * Function setting up drag logic for lists. Use only in setup function of components!
229
+ * This requires VcsListItems with unique keys (name property).
230
+ * @param {Object & { draggable: boolean }} props
231
+ * @param {import("vue").Ref<string>} query
232
+ * @param {(event: 'itemMoved', value: import("./VcsList.vue").ItemMovedEvent) => void} emit
233
+ * @returns {DraggableListSetup}
234
+ */
235
+ export function setupDraggableList(props, query, emit) {
236
+ /** @type {import("vue").Ref<number|undefined>} */
237
+ const hovering = ref(undefined);
238
+ /** @type {import("vue").Ref<number|undefined>} */
239
+ const dragging = ref(undefined);
240
+
241
+ /**
242
+ * @param {number} index
243
+ * @returns {boolean}
244
+ */
245
+ function borderBottom(index) {
246
+ return (
247
+ dragging.value !== undefined &&
248
+ dragging.value < index &&
249
+ index === hovering.value
250
+ );
251
+ }
252
+
253
+ /**
254
+ * @param {number} index
255
+ * @returns {boolean}
256
+ */
257
+ function borderTop(index) {
258
+ return (
259
+ dragging.value !== undefined &&
260
+ dragging.value > index &&
261
+ index === hovering.value
262
+ );
263
+ }
264
+
265
+ /**
266
+ * @type {import("./VcsListItemComponent.vue").VcsListItem|null}
267
+ */
268
+ let draggedItem = null;
269
+
270
+ /**
271
+ * @type {import("vue").ComputedRef<boolean>}
272
+ */
273
+ const isDraggable = computed(() => {
274
+ return !query.value && props.draggable;
275
+ });
276
+
277
+ /**
278
+ * @param {MouseEvent} e
279
+ * @param {number} targetIndex
280
+ */
281
+ function drop(e, targetIndex) {
282
+ if (isDraggable.value) {
283
+ if (draggedItem !== null && targetIndex !== undefined) {
284
+ emit('itemMoved', { item: draggedItem, targetIndex });
285
+ }
286
+ draggedItem = null;
287
+ dragging.value = undefined;
288
+ hovering.value = undefined;
289
+ }
290
+ }
291
+
292
+ /**
293
+ * @param {MouseEvent} e
294
+ * @param {import("./VcsListItemComponent.vue").VcsListItem} item
295
+ * @param {number} index
296
+ */
297
+ function dragStart(e, item, index) {
298
+ e.stopPropagation();
299
+ if (isDraggable.value) {
300
+ dragging.value = index;
301
+ draggedItem = item;
302
+ e.dataTransfer.effectAllowed = 'move';
303
+ }
304
+ }
305
+
306
+ /**
307
+ * @param {MouseEvent} e
308
+ * @param {number} index
309
+ */
310
+ function dragOver(e, index) {
311
+ e.stopPropagation();
312
+ e.preventDefault();
313
+ if (isDraggable.value) {
314
+ hovering.value = index;
315
+ }
316
+ }
317
+
318
+ /**
319
+ * @param {MouseEvent} e
320
+ */
321
+ function dragLeave(e) {
322
+ e.stopPropagation();
323
+ e.preventDefault();
324
+ hovering.value = undefined;
325
+ }
326
+
327
+ /**
328
+ * @param {MouseEvent} e
329
+ */
330
+ function dragEnd(e) {
331
+ e.stopPropagation();
332
+ dragging.value = undefined;
333
+ hovering.value = undefined;
334
+ }
335
+
336
+ return {
337
+ hovering,
338
+ dragging,
339
+ isDraggable,
340
+ borderBottom,
341
+ borderTop,
342
+ dragStart,
343
+ dragOver,
344
+ dragLeave,
345
+ dragEnd,
346
+ drop,
347
+ };
348
+ }
@@ -64,6 +64,7 @@
64
64
  * @vue-prop {Array<VcsAction>} headerActions - Icons to be displayed on the right side
65
65
  * @vue-prop {number} [actionButtonListOverflowCount] - overflow count to use for action lists in the title and items
66
66
  * @vue-prop {string} [helpText] - Optional help text. Must be plain string. Use 'help' slot for html based help texts. Help slot has precedence over helpText prop.
67
+ * @vue-prop {boolean} [startHelpOpen=false] - If help text starts open.
67
68
  * @vue-computed {Array<VcsAction>} actions - Returns header actions extended by a help action, if help prop is passed or help slot is used.
68
69
  */
69
70
  export default {
@@ -104,6 +105,10 @@
104
105
  type: String,
105
106
  default: undefined,
106
107
  },
108
+ startHelpOpen: {
109
+ type: Boolean,
110
+ default: false,
111
+ },
107
112
  },
108
113
  setup(props, { slots }) {
109
114
  const open = ref(props.startOpen);
@@ -116,7 +121,7 @@
116
121
  const helpAction = reactive({
117
122
  name: 'help',
118
123
  title: 'components.vcsFormSection.help',
119
- active: false,
124
+ active: props.startHelpOpen,
120
125
  icon: 'mdi-help-circle',
121
126
  callback() {
122
127
  this.active = !this.active;
@@ -128,7 +133,7 @@
128
133
  */
129
134
  const actions = computed(() => {
130
135
  if (props.helpText || (slots.help && slots.help().length > 0)) {
131
- return [helpAction, ...props.headerActions];
136
+ return [...props.headerActions, helpAction];
132
137
  }
133
138
  return props.headerActions;
134
139
  });
@@ -28,6 +28,10 @@ declare const _default: import("vue").DefineComponent<{
28
28
  type: StringConstructor;
29
29
  default: undefined;
30
30
  };
31
+ startHelpOpen: {
32
+ type: BooleanConstructor;
33
+ default: boolean;
34
+ };
31
35
  }, {
32
36
  open: import("vue").Ref<boolean>;
33
37
  showContent: import("vue").ComputedRef<boolean>;
@@ -64,6 +68,10 @@ declare const _default: import("vue").DefineComponent<{
64
68
  type: StringConstructor;
65
69
  default: undefined;
66
70
  };
71
+ startHelpOpen: {
72
+ type: BooleanConstructor;
73
+ default: boolean;
74
+ };
67
75
  }>>, {
68
76
  disabled: boolean;
69
77
  headerActions: unknown[];
@@ -72,5 +80,6 @@ declare const _default: import("vue").DefineComponent<{
72
80
  helpText: string;
73
81
  expandable: boolean;
74
82
  startOpen: boolean;
83
+ startHelpOpen: boolean;
75
84
  }, {}>;
76
85
  export default _default;
@@ -168,6 +168,7 @@
168
168
  * @vue-prop {boolean} [showSearchbar=true] - whether to show searchbar
169
169
  * @vue-prop {string} [searchbarPlaceholder] - placeholder for searchbar
170
170
  * @vue-prop {string} [itemSelectable='isSelectable'] - The property on each item that is used to determine if it is selectable or not. Non-selectable items are automatically disabled.
171
+ * @vue-prop {function(any, string|undefined, TableItem):boolean} [customFilter] - a function to customize filtering when searching. The first parameter represents the item values, with the function called for each of them. The second is the search term. The third is the complete item.
171
172
  * @vue-event {UpdateItemsEvent} update:items - Emits when one of the options properties is updated or on search input. Can be used to update items via API call to a server.
172
173
  * @vue-computed {Array<TableItem>} filteredItems - array of items with search filter applied on. If search string is empty, same as items array.
173
174
  * @vue-computed {Array<import("vuetify").DataTableHeader>} translatedHeaders - array of translated header items.
@@ -232,6 +233,10 @@
232
233
  type: String,
233
234
  default: 'isSelectable',
234
235
  },
236
+ customFilter: {
237
+ type: Function,
238
+ default: undefined,
239
+ },
235
240
  },
236
241
  setup(props, { attrs, emit, slots }) {
237
242
  const vm = getCurrentInstance().proxy;
@@ -272,6 +277,9 @@
272
277
  * @returns {boolean}
273
278
  */
274
279
  const handleFilter = (value, filter, item) => {
280
+ if (props.customFilter) {
281
+ return props.customFilter(value, filter, item.raw);
282
+ }
275
283
  return handleFilterInternal(value, filter, item.raw);
276
284
  };
277
285
 
@@ -300,9 +308,12 @@
300
308
  * @type {ComputedRef<Array<Object>>}
301
309
  */
302
310
  const filteredItems = computed(() =>
303
- props.items.filter((item) =>
304
- handleFilterInternal(item.value, search.value, item),
305
- ),
311
+ props.items.filter((item) => {
312
+ if (props.customFilter) {
313
+ return props.customFilter(item.value, search.value, item);
314
+ }
315
+ return handleFilterInternal(item.value, search.value, item);
316
+ }),
306
317
  );
307
318
  const numberOfItems = computed(() => {
308
319
  if (props.serverItemsLength > -1) {
@@ -40,6 +40,10 @@ declare const _default: import("vue").DefineComponent<{
40
40
  type: StringConstructor;
41
41
  default: string;
42
42
  };
43
+ customFilter: {
44
+ type: FunctionConstructor;
45
+ default: undefined;
46
+ };
43
47
  }, {
44
48
  hovering: import("vue").Ref<null>;
45
49
  search: Ref<UnwrapRef<string>>;
@@ -102,8 +106,13 @@ declare const _default: import("vue").DefineComponent<{
102
106
  type: StringConstructor;
103
107
  default: string;
104
108
  };
109
+ customFilter: {
110
+ type: FunctionConstructor;
111
+ default: undefined;
112
+ };
105
113
  }>>, {
106
114
  items: unknown[];
115
+ customFilter: Function;
107
116
  showSearchbar: boolean;
108
117
  searchbarPlaceholder: string;
109
118
  headers: unknown[];
@@ -218,7 +218,7 @@ declare const _default: import("vue").DefineComponent<{
218
218
  getPrimitiveOptions: (feature: import("ol/Feature.js", { with: { "resolution-mode": "import" } }).default<import("ol/geom.js", { with: { "resolution-mode": "import" } }).Geometry>) => import("@vcmap/core", { with: { "resolution-mode": "import" } }).VectorPropertiesPrimitiveOptions<import("@vcmap/core", { with: { "resolution-mode": "import" } }).PrimitiveOptionsType> | undefined;
219
219
  getPrimitive: (feature: import("ol/Feature.js", { with: { "resolution-mode": "import" } }).default<import("ol/geom.js", { with: { "resolution-mode": "import" } }).Geometry>) => import("@vcmap/core", { with: { "resolution-mode": "import" } }).VectorPropertiesPrimitive | null;
220
220
  getModel: (feature: import("ol/Feature.js", { with: { "resolution-mode": "import" } }).default<import("ol/geom.js", { with: { "resolution-mode": "import" } }).Geometry>) => import("@vcmap/core", { with: { "resolution-mode": "import" } }).VectorPropertiesModelOptions | null;
221
- renderAs: (feature: import("ol/Feature.js", { with: { "resolution-mode": "import" } }).default<import("ol/geom.js", { with: { "resolution-mode": "import" } }).Geometry>) => "geometry" | "model" | "primitive";
221
+ renderAs: (feature: import("ol/Feature.js", { with: { "resolution-mode": "import" } }).default<import("ol/geom.js", { with: { "resolution-mode": "import" } }).Geometry>) => "geometry" | "primitive" | "model";
222
222
  setVcsMeta: (vcsMeta: import("@vcmap/core", { with: { "resolution-mode": "import" } }).VcsMeta) => void;
223
223
  setValues: (options: import("@vcmap/core", { with: { "resolution-mode": "import" } }).VectorPropertiesOptions) => void;
224
224
  getValues: () => import("@vcmap/core", { with: { "resolution-mode": "import" } }).VectorPropertiesOptions;
@@ -20,7 +20,8 @@
20
20
  import { VSheet } from 'vuetify/components';
21
21
  import VcsTreeview from '../components/lists/VcsTreeview.vue';
22
22
 
23
- const openStateMapSymbol = Symbol('openStateMap');
23
+ /** The open state Symbol of the ContentTree */
24
+ export const openStateMapSymbol = Symbol('openStateMap');
24
25
  /**
25
26
  * @description
26
27
  * Implements Treeview and shows content tree
@@ -1,3 +1,5 @@
1
+ /** The open state Symbol of the ContentTree */
2
+ export const openStateMapSymbol: unique symbol;
1
3
  declare const _default: import("vue").DefineComponent<{
2
4
  windowState: {
3
5
  type: ObjectConstructor;
@@ -3,6 +3,7 @@
3
3
  * @returns {import("@vcmap/core").OverrideCollection<ContentTreeItem, ContentTreeCollection>}
4
4
  */
5
5
  export function createContentTreeCollection(app: import("@src/vcsUiApp.js").default): import("@vcmap/core").OverrideCollection<ContentTreeItem, ContentTreeCollection>;
6
+ export const defaultContentTreeComponentId: "Content";
6
7
  export default ContentTreeCollection;
7
8
  export type ParentTreeViewItem = {
8
9
  treeViewItem?: import("./contentTreeItem.js").TreeViewItem | undefined;
@@ -20,6 +20,8 @@ import { ButtonLocation } from '../manager/navbarManager.js';
20
20
  const subTreeOpenStateSymbol = Symbol('SubTreeOpenState');
21
21
  const subTreeItemWeight = Symbol('SubTreeItemWeight');
22
22
 
23
+ export const defaultContentTreeComponentId = 'Content';
24
+
23
25
  /**
24
26
  * @typedef {Object} ParentTreeViewItem
25
27
  * @property {import("./contentTreeItem.js").TreeViewItem} [treeViewItem]
@@ -77,7 +79,9 @@ class ContentTreeCollection extends IndexedCollection {
77
79
  contentTreeActiveOnStartup?.value &&
78
80
  contentTreeActiveOnStartup[moduleIdSymbol] !== this._app.dynamicModuleId
79
81
  ) {
80
- const action = this._app.navbarManager.get('Content')?.action;
82
+ const action = this._app.navbarManager.get(
83
+ defaultContentTreeComponentId,
84
+ )?.action;
81
85
  if (action && !action.active) {
82
86
  action.callback();
83
87
  }
@@ -119,7 +123,7 @@ class ContentTreeCollection extends IndexedCollection {
119
123
  */
120
124
  this._defaultSubtreeItem = new SubContentTreeItem(
121
125
  {
122
- name: 'Content',
126
+ name: defaultContentTreeComponentId,
123
127
  icon: '$vcsLayers',
124
128
  title: 'content.title',
125
129
  tooltip: 'content.title',
@@ -198,7 +202,7 @@ class ContentTreeCollection extends IndexedCollection {
198
202
  'contentTreeActiveOnStartup',
199
203
  );
200
204
  if (
201
- id === 'Content' &&
205
+ id === defaultContentTreeComponentId &&
202
206
  contentTreeActiveOnStartup?.value &&
203
207
  contentTreeActiveOnStartup[moduleIdSymbol] !== this._app.dynamicModuleId
204
208
  ) {
@@ -422,9 +422,11 @@ class ContentTreeItem {
422
422
  (a) => a[actionWeightSymbol] > weight,
423
423
  );
424
424
  if (insertIndex > -1) {
425
- this._actions.value.splice(insertIndex, 0, action);
425
+ const newActions = [...this._actions.value];
426
+ newActions.splice(insertIndex, 0, action);
427
+ this._actions.value = newActions;
426
428
  } else {
427
- this._actions.value.push(action);
429
+ this._actions.value = [...this._actions.value, action];
428
430
  }
429
431
  }
430
432
 
@@ -33,11 +33,13 @@ class GroupContentTreeItem extends ContentTreeItem {
33
33
  () => {
34
34
  const children = this._children.value;
35
35
  this.visible = children.some((c) => c.visible);
36
- if (children.every((c) => c.state === StateActionState.NONE)) {
36
+ if (
37
+ children.every((c) => c.state === StateActionState.NONE || !c.visible)
38
+ ) {
37
39
  this.state = StateActionState.NONE;
38
40
  } else {
39
41
  const childrenWithState = children.filter(
40
- (c) => c.state !== StateActionState.NONE,
42
+ (c) => c.visible && c.state !== StateActionState.NONE,
41
43
  );
42
44
  if (
43
45
  childrenWithState.every((c) => c.state === StateActionState.ACTIVE)
@@ -54,7 +56,7 @@ class GroupContentTreeItem extends ContentTreeItem {
54
56
  }
55
57
  }
56
58
  },
57
- { deep: true },
59
+ { deep: true, immediate: true },
58
60
  );
59
61
  }
60
62
 
@@ -0,0 +1,58 @@
1
+ <script setup>
2
+ import { ref, shallowRef, inject, onUnmounted } from 'vue';
3
+ import VcsGroupedList from '../components/lists/VcsGroupedList.vue';
4
+
5
+ const props = defineProps({
6
+ /** @type {import("../components/lists/VcsGroupedList.vue").VcsGroupedListItem} */
7
+ items: {
8
+ type: Array,
9
+ default: () => [],
10
+ },
11
+ /** @type {import("../components/lists/VcsGroupedList.vue").VcsListGroup} */
12
+ groups: {
13
+ type: Array,
14
+ default: () => [],
15
+ },
16
+ });
17
+
18
+ const app = inject('vcsApp');
19
+ const open = ref(true);
20
+ const selected = shallowRef([]);
21
+
22
+ const selectionListener = app.featureInfo.featureChanged.addEventListener(
23
+ (f) => {
24
+ if (f === null) {
25
+ selected.value = [];
26
+ } else {
27
+ const item = props.items.find((i) => i.name === f.getId());
28
+ if (item) {
29
+ selected.value = [item];
30
+ }
31
+ }
32
+ },
33
+ );
34
+
35
+ onUnmounted(() => {
36
+ selectionListener();
37
+ });
38
+ </script>
39
+
40
+ <template>
41
+ <div>
42
+ <template v-if="items.length > 0">
43
+ <vcs-grouped-list
44
+ v-if="open"
45
+ :items="items"
46
+ :groups="groups"
47
+ v-model="selected"
48
+ selectable
49
+ single-select
50
+ searchable
51
+ open-all
52
+ />
53
+ </template>
54
+ <p v-else>{{ $t('featureInfo.cluster.empty') }}</p>
55
+ </div>
56
+ </template>
57
+
58
+ <style scoped lang="scss"></style>
@@ -0,0 +1,6 @@
1
+ declare const _default: import("vue").DefineComponent<{}, {
2
+ $props: {
3
+ readonly [x: string]: any;
4
+ };
5
+ }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{}>>, {}, {}>;
6
+ export default _default;
@@ -1,7 +1,6 @@
1
- import { VcsObject } from '@vcmap/core';
1
+ import { renderTemplate, VcsObject } from '@vcmap/core';
2
2
  import { WindowSlot } from '../manager/window/windowManager.js';
3
3
  import { defaultTagOptions } from '../components/tables/VcsTable.vue';
4
- import { renderTemplate } from '../components/form-output/markdownHelper.js';
5
4
 
6
5
  /**
7
6
  * @typedef {Object} FeatureInfoProps