@vcmap/ui 5.0.0-rc.15 → 5.0.0-rc.17
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/build/buildHelpers.js +7 -1
- package/config/base.config.json +7 -45
- package/config/dev.config.json +5 -1
- package/config/www.config.json +14 -13
- package/dist/assets/{cesium.2e288a.js → cesium.41de56.js} +0 -0
- package/dist/assets/cesium.js +1 -1
- package/dist/assets/{core.8014d3.js → core.af84e3.js} +6077 -4544
- package/dist/assets/core.js +1 -1
- package/dist/assets/{index.3f74fa92.js → index.5b773cad.js} +1 -1
- package/dist/assets/{ol.31c3a5.js → ol.5c7490.js} +0 -0
- package/dist/assets/ol.js +1 -1
- package/dist/assets/ui.dffe32.css +1 -0
- package/dist/assets/{ui.36f84f.js → ui.dffe32.js} +7243 -6234
- package/dist/assets/ui.js +1 -1
- package/dist/assets/{vue.a39c10.js → vue.25da17.js} +0 -0
- package/dist/assets/vue.js +2 -2
- package/dist/assets/{vuetify.378637.css → vuetify.e4ece7.css} +1 -1
- package/dist/assets/{vuetify.378637.js → vuetify.e4ece7.js} +5 -2
- package/dist/assets/vuetify.js +2 -2
- package/dist/index.html +1 -1
- package/index.html +77 -0
- package/index.js +18 -3
- package/package.json +4 -2
- package/plugins/@vcmap/create-link/fallbackCreateLink.vue +4 -1
- package/plugins/@vcmap/create-link/index.js +4 -1
- package/plugins/@vcmap/pluginExample/exampleActions.js +45 -0
- package/plugins/@vcmap/pluginExample/index.js +26 -2
- package/plugins/@vcmap/pluginExample/pluginExampleComponent.vue +77 -42
- package/plugins/@vcmap/search-nominatim/nominatim.js +1 -1
- package/plugins/@vcmap/theme-changer/ThemeChangerComponent.vue +4 -2
- package/plugins/categoryTest/Categories.vue +27 -13
- package/plugins/categoryTest/Category.vue +7 -1
- package/plugins/categoryTest/index.js +1 -1
- package/plugins/notifier/index.js +31 -0
- package/plugins/notifier/notifierTester.vue +88 -0
- package/plugins/package.json +1 -1
- package/plugins/test/allIconsComponent.vue +5 -5
- package/plugins/test/emptyComponent.vue +1 -1
- package/plugins/test/index.js +27 -3
- package/plugins/test/myCustomHeader.vue +9 -1
- package/plugins/test/testList.vue +290 -0
- package/plugins/test/vcsContent.vue +1 -1
- package/plugins/test/windowManagerExample.vue +12 -7
- package/plugins/wizardExample/index.js +41 -0
- package/plugins/wizardExample/wizardExample.vue +77 -0
- package/src/actions/actionHelper.js +10 -9
- package/src/application/VcsApp.vue +43 -34
- package/src/components/form-inputs-controls/VcsCheckbox.vue +1 -0
- package/src/components/form-inputs-controls/VcsFormSection.vue +23 -15
- package/src/components/form-inputs-controls/VcsSelect.vue +33 -1
- package/src/components/form-inputs-controls/VcsTextField.vue +11 -3
- package/src/components/form-inputs-controls/VcsWizard.vue +133 -0
- package/src/components/imageElementInjector.vue +22 -0
- package/src/components/lists/VcsList.vue +468 -0
- package/src/components/lists/VcsTreeview.vue +1 -2
- package/src/components/lists/VcsTreeviewLeaf.vue +18 -50
- package/src/components/lists/VcsTreeviewSearchbar.vue +1 -23
- package/src/components/tables/VcsTable.vue +13 -1
- package/src/contentTree/LayerTree.vue +1 -1
- package/src/contentTree/contentTreeCollection.js +9 -0
- package/src/contentTree/contentTreeItem.js +13 -13
- package/src/contentTree/layerContentTreeItem.js +1 -1
- package/src/contentTree/subContentTreeItem.js +1 -1
- package/src/contentTree/vcsObjectContentTreeItem.js +1 -1
- package/src/featureInfo/BalloonComponent.vue +13 -8
- package/src/featureInfo/balloonFeatureInfoView.js +16 -22
- package/src/featureInfo/balloonHelper.js +26 -5
- package/src/featureInfo/featureInfo.js +14 -2
- package/src/featureInfo/featureInfoInteraction.js +1 -1
- package/src/i18n/de.js +13 -1
- package/src/i18n/en.js +13 -1
- package/src/icons/+all.js +4 -0
- package/src/icons/WandIcon.vue +63 -0
- package/src/manager/categoryManager/CategoryComponent.vue +115 -0
- package/src/manager/categoryManager/CategoryComponentList.vue +57 -0
- package/src/manager/categoryManager/CategoryManager.vue +35 -0
- package/src/manager/categoryManager/categoryManager.js +251 -165
- package/src/manager/contextMenu/contextMenuManager.js +8 -2
- package/src/manager/window/WindowComponent.vue +51 -70
- package/src/manager/window/WindowComponentHeader.vue +81 -13
- package/src/manager/window/WindowManager.vue +54 -30
- package/src/manager/window/windowHelper.js +341 -0
- package/src/manager/window/windowManager.js +173 -151
- package/src/navigation/overviewMap.js +10 -9
- package/src/notifier/notifier.js +120 -0
- package/src/notifier/notifierComponent.vue +84 -0
- package/src/styles/variables.scss +19 -3
- package/src/vcsUiApp.js +26 -2
- package/src/vuePlugins/vuetify.js +2 -0
- package/dist/assets/ui.36f84f.css +0 -1
- package/src/manager/categoryManager/ComponentsManager.vue +0 -30
@@ -0,0 +1,341 @@
|
|
1
|
+
import {
|
2
|
+
WindowPositions,
|
3
|
+
WindowSlot,
|
4
|
+
posToPixel,
|
5
|
+
windowPositionFromOptions,
|
6
|
+
} from './windowManager.js';
|
7
|
+
|
8
|
+
/**
|
9
|
+
* margin in px at the border of the map target
|
10
|
+
* limiting windows to be moved out of screen
|
11
|
+
* @type {{top: number, left: number, bottom: number, right: number}}
|
12
|
+
*/
|
13
|
+
export const windowMoveMargin = {
|
14
|
+
top: 0,
|
15
|
+
right: 64,
|
16
|
+
bottom: 32,
|
17
|
+
left: 64,
|
18
|
+
};
|
19
|
+
|
20
|
+
/**
|
21
|
+
* @enum {number}
|
22
|
+
* @property {number} TOP_LEFT
|
23
|
+
* @property {number} TOP_RIGHT
|
24
|
+
* @property {number} BOTTOM_LEFT
|
25
|
+
* @property {number} BOTTOM_RIGHT
|
26
|
+
*/
|
27
|
+
export const WindowAlignment = {
|
28
|
+
TOP_LEFT: 1,
|
29
|
+
TOP_RIGHT: 2,
|
30
|
+
BOTTOM_LEFT: 3,
|
31
|
+
BOTTOM_RIGHT: 4,
|
32
|
+
};
|
33
|
+
|
34
|
+
/**
|
35
|
+
*
|
36
|
+
* @param {HTMLElement} target
|
37
|
+
* @returns {DOMRect|null}
|
38
|
+
*/
|
39
|
+
export function getTargetSize(target) {
|
40
|
+
if (!target) {
|
41
|
+
return null;
|
42
|
+
}
|
43
|
+
return target.parentElement.getBoundingClientRect();
|
44
|
+
}
|
45
|
+
|
46
|
+
/**
|
47
|
+
* WindowPositionOptions from client position relative to a HTMLElement
|
48
|
+
* @param {number} x - client pixel position
|
49
|
+
* @param {number} y - client pixel position
|
50
|
+
* @param {HTMLElement} target - the map's target { @link @import("@vcmap/core").MapCollection }
|
51
|
+
* @param {WindowAlignment} [alignment=WindowAlignment.TOP_LEFT]
|
52
|
+
* @returns {WindowPositionOptions}
|
53
|
+
*/
|
54
|
+
export function getWindowPositionOptions(x, y, target, alignment = WindowAlignment.TOP_LEFT) {
|
55
|
+
const targetSize = getTargetSize(target);
|
56
|
+
if (!targetSize) {
|
57
|
+
return { left: x, top: y };
|
58
|
+
}
|
59
|
+
|
60
|
+
const { left, top, width, height } = targetSize;
|
61
|
+
if (alignment === WindowAlignment.TOP_LEFT) {
|
62
|
+
return { left: x - left, top: y - top };
|
63
|
+
} else if (alignment === WindowAlignment.TOP_RIGHT) {
|
64
|
+
return { right: (left + width) - x, top: y - top };
|
65
|
+
} else if (alignment === WindowAlignment.BOTTOM_LEFT) {
|
66
|
+
return { left: x - left, bottom: (height + top) - y };
|
67
|
+
}
|
68
|
+
return { right: (left + width) - x, bottom: (height + top) - y };
|
69
|
+
}
|
70
|
+
|
71
|
+
/**
|
72
|
+
* Get window position options based on a pixel in the map
|
73
|
+
* @param {import("@vcmap/cesium").Cartesian2} windowPosition - the window position, as retrieved from an InteractionEvent
|
74
|
+
* @param {HTMLElement} target - the map's target { @link @import("@vcmap/core").MapCollection }
|
75
|
+
* @param {WindowAlignment} [alignment]
|
76
|
+
* @returns {WindowPositionOptions}
|
77
|
+
*/
|
78
|
+
export function getWindowPositionOptionsFromMapEvent(windowPosition, target, alignment) {
|
79
|
+
const targetSize = getTargetSize(target);
|
80
|
+
if (!targetSize) {
|
81
|
+
return { left: windowPosition.x, top: windowPosition.y };
|
82
|
+
}
|
83
|
+
|
84
|
+
const { left, top } = targetSize;
|
85
|
+
return getWindowPositionOptions(windowPosition.x + left, windowPosition.y + top, target, alignment);
|
86
|
+
}
|
87
|
+
|
88
|
+
|
89
|
+
/**
|
90
|
+
* Fits a window aligned top left, so it fits into the parent. This will change the alignment to be bottom or right depending
|
91
|
+
* on if the window would not fit into the parent.
|
92
|
+
* @param {number} x - client pixel position
|
93
|
+
* @param {number} y - client pixel position
|
94
|
+
* @param {number} width - window width to fit
|
95
|
+
* @param {number} height - window height to fit
|
96
|
+
* @param {HTMLElement} target - the map's target { @link @import("@vcmap/core").MapCollection }
|
97
|
+
* @returns {WindowPositionOptions}
|
98
|
+
*/
|
99
|
+
export function getFittedWindowPositionOptions(x, y, width, height, target) {
|
100
|
+
const targetSize = getTargetSize(target);
|
101
|
+
if (!targetSize) {
|
102
|
+
return { left: x, top: y };
|
103
|
+
}
|
104
|
+
|
105
|
+
const { width: parentWidth, height: parentHeight } = targetSize;
|
106
|
+
const bottom = y + height > parentHeight;
|
107
|
+
const right = x + width > parentWidth;
|
108
|
+
let alignment = WindowAlignment.TOP_LEFT;
|
109
|
+
if (bottom) {
|
110
|
+
if (right) {
|
111
|
+
alignment = WindowAlignment.BOTTOM_RIGHT;
|
112
|
+
} else {
|
113
|
+
alignment = WindowAlignment.BOTTOM_LEFT;
|
114
|
+
}
|
115
|
+
} else if (right) {
|
116
|
+
alignment = WindowAlignment.TOP_RIGHT;
|
117
|
+
}
|
118
|
+
return getWindowPositionOptions(x, y, target, alignment);
|
119
|
+
}
|
120
|
+
|
121
|
+
/**
|
122
|
+
* Fits a window aligned top left, so it fits into currently active map. This will change the alignment to be bottom or right depending
|
123
|
+
* on if the window would not fit into active map element.
|
124
|
+
* @param {import("@vcmap/cesium").Cartesian2} windowPosition - the window position, as retrieved from an InteractionEvent
|
125
|
+
* @param {number} width
|
126
|
+
* @param {number} height
|
127
|
+
* @param {HTMLElement} target - the map's target { @link @import("@vcmap/core").MapCollection }
|
128
|
+
* @returns {WindowPositionOptions}
|
129
|
+
*/
|
130
|
+
export function getFittedWindowPositionOptionsFromMapEvent(windowPosition, width, height, target) {
|
131
|
+
const targetSize = getTargetSize(target);
|
132
|
+
if (!targetSize) {
|
133
|
+
return { left: windowPosition.x, top: windowPosition.y };
|
134
|
+
}
|
135
|
+
const { left, top } = targetSize;
|
136
|
+
return getFittedWindowPositionOptions(windowPosition.x + left, windowPosition.y + top, width, height, target);
|
137
|
+
}
|
138
|
+
|
139
|
+
/**
|
140
|
+
* Parses a position to numeric value. Non-numeric values return undefined.
|
141
|
+
* @param {string|number|undefined} pos
|
142
|
+
* @param {string} key - one of WindowPosition keys
|
143
|
+
* @param {DOMRect} targetSize - size of the current target
|
144
|
+
* @returns {number|undefined}
|
145
|
+
*/
|
146
|
+
export function posToNumber(pos, key, targetSize) {
|
147
|
+
if (typeof pos === 'string') {
|
148
|
+
if (pos.match(/^-?\d+\.?\d*px$/)) {
|
149
|
+
return parseInt(pos, 10);
|
150
|
+
} else if (targetSize && pos.match(/^-?\d+\.?\d*%$/)) {
|
151
|
+
const scalar = ['bottom', 'top', 'height', 'maxHeight'].includes(key) ? targetSize?.height : targetSize?.width;
|
152
|
+
return (parseInt(pos, 10) / 100) * scalar;
|
153
|
+
}
|
154
|
+
return undefined;
|
155
|
+
}
|
156
|
+
return pos;
|
157
|
+
}
|
158
|
+
|
159
|
+
/**
|
160
|
+
* @param {number} pos
|
161
|
+
* @param {string} key - one of WindowPosition keys
|
162
|
+
* @param {DOMRect} targetSize - size of the current target
|
163
|
+
* @returns {string}
|
164
|
+
*/
|
165
|
+
export function posToPercent(pos, key, targetSize) {
|
166
|
+
if (!targetSize) {
|
167
|
+
return undefined;
|
168
|
+
}
|
169
|
+
const scalar = ['bottom', 'top', 'height', 'maxHeight'].includes(key) ? targetSize.height : targetSize.width;
|
170
|
+
return `${((pos / scalar) * 100).toFixed(0)}%`;
|
171
|
+
}
|
172
|
+
|
173
|
+
/**
|
174
|
+
* Parses CSS position string properties to absolute numeric position properties
|
175
|
+
* @param {WindowPosition} windowPosition
|
176
|
+
* @param {DOMRect} targetSize - the map's target size
|
177
|
+
* @returns {WindowPositionOptions|null}
|
178
|
+
*/
|
179
|
+
export function optionsFromWindowPosition(windowPosition, targetSize) {
|
180
|
+
const options = {};
|
181
|
+
Object.keys(windowPosition).forEach((key) => {
|
182
|
+
if (windowPosition[key] !== undefined) {
|
183
|
+
options[key] = posToNumber(windowPosition[key], key, targetSize);
|
184
|
+
}
|
185
|
+
});
|
186
|
+
return options;
|
187
|
+
}
|
188
|
+
|
189
|
+
/**
|
190
|
+
* Returns an updated WindowPosition by applying new options keeping the original object unchanged.
|
191
|
+
* Ensures units are maintained.
|
192
|
+
* Previous values 'auto' and 'unset' will not be touched.
|
193
|
+
* @param {WindowPosition} previous
|
194
|
+
* @param {WindowPositionOptions} update
|
195
|
+
* @param {DOMRect} targetSize - the map's target size
|
196
|
+
* @returns {WindowPosition}
|
197
|
+
*/
|
198
|
+
export function updateWindowPosition(previous, update, targetSize) {
|
199
|
+
/**
|
200
|
+
* returns the position of a key in the same unit 'px' or '%' as previously
|
201
|
+
* @param {string} key
|
202
|
+
* @param {WindowPosition} prev
|
203
|
+
* @param {WindowPositionOptions} updated
|
204
|
+
* @returns {string}
|
205
|
+
*/
|
206
|
+
const toString = (key, prev, updated) => {
|
207
|
+
if (prev[key] === 'auto' || prev[key] === 'unset' || updated[key] === undefined) {
|
208
|
+
return prev[key];
|
209
|
+
} else if (updated[key] !== 'auto' && updated[key] !== 'unset') {
|
210
|
+
const numeric = posToNumber(updated[key], key, targetSize);
|
211
|
+
if (prev[key] && prev[key].match(/^-?\d+\.?\d*px$/)) {
|
212
|
+
return posToPixel(numeric);
|
213
|
+
} else if (prev[key] && prev[key].match(/^-?\d+%$/)) {
|
214
|
+
return posToPercent(numeric, key, targetSize);
|
215
|
+
}
|
216
|
+
}
|
217
|
+
return updated[key];
|
218
|
+
};
|
219
|
+
|
220
|
+
const updatedPosition = { ...update };
|
221
|
+
Object.keys(previous).forEach((key) => {
|
222
|
+
updatedPosition[key] = toString(key, previous, update);
|
223
|
+
});
|
224
|
+
return updatedPosition;
|
225
|
+
}
|
226
|
+
|
227
|
+
|
228
|
+
/**
|
229
|
+
* Move window position in x and y.
|
230
|
+
* Rightward and downward movements are positive.
|
231
|
+
* @param {string} id - the window id
|
232
|
+
* @param {{dx: number, dy: number}} translation - translation in px
|
233
|
+
* @param {WindowManager} windowManager
|
234
|
+
* @param {DOMRect} targetSize - the map's target size
|
235
|
+
*/
|
236
|
+
export function moveWindow(id, translation, windowManager, targetSize) {
|
237
|
+
const { position, slot } = windowManager.get(id);
|
238
|
+
if (slot.value === WindowSlot.STATIC) {
|
239
|
+
return;
|
240
|
+
}
|
241
|
+
const windowPositionOptions = optionsFromWindowPosition(position, targetSize);
|
242
|
+
if (windowPositionOptions.top !== undefined) {
|
243
|
+
windowPositionOptions.top += translation.dy;
|
244
|
+
}
|
245
|
+
if (windowPositionOptions.bottom !== undefined) {
|
246
|
+
windowPositionOptions.bottom -= translation.dy;
|
247
|
+
}
|
248
|
+
if (windowPositionOptions.left !== undefined) {
|
249
|
+
windowPositionOptions.left += translation.dx;
|
250
|
+
}
|
251
|
+
if (windowPositionOptions.right !== undefined) {
|
252
|
+
windowPositionOptions.right -= translation.dx;
|
253
|
+
}
|
254
|
+
// clear size restrictions
|
255
|
+
if (position.maxHeight === WindowPositions.TOP_RIGHT.maxHeight &&
|
256
|
+
slot.value === WindowSlot.DYNAMIC_RIGHT) {
|
257
|
+
windowPositionOptions.maxHeight = 'unset';
|
258
|
+
}
|
259
|
+
if (position.maxWidth === WindowPositions.TOP_LEFT.maxWidth &&
|
260
|
+
slot.value === WindowSlot.DYNAMIC_LEFT) {
|
261
|
+
windowPositionOptions.maxWidth = 'unset';
|
262
|
+
}
|
263
|
+
const updatedPosition = updateWindowPosition(position, windowPositionOptions, targetSize);
|
264
|
+
windowManager.setWindowPositionOptions(id, updatedPosition);
|
265
|
+
}
|
266
|
+
|
267
|
+
/**
|
268
|
+
* Clips a provided WindowPosition corresponding to the size of its target
|
269
|
+
* @param {WindowPositionOptions} windowPositionOptions - numerical WindowPositionOptions
|
270
|
+
* @param {DOMRect} targetSize - the map's target size
|
271
|
+
* @returns {WindowPositionOptions}
|
272
|
+
*/
|
273
|
+
export function clipToTargetSize(windowPositionOptions, targetSize) {
|
274
|
+
const { width: targetWidth, height: targetHeight } = targetSize;
|
275
|
+
if (!targetWidth || !targetHeight) {
|
276
|
+
return windowPositionOptions;
|
277
|
+
}
|
278
|
+
const clippedPosition = {};
|
279
|
+
if (windowPositionOptions.top !== undefined) {
|
280
|
+
clippedPosition.top = Math.min(
|
281
|
+
Math.max(0, windowPositionOptions.top),
|
282
|
+
targetHeight - windowMoveMargin.bottom,
|
283
|
+
);
|
284
|
+
}
|
285
|
+
if (windowPositionOptions.bottom !== undefined) {
|
286
|
+
const height = windowPositionOptions.height ||
|
287
|
+
targetHeight - windowPositionOptions.bottom - windowPositionOptions.top || windowMoveMargin.bottom;
|
288
|
+
clippedPosition.bottom = Math.min(
|
289
|
+
Math.max(windowPositionOptions.bottom, -height + windowMoveMargin.bottom),
|
290
|
+
targetHeight - height,
|
291
|
+
);
|
292
|
+
}
|
293
|
+
if (windowPositionOptions.left !== undefined) {
|
294
|
+
const width = windowPositionOptions.width ||
|
295
|
+
targetWidth - windowPositionOptions.right - windowPositionOptions.left;
|
296
|
+
clippedPosition.left = Math.min(
|
297
|
+
Math.max(windowPositionOptions.left, -width + windowMoveMargin.left),
|
298
|
+
targetWidth - windowMoveMargin.left,
|
299
|
+
);
|
300
|
+
}
|
301
|
+
if (windowPositionOptions.right !== undefined) {
|
302
|
+
const width = windowPositionOptions.width ||
|
303
|
+
targetWidth - windowPositionOptions.right - windowPositionOptions.left;
|
304
|
+
clippedPosition.right = Math.min(
|
305
|
+
Math.max(windowPositionOptions.right, -width + windowMoveMargin.right),
|
306
|
+
targetWidth - windowMoveMargin.right,
|
307
|
+
);
|
308
|
+
}
|
309
|
+
if (windowPositionOptions.width !== undefined) {
|
310
|
+
clippedPosition.width = windowPositionOptions.width;
|
311
|
+
}
|
312
|
+
if (windowPositionOptions.height !== undefined) {
|
313
|
+
clippedPosition.height = windowPositionOptions.height;
|
314
|
+
}
|
315
|
+
clippedPosition.maxWidth = targetWidth;
|
316
|
+
clippedPosition.maxHeight = targetHeight;
|
317
|
+
if (windowPositionOptions.maxWidth !== undefined) {
|
318
|
+
clippedPosition.maxWidth = Math.min(windowPositionOptions.maxWidth, targetWidth);
|
319
|
+
}
|
320
|
+
if (windowPositionOptions.maxHeight !== undefined) {
|
321
|
+
clippedPosition.maxHeight = Math.min(windowPositionOptions.maxHeight, targetHeight);
|
322
|
+
}
|
323
|
+
|
324
|
+
return clippedPosition;
|
325
|
+
}
|
326
|
+
|
327
|
+
/**
|
328
|
+
* Applies the position on the target clipping the position to the target's size.
|
329
|
+
* @param {WindowPosition} position
|
330
|
+
* @param {DOMRect} targetSize
|
331
|
+
* @returns {WindowPosition}
|
332
|
+
*/
|
333
|
+
export function applyPositionOnTarget(position, targetSize) {
|
334
|
+
if (!targetSize) {
|
335
|
+
return position;
|
336
|
+
}
|
337
|
+
const windowPositionOptions = optionsFromWindowPosition(position, targetSize);
|
338
|
+
const clippedPosition = clipToTargetSize(windowPositionOptions, targetSize);
|
339
|
+
const updatedPosition = updateWindowPosition(position, clippedPosition, targetSize);
|
340
|
+
return windowPositionFromOptions(updatedPosition);
|
341
|
+
}
|