@vcmap/ui 5.0.0-rc.10 → 5.0.0-rc.11

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 (116) hide show
  1. package/README.md +11 -4
  2. package/build/build.js +0 -3
  3. package/build/buildHelpers.js +0 -1
  4. package/build/buildPreview.js +7 -0
  5. package/config/aerowest.config.json +13 -3
  6. package/config/base.config.json +89 -64
  7. package/config/codes.config.json +397 -0
  8. package/config/dev.config.json +169 -0
  9. package/config/graphFeatureInfo.config.json +100 -0
  10. package/config/www.config.json +1232 -0
  11. package/dist/assets/{cesium.eb5667.js → cesium.e67536.js} +0 -0
  12. package/dist/assets/cesium.js +1 -1
  13. package/dist/assets/core.ebf665.js +4 -0
  14. package/dist/assets/core.js +1 -1
  15. package/dist/assets/{index.4ccd4433.js → index.9b213929.js} +1 -1
  16. package/dist/assets/{ol.ef03b1.js → ol.8bbd50.js} +0 -0
  17. package/dist/assets/ol.js +1 -1
  18. package/dist/assets/ui.fdfe0d.css +1 -0
  19. package/dist/assets/ui.fdfe0d.js +68 -0
  20. package/dist/assets/ui.js +1 -1
  21. package/dist/assets/vue.0bb7c6.js +9 -0
  22. package/dist/assets/vue.js +2 -1
  23. package/dist/assets/{vuetify.401a29.css → vuetify.53300f.css} +1 -1
  24. package/dist/assets/{vuetify.401a29.js → vuetify.53300f.js} +71 -71
  25. package/dist/assets/vuetify.js +2 -2
  26. package/dist/index.html +1 -1
  27. package/index.js +36 -5
  28. package/lib/vue.js +1 -0
  29. package/map.config.json +15 -6
  30. package/package.json +6 -7
  31. package/plugins/@vcmap/create-link/fallbackCreateLink.vue +71 -0
  32. package/plugins/@vcmap/create-link/index.js +83 -0
  33. package/plugins/@vcmap/create-link/package.json +6 -0
  34. package/plugins/@vcmap/pluginExample/index.js +1 -1
  35. package/plugins/@vcmap/pluginExample/pluginExampleComponent.vue +20 -3
  36. package/plugins/@vcmap/project-selector/ProjectSelectorComponent.vue +1 -1
  37. package/plugins/@vcmap/project-selector/index.js +1 -1
  38. package/plugins/@vcmap/project-selector/package.json +1 -2
  39. package/plugins/@vcmap/theme-changer/ThemeChangerComponent.vue +1 -1
  40. package/plugins/@vcmap/theme-changer/index.js +1 -1
  41. package/plugins/@vcmap/theme-changer/package.json +1 -2
  42. package/plugins/categoryTest/Categories.vue +89 -1
  43. package/plugins/categoryTest/Category.vue +1 -1
  44. package/plugins/simple-graph/README.md +51 -0
  45. package/plugins/simple-graph/SimpleGraphComponent.vue +70 -0
  46. package/plugins/simple-graph/index.js +17 -0
  47. package/plugins/simple-graph/package.json +11 -0
  48. package/plugins/simple-graph/simpleGraphView.js +76 -0
  49. package/plugins/test/editor.vue +1 -1
  50. package/plugins/test/index.js +63 -2
  51. package/plugins/test/windowManagerExample.vue +1 -1
  52. package/src/actions/stateRefAction.js +2 -2
  53. package/src/actions/styleSelector.vue +1 -1
  54. package/src/application/Navbar.vue +13 -2
  55. package/src/application/VcsApp.vue +201 -92
  56. package/src/application/VcsMap.vue +1 -1
  57. package/src/application/VcsSettings.vue +1 -1
  58. package/src/application/vcsAppWrapper.vue +1 -0
  59. package/src/components/form-inputs-controls/VcsCheckbox.vue +13 -0
  60. package/src/components/form-inputs-controls/VcsColorPicker.vue +1 -1
  61. package/src/components/form-inputs-controls/VcsRadio.vue +123 -0
  62. package/src/components/form-output/VcsFormattedNumber.vue +1 -1
  63. package/src/components/lists/VcsActionList.vue +13 -4
  64. package/src/components/lists/VcsTreeview.vue +4 -4
  65. package/src/components/lists/VcsTreeviewLeaf.vue +9 -2
  66. package/src/components/lists/VcsTreeviewSearchbar.vue +1 -2
  67. package/src/components/tables/VcsTable.vue +245 -0
  68. package/src/contentTree/LayerTree.vue +1 -1
  69. package/src/contentTree/contentTreeCollection.js +4 -4
  70. package/src/contentTree/contentTreeItem.js +9 -9
  71. package/src/contentTree/groupContentTreeItem.js +1 -1
  72. package/src/contentTree/layerContentTreeItem.js +15 -1
  73. package/src/contentTree/layerGroupContentTreeItem.js +21 -1
  74. package/src/contentTree/nodeContentTreeItem.js +1 -1
  75. package/src/featureInfo/AddressBalloonComponent.vue +47 -0
  76. package/src/featureInfo/BalloonComponent.vue +138 -0
  77. package/src/featureInfo/abstractFeatureInfoView.js +313 -0
  78. package/src/featureInfo/addressBalloonFeatureInfoView.js +118 -0
  79. package/src/featureInfo/balloonFeatureInfoView.js +151 -0
  80. package/src/featureInfo/balloonHelper.js +132 -0
  81. package/src/featureInfo/featureInfo.js +455 -0
  82. package/src/featureInfo/featureInfoInteraction.js +42 -0
  83. package/src/featureInfo/iframeFeatureInfoView.js +95 -0
  84. package/src/featureInfo/tableFeatureInfoView.js +106 -0
  85. package/src/i18n/de.js +16 -0
  86. package/src/i18n/en.js +16 -0
  87. package/src/i18n/i18nCollection.js +17 -0
  88. package/src/manager/buttonManager.js +5 -5
  89. package/src/manager/categoryManager/ComponentsManager.vue +30 -0
  90. package/src/manager/categoryManager/categoryManager.js +500 -0
  91. package/src/manager/contextMenu/contextMenuComponent.vue +43 -0
  92. package/src/manager/contextMenu/contextMenuInteraction.js +42 -0
  93. package/src/manager/contextMenu/contextMenuManager.js +197 -0
  94. package/src/manager/navbarManager.js +8 -8
  95. package/src/manager/toolbox/ToolboxManager.vue +2 -2
  96. package/src/manager/toolbox/toolboxManager.js +7 -3
  97. package/src/manager/window/WindowComponent.vue +1 -1
  98. package/src/manager/window/WindowManager.vue +5 -3
  99. package/src/manager/window/windowManager.js +118 -14
  100. package/src/navigation/mapNavigation.vue +3 -5
  101. package/src/navigation/overviewMap.js +28 -5
  102. package/src/navigation/vcsCompass.vue +1 -1
  103. package/src/setup.js +0 -2
  104. package/src/state.js +256 -0
  105. package/src/styles/_theming.scss +0 -5
  106. package/src/uiConfig.js +79 -0
  107. package/src/vcsUiApp.js +210 -20
  108. package/src/vuePlugins/vuetify.js +14 -4
  109. package/config/berlin.config.json +0 -510
  110. package/dist/assets/core.216494.js +0 -4
  111. package/dist/assets/ui.99a1a7.css +0 -1
  112. package/dist/assets/ui.99a1a7.js +0 -70
  113. package/dist/assets/vue-composition-api.c5aca1.js +0 -14
  114. package/dist/assets/vue-composition-api.js +0 -2
  115. package/dist/assets/vue.762edd.js +0 -9
  116. package/lib/vue-composition-api.js +0 -2
@@ -0,0 +1,500 @@
1
+ import { ref } from 'vue';
2
+ import { contextIdSymbol, IndexedCollection } from '@vcmap/core';
3
+ import { check } from '@vcsuite/check';
4
+ import { sortByOwner } from '../navbarManager.js';
5
+ import { validateAction, validateActions } from '../../components/lists/VcsActionList.vue';
6
+
7
+ /**
8
+ * @callback MappingFunction
9
+ * @param {T} item
10
+ * @param {import("@vcmap/core").Category<T>} category
11
+ * @param {import("@vcmap/ui").TreeViewItem} treeViewItem
12
+ * @template {Object} T
13
+ */
14
+
15
+ /**
16
+ * @callback PredicateFunction
17
+ * @param {T} item
18
+ * @param {import("@vcmap/core").Category<T>} category
19
+ * @returns {boolean}
20
+ * @template {Object} T
21
+ */
22
+
23
+ /**
24
+ * @typedef {Object} ItemMapping
25
+ * @property {MappingFunction<T>} mappingFunction
26
+ * @property {PredicateFunction<T>} predicate
27
+ * @property {Array<string>} categoryNames
28
+ * @property {string | symbol} owner
29
+ * @template T
30
+ */
31
+
32
+ /**
33
+ * uses the itemMappings to transform the given Item to an TreeViewItem usable in the VCSTreeView
34
+ * @param {T} item
35
+ * @param {import("@vcmap/core").Category<T>} category
36
+ * @param {Array<ItemMapping<T>>} itemMappings
37
+ * @returns {import("@vcmap/ui").TreeViewItem}
38
+ * @template T
39
+ * @private
40
+ */
41
+ function transformItem(item, category, itemMappings) {
42
+ const keyProperty = category.collection.uniqueKey;
43
+ const treeViewItem = {
44
+ get id() { return item[keyProperty]; },
45
+ title: item?.properties?.title || item[keyProperty],
46
+ actions: [],
47
+ children: [],
48
+ };
49
+ itemMappings.forEach((itemMapping) => {
50
+ if (itemMapping.predicate(item, category)) {
51
+ itemMapping.mappingFunction(item, category, treeViewItem);
52
+ }
53
+ });
54
+ treeViewItem.actions = treeViewItem.actions.filter((action) => {
55
+ return validateAction(action);
56
+ });
57
+ return treeViewItem;
58
+ }
59
+
60
+ /**
61
+ * Inserts the item into the children array at the correct relative position in respect to the position of the item
62
+ * in the collection
63
+ * @param {import("@vcmap/ui").TreeViewItem} item
64
+ * @param {import("@vcmap/core").Collection} collection
65
+ * @param {Array<import("@vcmap/ui").TreeViewItem>} children
66
+ * @private
67
+ */
68
+ function insertItem(item, collection, children) {
69
+ if (collection instanceof IndexedCollection) {
70
+ const newItemIndex = collection.indexOfKey(item.id);
71
+ if (newItemIndex === collection.size - 1) {
72
+ children.push(item);
73
+ } else {
74
+ const positionInChildren = children.findIndex((treeViewItem) => {
75
+ const treeViewItemIndex = collection.indexOfKey(treeViewItem.id);
76
+ return newItemIndex < treeViewItemIndex;
77
+ });
78
+ if (positionInChildren >= 0) {
79
+ children.splice(positionInChildren, 0, item);
80
+ }
81
+ }
82
+ } else {
83
+ children.push(item);
84
+ }
85
+ }
86
+
87
+ /**
88
+ * a categoryManager manages categories, and synchronizes a tree of VcsTreeView Items.
89
+ * provides an API to add/remove Categories.
90
+ */
91
+ export default class CategoryManager {
92
+ /**
93
+ * @param {import("@vcmap/ui").VcsUiApp} app
94
+ */
95
+ constructor(app) {
96
+ /**
97
+ * @type {import("@vcmap/ui").VcsUiApp}
98
+ * @private
99
+ */
100
+ this._app = app;
101
+
102
+ /**
103
+ * @type {Map<string, Map<string|symbol, Array<import("@vcmap/ui").VcsAction>>>}
104
+ * @private
105
+ */
106
+ this._managedCategories = new Map();
107
+
108
+ /**
109
+ * @type {Map<string, Array<function():void>>}
110
+ * @private
111
+ */
112
+ this._managedCategoriesListeners = new Map();
113
+
114
+ /**
115
+ * @type {function():void}
116
+ * @private
117
+ */
118
+ this._dynamicContextIdListener = this._app.dynamicContextIdChanged.addEventListener((id) => {
119
+ this._dynamicContextId = id;
120
+ this._resetItems();
121
+ });
122
+
123
+ /**
124
+ * @type {function():void}
125
+ * @private
126
+ */
127
+ this._appCategoriesRemovedListener = this._app.categories.removed.addEventListener((category) => {
128
+ this._removeCategory(category.name);
129
+ });
130
+
131
+ /**
132
+ * @type {string}
133
+ * @private
134
+ */
135
+ this._dynamicContextId = this._app.dynamicContextId;
136
+
137
+ /**
138
+ * @type {Array<ItemMapping<*>>}
139
+ * @private
140
+ */
141
+ this._itemMappings = [];
142
+
143
+ /**
144
+ * @type {import("vue").Ref<Array<import("@vcmap/ui").TreeViewItem>>}
145
+ * @private
146
+ */
147
+ this._items = ref([]);
148
+ }
149
+
150
+ /**
151
+ * synchronizes the category items with the internal items list.
152
+ * @param {T} item
153
+ * @param {import("@vcmap/core").Category<T>} category
154
+ * @template T
155
+ * @private
156
+ */
157
+ _handleItemAdded(item, category) {
158
+ const itemMappings = this._itemMappings.filter((itemMapping) => {
159
+ return itemMapping.categoryNames.includes(category.name);
160
+ });
161
+ const finishedUiItem = transformItem(item, category, itemMappings);
162
+ const categoryItem = this.items.value.find((elem) => { return elem.id === category.name; });
163
+ if (categoryItem) {
164
+ insertItem(finishedUiItem, category.collection, categoryItem.children);
165
+ /* if (category.collection instanceof IndexedCollection) {
166
+ const newItemIndex = category.collection.indexOf(item);
167
+ let indexToInsert = 0;
168
+ // eslint-disable-next-line for-direction
169
+ for (let index = categoryItem.children.length - 1; index >= 0; index--) {
170
+ const treeViewItem = categoryItem.children[index];
171
+ const treeViewItemIndex = category.collection.indexOfKey(treeViewItem.id);
172
+ if (treeViewItemIndex < newItemIndex) {
173
+ // should be added directly after this item
174
+ indexToInsert = index + 1;
175
+ break;
176
+ }
177
+ }
178
+ categoryItem.children.splice(indexToInsert, 0, finishedUiItem);
179
+ } else {
180
+ categoryItem.children.push(finishedUiItem);
181
+ } */
182
+ }
183
+ }
184
+
185
+ /**
186
+ * synchronizes the order of the treeViewItems with respect to the order of the items in the collection.
187
+ * removes and reinserts the moved item.
188
+ * @param {T} item
189
+ * @param {import("@vcmap/core").Category<T>} category
190
+ * @template T
191
+ * @private
192
+ */
193
+ _handleItemMoved(item, category) {
194
+ const categoryItem = this.items.value.find((elem) => { return elem.id === category.name; });
195
+ if (categoryItem) {
196
+ const index = categoryItem.children.findIndex((elem) => { return elem.id === item.name; });
197
+ if (index > -1) {
198
+ const treeViewItem = categoryItem.children[index];
199
+ categoryItem.children.splice(index, 1);
200
+ insertItem(treeViewItem, category.collection, categoryItem.children);
201
+ }
202
+ }
203
+ }
204
+
205
+ /**
206
+ * synchronizes the category items with the internal items list.
207
+ * @param {T} item
208
+ * @param {import("@vcmap/core").Category<T>} category
209
+ * @template T
210
+ * @private
211
+ */
212
+ _handleItemRemoved(item, category) {
213
+ const categoryItem = this.items.value.find((elem) => { return elem.id === category.name; });
214
+ if (categoryItem) {
215
+ const index = categoryItem.children.findIndex((elem) => { return elem.id === item.name; });
216
+ if (index > -1) {
217
+ categoryItem.children.splice(index, 1);
218
+ }
219
+ }
220
+ }
221
+
222
+ /**
223
+ * removes all Items and rebuilds the item tree depending on the ContextId
224
+ * @private
225
+ */
226
+ _resetItems() {
227
+ this.items.value.splice(0);
228
+ this._managedCategories.forEach((value, categoryName) => {
229
+ this._resetCategory(categoryName);
230
+ });
231
+ }
232
+
233
+ /**
234
+ * resets the category, removes the currently managed state and rebuilds the categoryItem and all children
235
+ * @param {string} categoryName
236
+ * @private
237
+ */
238
+ _resetCategory(categoryName) {
239
+ const category = this._app.categories.getByKey(categoryName);
240
+ if (!category) {
241
+ throw new Error(`Could not find Category: ${categoryName}`);
242
+ }
243
+ // cleanup existing listeners
244
+ if (this._managedCategoriesListeners.has(categoryName)) {
245
+ this._managedCategoriesListeners.get(categoryName).forEach((listener) => {
246
+ listener();
247
+ });
248
+ this._managedCategoriesListeners.delete(categoryName);
249
+ }
250
+
251
+ const categoryItemIndex = this._items.value.findIndex((item) => {
252
+ return item.id === category.name;
253
+ });
254
+ const actions = [...this._managedCategories.get(category.name).values()].flatMap(ownerActions => ownerActions);
255
+
256
+ const itemMappings = this._itemMappings.filter((itemMapping) => {
257
+ return itemMapping.categoryNames.includes(category.name);
258
+ });
259
+ const children = [...category.collection]
260
+ .filter((item) => {
261
+ return item[contextIdSymbol] === this._dynamicContextId;
262
+ })
263
+ .map((item) => {
264
+ return transformItem(item, category, itemMappings);
265
+ });
266
+
267
+
268
+ const categoryItem = {
269
+ id: category.name,
270
+ title: category.title,
271
+ children,
272
+ actions,
273
+ };
274
+ if (categoryItemIndex >= 0) {
275
+ this._items.value.splice(categoryItemIndex, 1, categoryItem);
276
+ } else {
277
+ this._items.value.push(categoryItem);
278
+ }
279
+
280
+ const listeners = [
281
+ category.collection.added.addEventListener((item) => {
282
+ if (item[contextIdSymbol] === this._dynamicContextId) {
283
+ this._handleItemAdded(item, category);
284
+ }
285
+ }),
286
+ category.collection.removed.addEventListener((item) => {
287
+ if (item[contextIdSymbol] === this._dynamicContextId) {
288
+ this._handleItemRemoved(item, category);
289
+ }
290
+ }),
291
+ category.collection.replaced.addEventListener((replacedEvent) => {
292
+ if (replacedEvent.old[contextIdSymbol] === this._dynamicContextId) {
293
+ this._handleItemRemoved(replacedEvent.old, category);
294
+ }
295
+ }),
296
+ ];
297
+
298
+ if (category.collection instanceof IndexedCollection) {
299
+ listeners.push(category.collection.moved.addEventListener((item) => {
300
+ if (item[contextIdSymbol] === this._dynamicContextId) {
301
+ this._handleItemMoved(item, category);
302
+ }
303
+ }));
304
+ }
305
+
306
+ this._managedCategoriesListeners.set(category.name, listeners);
307
+ }
308
+
309
+ /**
310
+ * updates the root item of this category in the items array.
311
+ * Only updates the actions
312
+ * @param {string} categoryName
313
+ * @private
314
+ */
315
+ _updateCategory(categoryName) {
316
+ if (this._managedCategories.has(categoryName)) {
317
+ const categoryUiItem = this._items.value.find((item) => {
318
+ return item.id === categoryName;
319
+ });
320
+ if (categoryUiItem) {
321
+ const pluginNames = [...this._app.plugins].map(p => p.name);
322
+ const actions = [...this._managedCategories.get(categoryName).entries()]
323
+ .sort(([ownerA], [ownerB]) => sortByOwner(ownerA, ownerB, pluginNames))
324
+ .map(([, value]) => value)
325
+ .flatMap(ownerActions => ownerActions);
326
+ categoryUiItem.actions = actions;
327
+ }
328
+ }
329
+ }
330
+
331
+ /**
332
+ * adds a category to this manager, the category will be shown in the components window.
333
+ * If a category has been added by several owners the actions will be merged and sorted by the order of the
334
+ * owner in the app.plugins collection.
335
+ * @param {string} categoryName
336
+ * @param {string | symbol} owner
337
+ * @param {Array<VcsAction>} actions
338
+ */
339
+ addCategory(categoryName, owner, actions) {
340
+ check(categoryName, String);
341
+ check(owner, [String, Symbol]);
342
+ if (!validateActions(actions)) {
343
+ throw new Error('Invalid actions Array');
344
+ }
345
+ if (!this._app.categories.hasKey(categoryName)) {
346
+ throw new Error(`Could not find category: ${categoryName}`);
347
+ }
348
+
349
+ if (this._managedCategories.get(categoryName)?.has(owner)) {
350
+ throw new Error(`Category has already been added by this owner: ${categoryName}, ${owner}`);
351
+ }
352
+
353
+ if (!this._managedCategories.has(categoryName)) {
354
+ const managedCategory = new Map();
355
+ managedCategory.set(owner, actions.slice());
356
+ this._managedCategories.set(categoryName, managedCategory);
357
+ this._resetCategory(categoryName);
358
+ } else {
359
+ this._managedCategories.get(categoryName).set(owner, actions.slice());
360
+ this._updateCategory(categoryName);
361
+ }
362
+ }
363
+
364
+ /**
365
+ * removes a category from this manager
366
+ * @param {string} categoryName
367
+ * @param {string | symbol} owner
368
+ */
369
+ removeCategory(categoryName, owner) {
370
+ check(categoryName, String);
371
+ check(owner, [String, Symbol]);
372
+ if (!this._managedCategories.has(categoryName)) {
373
+ return;
374
+ }
375
+ this._managedCategories.get(categoryName).delete(owner);
376
+ if (this._managedCategories.get(categoryName).size > 0) {
377
+ this._updateCategory(categoryName);
378
+ } else {
379
+ this._removeCategory(categoryName);
380
+ }
381
+ }
382
+
383
+ /**
384
+ * removes a Category from management, removes all Listeners, and updates the treeViewItems
385
+ * @param {string} categoryName
386
+ * @private
387
+ */
388
+ _removeCategory(categoryName) {
389
+ // remove rootCategoryItem
390
+ const categoryItemIndex = this._items.value.findIndex((item) => {
391
+ return item.id === categoryName;
392
+ });
393
+ if (categoryItemIndex >= 0) {
394
+ this._items.value.splice(categoryItemIndex, 1);
395
+ }
396
+ this._managedCategoriesListeners.get(categoryName)
397
+ ?.forEach((listenerCallback) => {
398
+ listenerCallback();
399
+ });
400
+ this._managedCategoriesListeners.delete(categoryName);
401
+ this._managedCategories.delete(categoryName);
402
+ }
403
+
404
+ /**
405
+ * adds MappingFunction the categoryManager. For the given categoryNames each Item will be transformed by the
406
+ * mappingFunction if the predicate returns true.
407
+ * @param {PredicateFunction} predicate
408
+ * @param {MappingFunction} mappingFunction
409
+ * @param {Array<string>} categoryNames list of categories this mappingFunction should be used on
410
+ * @param {string | symbol} owner
411
+ */
412
+ addMappingFunction(predicate, mappingFunction, categoryNames, owner) {
413
+ check(predicate, Function);
414
+ check(mappingFunction, Function);
415
+ check(categoryNames, [String]);
416
+ check(owner, [String, Symbol]);
417
+ if (categoryNames.length === 0) {
418
+ throw new Error('Provide at least one categoryName');
419
+ }
420
+ if (this._itemMappings.find((itemMapping) => {
421
+ return itemMapping.mappingFunction === mappingFunction && itemMapping.owner === owner;
422
+ })) {
423
+ throw new Error('Could not add MappingFunction, the MappingFunction is already under management');
424
+ }
425
+ /** @type {ItemMapping} */
426
+ const itemMapping = {
427
+ predicate,
428
+ mappingFunction,
429
+ categoryNames: categoryNames.slice(),
430
+ owner,
431
+ };
432
+ this._itemMappings.push(itemMapping);
433
+ itemMapping.categoryNames.forEach((categoryName) => {
434
+ if (this._managedCategories.has(categoryName)) {
435
+ this._resetCategory(categoryName);
436
+ }
437
+ });
438
+ }
439
+
440
+ /**
441
+ * removes the given mappingFunction
442
+ * @param {MappingFunction} mappingFunction
443
+ * @param {string | symbol} owner
444
+ */
445
+ removeMappingFunction(mappingFunction, owner) {
446
+ check(mappingFunction, Function);
447
+ check(owner, [String, Symbol]);
448
+ const affectedCategories = [];
449
+ this._itemMappings = this._itemMappings.filter((itemMapping) => {
450
+ if (itemMapping.mappingFunction === mappingFunction && itemMapping.owner === owner) {
451
+ affectedCategories.push(...itemMapping.categoryNames);
452
+ return false;
453
+ }
454
+ return true;
455
+ });
456
+ new Set(affectedCategories).forEach((categoryName) => {
457
+ this._resetCategory(categoryName);
458
+ });
459
+ }
460
+
461
+ /**
462
+ * removes managed categories and mappingFunctions belonging to the given owner.
463
+ * @param {string | symbol} owner
464
+ */
465
+ removeOwner(owner) {
466
+ check(owner, [String, Symbol]);
467
+ this._managedCategories.forEach((managedCategory, categoryName) => {
468
+ managedCategory.delete(owner);
469
+ if (managedCategory.size === 0) {
470
+ this._managedCategories.delete(categoryName);
471
+ }
472
+ });
473
+ this._itemMappings = this._itemMappings.filter((itemMapping) => {
474
+ return itemMapping.owner !== owner;
475
+ });
476
+ this._resetItems();
477
+ }
478
+
479
+ /**
480
+ * Array to render in TreeView
481
+ * @returns {import("vue").Ref<Array<import("@vcmap/ui").TreeViewItem>>}
482
+ */
483
+ get items() {
484
+ return this._items;
485
+ }
486
+
487
+ /**
488
+ * destroys the categoryManager, removes all Listeners and clears all Managed Categories
489
+ */
490
+ destroy() {
491
+ this._dynamicContextIdListener();
492
+ this._appCategoriesRemovedListener();
493
+ this.items.value.splice(0);
494
+ this._managedCategories.clear();
495
+ [...this._managedCategoriesListeners.values()].forEach((listeners) => {
496
+ listeners.forEach((listener) => { listener(); });
497
+ });
498
+ this._managedCategoriesListeners.clear();
499
+ }
500
+ }
@@ -0,0 +1,43 @@
1
+ <template>
2
+ <div @click.stop="close">
3
+ <VcsActionList
4
+ :actions="actions"
5
+ :show-icon="true"
6
+ />
7
+ </div>
8
+ </template>
9
+
10
+ <script>
11
+ import { inject } from 'vue';
12
+ import VcsActionList from '../../components/lists/VcsActionList.vue';
13
+
14
+ /**
15
+ * @type {string}
16
+ */
17
+ export const contextMenuWindowId = 'contextMenuWindow';
18
+
19
+ export default {
20
+ name: 'ContextMenuComponent',
21
+ components: { VcsActionList },
22
+ props: {
23
+ actions: {
24
+ type: Array,
25
+ required: true,
26
+ },
27
+ },
28
+ setup() {
29
+ const app = inject('vcsApp');
30
+
31
+ const close = () => {
32
+ app.windowManager.remove(contextMenuWindowId);
33
+ };
34
+
35
+ return {
36
+ close,
37
+ };
38
+ },
39
+ };
40
+ </script>
41
+
42
+ <style scoped>
43
+ </style>
@@ -0,0 +1,42 @@
1
+ import { AbstractInteraction, EventType, ModificationKeyType, PointerKeyType } from '@vcmap/core';
2
+
3
+ /**
4
+ * Class to call a callback on right click and a callback on any other click
5
+ * @class
6
+ * @extends {AbstractInteraction}
7
+ */
8
+ class ContextMenuInteraction extends AbstractInteraction {
9
+ /**
10
+ * @param {function(import("@vcmap/core").InteractionEvent):Promise<void>} rightClick - the right click callback, called on right click only
11
+ * @param {function(import("@vcmap/core").InteractionEvent):Promise<void>} clear - the clear callback
12
+ */
13
+ constructor(rightClick, clear) {
14
+ super(EventType.CLICK, ModificationKeyType.ALL, PointerKeyType.ALL);
15
+ /**
16
+ * @type {function(import("@vcmap/core").InteractionEvent): Promise<void>}
17
+ * @private
18
+ */
19
+ this._clear = clear;
20
+ /**
21
+ * @type {function(import("@vcmap/core").InteractionEvent): Promise<void>}
22
+ * @private
23
+ */
24
+ this._rightClick = rightClick;
25
+ }
26
+
27
+ /**
28
+ * @inheritDoc
29
+ * @param {import("@vcmap/core").InteractionEvent} event
30
+ * @returns {Promise<import("@vcmap/core").InteractionEvent>}
31
+ */
32
+ async pipe(event) {
33
+ if (event.pointer & PointerKeyType.RIGHT) {
34
+ await this._rightClick(event);
35
+ } else {
36
+ await this._clear(event);
37
+ }
38
+ return event;
39
+ }
40
+ }
41
+
42
+ export default ContextMenuInteraction;