@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.
- package/config/base.config.json +6 -0
- package/config/clipping.config.json +384 -0
- package/config/cluster.config.json +106 -0
- package/config/concepts-show-case.config.json +4 -0
- package/config/projects.config.json +5 -2
- package/dist/assets/{cesium-11e5bbc6.js → cesium-87d5e72d.js} +438 -432
- package/dist/assets/cesium.js +1 -1
- package/dist/assets/{core-9d0cfec3.js → core-72f9f393.js} +4907 -4514
- package/dist/assets/core.js +1 -1
- package/dist/assets/{ol-0d0ebb27.js → ol-e468ba43.js} +23518 -22404
- package/dist/assets/ol.js +1 -1
- package/dist/assets/ui-73257b15.css +1 -0
- package/dist/assets/{ui-08446666.js → ui-73257b15.js} +13703 -12977
- package/dist/assets/ui.js +1 -1
- package/dist/assets/vue.js +1 -1
- package/dist/assets/{vuetify-67025c41.css → vuetify-2437380c.css} +2 -2
- package/dist/assets/{vuetify-67025c41.js → vuetify-2437380c.js} +8024 -7634
- package/dist/assets/vuetify.js +1 -1
- package/index.d.ts +40 -19
- package/index.js +36 -6
- package/lib/olLib.js +25 -3
- package/package.json +6 -6
- package/plugins/@vcmap-show-case/callback-tester/README.md +3 -0
- package/plugins/@vcmap-show-case/callback-tester/package.json +5 -0
- package/plugins/@vcmap-show-case/callback-tester/src/CallbackTester.vue +62 -0
- package/plugins/@vcmap-show-case/callback-tester/src/index.js +48 -0
- package/plugins/@vcmap-show-case/form-inputs-example/src/FormInputsExample.vue +1 -0
- package/src/actions/actionHelper.d.ts +1 -0
- package/src/actions/actionHelper.js +70 -19
- package/src/application/VcsApp.vue +83 -50
- package/src/application/VcsApp.vue.d.ts +28 -2
- package/src/application/VcsContainer.vue +5 -3
- package/src/application/VcsContainer.vue.d.ts +14 -0
- package/src/application/VcsNavbar.vue +10 -6
- package/src/application/VcsNavbar.vue.d.ts +2 -0
- package/src/application/VcsObliqueFooter.vue +9 -3
- package/src/application/VcsSplashScreen.vue +37 -0
- package/src/application/VcsSplashScreen.vue.d.ts +6 -0
- package/src/application/positionDisplayInteraction.js +1 -1
- package/src/callback/activateClippingPolygonCallback.d.ts +29 -0
- package/src/callback/activateClippingPolygonCallback.js +54 -0
- package/src/callback/closeSplashScreenCallback.d.ts +8 -0
- package/src/callback/closeSplashScreenCallback.js +33 -0
- package/src/callback/deactivateClippingPolygonCallback.d.ts +29 -0
- package/src/callback/deactivateClippingPolygonCallback.js +54 -0
- package/src/callback/openSplashScreenCallback.d.ts +8 -0
- package/src/callback/openSplashScreenCallback.js +35 -0
- package/src/callback/toggleNavbarButtonCallback.d.ts +36 -0
- package/src/callback/toggleNavbarButtonCallback.js +62 -0
- package/src/components/buttons/VcsActionButtonList.vue +6 -4
- package/src/components/buttons/VcsToolButton.vue +0 -1
- package/src/components/form-inputs-controls/VcsDatePicker.vue +7 -1
- package/src/components/form-inputs-controls/VcsDatePicker.vue.d.ts +9 -0
- package/src/components/form-inputs-controls/VcsSelect.vue +1 -1
- package/src/components/form-inputs-controls/VcsTextArea.vue +13 -8
- package/src/components/form-output/markdownHelper.d.ts +0 -25
- package/src/components/form-output/markdownHelper.js +1 -386
- package/src/components/import/VcsImportComponent.vue +2 -0
- package/src/components/lists/VcsGroupedList.vue +178 -0
- package/src/components/lists/VcsGroupedList.vue.d.ts +17 -0
- package/src/components/lists/VcsList.vue +144 -394
- package/src/components/lists/VcsList.vue.d.ts +38 -159
- package/src/components/lists/VcsTreeNode.vue +18 -11
- package/src/components/lists/VcsTreeview.vue +27 -20
- package/src/components/lists/VcsTreeview.vue.d.ts +18 -1
- package/src/components/lists/listHelper.d.ts +87 -0
- package/src/components/lists/listHelper.js +348 -0
- package/src/components/section/VcsFormSection.vue +7 -2
- package/src/components/section/VcsFormSection.vue.d.ts +9 -0
- package/src/components/tables/VcsDataTable.vue +14 -3
- package/src/components/tables/VcsDataTable.vue.d.ts +9 -0
- package/src/components/vector-properties/VcsVectorPropertiesComponent.vue.d.ts +1 -1
- package/src/contentTree/LayerTree.vue +2 -1
- package/src/contentTree/LayerTree.vue.d.ts +2 -0
- package/src/contentTree/contentTreeCollection.d.ts +1 -0
- package/src/contentTree/contentTreeCollection.js +7 -3
- package/src/contentTree/contentTreeItem.js +4 -2
- package/src/contentTree/groupContentTreeItem.js +5 -3
- package/src/featureInfo/ClusterFeatureComponent.vue +58 -0
- package/src/featureInfo/ClusterFeatureComponent.vue.d.ts +6 -0
- package/src/featureInfo/abstractFeatureInfoView.js +1 -2
- package/src/featureInfo/featureInfo.d.ts +87 -1
- package/src/featureInfo/featureInfo.js +342 -34
- package/src/featureInfo/featureInfoInteraction.js +18 -3
- package/src/featureInfo/iframeFeatureInfoView.js +1 -1
- package/src/featureInfo/markdownBalloonFeatureInfoView.js +2 -4
- package/src/featureInfo/markdownFeatureInfoView.js +1 -1
- package/src/i18n/de.d.ts +17 -4
- package/src/i18n/de.js +7 -0
- package/src/i18n/en.d.ts +17 -4
- package/src/i18n/en.js +7 -0
- package/src/legend/VcsLegend.vue +1 -1
- package/src/legend/legendHelper.d.ts +1 -1
- package/src/legend/legendHelper.js +52 -9
- package/src/localStorage.d.ts +21 -0
- package/src/localStorage.js +51 -0
- package/src/manager/collectionManager/CollectionComponent.vue +1 -1
- package/src/manager/collectionManager/CollectionComponentContent.vue +2 -3
- package/src/manager/collectionManager/CollectionComponentList.vue +2 -3
- package/src/manager/collectionManager/CollectionComponentStandalone.vue +1 -1
- package/src/manager/navbarManager.js +9 -4
- package/src/manager/toolbox/ToolboxManagerComponent.vue +14 -12
- package/src/manager/toolbox/ToolboxManagerComponent.vue.d.ts +13 -2
- package/src/manager/toolbox/toolboxManager.d.ts +5 -0
- package/src/manager/toolbox/toolboxManager.js +7 -1
- package/src/manager/window/WindowComponent.vue +10 -0
- package/src/manager/window/WindowComponent.vue.d.ts +1 -0
- package/src/manager/window/WindowManager.vue +14 -4
- package/src/manager/window/WindowManager.vue.d.ts +1 -0
- package/src/manager/window/windowHelper.d.ts +7 -3
- package/src/manager/window/windowHelper.js +30 -10
- package/src/navigation/MapNavigation.vue +5 -5
- package/src/navigation/MapNavigation.vue.d.ts +1 -1
- package/src/navigation/overviewMap.d.ts +7 -0
- package/src/navigation/overviewMap.js +18 -4
- package/src/pluginHelper.d.ts +7 -0
- package/src/pluginHelper.js +18 -4
- package/src/search/ResultItem.vue.d.ts +1 -1
- package/src/search/markText.d.ts +1 -1
- package/src/search/markText.js +4 -4
- package/src/search/search.js +1 -1
- package/src/state.d.ts +4 -2
- package/src/state.js +54 -31
- package/src/uiConfig.d.ts +36 -0
- package/src/uiConfig.js +17 -1
- package/src/vcsUiApp.js +7 -11
- package/dist/assets/ui-08446666.css +0 -1
- /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:
|
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 [
|
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
|
-
|
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" | "
|
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
|
-
|
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
|
@@ -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(
|
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:
|
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 ===
|
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
|
425
|
+
const newActions = [...this._actions.value];
|
426
|
+
newActions.splice(insertIndex, 0, action);
|
427
|
+
this._actions.value = newActions;
|
426
428
|
} else {
|
427
|
-
this._actions.value.
|
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 (
|
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
|