@vcmap/ui 6.1.0-rc.6 → 6.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/config/base.config.json +7 -3
- package/config/cluster.config.json +5 -14
- package/config/dev.config.json +175 -56
- package/config/projects.config.json +2 -1
- package/config/splashscreen.config.json +6 -10
- package/config/vectorTile.config.json +42 -1
- package/dist/assets/{cesium-f5e8e354.js → cesium-664ad022.js} +53 -23
- package/dist/assets/cesium.js +1 -1
- package/dist/assets/{core-c134a524.js → core-841b71a4.js} +8458 -5828
- package/dist/assets/core.js +1 -1
- package/dist/assets/{ol-2752311f.js → ol-2e095c08.js} +87 -37
- package/dist/assets/ol.js +1 -1
- package/dist/assets/ui-2fd6f47d.css +1 -0
- package/dist/assets/{ui-83514586.js → ui-2fd6f47d.js} +21376 -20063
- package/dist/assets/ui.js +1 -1
- package/dist/assets/vue.js +1 -1
- package/dist/assets/{vuetify-5dbe2644.css → vuetify-4bc77ff7.css} +2 -2
- package/dist/assets/{vuetify-5dbe2644.js → vuetify-4bc77ff7.js} +7520 -7373
- package/dist/assets/vuetify.js +1 -1
- package/dist/index.html +1 -1
- package/index.d.ts +15 -5
- package/index.html +1 -1
- package/index.js +14 -5
- package/package.json +12 -8
- package/plugins/@vcmap-show-case/theming-example/src/index.js +1 -0
- package/plugins/@vcmap-show-case/vector-properties-example/src/LayerSettings.vue +39 -0
- package/plugins/@vcmap-show-case/vector-properties-example/src/VectorPropertiesExample.vue +3 -0
- package/plugins/@vcmap-show-case/vector-properties-example/src/lib.js +13 -0
- package/plugins/@vcmap-show-case/window-tester/src/WindowExample.vue +9 -0
- package/plugins/package.json +7 -5
- package/src/actions/actionHelper.d.ts +6 -0
- package/src/actions/actionHelper.js +22 -0
- package/src/actions/deepPickingAction.d.ts +23 -0
- package/src/actions/deepPickingAction.js +399 -0
- package/src/application/MapsGroupMobileMenu.vue +105 -0
- package/src/application/MapsGroupMobileMenu.vue.d.ts +7 -0
- package/src/application/VcsApp.vue +51 -24
- package/src/application/VcsApp.vue.d.ts +9 -2
- package/src/application/VcsAttributionsFooter.vue +1 -0
- package/src/application/VcsContainer.vue +36 -13
- package/src/application/VcsContainer.vue.d.ts +7 -0
- package/src/application/VcsMobileMenuList.vue +111 -0
- package/src/application/VcsMobileMenuList.vue.d.ts +2 -0
- package/src/application/VcsNavbar.vue +15 -3
- package/src/application/VcsNavbarMobile.vue +206 -0
- package/src/application/VcsNavbarMobile.vue.d.ts +42 -0
- package/src/application/VcsPositionDisplay.vue +1 -0
- package/src/application/VcsSplashScreen.vue +39 -7
- package/src/application/VcsSplashScreen.vue.d.ts +6 -0
- package/src/application/uiConfigHelper.d.ts +12 -0
- package/src/application/uiConfigHelper.js +37 -0
- package/src/components/buttons/VcsActionButtonList.vue +1 -0
- package/src/components/buttons/VcsToolButton.vue +8 -1
- package/src/components/buttons/VcsToolButton.vue.d.ts +1 -0
- package/src/components/form-inputs-controls/VcsSelect.vue +8 -6
- package/src/components/form-output/VcsTemplateMarkdown.vue +43 -0
- package/src/components/form-output/VcsTemplateMarkdown.vue.d.ts +9 -0
- package/src/components/icons/+all.d.ts +5 -0
- package/src/components/icons/+all.js +14 -0
- package/src/components/lists/VcsActionList.vue +1 -0
- package/src/components/lists/VcsGroupedList.vue +2 -1
- package/src/components/lists/VcsListItemComponent.vue +1 -0
- package/src/components/lists/VcsTreeNode.vue +11 -2
- package/src/components/lists/VcsTreeview.vue +40 -3
- package/src/components/lists/VcsTreeview.vue.d.ts +1 -0
- package/src/components/lists/VcsTreeviewTitle.vue +8 -1
- package/src/components/style/{MenuWrapper.vue → StyleMenuWrapper.vue} +2 -1
- package/src/components/style/VcsFillMenu.vue +4 -4
- package/src/components/style/VcsImageMenu.vue +4 -4
- package/src/components/style/VcsStrokeMenu.vue +4 -4
- package/src/components/style/VcsTextMenu.vue +4 -4
- package/src/contentTree/LayerTree.vue +8 -46
- package/src/contentTree/LayerTree.vue.d.ts +1 -3
- package/src/contentTree/contentTreeCollection.d.ts +7 -0
- package/src/contentTree/contentTreeCollection.js +31 -10
- package/src/contentTree/contentTreeItem.d.ts +4 -4
- package/src/contentTree/contentTreeItem.js +2 -2
- package/src/contentTree/flightContentTreeItem.d.ts +8 -1
- package/src/contentTree/flightContentTreeItem.js +26 -3
- package/src/contentTree/groupContentTreeItem.d.ts +21 -0
- package/src/contentTree/groupContentTreeItem.js +32 -2
- package/src/contentTree/layerContentTreeItem.d.ts +8 -1
- package/src/contentTree/layerContentTreeItem.js +26 -4
- package/src/contentTree/layerGroupContentTreeItem.d.ts +6 -0
- package/src/contentTree/layerGroupContentTreeItem.js +27 -3
- package/src/contentTree/nodeContentTreeItem.d.ts +21 -0
- package/src/contentTree/nodeContentTreeItem.js +31 -2
- package/src/contentTree/obliqueCollectionContentTreeItem.d.ts +6 -0
- package/src/contentTree/obliqueCollectionContentTreeItem.js +22 -2
- package/src/contentTree/wmsChildContentTreeItem.d.ts +56 -0
- package/src/contentTree/wmsChildContentTreeItem.js +159 -0
- package/src/contentTree/wmsGroupContentTreeItem.d.ts +171 -0
- package/src/contentTree/wmsGroupContentTreeItem.js +619 -0
- package/src/featureInfo/BalloonComponent.vue +6 -6
- package/src/featureInfo/ClusterFeatureComponent.vue +47 -11
- package/src/featureInfo/ClusterFeatureComponent.vue.d.ts +1 -0
- package/src/featureInfo/MarkdownBalloonComponent.vue +3 -9
- package/src/featureInfo/MarkdownBalloonComponent.vue.d.ts +1 -11
- package/src/featureInfo/balloonFeatureInfoView.d.ts +3 -0
- package/src/featureInfo/balloonFeatureInfoView.js +78 -11
- package/src/featureInfo/balloonHelper.js +9 -13
- package/src/featureInfo/featureInfo.d.ts +32 -7
- package/src/featureInfo/featureInfo.js +192 -93
- package/src/featureInfo/markdownBalloonFeatureInfoView.d.ts +0 -6
- package/src/featureInfo/markdownBalloonFeatureInfoView.js +5 -14
- package/src/featureInfo/markdownFeatureInfoView.d.ts +2 -8
- package/src/featureInfo/markdownFeatureInfoView.js +6 -15
- package/src/i18n/de.d.ts +64 -50
- package/src/i18n/de.js +9 -0
- package/src/i18n/en.d.ts +64 -50
- package/src/i18n/en.js +9 -0
- package/src/legend/VcsLegend.vue +21 -2
- package/src/legend/VcsLegend.vue.d.ts +1 -0
- package/src/legend/legendHelper.d.ts +0 -13
- package/src/legend/legendHelper.js +3 -27
- package/src/manager/navbarManager.d.ts +14 -1
- package/src/manager/navbarManager.js +22 -2
- package/src/manager/toolbox/GroupToolboxComponent.vue +17 -3
- package/src/manager/toolbox/GroupToolboxComponent.vue.d.ts +1 -0
- package/src/manager/toolbox/SelectToolboxComponent.vue +17 -3
- package/src/manager/toolbox/SelectToolboxComponent.vue.d.ts +1 -0
- package/src/manager/toolbox/ToolboxManagerComponent.vue +45 -14
- package/src/manager/toolbox/ToolboxManagerComponent.vue.d.ts +9 -0
- package/src/manager/toolbox/toolboxManager.d.ts +2 -1
- package/src/manager/toolbox/toolboxManager.js +13 -1
- package/src/manager/window/WindowComponent.vue +3 -2
- package/src/manager/window/WindowComponentHeader.vue +9 -1
- package/src/manager/window/WindowComponentHeader.vue.d.ts +1 -0
- package/src/manager/window/WindowManager.vue +175 -30
- package/src/manager/window/WindowManager.vue.d.ts +5 -0
- package/src/manager/window/windowManager.d.ts +2 -2
- package/src/manager/window/windowManager.js +12 -10
- package/src/navigation/MapNavigation.vue +29 -19
- package/src/navigation/MapNavigation.vue.d.ts +1 -0
- package/src/notifier/NotifierComponent.vue +1 -0
- package/src/search/ResultsComponent.vue +44 -17
- package/src/search/ResultsComponent.vue.d.ts +11 -1
- package/src/search/SearchComponent.vue +60 -9
- package/src/search/SearchComponent.vue.d.ts +2 -0
- package/src/search/search.js +3 -16
- package/src/state.d.ts +2 -1
- package/src/state.js +2 -1
- package/src/uiConfig.d.ts +9 -0
- package/src/uiConfig.js +1 -0
- package/src/vuePlugins/vuetify.d.ts +4 -0
- package/src/vuePlugins/vuetify.js +49 -3
- package/dist/assets/ui-83514586.css +0 -1
- /package/dist/assets/{vue-f8b1b5f8.js → vue-71fd14e8.js} +0 -0
- /package/src/components/style/{MenuWrapper.vue.d.ts → StyleMenuWrapper.vue.d.ts} +0 -0
@@ -1,10 +1,5 @@
|
|
1
1
|
<template>
|
2
|
-
<div
|
3
|
-
:class="{
|
4
|
-
'win-container-mobile': addMobileClass,
|
5
|
-
}"
|
6
|
-
class="window-manager"
|
7
|
-
>
|
2
|
+
<div class="window-manager" :class="{ oblique: isOblique, mobile: xs }">
|
8
3
|
<WindowComponent
|
9
4
|
v-for="id in componentIds"
|
10
5
|
:key="id"
|
@@ -13,6 +8,9 @@
|
|
13
8
|
:z-index="getComponent(id).zIndex"
|
14
9
|
@moved="move(id, $event)"
|
15
10
|
@mousedown="bringWindowToTop(id)"
|
11
|
+
@touchstart="onTouchStart($event)"
|
12
|
+
@touchmove="onTouchMove($event)"
|
13
|
+
@touchend="onTouchEnd($event, id)"
|
16
14
|
:style="getStyles(id).value"
|
17
15
|
:class="getState(id).classes"
|
18
16
|
:is-on-top="isOnTop(id)"
|
@@ -39,30 +37,50 @@
|
|
39
37
|
</template>
|
40
38
|
|
41
39
|
<style scoped lang="scss">
|
42
|
-
.
|
40
|
+
.mobile > div:not(#window-component--searchId) {
|
43
41
|
position: fixed;
|
44
|
-
bottom: 56px;
|
45
42
|
left: 0;
|
46
43
|
right: 0;
|
47
44
|
z-index: 2;
|
48
45
|
display: contents;
|
46
|
+
width: 100% !important;
|
47
|
+
max-width: 100% !important;
|
48
|
+
inset: unset !important;
|
49
|
+
border-radius: 0 !important;
|
50
|
+
overflow: auto;
|
51
|
+
bottom: 0 !important;
|
52
|
+
max-height: 50% !important;
|
49
53
|
}
|
50
|
-
.
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
54
|
+
.mobile > div {
|
55
|
+
transition: transform 0.4s ease;
|
56
|
+
}
|
57
|
+
|
58
|
+
.mobile > #window-component--searchId {
|
59
|
+
position: fixed !important;
|
60
|
+
top: calc(var(--v-vcs-font-size) * 5 + 28px) !important;
|
61
|
+
left: 5px !important;
|
62
|
+
right: calc(var(--v-vcs-font-size) * 5 + 2px) !important;
|
63
|
+
z-index: 2;
|
64
|
+
border-radius: 4px !important;
|
65
|
+
width: inherit !important;
|
66
|
+
padding-right: 1px !important;
|
67
|
+
.py-1 {
|
68
|
+
padding: 0px !important;
|
59
69
|
}
|
60
70
|
}
|
71
|
+
.mobile > #window-component--searchId > div > div {
|
72
|
+
border-radius: 4px !important;
|
73
|
+
}
|
74
|
+
|
75
|
+
.oblique > #window-component--searchId {
|
76
|
+
right: calc(var(--v-vcs-font-size) * 6.25 + 2px) !important;
|
77
|
+
}
|
61
78
|
</style>
|
62
79
|
|
63
80
|
<script>
|
64
|
-
import { computed, inject, onUnmounted, ref } from 'vue';
|
81
|
+
import { computed, inject, onUnmounted, ref, watch } from 'vue';
|
65
82
|
import { useDisplay } from 'vuetify';
|
83
|
+
import { ObliqueMap } from '@vcmap/core';
|
66
84
|
import WindowComponent from './WindowComponent.vue';
|
67
85
|
import WindowComponentHeader from './WindowComponentHeader.vue';
|
68
86
|
import BalloonComponent from '../../featureInfo/BalloonComponent.vue';
|
@@ -71,6 +89,8 @@
|
|
71
89
|
getTargetSize,
|
72
90
|
moveWindow,
|
73
91
|
} from './windowHelper.js';
|
92
|
+
import { mobileMenuListId } from '../../application/VcsNavbarMobile.vue';
|
93
|
+
import { useFontSize } from '../../vuePlugins/vuetify.js';
|
74
94
|
|
75
95
|
/**
|
76
96
|
* @description WindowManager rendering all registered WindowComponents
|
@@ -81,9 +101,14 @@
|
|
81
101
|
setup() {
|
82
102
|
const app = inject('vcsApp');
|
83
103
|
/** @type {WindowManager} */
|
84
|
-
const { windowManager } = app;
|
104
|
+
const { windowManager, toolboxManager } = app;
|
85
105
|
const { componentIds } = windowManager;
|
86
106
|
const targetSize = ref(null);
|
107
|
+
const touchStartY = ref(0);
|
108
|
+
const touchCurrentY = ref(0);
|
109
|
+
const isTouching = ref(false);
|
110
|
+
const fontSize = useFontSize();
|
111
|
+
const { sm } = useDisplay();
|
87
112
|
/**
|
88
113
|
* @param {string} id
|
89
114
|
* @returns {WindowState}
|
@@ -128,14 +153,28 @@
|
|
128
153
|
// do not clip balloons to target
|
129
154
|
return windowComponent?.position;
|
130
155
|
}
|
156
|
+
// reduce target size for Tablet View to compensate for the toolbar not overlapping
|
157
|
+
const size = structuredClone(targetSize.value);
|
158
|
+
if (toolboxManager.open.value && sm.value && size) {
|
159
|
+
size.height -= fontSize.value * 3 + 6;
|
160
|
+
}
|
161
|
+
|
131
162
|
return getPositionAppliedOnTarget(
|
132
163
|
windowComponent?.position,
|
133
|
-
|
164
|
+
size,
|
134
165
|
getPosition(parentComponent),
|
135
166
|
);
|
136
167
|
};
|
137
168
|
const display = useDisplay();
|
138
169
|
|
170
|
+
const addMobileClass = computed(() => {
|
171
|
+
return display.xs.value && componentIds.length > 0;
|
172
|
+
});
|
173
|
+
|
174
|
+
const addTabletClass = computed(() => {
|
175
|
+
return display.sm.value && componentIds.length > 0;
|
176
|
+
});
|
177
|
+
|
139
178
|
/**
|
140
179
|
* @param {string} id
|
141
180
|
* @returns {import("vue").ComputedRef<Object>}
|
@@ -143,14 +182,22 @@
|
|
143
182
|
const getStyles = (id) =>
|
144
183
|
computed(() => {
|
145
184
|
const windowComponent = windowManager.get(id);
|
146
|
-
const zIndexOffset =
|
185
|
+
const zIndexOffset =
|
186
|
+
Number(display.sm.value) || Number(display.xs.value); // add z-Index Offset for Tablet View to keep the windows above the detached Icon
|
147
187
|
return {
|
148
|
-
zIndex: windowComponent.zIndex.value + zIndexOffset
|
188
|
+
zIndex: `${windowComponent.zIndex.value + zIndexOffset} !important`,
|
149
189
|
...getPosition(windowComponent),
|
150
190
|
...(windowComponent?.state?.styles || {}),
|
151
191
|
};
|
152
192
|
});
|
153
193
|
|
194
|
+
const isOblique = ref(false);
|
195
|
+
// fix search width to oblique map
|
196
|
+
const mobileSearchObliqueListener =
|
197
|
+
app.maps.mapActivated.addEventListener((map) => {
|
198
|
+
isOblique.value = map instanceof ObliqueMap;
|
199
|
+
});
|
200
|
+
|
154
201
|
/**
|
155
202
|
* @param {string} id
|
156
203
|
*/
|
@@ -169,14 +216,6 @@
|
|
169
216
|
moveWindow(id, translation, windowManager, targetSize.value, position);
|
170
217
|
};
|
171
218
|
|
172
|
-
const addMobileClass = computed(() => {
|
173
|
-
return display.xs.value && componentIds.length > 0;
|
174
|
-
});
|
175
|
-
|
176
|
-
const addTabletClass = computed(() => {
|
177
|
-
return display.sm.value && componentIds.length > 0;
|
178
|
-
});
|
179
|
-
|
180
219
|
const setTargetSize = () => {
|
181
220
|
targetSize.value = getTargetSize(app.maps.target);
|
182
221
|
};
|
@@ -184,11 +223,112 @@
|
|
184
223
|
const setTargetDestroy =
|
185
224
|
app.maps.mapActivated.addEventListener(setTargetSize);
|
186
225
|
|
226
|
+
let exclusiveWindowListener;
|
227
|
+
|
228
|
+
/**
|
229
|
+
* Sets up an exclusive window listener for mobile view.
|
230
|
+
* When a new window is added, it removes all other windows except the search window.
|
231
|
+
* The search window is placed at the top of the page and allows opening of one other window, e.g. for displaying feature information.
|
232
|
+
*/
|
233
|
+
function setupExclusiveWindowListener() {
|
234
|
+
if (display.xs.value) {
|
235
|
+
exclusiveWindowListener = app.windowManager.added.addEventListener(
|
236
|
+
(e) => {
|
237
|
+
componentIds
|
238
|
+
.filter((id) => id !== e.id)
|
239
|
+
.forEach((id) => {
|
240
|
+
if (id !== 'searchId') {
|
241
|
+
app.windowManager.remove(id);
|
242
|
+
} else if (
|
243
|
+
id === 'searchId' &&
|
244
|
+
componentIds.includes('Content')
|
245
|
+
) {
|
246
|
+
app.windowManager.remove('searchId');
|
247
|
+
}
|
248
|
+
});
|
249
|
+
},
|
250
|
+
);
|
251
|
+
} else {
|
252
|
+
exclusiveWindowListener?.();
|
253
|
+
}
|
254
|
+
}
|
255
|
+
|
256
|
+
setupExclusiveWindowListener();
|
257
|
+
|
258
|
+
watch(display.xs, () => {
|
259
|
+
setupExclusiveWindowListener();
|
260
|
+
if (componentIds.includes(mobileMenuListId)) {
|
261
|
+
windowManager.remove(mobileMenuListId);
|
262
|
+
}
|
263
|
+
});
|
264
|
+
|
187
265
|
onUnmounted(() => {
|
188
266
|
window.removeEventListener('resize', setTargetSize);
|
267
|
+
exclusiveWindowListener?.();
|
189
268
|
setTargetDestroy();
|
269
|
+
mobileSearchObliqueListener();
|
190
270
|
});
|
191
271
|
|
272
|
+
/**
|
273
|
+
* Handles the touch start event for mobile view.
|
274
|
+
* Initializes the touch start position and sets the isTouching flag.
|
275
|
+
* Only starts the drag if the touch starts within the first 50 pixels of the window.
|
276
|
+
* @param {TouchEvent} event - The touch start event.
|
277
|
+
*/
|
278
|
+
const onTouchStart = (event) => {
|
279
|
+
if (!addMobileClass.value) return; // Only on mobile view
|
280
|
+
const windowElement = event.currentTarget;
|
281
|
+
// Get the Y-coordinate of the drag start relative to the window's top
|
282
|
+
const touchStartYRelativeToWindow =
|
283
|
+
event.touches[0].clientY - windowElement.getBoundingClientRect().top;
|
284
|
+
// Only start drag if the starting position is within the first 50 pixels of the window
|
285
|
+
if (touchStartYRelativeToWindow > 50) return;
|
286
|
+
touchStartY.value = event.touches[0].clientY;
|
287
|
+
touchCurrentY.value = touchStartY.value;
|
288
|
+
isTouching.value = true;
|
289
|
+
};
|
290
|
+
|
291
|
+
/**
|
292
|
+
* Handles the touch move event for mobile view.
|
293
|
+
* Adjusts the window position during drag based on the touch movement.
|
294
|
+
* @param {TouchEvent} event - The touch move event.
|
295
|
+
*/
|
296
|
+
const onTouchMove = (event) => {
|
297
|
+
if (!isTouching.value) return;
|
298
|
+
touchCurrentY.value = event.touches[0].clientY;
|
299
|
+
|
300
|
+
// Adjust the window position during drag
|
301
|
+
const deltaY = touchCurrentY.value - touchStartY.value;
|
302
|
+
const windowElement = event.currentTarget;
|
303
|
+
if (windowElement) {
|
304
|
+
windowElement.style.transform = `translateY(${Math.max(0, deltaY)}px)`;
|
305
|
+
}
|
306
|
+
};
|
307
|
+
|
308
|
+
/**
|
309
|
+
* Handles the touch end event for mobile view.
|
310
|
+
* Resets the isTouching flag and checks if the window should be closed based on the drag distance.
|
311
|
+
* @param {TouchEvent} event - The touch end event.
|
312
|
+
* @param {string} id - The ID of the window component.
|
313
|
+
*/
|
314
|
+
const onTouchEnd = (event, id) => {
|
315
|
+
if (!isTouching.value) return;
|
316
|
+
isTouching.value = false;
|
317
|
+
|
318
|
+
const deltaY = touchCurrentY.value - touchStartY.value;
|
319
|
+
const windowElement = event.currentTarget;
|
320
|
+
|
321
|
+
if (windowElement) {
|
322
|
+
// reset the transform style so it opens fully again if the window is not fully closed
|
323
|
+
windowElement.style.transform = '';
|
324
|
+
|
325
|
+
// Close if dragged down far enough 1/3 of the window height
|
326
|
+
if (deltaY > windowElement.offsetHeight / 3) {
|
327
|
+
windowManager.remove(id);
|
328
|
+
}
|
329
|
+
}
|
330
|
+
};
|
331
|
+
|
192
332
|
return {
|
193
333
|
componentIds,
|
194
334
|
getComponent: (id) => windowManager.get(id).component,
|
@@ -209,6 +349,11 @@
|
|
209
349
|
move,
|
210
350
|
addMobileClass,
|
211
351
|
addTabletClass,
|
352
|
+
onTouchStart,
|
353
|
+
onTouchMove,
|
354
|
+
onTouchEnd,
|
355
|
+
isOblique,
|
356
|
+
xs: display.xs,
|
212
357
|
};
|
213
358
|
},
|
214
359
|
};
|
@@ -16,5 +16,10 @@ declare const _default: import("vue").DefineComponent<{}, {
|
|
16
16
|
}) => void;
|
17
17
|
addMobileClass: import("vue").ComputedRef<boolean>;
|
18
18
|
addTabletClass: import("vue").ComputedRef<boolean>;
|
19
|
+
onTouchStart: (event: TouchEvent) => void;
|
20
|
+
onTouchMove: (event: TouchEvent) => void;
|
21
|
+
onTouchEnd: (event: TouchEvent, id: string) => void;
|
22
|
+
isOblique: import("vue").Ref<boolean>;
|
23
|
+
xs: import("vue").Ref<boolean>;
|
19
24
|
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{}>>, {}, {}>;
|
20
25
|
export default _default;
|
@@ -76,7 +76,7 @@ export function isSlotPosition(windowPosition: WindowPosition): boolean;
|
|
76
76
|
* headerComponent?: import("vue").Component<T, unknown, unknown>,
|
77
77
|
* state : Partial<WindowState>,
|
78
78
|
* position : Partial<WindowPositionOptions>,
|
79
|
-
* slot: WindowSlot
|
79
|
+
* slot: import("vue").Ref<WindowSlot>,
|
80
80
|
* props: T,
|
81
81
|
* provides: Record<string, unknown>,
|
82
82
|
* zIndex: import("vue").ComputedGetter<number>
|
@@ -249,7 +249,7 @@ export type WindowComponent<T extends Object = Object> = {
|
|
249
249
|
headerComponent?: import("vue").Component<T, unknown, unknown>;
|
250
250
|
state: Partial<WindowState>;
|
251
251
|
position: Partial<WindowPositionOptions>;
|
252
|
-
slot: WindowSlot
|
252
|
+
slot: import("vue").Ref<WindowSlot>;
|
253
253
|
props: T;
|
254
254
|
provides: Record<string, unknown>;
|
255
255
|
zIndex: import("vue").ComputedGetter<number>;
|
@@ -170,7 +170,7 @@ export function isSlotPosition(windowPosition) {
|
|
170
170
|
* headerComponent?: import("vue").Component<T, unknown, unknown>,
|
171
171
|
* state : Partial<WindowState>,
|
172
172
|
* position : Partial<WindowPositionOptions>,
|
173
|
-
* slot: WindowSlot
|
173
|
+
* slot: import("vue").Ref<WindowSlot>,
|
174
174
|
* props: T,
|
175
175
|
* provides: Record<string, unknown>,
|
176
176
|
* zIndex: import("vue").ComputedGetter<number>
|
@@ -545,15 +545,17 @@ class WindowManager {
|
|
545
545
|
* @private
|
546
546
|
*/
|
547
547
|
_cachePosition(windowComponent) {
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
548
|
+
if (windowComponent.slot.value === WindowSlot.DETACHED) {
|
549
|
+
const initialWindowPosition = windowPositionFromOptions(
|
550
|
+
windowComponent.initialPositionOptions,
|
551
|
+
);
|
552
|
+
if (
|
553
|
+
!compareWindowPositions(initialWindowPosition, windowComponent.position)
|
554
|
+
) {
|
555
|
+
this._windowPositionsCache.set(windowComponent.id, {
|
556
|
+
...windowComponent.position,
|
557
|
+
});
|
558
|
+
}
|
557
559
|
}
|
558
560
|
}
|
559
561
|
|
@@ -1,6 +1,8 @@
|
|
1
1
|
<template>
|
2
2
|
<v-container
|
3
|
-
:class="
|
3
|
+
:class="
|
4
|
+
xs || mobileLandscape ? 'nav-container mobile no-zoom ' : 'nav-container'
|
5
|
+
"
|
4
6
|
class="map-navigation"
|
5
7
|
>
|
6
8
|
<v-row>
|
@@ -25,7 +27,7 @@
|
|
25
27
|
></OrientationToolsButton>
|
26
28
|
</v-row>
|
27
29
|
</template>
|
28
|
-
<template v-if="smAndUp">
|
30
|
+
<template v-if="smAndUp && !mobileLandscape">
|
29
31
|
<v-row justify="center">
|
30
32
|
<VcsZoomButton
|
31
33
|
@zoom-out="zoomOut()"
|
@@ -33,7 +35,7 @@
|
|
33
35
|
:disabled="movementApiCallsDisabled"
|
34
36
|
/>
|
35
37
|
</v-row>
|
36
|
-
<v-row justify="center" v-if="is3D
|
38
|
+
<v-row justify="center" v-if="is3D">
|
37
39
|
<TiltSlider v-model="tilt" :disabled="movementApiCallsDisabled" />
|
38
40
|
</v-row>
|
39
41
|
<v-row v-if="!hideRotationButton && is3D" justify="center">
|
@@ -45,15 +47,17 @@
|
|
45
47
|
:disabled="rotationAction.disabled"
|
46
48
|
/>
|
47
49
|
</v-row>
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
50
|
+
</template>
|
51
|
+
<v-row justify="center">
|
52
|
+
<OrientationToolsButton
|
53
|
+
v-if="homeAction.icon"
|
54
|
+
:icon="homeAction.icon"
|
55
|
+
:tooltip="homeAction.title"
|
56
|
+
@click.stop="homeAction.callback($event)"
|
57
|
+
:disabled="movementApiCallsDisabled"
|
58
|
+
/>
|
59
|
+
</v-row>
|
60
|
+
<template v-if="!mobileLandscape">
|
57
61
|
<v-row justify="center">
|
58
62
|
<OrientationToolsButton
|
59
63
|
v-if="showOverviewButton"
|
@@ -90,6 +94,7 @@
|
|
90
94
|
import TiltSlider from './TiltSlider.vue';
|
91
95
|
import ObliqueRotation from './ObliqueRotation.vue';
|
92
96
|
import OrientationToolsButton from './OrientationToolsButton.vue';
|
97
|
+
import { isMobileLandscape } from '../vuePlugins/vuetify.js';
|
93
98
|
|
94
99
|
/**
|
95
100
|
* @description Creates a go-to viewpoint action from a startingViewpointName defined in a module. If no startingViewpointName is defined, uses default map view as fallback.
|
@@ -183,6 +188,8 @@
|
|
183
188
|
options.keyEvents === true &&
|
184
189
|
options.apiCalls === true &&
|
185
190
|
options.pointerEvents === true;
|
191
|
+
|
192
|
+
stopRotation = null;
|
186
193
|
});
|
187
194
|
return {
|
188
195
|
action,
|
@@ -280,6 +287,7 @@
|
|
280
287
|
const viewMode = ref(OrientationToolsViewMode.TWO_D);
|
281
288
|
const headingRef = ref(0);
|
282
289
|
const tiltRef = ref(0);
|
290
|
+
const mobileLandscape = isMobileLandscape();
|
283
291
|
|
284
292
|
const handleRenderEvent = ({ map }) => {
|
285
293
|
viewMode.value = getViewModeForMap(map);
|
@@ -306,13 +314,10 @@
|
|
306
314
|
return headingRef.value;
|
307
315
|
},
|
308
316
|
async set(headingValue) {
|
309
|
-
|
310
|
-
|
311
|
-
vp = await app.maps.activeMap.getViewpoint();
|
312
|
-
} else {
|
313
|
-
vp = app.maps.activeMap.getViewpointSync();
|
314
|
-
}
|
317
|
+
const vp = await app.maps.activeMap.getViewpoint();
|
318
|
+
delete vp.cameraPosition;
|
315
319
|
vp.heading = headingValue;
|
320
|
+
vp.animate = true;
|
316
321
|
app.maps.activeMap.gotoViewpoint(vp);
|
317
322
|
},
|
318
323
|
});
|
@@ -430,6 +435,7 @@
|
|
430
435
|
homeAction,
|
431
436
|
rotationAction,
|
432
437
|
movementApiCallsDisabled,
|
438
|
+
mobileLandscape,
|
433
439
|
};
|
434
440
|
},
|
435
441
|
};
|
@@ -445,7 +451,8 @@
|
|
445
451
|
width: unset;
|
446
452
|
padding: 12px;
|
447
453
|
&.mobile {
|
448
|
-
|
454
|
+
// same height as mobile Icon
|
455
|
+
padding-top: 0px;
|
449
456
|
right: 1rem;
|
450
457
|
bottom: auto;
|
451
458
|
}
|
@@ -456,4 +463,7 @@
|
|
456
463
|
margin-bottom: 0;
|
457
464
|
}
|
458
465
|
}
|
466
|
+
.no-zoom {
|
467
|
+
touch-action: none; /* Disable gestures like pinch and double-tap zoom */
|
468
|
+
}
|
459
469
|
</style>
|
@@ -83,5 +83,6 @@ declare const _default: import("vue").DefineComponent<{}, {
|
|
83
83
|
homeAction: any;
|
84
84
|
rotationAction: any;
|
85
85
|
movementApiCallsDisabled: import("vue").Ref<boolean>;
|
86
|
+
mobileLandscape: import("vue").ComputedRef<boolean>;
|
86
87
|
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{}>>, {}, {}>;
|
87
88
|
export default _default;
|
@@ -1,6 +1,7 @@
|
|
1
1
|
<template>
|
2
2
|
<v-list
|
3
|
-
class="ma-0 overflow-y-auto
|
3
|
+
class="ma-0 overflow-y-auto results-component"
|
4
|
+
:class="xs ? 'vcs-search-results-mobile' : 'vcs-search-results'"
|
4
5
|
v-model:selected="highlighted"
|
5
6
|
>
|
6
7
|
<ResultItem
|
@@ -8,10 +9,10 @@
|
|
8
9
|
:query="query"
|
9
10
|
class="cursor-pointer"
|
10
11
|
:class="{
|
11
|
-
'vcs-search-result-border': index <
|
12
|
+
'vcs-search-result-border': index < renderingItems.length - 1,
|
12
13
|
selected: index === selectedIndex,
|
13
14
|
}"
|
14
|
-
v-for="(item, index) in
|
15
|
+
v-for="(item, index) in renderingItems"
|
15
16
|
:key="index"
|
16
17
|
:value="item.value"
|
17
18
|
/>
|
@@ -21,6 +22,7 @@
|
|
21
22
|
<script>
|
22
23
|
import { inject, onUnmounted, ref, computed } from 'vue';
|
23
24
|
import { VList } from 'vuetify/components';
|
25
|
+
import { useDisplay } from 'vuetify';
|
24
26
|
import ResultItem from './ResultItem.vue';
|
25
27
|
|
26
28
|
/**
|
@@ -48,6 +50,10 @@
|
|
48
50
|
type: Number,
|
49
51
|
default: -1,
|
50
52
|
},
|
53
|
+
showSelectedOnly: {
|
54
|
+
type: Boolean,
|
55
|
+
default: false,
|
56
|
+
},
|
51
57
|
},
|
52
58
|
setup(props) {
|
53
59
|
const items = computed(() => {
|
@@ -75,25 +81,43 @@
|
|
75
81
|
},
|
76
82
|
);
|
77
83
|
|
84
|
+
const { xs } = useDisplay();
|
85
|
+
|
86
|
+
const highlighted = computed({
|
87
|
+
get() {
|
88
|
+
return selectedRef.value;
|
89
|
+
},
|
90
|
+
set(value) {
|
91
|
+
selectedRef.value = value;
|
92
|
+
const [index] = value;
|
93
|
+
if (index >= 0) {
|
94
|
+
const item = items.value[index];
|
95
|
+
item.clicked();
|
96
|
+
}
|
97
|
+
},
|
98
|
+
});
|
99
|
+
|
78
100
|
onUnmounted(() => {
|
79
101
|
selectedListener();
|
80
102
|
});
|
81
103
|
|
104
|
+
// Dynamically filter items based on showSelectedOnly
|
105
|
+
const renderingItems = computed(() => {
|
106
|
+
if (props.showSelectedOnly) {
|
107
|
+
const index = selectedRef.value[0];
|
108
|
+
if (index !== undefined && index !== null) {
|
109
|
+
return [items.value[index]];
|
110
|
+
} else {
|
111
|
+
return [];
|
112
|
+
}
|
113
|
+
}
|
114
|
+
return items.value;
|
115
|
+
});
|
116
|
+
|
82
117
|
return {
|
83
|
-
|
84
|
-
highlighted
|
85
|
-
|
86
|
-
return selectedRef.value;
|
87
|
-
},
|
88
|
-
set(value) {
|
89
|
-
selectedRef.value = value;
|
90
|
-
const [index] = value;
|
91
|
-
if (index >= 0) {
|
92
|
-
const item = items.value[index];
|
93
|
-
item.clicked();
|
94
|
-
}
|
95
|
-
},
|
96
|
-
}),
|
118
|
+
renderingItems,
|
119
|
+
highlighted,
|
120
|
+
xs,
|
97
121
|
};
|
98
122
|
},
|
99
123
|
};
|
@@ -103,6 +127,9 @@
|
|
103
127
|
.vcs-search-results {
|
104
128
|
max-height: 400px;
|
105
129
|
}
|
130
|
+
.vcs-search-results-mobile {
|
131
|
+
max-height: 300px;
|
132
|
+
}
|
106
133
|
.vcs-search-result-border {
|
107
134
|
border-bottom: thin solid;
|
108
135
|
border-color: rgb(var(--v-theme-base-lighten-2));
|
@@ -11,9 +11,14 @@ declare const _default: import("vue").DefineComponent<{
|
|
11
11
|
type: NumberConstructor;
|
12
12
|
default: number;
|
13
13
|
};
|
14
|
+
showSelectedOnly: {
|
15
|
+
type: BooleanConstructor;
|
16
|
+
default: boolean;
|
17
|
+
};
|
14
18
|
}, {
|
15
|
-
|
19
|
+
renderingItems: import("vue").ComputedRef<any[]>;
|
16
20
|
highlighted: import("vue").WritableComputedRef<never[]>;
|
21
|
+
xs: import("vue").Ref<boolean>;
|
17
22
|
}, any, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
18
23
|
query: {
|
19
24
|
type: StringConstructor;
|
@@ -27,8 +32,13 @@ declare const _default: import("vue").DefineComponent<{
|
|
27
32
|
type: NumberConstructor;
|
28
33
|
default: number;
|
29
34
|
};
|
35
|
+
showSelectedOnly: {
|
36
|
+
type: BooleanConstructor;
|
37
|
+
default: boolean;
|
38
|
+
};
|
30
39
|
}>>, {
|
31
40
|
query: string;
|
32
41
|
selectedIndex: number;
|
42
|
+
showSelectedOnly: boolean;
|
33
43
|
}, {}>;
|
34
44
|
export default _default;
|