@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.
Files changed (91) hide show
  1. package/build/buildHelpers.js +7 -1
  2. package/config/base.config.json +7 -45
  3. package/config/dev.config.json +5 -1
  4. package/config/www.config.json +14 -13
  5. package/dist/assets/{cesium.2e288a.js → cesium.41de56.js} +0 -0
  6. package/dist/assets/cesium.js +1 -1
  7. package/dist/assets/{core.8014d3.js → core.af84e3.js} +6077 -4544
  8. package/dist/assets/core.js +1 -1
  9. package/dist/assets/{index.3f74fa92.js → index.5b773cad.js} +1 -1
  10. package/dist/assets/{ol.31c3a5.js → ol.5c7490.js} +0 -0
  11. package/dist/assets/ol.js +1 -1
  12. package/dist/assets/ui.dffe32.css +1 -0
  13. package/dist/assets/{ui.36f84f.js → ui.dffe32.js} +7243 -6234
  14. package/dist/assets/ui.js +1 -1
  15. package/dist/assets/{vue.a39c10.js → vue.25da17.js} +0 -0
  16. package/dist/assets/vue.js +2 -2
  17. package/dist/assets/{vuetify.378637.css → vuetify.e4ece7.css} +1 -1
  18. package/dist/assets/{vuetify.378637.js → vuetify.e4ece7.js} +5 -2
  19. package/dist/assets/vuetify.js +2 -2
  20. package/dist/index.html +1 -1
  21. package/index.html +77 -0
  22. package/index.js +18 -3
  23. package/package.json +4 -2
  24. package/plugins/@vcmap/create-link/fallbackCreateLink.vue +4 -1
  25. package/plugins/@vcmap/create-link/index.js +4 -1
  26. package/plugins/@vcmap/pluginExample/exampleActions.js +45 -0
  27. package/plugins/@vcmap/pluginExample/index.js +26 -2
  28. package/plugins/@vcmap/pluginExample/pluginExampleComponent.vue +77 -42
  29. package/plugins/@vcmap/search-nominatim/nominatim.js +1 -1
  30. package/plugins/@vcmap/theme-changer/ThemeChangerComponent.vue +4 -2
  31. package/plugins/categoryTest/Categories.vue +27 -13
  32. package/plugins/categoryTest/Category.vue +7 -1
  33. package/plugins/categoryTest/index.js +1 -1
  34. package/plugins/notifier/index.js +31 -0
  35. package/plugins/notifier/notifierTester.vue +88 -0
  36. package/plugins/package.json +1 -1
  37. package/plugins/test/allIconsComponent.vue +5 -5
  38. package/plugins/test/emptyComponent.vue +1 -1
  39. package/plugins/test/index.js +27 -3
  40. package/plugins/test/myCustomHeader.vue +9 -1
  41. package/plugins/test/testList.vue +290 -0
  42. package/plugins/test/vcsContent.vue +1 -1
  43. package/plugins/test/windowManagerExample.vue +12 -7
  44. package/plugins/wizardExample/index.js +41 -0
  45. package/plugins/wizardExample/wizardExample.vue +77 -0
  46. package/src/actions/actionHelper.js +10 -9
  47. package/src/application/VcsApp.vue +43 -34
  48. package/src/components/form-inputs-controls/VcsCheckbox.vue +1 -0
  49. package/src/components/form-inputs-controls/VcsFormSection.vue +23 -15
  50. package/src/components/form-inputs-controls/VcsSelect.vue +33 -1
  51. package/src/components/form-inputs-controls/VcsTextField.vue +11 -3
  52. package/src/components/form-inputs-controls/VcsWizard.vue +133 -0
  53. package/src/components/imageElementInjector.vue +22 -0
  54. package/src/components/lists/VcsList.vue +468 -0
  55. package/src/components/lists/VcsTreeview.vue +1 -2
  56. package/src/components/lists/VcsTreeviewLeaf.vue +18 -50
  57. package/src/components/lists/VcsTreeviewSearchbar.vue +1 -23
  58. package/src/components/tables/VcsTable.vue +13 -1
  59. package/src/contentTree/LayerTree.vue +1 -1
  60. package/src/contentTree/contentTreeCollection.js +9 -0
  61. package/src/contentTree/contentTreeItem.js +13 -13
  62. package/src/contentTree/layerContentTreeItem.js +1 -1
  63. package/src/contentTree/subContentTreeItem.js +1 -1
  64. package/src/contentTree/vcsObjectContentTreeItem.js +1 -1
  65. package/src/featureInfo/BalloonComponent.vue +13 -8
  66. package/src/featureInfo/balloonFeatureInfoView.js +16 -22
  67. package/src/featureInfo/balloonHelper.js +26 -5
  68. package/src/featureInfo/featureInfo.js +14 -2
  69. package/src/featureInfo/featureInfoInteraction.js +1 -1
  70. package/src/i18n/de.js +13 -1
  71. package/src/i18n/en.js +13 -1
  72. package/src/icons/+all.js +4 -0
  73. package/src/icons/WandIcon.vue +63 -0
  74. package/src/manager/categoryManager/CategoryComponent.vue +115 -0
  75. package/src/manager/categoryManager/CategoryComponentList.vue +57 -0
  76. package/src/manager/categoryManager/CategoryManager.vue +35 -0
  77. package/src/manager/categoryManager/categoryManager.js +251 -165
  78. package/src/manager/contextMenu/contextMenuManager.js +8 -2
  79. package/src/manager/window/WindowComponent.vue +51 -70
  80. package/src/manager/window/WindowComponentHeader.vue +81 -13
  81. package/src/manager/window/WindowManager.vue +54 -30
  82. package/src/manager/window/windowHelper.js +341 -0
  83. package/src/manager/window/windowManager.js +173 -151
  84. package/src/navigation/overviewMap.js +10 -9
  85. package/src/notifier/notifier.js +120 -0
  86. package/src/notifier/notifierComponent.vue +84 -0
  87. package/src/styles/variables.scss +19 -3
  88. package/src/vcsUiApp.js +26 -2
  89. package/src/vuePlugins/vuetify.js +2 -0
  90. package/dist/assets/ui.36f84f.css +0 -1
  91. 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
+ }