@vcmap/ui 5.0.0-rc.14 → 5.0.0-rc.16

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 (132) hide show
  1. package/README.md +33 -31
  2. package/build/build.js +9 -0
  3. package/build/buildHelpers.js +12 -10
  4. package/build/commonViteConfig.js +3 -10
  5. package/config/base.config.json +30 -24
  6. package/config/dev.config.json +13 -1
  7. package/config/www.config.json +104 -17
  8. package/dist/assets/cesium.430460.js +137226 -0
  9. package/dist/assets/cesium.js +1 -1
  10. package/dist/assets/core.5089ba.js +16024 -0
  11. package/dist/assets/core.js +1 -1
  12. package/dist/assets/index.854f8e2b.js +1 -0
  13. package/dist/assets/ol.9be53a.js +44279 -0
  14. package/dist/assets/ol.js +1 -1
  15. package/dist/assets/{ui.15ef6a.css → ui.49010a.css} +1 -1
  16. package/dist/assets/ui.49010a.js +16776 -0
  17. package/dist/assets/ui.js +1 -1
  18. package/dist/assets/vue.247c1c.js +4675 -0
  19. package/dist/assets/vue.js +5 -2
  20. package/dist/assets/{vuetify.202322.css → vuetify.735e58.css} +1 -1
  21. package/dist/assets/vuetify.735e58.js +21019 -0
  22. package/dist/assets/vuetify.js +5 -2
  23. package/dist/index.html +1 -1
  24. package/index.html +77 -0
  25. package/index.js +8 -1
  26. package/package.json +12 -10
  27. package/plugins/@vcmap/create-link/fallbackCreateLink.vue +4 -1
  28. package/plugins/@vcmap/create-link/index.js +4 -1
  29. package/plugins/@vcmap/pluginExample/exampleActions.js +45 -0
  30. package/plugins/@vcmap/pluginExample/index.js +38 -1
  31. package/plugins/@vcmap/pluginExample/pluginExampleComponent.vue +152 -98
  32. package/plugins/@vcmap/project-selector/ContextsListComponent.vue +8 -1
  33. package/plugins/@vcmap/project-selector/ProjectSelectorComponent.vue +27 -1
  34. package/plugins/@vcmap/search-nominatim/LICENSE.md +14 -0
  35. package/plugins/@vcmap/search-nominatim/README.md +2 -0
  36. package/plugins/@vcmap/search-nominatim/config.json +4 -0
  37. package/plugins/@vcmap/search-nominatim/index.js +26 -0
  38. package/plugins/@vcmap/search-nominatim/nominatim.js +170 -0
  39. package/plugins/@vcmap/search-nominatim/package.json +43 -0
  40. package/plugins/@vcmap/theme-changer/ThemeChangerComponent.vue +26 -0
  41. package/plugins/buttonExamples/ButtonExamples.vue +28 -1
  42. package/plugins/categoryTest/Categories.vue +16 -0
  43. package/plugins/categoryTest/Category.vue +30 -4
  44. package/plugins/example/mySuperComponent.vue +12 -1
  45. package/plugins/notifier/index.js +31 -0
  46. package/plugins/notifier/notifierTester.vue +88 -0
  47. package/plugins/package.json +2 -1
  48. package/plugins/simple-graph/SimpleGraphComponent.vue +5 -11
  49. package/plugins/test/allIconsComponent.vue +16 -0
  50. package/plugins/test/editor.vue +3 -0
  51. package/plugins/test/emptyComponent.vue +3 -0
  52. package/plugins/test/index.js +22 -0
  53. package/plugins/test/myCustomHeader.vue +9 -1
  54. package/plugins/test/testList.vue +287 -0
  55. package/plugins/test/vcsContent.vue +3 -0
  56. package/plugins/test/windowManagerExample.vue +3 -0
  57. package/plugins/wizardExample/index.js +41 -0
  58. package/plugins/wizardExample/wizardExample.vue +77 -0
  59. package/src/actions/actionHelper.js +103 -2
  60. package/src/actions/styleSelector.vue +9 -0
  61. package/src/application/VcsApp.vue +95 -17
  62. package/src/application/VcsAttributions.vue +63 -0
  63. package/src/application/VcsAttributionsFooter.vue +87 -0
  64. package/src/application/{Navbar.vue → VcsNavbar.vue} +35 -2
  65. package/src/application/VcsSettings.vue +4 -0
  66. package/src/application/attributionsHelper.js +150 -0
  67. package/src/application/vcsAppWrapper.vue +5 -1
  68. package/src/components/buttons/VcsActionButtonList.vue +8 -1
  69. package/src/components/buttons/VcsButton.vue +7 -1
  70. package/src/components/form-inputs-controls/VcsCheckbox.vue +7 -2
  71. package/src/components/form-inputs-controls/VcsColorPicker.vue +4 -0
  72. package/src/components/form-inputs-controls/VcsFormSection.vue +55 -9
  73. package/src/components/form-inputs-controls/VcsRadio.vue +7 -1
  74. package/src/components/form-inputs-controls/VcsSelect.vue +38 -2
  75. package/src/components/form-inputs-controls/VcsTextArea.vue +2 -0
  76. package/src/components/form-inputs-controls/VcsTextField.vue +16 -4
  77. package/src/components/form-inputs-controls/VcsWizard.vue +133 -0
  78. package/src/components/imageElementInjector.vue +22 -0
  79. package/src/components/lists/VcsActionList.vue +12 -1
  80. package/src/components/lists/VcsList.vue +466 -0
  81. package/src/components/lists/VcsTreeview.vue +7 -3
  82. package/src/components/lists/VcsTreeviewLeaf.vue +23 -51
  83. package/src/components/lists/VcsTreeviewSearchbar.vue +6 -23
  84. package/src/components/notification/VcsTooltip.vue +14 -9
  85. package/src/components/tables/VcsTable.vue +129 -38
  86. package/src/contentTree/LayerTree.vue +1 -1
  87. package/src/contentTree/contentTreeItem.js +13 -13
  88. package/src/contentTree/subContentTreeItem.js +1 -1
  89. package/src/contentTree/vcsObjectContentTreeItem.js +1 -1
  90. package/src/featureInfo/AddressBalloonComponent.vue +17 -1
  91. package/src/featureInfo/BalloonComponent.vue +63 -27
  92. package/src/featureInfo/balloonFeatureInfoView.js +14 -14
  93. package/src/featureInfo/balloonHelper.js +4 -0
  94. package/src/featureInfo/featureInfo.js +23 -2
  95. package/src/featureInfo/featureInfoInteraction.js +1 -1
  96. package/src/i18n/de.js +22 -0
  97. package/src/i18n/en.js +22 -0
  98. package/src/icons/+all.js +4 -0
  99. package/src/icons/WandIcon.vue +63 -0
  100. package/src/legend/legendHelper.js +18 -12
  101. package/src/legend/styleLegendItem.vue +20 -1
  102. package/src/legend/vcsLegend.vue +29 -3
  103. package/src/manager/toolbox/GroupToolboxComponent.vue +13 -1
  104. package/src/manager/toolbox/SelectToolboxComponent.vue +13 -1
  105. package/src/manager/toolbox/ToolboxManager.vue +3 -0
  106. package/src/manager/window/WindowComponent.vue +15 -2
  107. package/src/manager/window/WindowComponentHeader.vue +38 -7
  108. package/src/manager/window/WindowManager.vue +1 -0
  109. package/src/manager/window/windowManager.js +11 -1
  110. package/src/navigation/mapNavigation.vue +15 -36
  111. package/src/navigation/orientationToolsButton.vue +6 -1
  112. package/src/navigation/overviewMap.js +19 -47
  113. package/src/navigation/tiltSlider.vue +3 -0
  114. package/src/navigation/vcsCompass.vue +2 -0
  115. package/src/notifier/notifier.js +121 -0
  116. package/src/notifier/notifierComponent.vue +84 -0
  117. package/src/search/resultItem.vue +89 -0
  118. package/src/search/resultsComponent.vue +98 -0
  119. package/src/search/search.js +326 -0
  120. package/src/search/searchComponent.vue +90 -0
  121. package/src/styles/_typography.scss +3 -0
  122. package/src/styles/utils/_cursor.scss +4 -0
  123. package/src/styles/variables.scss +23 -4
  124. package/src/vcsUiApp.js +35 -1
  125. package/src/vuePlugins/vuetify.js +2 -0
  126. package/dist/assets/cesium.9489f8.js +0 -8699
  127. package/dist/assets/core.aa346a.js +0 -4
  128. package/dist/assets/index.3cd4fffa.js +0 -1
  129. package/dist/assets/ol.39651b.js +0 -439
  130. package/dist/assets/ui.15ef6a.js +0 -71
  131. package/dist/assets/vue.cbe9d8.js +0 -9
  132. package/dist/assets/vuetify.202322.js +0 -148
@@ -59,7 +59,7 @@ function getLogger() {
59
59
  * @param {string} defaultFillColor
60
60
  * @returns {import("ol/style/Style").default|import("@vcmap/core").VectorStyleItem}
61
61
  */
62
- function getHighlightStyle(feature, layer, defaultFillColor) {
62
+ export function getHighlightStyle(feature, layer, defaultFillColor) {
63
63
  if (layer && layer.highlightStyle) {
64
64
  return layer.highlightStyle;
65
65
  }
@@ -175,6 +175,12 @@ function setupFeatureInfoTool(app) {
175
175
  */
176
176
  export const featureInfoClassRegistry = new ClassRegistry();
177
177
 
178
+ /**
179
+ * Symbol added to features to overwrite the layers predefined feature info
180
+ * @type {symbol}
181
+ */
182
+ export const featureInfoViewSymbol = Symbol('featureInfoView');
183
+
178
184
  /**
179
185
  * @class FeatureInfo
180
186
  * @description Provides registration of featureInfoClasses and stores featureInfoView instances in its collection.
@@ -225,6 +231,11 @@ class FeatureInfo {
225
231
  * @private
226
232
  */
227
233
  this._selectedFeature = null;
234
+ /**
235
+ * @type {string|null}
236
+ * @private
237
+ */
238
+ this._selectedFeatureId = null;
228
239
  /**
229
240
  * @type {Array<function():void>}
230
241
  * @private
@@ -293,6 +304,12 @@ class FeatureInfo {
293
304
  */
294
305
  get selectedFeature() { return this._selectedFeature; }
295
306
 
307
+ /**
308
+ * @type {null|string}
309
+ * @readonly
310
+ */
311
+ get selectedFeatureId() { return this._selectedFeatureId; }
312
+
296
313
  /**
297
314
  * The window id of the current features FeatureInfoView window
298
315
  * @type {string|null}
@@ -355,7 +372,9 @@ class FeatureInfo {
355
372
  checkMaybe(windowPosition, [Number]);
356
373
  checkMaybe(featureInfoView, AbstractFeatureInfoView);
357
374
 
358
- const usedFeatureInfoView = featureInfoView ?? this._getFeatureInfoViewForFeature(feature);
375
+ const usedFeatureInfoView = feature[featureInfoViewSymbol] ??
376
+ featureInfoView ??
377
+ this._getFeatureInfoViewForFeature(feature);
359
378
  const layer = this._app.layers.getByKey(feature[vcsLayerName]);
360
379
 
361
380
  if (usedFeatureInfoView && layer) {
@@ -396,6 +415,7 @@ class FeatureInfo {
396
415
  );
397
416
 
398
417
  this._selectedFeature = feature;
418
+ this._selectedFeatureId = feature.getId();
399
419
  this._featureChanged.raiseEvent(this._selectedFeature);
400
420
  } else {
401
421
  this.clear();
@@ -428,6 +448,7 @@ class FeatureInfo {
428
448
  this._clearInternal();
429
449
  if (this._selectedFeature) {
430
450
  this._selectedFeature = null;
451
+ this._selectedFeatureId = null;
431
452
  this._featureChanged.raiseEvent(this._selectedFeature);
432
453
  }
433
454
  }
@@ -24,7 +24,7 @@ class FeatureInfoInteraction extends AbstractInteraction {
24
24
  */
25
25
  async pipe(event) {
26
26
  if (event.feature) {
27
- if (!this._featureInfo.selectedFeature || event.feature.getId() !== this._featureInfo.selectedFeature.getId()) {
27
+ if (!this._featureInfo.selectedFeature || event.feature.getId() !== this._featureInfo.selectedFeatureId) {
28
28
  event.stopPropagation = true;
29
29
  await this._featureInfo.selectFeature(
30
30
  event.feature,
package/src/i18n/de.js CHANGED
@@ -44,11 +44,16 @@ const messages = {
44
44
  components: {
45
45
  title: 'Komponenten',
46
46
  tooltip: 'Komponenten',
47
+ close: 'Fenster schließen.',
48
+ vcsFormSection: {
49
+ help: 'Hilfe anzeigen.',
50
+ },
47
51
  vcsTable: {
48
52
  key: 'Name',
49
53
  value: 'Wert',
50
54
  searchbarPlaceholder: 'Name, Wert, ...',
51
55
  itemsPerPage: 'pro Seite',
56
+ ofItems: 'von',
52
57
  nextPage: 'Nächste Seite',
53
58
  formerPage: 'Vorherige Seite',
54
59
  },
@@ -69,12 +74,29 @@ const messages = {
69
74
  openInNew: 'In neuem Browser Tab öffnen',
70
75
  defaultLabelText: 'Text',
71
76
  },
77
+ search: {
78
+ title: 'Suche',
79
+ tooltip: 'Suche',
80
+ select: 'Suchergebnis selektieren',
81
+ placeholder: 'Suche nach Straße, Adresse, Ort, POI',
82
+ zoomToFeatureAction: 'Auf Ergebnis zoomen',
83
+ },
72
84
  toolbox: {
73
85
  flight: 'Flug',
74
86
  miscellaneous: 'Verschiedenes',
75
87
  },
76
88
  footer: {
77
89
  title: 'Fußzeile',
90
+ attributions: {
91
+ title: 'Attribution',
92
+ tooltip: 'Öffne Attribution Fenster',
93
+ },
94
+ },
95
+ notification: {
96
+ error: 'Fehler',
97
+ warning: 'Warnung',
98
+ information: 'Information',
99
+ success: 'Erfolg',
78
100
  },
79
101
  };
80
102
 
package/src/i18n/en.js CHANGED
@@ -44,11 +44,16 @@ const messages = {
44
44
  components: {
45
45
  title: 'Components',
46
46
  tooltip: 'Components',
47
+ close: 'Close window.',
48
+ vcsFormSection: {
49
+ help: 'Show help.',
50
+ },
47
51
  vcsTable: {
48
52
  key: 'Name',
49
53
  value: 'Value',
50
54
  searchbarPlaceholder: 'Name, Value, ...',
51
55
  itemsPerPage: 'per page',
56
+ ofItems: 'of',
52
57
  nextPage: 'Next page',
53
58
  formerPage: 'Former page',
54
59
  },
@@ -69,12 +74,29 @@ const messages = {
69
74
  openInNew: 'Open in new tab',
70
75
  defaultLabelText: 'Text',
71
76
  },
77
+ search: {
78
+ title: 'Search',
79
+ tooltip: 'Search',
80
+ select: 'Select result item',
81
+ placeholder: 'Search for Street, Address, Landmark, POI',
82
+ zoomToFeatureAction: 'Zoom to result',
83
+ },
72
84
  toolbox: {
73
85
  flight: 'flight',
74
86
  miscellaneous: 'miscellaneous',
75
87
  },
76
88
  footer: {
77
89
  title: 'Footer',
90
+ attributions: {
91
+ title: 'Attributions',
92
+ tooltip: 'Open Attributions Window',
93
+ },
94
+ },
95
+ notification: {
96
+ error: 'Error',
97
+ warning: 'Warning',
98
+ information: 'Information',
99
+ success: 'Success',
78
100
  },
79
101
  };
80
102
 
package/src/icons/+all.js CHANGED
@@ -100,6 +100,7 @@ import Viewshed360Icon from './Viewshed360Icon.vue';
100
100
  import ViewshedConeIcon from './ViewshedConeIcon.vue';
101
101
  import WalkingIcon from './WalkingIcon.vue';
102
102
  import WallIcon from './WallIcon.vue';
103
+ import WandIcon from './WandIcon.vue';
103
104
 
104
105
  // * // IconMap.boundingBox
105
106
  // * <v-icon size="16" v-text="'$vcsBoundingBox'" />
@@ -431,6 +432,9 @@ const IconMap = {
431
432
  walking: {
432
433
  component: WalkingIcon,
433
434
  },
435
+ wand: {
436
+ component: WandIcon,
437
+ },
434
438
  };
435
439
 
436
440
  const nameCapitalized = (name) => { return name.charAt(0).toUpperCase() + name.slice(1); };
@@ -0,0 +1,63 @@
1
+ <!-- eslint-disable max-len -->
2
+
3
+ <template>
4
+ <svg id="icon_wizard" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
5
+ <g id="wand" transform="translate(1.706 1.705)">
6
+ <g id="Gruppe_1465" data-name="Gruppe 1465" transform="translate(0 10.491)">
7
+ <g id="Gruppe_1464" data-name="Gruppe 1464">
8
+ <path id="Pfad_540" data-name="Pfad 540" d="M1.574,22.1a.476.476,0,0,1-.367-.157L.157,20.892a.507.507,0,0,1,0-.734.507.507,0,0,1,.734,0l1.049,1.049a.507.507,0,0,1,0,.734A.476.476,0,0,1,1.574,22.1Z" transform="translate(0 -20)" fill="currentColor" />
9
+ </g>
10
+ </g>
11
+ <g id="Gruppe_1467" data-name="Gruppe 1467" transform="translate(1.049 1.049)">
12
+ <g id="Gruppe_1466" data-name="Gruppe 1466">
13
+ <path id="Pfad_541" data-name="Pfad 541" d="M2.525,13.54a.476.476,0,0,1-.367-.157.507.507,0,0,1,0-.734L12.648,2.157a.519.519,0,1,1,.734.734L2.892,13.382A.476.476,0,0,1,2.525,13.54Z" transform="translate(-2 -2)" fill="currentColor" />
14
+ </g>
15
+ </g>
16
+ <g id="Gruppe_1469" data-name="Gruppe 1469" transform="translate(10.491 0)">
17
+ <g id="Gruppe_1468" data-name="Gruppe 1468">
18
+ <path id="Pfad_542" data-name="Pfad 542" d="M21.574,2.1a.476.476,0,0,1-.367-.157L20.157.892a.507.507,0,0,1,0-.734.507.507,0,0,1,.734,0l1.049,1.049a.507.507,0,0,1,0,.734A.476.476,0,0,1,21.574,2.1Z" transform="translate(-20 0)" fill="currentColor" />
19
+ </g>
20
+ </g>
21
+ <g id="Gruppe_1471" data-name="Gruppe 1471" transform="translate(0 0)">
22
+ <g id="Gruppe_1470" data-name="Gruppe 1470">
23
+ <path id="Pfad_543" data-name="Pfad 543" d="M.525,11.54a.476.476,0,0,1-.367-.157.507.507,0,0,1,0-.734L10.648.157a.507.507,0,0,1,.734,0,.507.507,0,0,1,0,.734L.892,11.382A.476.476,0,0,1,.525,11.54Z" transform="translate(0 0)" fill="currentColor" />
24
+ </g>
25
+ </g>
26
+ <g id="Gruppe_1473" data-name="Gruppe 1473" transform="translate(8.393 2.098)">
27
+ <g id="Gruppe_1472" data-name="Gruppe 1472">
28
+ <path id="Pfad_544" data-name="Pfad 544" d="M17.574,6.1a.476.476,0,0,1-.367-.157L16.157,4.892a.519.519,0,0,1,.734-.734l1.049,1.049a.507.507,0,0,1,0,.734A.476.476,0,0,1,17.574,6.1Z" transform="translate(-16 -4)" fill="currentColor" />
29
+ </g>
30
+ </g>
31
+ <g id="Gruppe_1475" data-name="Gruppe 1475" transform="translate(7.344 7.344)">
32
+ <g id="Gruppe_1474" data-name="Gruppe 1474">
33
+ <path id="Pfad_545" data-name="Pfad 545" d="M14.525,16.1A.5.5,0,0,1,14,15.574V14.525a.525.525,0,1,1,1.049,0v1.049A.5.5,0,0,1,14.525,16.1Z" transform="translate(-14 -14)" fill="currentColor" />
34
+ </g>
35
+ </g>
36
+ <g id="Gruppe_1477" data-name="Gruppe 1477" transform="translate(7.344)">
37
+ <g id="Gruppe_1476" data-name="Gruppe 1476">
38
+ <path id="Pfad_546" data-name="Pfad 546" d="M14.525,2.1A.5.5,0,0,1,14,1.574V.525a.525.525,0,0,1,1.049,0V1.574A.5.5,0,0,1,14.525,2.1Z" transform="translate(-14)" fill="currentColor" />
39
+ </g>
40
+ </g>
41
+ <g id="Gruppe_1479" data-name="Gruppe 1479" transform="translate(3.147 4.196)">
42
+ <g id="Gruppe_1478" data-name="Gruppe 1478">
43
+ <path id="Pfad_547" data-name="Pfad 547" d="M7.574,9.049H6.525A.525.525,0,0,1,6.525,8H7.574a.525.525,0,0,1,0,1.049Z" transform="translate(-6 -8)" fill="currentColor" />
44
+ </g>
45
+ </g>
46
+ <g id="Gruppe_1481" data-name="Gruppe 1481" transform="translate(10.491 4.196)">
47
+ <g id="Gruppe_1480" data-name="Gruppe 1480">
48
+ <path id="Pfad_548" data-name="Pfad 548" d="M21.574,9.049H20.525a.525.525,0,0,1,0-1.049h1.049a.525.525,0,1,1,0,1.049Z" transform="translate(-20 -8)" fill="currentColor" />
49
+ </g>
50
+ </g>
51
+ <g id="Gruppe_1483" data-name="Gruppe 1483" transform="translate(3.986 0.839)">
52
+ <g id="Gruppe_1482" data-name="Gruppe 1482">
53
+ <path id="Pfad_549" data-name="Pfad 549" d="M9.279,3.8a.476.476,0,0,1-.367-.157L7.757,2.492a.519.519,0,0,1,.734-.734l1.1,1.1a.507.507,0,0,1,0,.734A.326.326,0,0,1,9.279,3.8Z" transform="translate(-7.6 -1.6)" fill="currentColor" />
54
+ </g>
55
+ </g>
56
+ <g id="Gruppe_1485" data-name="Gruppe 1485" transform="translate(9.599 6.452)">
57
+ <g id="Gruppe_1484" data-name="Gruppe 1484">
58
+ <path id="Pfad_550" data-name="Pfad 550" d="M19.926,14.451a.476.476,0,0,1-.367-.157l-1.1-1.1a.519.519,0,1,1,.734-.734l1.1,1.1a.507.507,0,0,1,0,.734A.567.567,0,0,1,19.926,14.451Z" transform="translate(-18.3 -12.3)" fill="currentColor" />
59
+ </g>
60
+ </g>
61
+ </g>
62
+ </svg>
63
+ </template>
@@ -1,5 +1,5 @@
1
1
  import { getShapeFromOptions } from '@vcmap/core';
2
- import Vue, { reactive } from 'vue';
2
+ import { ref } from 'vue';
3
3
 
4
4
  /**
5
5
  * @enum {string}
@@ -104,6 +104,7 @@ export function getImageSrcFromShape(image) {
104
104
 
105
105
  /**
106
106
  * @typedef {Object} LegendEntry
107
+ * @property {string} key
107
108
  * @property {string} title - layer or entry name
108
109
  * @property {Array<LegendItem>} legend - legend properties
109
110
  * @property {Array<VcsAction>} actions - popout actions
@@ -111,11 +112,12 @@ export function getImageSrcFromShape(image) {
111
112
 
112
113
  /**
113
114
  * creates a LegendEntry with title, options and optionally popout action to the entries array
115
+ * @param {string} key - layerName
114
116
  * @param {string} title
115
117
  * @param {Array<LegendItem>} legend
116
118
  * @returns {LegendEntry}
117
119
  */
118
- export function createLayerLegendEntry(title, legend) {
120
+ export function createLayerLegendEntry(key, title, legend) {
119
121
  const actions = [];
120
122
  legend.forEach((item) => {
121
123
  // XXX only one popout button allowed. Rethink if use case for multiple popout buttons comes up.
@@ -128,19 +130,19 @@ export function createLayerLegendEntry(title, legend) {
128
130
  });
129
131
  }
130
132
  });
131
- return { title, legend, actions };
133
+ return { key, title, legend, actions };
132
134
  }
133
135
 
134
136
  /**
135
137
  *
136
138
  * @param {VcsUiApp} app
137
- * @returns {{entries: import("vue").Reactive<{string,LegendEntry}>, destroy: (function():void)}}
139
+ * @returns {{entries: import("vue").Ref<Array<LegendEntry>>, destroy: (function():void)}}
138
140
  */
139
141
  export function getLegendEntries(app) {
140
142
  /**
141
- * @type {import("vue").Reactive<{string,LegendEntry}>}
143
+ * @type {import("vue").Ref<Array<LegendEntry>>}>}
142
144
  */
143
- const entries = reactive({});
145
+ const entries = ref([]);
144
146
  /**
145
147
  * @type {Object<string,function():void>}
146
148
  */
@@ -150,11 +152,14 @@ export function getLegendEntries(app) {
150
152
  * @param {import("@vcmap/core").Layer} layer
151
153
  */
152
154
  function removeEntryForLayer(layer) {
153
- const key = layer.name;
154
- Vue.delete(entries, key); // XXX Vue.delete can be removed on Vue3
155
- if (styleChangedListener[key]) {
156
- styleChangedListener[key]();
157
- delete styleChangedListener[key];
155
+ const layerName = layer.name;
156
+ const index = entries.value.findIndex(({ key }) => { return key === layerName; });
157
+ if (index >= 0) {
158
+ entries.value.splice(index, 1);
159
+ }
160
+ if (styleChangedListener[layerName]) {
161
+ styleChangedListener[layerName]();
162
+ delete styleChangedListener[layerName];
158
163
  }
159
164
  }
160
165
 
@@ -170,7 +175,8 @@ export function getLegendEntries(app) {
170
175
  const title = layer.properties.title || layer.name;
171
176
  const legend = layer.style?.properties?.legend ?? layer.properties?.legend;
172
177
  if (legend) {
173
- Vue.set(entries, key, createLayerLegendEntry(title, legend)); // XXX Vue.set can be removed on Vue3
178
+ const legendEntry = createLayerLegendEntry(key, title, legend);
179
+ entries.value.push(legendEntry);
174
180
  }
175
181
  if (layer.styleChanged) {
176
182
  styleChangedListener[layer.name] = layer.styleChanged.addEventListener(() => syncLayerLegendEntries(layer));
@@ -92,6 +92,16 @@
92
92
  <script>
93
93
 
94
94
  import { getStringColor } from '@vcmap/core';
95
+ import {
96
+ VFlex,
97
+ VImg,
98
+ VLayout,
99
+ VList,
100
+ VListItem,
101
+ VListItemContent,
102
+ VListItemIcon,
103
+ VListItemTitle,
104
+ } from 'vuetify/lib';
95
105
  import { StyleRowType, getImageSrcFromShape } from './legendHelper.js';
96
106
 
97
107
  /**
@@ -100,7 +110,16 @@
100
110
  */
101
111
  export default {
102
112
  name: 'StyleLegendItem',
103
- components: { },
113
+ components: {
114
+ VList,
115
+ VLayout,
116
+ VFlex,
117
+ VListItem,
118
+ VListItemIcon,
119
+ VImg,
120
+ VListItemContent,
121
+ VListItemTitle,
122
+ },
104
123
  props: {
105
124
  item: {
106
125
  type: Object,
@@ -50,17 +50,38 @@
50
50
 
51
51
  <script>
52
52
 
53
+ import {
54
+ VCard,
55
+ VExpansionPanels,
56
+ VExpansionPanel,
57
+ VExpansionPanelHeader,
58
+ VExpansionPanelContent,
59
+ VIcon,
60
+ VList,
61
+ VImg,
62
+ } from 'vuetify/lib';
53
63
  import { LegendType } from './legendHelper.js';
54
64
  import StyleLegendItem from './styleLegendItem.vue';
55
65
  import VcsTreeviewLeaf from '../components/lists/VcsTreeviewLeaf.vue';
56
66
 
57
67
  /**
58
68
  * @description A component rendering configured legend information for active layers.
59
- * @vue-prop {import("vue").Reactive<{string,LegendEntry}>} entries - legend entries to be displayed
69
+ * @vue-prop {import("vue").Ref<Array<LegendEntry>>} entries - legend entries to be displayed
60
70
  */
61
71
  export default {
62
72
  name: 'VcsLegend',
63
- components: { VcsTreeviewLeaf, StyleLegendItem },
73
+ components: {
74
+ VcsTreeviewLeaf,
75
+ StyleLegendItem,
76
+ VCard,
77
+ VExpansionPanels,
78
+ VExpansionPanel,
79
+ VExpansionPanelHeader,
80
+ VExpansionPanelContent,
81
+ VIcon,
82
+ VList,
83
+ VImg,
84
+ },
64
85
  props: {
65
86
  entries: {
66
87
  type: Object,
@@ -85,8 +106,13 @@
85
106
  };
86
107
  </script>
87
108
 
88
- <style scoped>
109
+ <style lang="scss" scoped>
89
110
  .v-list-item--dense {
90
111
  height: 32px;
91
112
  }
113
+ ::v-deep {
114
+ .treeview-label {
115
+ max-width: 189px;
116
+ }
117
+ }
92
118
  </style>
@@ -62,6 +62,12 @@
62
62
  </style>
63
63
  <script>
64
64
  import { computed, ref } from 'vue';
65
+ import {
66
+ VMenu,
67
+ VIcon,
68
+ VToolbar,
69
+ VToolbarItems,
70
+ } from 'vuetify/lib';
65
71
  import VcsButton from '../../components/buttons/VcsButton.vue';
66
72
  import { getComponentsByOrder } from './toolboxManager.js';
67
73
 
@@ -78,7 +84,13 @@
78
84
  */
79
85
  export default {
80
86
  name: 'ToolboxActionGroup',
81
- components: { VcsButton },
87
+ components: {
88
+ VcsButton,
89
+ VMenu,
90
+ VIcon,
91
+ VToolbar,
92
+ VToolbarItems,
93
+ },
82
94
  props: {
83
95
  group: {
84
96
  type: Object,
@@ -88,6 +88,12 @@
88
88
  </style>
89
89
  <script>
90
90
  import { ref, computed } from 'vue';
91
+ import {
92
+ VMenu,
93
+ VIcon,
94
+ VToolbar,
95
+ VToolbarItems,
96
+ } from 'vuetify/lib';
91
97
  import VcsButton from '../../components/buttons/VcsButton.vue';
92
98
 
93
99
  /**
@@ -98,7 +104,13 @@
98
104
  */
99
105
  export default {
100
106
  name: 'ToolboxActionSelect',
101
- components: { VcsButton },
107
+ components: {
108
+ VcsButton,
109
+ VMenu,
110
+ VIcon,
111
+ VToolbar,
112
+ VToolbarItems,
113
+ },
102
114
  props: {
103
115
  group: {
104
116
  type: Object,
@@ -72,6 +72,7 @@
72
72
  <script>
73
73
  import { inject, ref, computed, watch, onUnmounted } from 'vue';
74
74
  import { ButtonLocation, vcsAppSymbol } from '@vcmap/ui';
75
+ import { VToolbar, VToolbarItems } from 'vuetify/lib';
75
76
  import { getComponentsByOrder, ToolboxType } from './toolboxManager.js';
76
77
  import ToolboxActionSelect from './SelectToolboxComponent.vue';
77
78
  import ToolboxActionGroup from './GroupToolboxComponent.vue';
@@ -104,6 +105,8 @@
104
105
  ToolboxActionSelect,
105
106
  ToolboxActionGroup,
106
107
  VcsButton,
108
+ VToolbar,
109
+ VToolbarItems,
107
110
  },
108
111
  setup() {
109
112
  const app = inject('vcsApp');
@@ -19,7 +19,7 @@
19
19
  }"
20
20
  :draggable="isDynamic"
21
21
  >
22
- <slot name="headerComponent" />
22
+ <slot name="headerComponent" :props="$attrs" />
23
23
  </div>
24
24
  <v-divider />
25
25
  <div
@@ -40,13 +40,19 @@
40
40
 
41
41
  <script>
42
42
  import {
43
- onMounted, onUnmounted, computed, ref, nextTick,
43
+ onMounted, onUnmounted, computed, ref, nextTick, inject, provide,
44
44
  } from 'vue';
45
45
  import { fromEvent } from 'rxjs';
46
46
  import { switchMap, take, map, tap } from 'rxjs/operators';
47
+ import { VDivider, VSheet } from 'vuetify/lib';
47
48
  import { WindowSlot } from './windowManager.js';
48
49
 
49
50
  export default {
51
+ name: 'WindowComponent',
52
+ components: {
53
+ VSheet,
54
+ VDivider,
55
+ },
50
56
  props: {
51
57
  windowState: {
52
58
  type: Object,
@@ -127,6 +133,13 @@
127
133
  dropSub.unsubscribe();
128
134
  }
129
135
  });
136
+
137
+ const app = inject('vcsApp');
138
+ const { provides } = app.windowManager.get(windowState.id);
139
+ Object.entries(provides)
140
+ .forEach(([key, value]) => {
141
+ provide(key, value);
142
+ });
130
143
  return {
131
144
  isDynamic,
132
145
  isDocked,
@@ -10,25 +10,56 @@
10
10
  {{ $t(windowState.headerTitle) }}
11
11
  </h3>
12
12
  </span>
13
- <VcsButton
14
- @click.stop="close"
15
- small
16
- icon="mdi-close-thick"
17
- />
13
+ <div class="d-flex justify-space-between align-center">
14
+ <template v-if="windowState.headerActions?.length > 0">
15
+ <VcsActionButtonList
16
+ :actions="windowState.headerActions"
17
+ :overflow-count="windowState.headerActionsOverflowCount ?? 3"
18
+ small
19
+ />
20
+ <v-divider
21
+ vertical
22
+ inset
23
+ class="mx-2"
24
+ />
25
+ </template>
26
+ <VcsButton
27
+ @click.stop="close"
28
+ small
29
+ icon="mdi-close-thick"
30
+ tooltip="components.close"
31
+ />
32
+ </div>
18
33
  </span>
19
34
  </template>
20
35
 
21
- <style>
36
+ <style lang="scss" scoped>
22
37
  .window-component-header{
23
38
  max-height: 16px;
39
+
40
+ .v-divider--vertical.v-divider--inset {
41
+ margin-top: 2px;
42
+ }
24
43
  }
25
44
  </style>
26
45
 
27
46
  <script>
47
+ import { VIcon, VDivider } from 'vuetify/lib';
28
48
  import VcsButton from '../../components/buttons/VcsButton.vue';
49
+ import VcsActionButtonList from '../../components/buttons/VcsActionButtonList.vue';
29
50
 
51
+ /**
52
+ * Default window component header with drag functionality close action and further optional window actions.
53
+ * @vue-prop {WindowState} windowState - state of the window component.
54
+ */
30
55
  export default {
31
- components: { VcsButton },
56
+ name: 'WindowComponentHeader',
57
+ components: {
58
+ VcsActionButtonList,
59
+ VcsButton,
60
+ VIcon,
61
+ VDivider,
62
+ },
32
63
  props: {
33
64
  windowState: {
34
65
  type: Object,
@@ -23,6 +23,7 @@
23
23
  <component
24
24
  :is="getHeaderComponent(id)"
25
25
  :window-state="getState(id)"
26
+ v-bind="getProps(id)"
26
27
  @close="close(id)"
27
28
  />
28
29
  </template>