@vcmap/ui 6.2.2 → 6.2.4

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 (54) hide show
  1. package/config/dev.config.json +366 -2
  2. package/dist/assets/cesium.js +1 -1
  3. package/dist/assets/{core-4cd2e30d.js → core-b61fb7c0.js} +10577 -8847
  4. package/dist/assets/core-workers/panoramaImageWorker.js +1 -1
  5. package/dist/assets/core.js +1 -1
  6. package/dist/assets/ol.js +1 -1
  7. package/dist/assets/{ui-b13e28a1.css → ui-f33a5ee2.css} +1 -1
  8. package/dist/assets/{ui-b13e28a1.js → ui-f33a5ee2.js} +6864 -6737
  9. package/dist/assets/ui.js +1 -1
  10. package/dist/assets/vue.js +1 -1
  11. package/dist/assets/{vuetify-a1930526.js → vuetify-2fc014c4.js} +1 -1
  12. package/dist/assets/vuetify.js +1 -1
  13. package/index.d.ts +5 -1
  14. package/index.js +2 -1
  15. package/package.json +1 -1
  16. package/plugins/@vcmap-show-case/extent-example/src/ExtentExample.vue +28 -0
  17. package/plugins/@vcmap-show-case/extent-example/src/index.js +3 -14
  18. package/src/actions/actionHelper.d.ts +0 -1
  19. package/src/actions/actionHelper.js +3 -3
  20. package/src/application/VcsSettings.vue +4 -0
  21. package/src/components/extent/VcsExtent.vue +12 -1
  22. package/src/components/extent/VcsExtent.vue.d.ts +1 -0
  23. package/src/components/flight/VcsFlightAnchorsComponent.vue +2 -2
  24. package/src/components/lists/VcsList.vue +10 -18
  25. package/src/components/lists/VcsTreeNode.vue +8 -3
  26. package/src/components/lists/VcsTreeNode.vue.d.ts +4 -0
  27. package/src/components/lists/VcsTreeview.vue +2 -6
  28. package/src/components/lists/VcsTreeview.vue.d.ts +0 -1
  29. package/src/components/lists/dragHelper.d.ts +9 -2
  30. package/src/components/lists/dragHelper.js +47 -21
  31. package/src/contentTree/LayerSwap.vue +15 -4
  32. package/src/contentTree/LayerSwap.vue.d.ts +4 -4
  33. package/src/contentTree/contentTreeItem.js +1 -1
  34. package/src/contentTree/wmsGroupContentTreeItem.d.ts +74 -9
  35. package/src/contentTree/wmsGroupContentTreeItem.js +250 -88
  36. package/src/i18n/de.d.ts +1 -0
  37. package/src/i18n/de.js +1 -0
  38. package/src/i18n/en.d.ts +1 -0
  39. package/src/i18n/en.js +1 -0
  40. package/src/manager/collectionManager/CollectionComponentContent.vue +4 -4
  41. package/src/manager/collectionManager/CollectionComponentList.vue +2 -24
  42. package/src/manager/collectionManager/CollectionComponentList.vue.d.ts +0 -8
  43. package/src/manager/collectionManager/CollectionManager.vue +14 -1
  44. package/src/search/SearchComponent.vue +9 -11
  45. package/src/search/SearchComponent.vue.d.ts +2 -1
  46. package/src/state.d.ts +14 -0
  47. package/src/state.js +41 -0
  48. package/src/vcsUiApp.d.ts +9 -36
  49. package/src/vcsUiApp.js +45 -11
  50. /package/dist/assets/{cesium-b021f072.js → cesium-bc979301.js} +0 -0
  51. /package/dist/assets/core-workers/{panoramaImageWorker.js-90c60e81.js → panoramaImageWorker.js-2cf50d2d.js} +0 -0
  52. /package/dist/assets/{ol-c927b883.js → ol-28f9c83c.js} +0 -0
  53. /package/dist/assets/{vue-6a295c0b.js → vue-004523e0.js} +0 -0
  54. /package/dist/assets/{vuetify-a1930526.css → vuetify-2fc014c4.css} +0 -0
@@ -1,6 +1,7 @@
1
1
  export default WMSGroupContentTreeItem;
2
2
  export type WMSGroupContentTreeItemOptions = import('./contentTreeItem.js').ContentTreeItemOptions & {
3
3
  layerName: string;
4
+ loadOnStartup?: boolean;
4
5
  showWhenNotSupported?: boolean;
5
6
  setWMSLayersExclusive?: boolean;
6
7
  hideStyleSelector?: boolean;
@@ -15,18 +16,41 @@ export type WMSEntry = {
15
16
  name: string;
16
17
  active: import("vue").Ref<boolean>;
17
18
  activeStyle: import("vue").Ref<string>;
18
- title: string;
19
- extent: import("@vcmap/core").Extent;
20
- styles: Array<WMSStyleEntry>;
19
+ title?: string | undefined;
20
+ extent?: import("@vcmap/core").Extent | undefined;
21
+ styles?: WMSStyleEntry[] | undefined;
22
+ };
23
+ export type SerializedWMSLegend = {
24
+ url: string;
25
+ width: number;
26
+ height: number;
27
+ };
28
+ export type SerializedWMSStyle = {
29
+ name: string;
30
+ title?: string | undefined;
31
+ legend?: SerializedWMSLegend[] | undefined;
32
+ };
33
+ export type SerializedWMSLayer = {
34
+ name: string;
35
+ title?: string | undefined;
36
+ /**
37
+ * Layer extent, in WGS84 coordinates
38
+ */
39
+ extent?: number[] | undefined;
40
+ styles?: SerializedWMSStyle[] | undefined;
41
+ };
42
+ export type SerializedWMSCapabilities = {
43
+ layers: Array<SerializedWMSLayer>;
21
44
  };
22
45
  /**
23
46
  * @typedef {import('./contentTreeItem.js').ContentTreeItemOptions &
24
- * { layerName: string, showWhenNotSupported?: boolean, setWMSLayersExclusive?:boolean, hideStyleSelector?:boolean, allowedWMSLayers?:string[]}} WMSGroupContentTreeItemOptions
25
- * @property {boolean} showWhenNotSupported - optional flag to show the item even if it is not supported by the activeMap.
47
+ * { layerName: string, loadOnStartup?: boolean, showWhenNotSupported?: boolean, setWMSLayersExclusive?:boolean, hideStyleSelector?:boolean, allowedWMSLayers?:string[]}} WMSGroupContentTreeItemOptions
26
48
  * @property {string} layerName - The name of the WMSLayer to show the children of.
49
+ * @property {boolean} [loadOnStartup=false] - optional flag to load the capabilities on startup, will be loaded on click otherwise. Leads to an inherent "initOpen" flag if not true.
50
+ * @property {boolean} [showWhenNotSupported=false] - optional flag to show the item even if it is not supported by the activeMap.
27
51
  * @property {boolean} [setWMSLayersExclusive=false] - Whether the WMSlayers are mutually exclusive.
28
52
  * @property {boolean} [hideStyleSelector=false] - Whether the layer style can be selected. Will add a StyleSelector action to compatible items if the Layer has more than one style.
29
- * @property {string[]} allowedWMSLayers - The list of layers to be shown, other available layers will not be shown.
53
+ * @property {string[]} [allowedWMSLayers] - The list of layers to be shown, other available layers will not be shown.
30
54
  */
31
55
  /**
32
56
  * @typedef {Object} WMSStyleEntry
@@ -39,9 +63,33 @@ export type WMSEntry = {
39
63
  * @property {string} name
40
64
  * @property {import("vue").Ref<boolean>} active
41
65
  * @property {import("vue").Ref<string>} activeStyle
42
- * @property {string} title
43
- * @property {import("@vcmap/core").Extent} extent
44
- * @property {Array<WMSStyleEntry>} styles
66
+ * @property {string} [title]
67
+ * @property {import("@vcmap/core").Extent} [extent]
68
+ * @property {Array<WMSStyleEntry>} [styles]
69
+ */
70
+ /**
71
+ * @typedef {Object} SerializedWMSLegend
72
+ * @property {string} url
73
+ * @property {number} width
74
+ * @property {number} height
75
+ */
76
+ /**
77
+ * @typedef {Object} SerializedWMSStyle
78
+ * @property {string} name
79
+ * @property {string} [title]
80
+ * @property {SerializedWMSLegend[]} [legend]
81
+ */
82
+ /**
83
+ * @typedef {Object} SerializedWMSLayer
84
+ * @property {string} name
85
+ * @property {string} [title]
86
+ * @property {number[]} [extent] Layer extent, in WGS84 coordinates
87
+ * @property {SerializedWMSStyle[]} [styles]
88
+ */
89
+ /**
90
+ * @description The serialized form of WMS Capabilities are used in the configuration to avoid fetching the capabilities on every startup.
91
+ * @typedef {Object} SerializedWMSCapabilities
92
+ * @property {Array<SerializedWMSLayer>} layers
45
93
  */
46
94
  /**
47
95
  * A WMSGroupItem, will take over a WMSLayer and request the Capabilities of the layer to show all available
@@ -61,6 +109,11 @@ declare class WMSGroupContentTreeItem extends VcsObjectContentTreeItem<import(".
61
109
  * @private
62
110
  */
63
111
  private _layerName;
112
+ /**
113
+ * @type {boolean}
114
+ * @private
115
+ */
116
+ private _loadOnStartup;
64
117
  /**
65
118
  * @type {boolean}
66
119
  * @private
@@ -115,6 +168,12 @@ declare class WMSGroupContentTreeItem extends VcsObjectContentTreeItem<import(".
115
168
  * @private
116
169
  */
117
170
  private _pauseStateChangedListener;
171
+ /**
172
+ * Flag to track if children have been loaded
173
+ * @type {boolean}
174
+ * @private
175
+ */
176
+ private _childrenLoaded;
118
177
  /**
119
178
  * readonly access, do not manipulate the entries directly.
120
179
  * @type {Array<WMSEntry>}
@@ -157,6 +216,12 @@ declare class WMSGroupContentTreeItem extends VcsObjectContentTreeItem<import(".
157
216
  * @private
158
217
  */
159
218
  private _setStateFromLayer;
219
+ /**
220
+ * Loads WMS entries and creates child items
221
+ * @returns {Promise<void>}
222
+ * @private
223
+ */
224
+ private _loadWMSChildren;
160
225
  /**
161
226
  * @returns {Promise<void>}
162
227
  * @private
@@ -2,6 +2,7 @@ import { markVolatile } from '@vcmap/core';
2
2
  import { getLogger } from '@vcsuite/logger';
3
3
  import { ref } from 'vue';
4
4
  import { parseBoolean } from '@vcsuite/parsers';
5
+ import { is } from '@vcsuite/check';
5
6
  import deepEqual from 'fast-deep-equal';
6
7
  import WMSCapabilities from 'ol/format/WMSCapabilities';
7
8
  import { StateActionState } from '../actions/stateRefAction.js';
@@ -10,6 +11,90 @@ import WmsChildContentTreeItem from './wmsChildContentTreeItem.js';
10
11
  import VcsObjectContentTreeItem from './vcsObjectContentTreeItem.js';
11
12
  import { legendSymbol } from '../legend/legendHelper.js';
12
13
 
14
+ /**
15
+ *
16
+ * @param {string} src The OnlineRessource property of the legend
17
+ * @param {number} width The width of the image
18
+ * @param {string} title The title of the layer.
19
+ * @returns {import('../legend/legendHelper.js').StyleLegendItem}
20
+ */
21
+ function parseLegend(src, width, title) {
22
+ if (width < 25) {
23
+ return {
24
+ type: 'StyleLegendItem',
25
+ colNr: 1,
26
+ rows: [{ type: 'IconLegendRow', title, image: { src } }],
27
+ };
28
+ }
29
+ return { type: 'ImageLegendItem', popoutBtn: true, src };
30
+ }
31
+
32
+ /**
33
+ *
34
+ * @param {SerializedWMSCapabilities} capabilities
35
+ * @returns {WMSEntry[]}
36
+ */
37
+ function parseSerializedCapabilities(capabilities) {
38
+ if (capabilities?.layers?.length > 0) {
39
+ return capabilities.layers
40
+ .filter((layer) => {
41
+ if (!is(layer, { name: String })) {
42
+ getLogger(this.className).warn(
43
+ `Ignoring WMS Layer without name in layer ${this._layerName}`,
44
+ );
45
+ return false;
46
+ }
47
+ return true;
48
+ })
49
+ .map((layer) => {
50
+ const styles = layer.styles
51
+ ?.filter((s) => {
52
+ if (!is(s, { name: String })) {
53
+ getLogger(this.className).warn(
54
+ `Ignoring WMS Style without name in layer ${this._layerName}`,
55
+ );
56
+ return false;
57
+ }
58
+ return true;
59
+ })
60
+ .map((s) => ({
61
+ name: s.name,
62
+ title: s.title,
63
+ legend:
64
+ s.legend
65
+ ?.filter((l) => {
66
+ if (!is(l, { url: String, width: Number, height: Number })) {
67
+ getLogger(this.className).warn(
68
+ `Ignoring invalid WMS Legend in style ${s.name} in layer ${this._layerName}`,
69
+ );
70
+ return false;
71
+ }
72
+ return true;
73
+ })
74
+ .map((l) => parseLegend(l.url, l.width, s.title || '')) || [],
75
+ }));
76
+
77
+ const wmsEntry = {
78
+ name: layer.name,
79
+ active: ref(false),
80
+ activeStyle: ref(''),
81
+ };
82
+ if (layer.title) {
83
+ wmsEntry.title = layer.title;
84
+ }
85
+ if (layer.extent) {
86
+ wmsEntry.extent = layer.extent;
87
+ }
88
+ if (styles?.length > 0) {
89
+ wmsEntry.styles = styles;
90
+ }
91
+ return wmsEntry;
92
+ });
93
+ } else {
94
+ return [];
95
+ }
96
+ }
97
+
13
98
  /**
14
99
  * @param {string} rawUrl
15
100
  * @param {Record<string, string>} parameters
@@ -49,27 +134,9 @@ async function getWMSEntries(rawUrl, parameters) {
49
134
  title: style.Title,
50
135
  legend: style.LegendURL?.filter(
51
136
  (legend) => legend.OnlineResource,
52
- ).map((legend) => {
53
- const src = legend.OnlineResource;
54
- if (legend.size[0] < 25) {
55
- return {
56
- type: 'StyleLegendItem',
57
- colNr: 1,
58
- rows: [
59
- {
60
- type: 'IconLegendRow',
61
- title: layer.Title,
62
- image: { src },
63
- },
64
- ],
65
- };
66
- }
67
- return {
68
- type: 'ImageLegendItem',
69
- src,
70
- popoutBtn: true,
71
- };
72
- }),
137
+ ).map((legend) =>
138
+ parseLegend(legend.OnlineResource, legend.size[0], layer.Title),
139
+ ),
73
140
  };
74
141
  }) ?? [];
75
142
  return {
@@ -112,12 +179,13 @@ function createWMSChildContentTreeItem(
112
179
 
113
180
  /**
114
181
  * @typedef {import('./contentTreeItem.js').ContentTreeItemOptions &
115
- * { layerName: string, showWhenNotSupported?: boolean, setWMSLayersExclusive?:boolean, hideStyleSelector?:boolean, allowedWMSLayers?:string[]}} WMSGroupContentTreeItemOptions
116
- * @property {boolean} showWhenNotSupported - optional flag to show the item even if it is not supported by the activeMap.
182
+ * { layerName: string, loadOnStartup?: boolean, showWhenNotSupported?: boolean, setWMSLayersExclusive?:boolean, hideStyleSelector?:boolean, allowedWMSLayers?:string[]}} WMSGroupContentTreeItemOptions
117
183
  * @property {string} layerName - The name of the WMSLayer to show the children of.
184
+ * @property {boolean} [loadOnStartup=false] - optional flag to load the capabilities on startup, will be loaded on click otherwise. Leads to an inherent "initOpen" flag if not true.
185
+ * @property {boolean} [showWhenNotSupported=false] - optional flag to show the item even if it is not supported by the activeMap.
118
186
  * @property {boolean} [setWMSLayersExclusive=false] - Whether the WMSlayers are mutually exclusive.
119
187
  * @property {boolean} [hideStyleSelector=false] - Whether the layer style can be selected. Will add a StyleSelector action to compatible items if the Layer has more than one style.
120
- * @property {string[]} allowedWMSLayers - The list of layers to be shown, other available layers will not be shown.
188
+ * @property {string[]} [allowedWMSLayers] - The list of layers to be shown, other available layers will not be shown.
121
189
  */
122
190
 
123
191
  /**
@@ -132,9 +200,34 @@ function createWMSChildContentTreeItem(
132
200
  * @property {string} name
133
201
  * @property {import("vue").Ref<boolean>} active
134
202
  * @property {import("vue").Ref<string>} activeStyle
135
- * @property {string} title
136
- * @property {import("@vcmap/core").Extent} extent
137
- * @property {Array<WMSStyleEntry>} styles
203
+ * @property {string} [title]
204
+ * @property {import("@vcmap/core").Extent} [extent]
205
+ * @property {Array<WMSStyleEntry>} [styles]
206
+ */
207
+
208
+ /**
209
+ * @typedef {Object} SerializedWMSLegend
210
+ * @property {string} url
211
+ * @property {number} width
212
+ * @property {number} height
213
+ */
214
+ /**
215
+ * @typedef {Object} SerializedWMSStyle
216
+ * @property {string} name
217
+ * @property {string} [title]
218
+ * @property {SerializedWMSLegend[]} [legend]
219
+ */
220
+ /**
221
+ * @typedef {Object} SerializedWMSLayer
222
+ * @property {string} name
223
+ * @property {string} [title]
224
+ * @property {number[]} [extent] Layer extent, in WGS84 coordinates
225
+ * @property {SerializedWMSStyle[]} [styles]
226
+ */
227
+ /**
228
+ * @description The serialized form of WMS Capabilities are used in the configuration to avoid fetching the capabilities on every startup.
229
+ * @typedef {Object} SerializedWMSCapabilities
230
+ * @property {Array<SerializedWMSLayer>} layers
138
231
  */
139
232
 
140
233
  /**
@@ -154,7 +247,7 @@ class WMSGroupContentTreeItem extends VcsObjectContentTreeItem {
154
247
  * @param {import("../vcsUiApp.js").default} app
155
248
  */
156
249
  constructor(options, app) {
157
- super(options, app);
250
+ super({ initOpen: !options.loadOnStartup, ...options }, app);
158
251
 
159
252
  /**
160
253
  * @type {string}
@@ -162,6 +255,12 @@ class WMSGroupContentTreeItem extends VcsObjectContentTreeItem {
162
255
  */
163
256
  this._layerName = options.layerName;
164
257
 
258
+ /**
259
+ * @type {boolean}
260
+ * @private
261
+ */
262
+ this._loadOnStartup = parseBoolean(options.loadOnStartup, false);
263
+
165
264
  /**
166
265
  * @type {boolean}
167
266
  * @private
@@ -180,7 +279,7 @@ class WMSGroupContentTreeItem extends VcsObjectContentTreeItem {
180
279
  false,
181
280
  );
182
281
  // if WMSLayers should be handled exclusive, the item should handle like a NodeContentTreeItem.
183
- this.clickable = !this._setWMSLayersExclusive;
282
+ this.clickable = !this._setWMSLayersExclusive || !this._loadOnStartup;
184
283
 
185
284
  /**
186
285
  * @type {boolean}
@@ -188,9 +287,10 @@ class WMSGroupContentTreeItem extends VcsObjectContentTreeItem {
188
287
  */
189
288
  this._hideStyleSelector = parseBoolean(options.hideStyleSelector, false);
190
289
 
191
- this.state = this._setWMSLayersExclusive
192
- ? StateActionState.NONE
193
- : StateActionState.INACTIVE;
290
+ this.state =
291
+ this._setWMSLayersExclusive || !this._loadOnStartup
292
+ ? StateActionState.NONE
293
+ : StateActionState.INACTIVE;
194
294
 
195
295
  /**
196
296
  * @type {boolean}
@@ -238,6 +338,13 @@ class WMSGroupContentTreeItem extends VcsObjectContentTreeItem {
238
338
  */
239
339
  this._pauseStateChangedListener = false;
240
340
 
341
+ /**
342
+ * Flag to track if children have been loaded
343
+ * @type {boolean}
344
+ * @private
345
+ */
346
+ this._childrenLoaded = false;
347
+
241
348
  this._setup();
242
349
  }
243
350
 
@@ -421,6 +528,10 @@ class WMSGroupContentTreeItem extends VcsObjectContentTreeItem {
421
528
  this._listeners.splice(0);
422
529
  this._availableWMSEntries = [];
423
530
  this._legendSet = false;
531
+ this._childrenLoaded = false;
532
+
533
+ // Reset clickable state based on initial configuration
534
+ this.clickable = !this._setWMSLayersExclusive || !this._loadOnStartup;
424
535
  }
425
536
 
426
537
  /**
@@ -463,6 +574,90 @@ class WMSGroupContentTreeItem extends VcsObjectContentTreeItem {
463
574
  }
464
575
  }
465
576
 
577
+ /**
578
+ * Loads WMS entries and creates child items
579
+ * @returns {Promise<void>}
580
+ * @private
581
+ */
582
+ async _loadWMSChildren() {
583
+ if (this._childrenLoaded || !this._layer) {
584
+ return;
585
+ }
586
+
587
+ this.state = StateActionState.LOADING;
588
+ this.clickable = !this._setWMSLayersExclusive;
589
+
590
+ try {
591
+ let availableWMSEntries = [];
592
+ if (this._layer.properties.capabilities) {
593
+ availableWMSEntries = parseSerializedCapabilities(
594
+ this._layer.properties.capabilities,
595
+ );
596
+ } else {
597
+ availableWMSEntries = await getWMSEntries(
598
+ this._layer.url,
599
+ this._layer.parameters,
600
+ );
601
+ }
602
+ // check if the layer still exists, it can happen that the layer was removed while fetching the capabilities.
603
+ if (!this._layer) {
604
+ return;
605
+ }
606
+ this._availableWMSEntries = availableWMSEntries.filter((wmsEntry) => {
607
+ return this._allowedWMSLayers
608
+ ? this._allowedWMSLayers.includes(wmsEntry.name)
609
+ : true;
610
+ });
611
+ const childItems = this._availableWMSEntries.map((wmsEntry) =>
612
+ createWMSChildContentTreeItem(
613
+ this._app,
614
+ wmsEntry,
615
+ this.name,
616
+ this._hideStyleSelector,
617
+ ),
618
+ );
619
+ childItems.forEach((childItem) => {
620
+ this._app.contentTree.add(childItem);
621
+ childItem.disabled = this.disabled;
622
+ this._listeners.push(
623
+ childItem.clickedEvent.addEventListener(() => {
624
+ this._handleChildClickedEvent(childItem);
625
+ }),
626
+ childItem.styleSelected.addEventListener((style) => {
627
+ this._handleStyleSelectedEvent(childItem, style);
628
+ }),
629
+ );
630
+ });
631
+ this._childItems = childItems;
632
+ // check if we do have a legend already configured, if yes we set a flag, that we do not need to set the legend.
633
+ if (this._layer.properties.legend) {
634
+ this._legendSet = true;
635
+ }
636
+ // we need to get the Initial State from the Layer, to set the correct State to the children.
637
+ this._setStateFromLayer();
638
+ // the layer State maybe incomplete or does not fit to the wmsGroupContentTreeItem, so we need to set the State to the Layer.
639
+ this._setState();
640
+ this._setLegend();
641
+ this._childrenLoaded = true;
642
+
643
+ // Update clickable state after children are loaded
644
+ if (!this._setWMSLayersExclusive) {
645
+ this.clickable = true;
646
+ }
647
+ } catch (e) {
648
+ // if the layer is not there it has been removed while fetching the capabilities.
649
+ if (this._layer) {
650
+ this._layer.deactivate();
651
+ this.visible = false;
652
+ this._invalid = true;
653
+ }
654
+ getLogger(this.className).error(
655
+ `An error occured while fetching the ${this._layerName} capabilities:`,
656
+ e,
657
+ );
658
+ }
659
+ }
660
+
466
661
  /**
467
662
  * @returns {Promise<void>}
468
663
  * @private
@@ -489,7 +684,6 @@ class WMSGroupContentTreeItem extends VcsObjectContentTreeItem {
489
684
  if (this._showWhenNotSupported) {
490
685
  this.disabled = !isSupported;
491
686
  }
492
- this.state = StateActionState.LOADING;
493
687
  this.setPropertiesFromObject(this._layer);
494
688
 
495
689
  this._listeners.push(
@@ -517,67 +711,19 @@ class WMSGroupContentTreeItem extends VcsObjectContentTreeItem {
517
711
  }
518
712
  }),
519
713
  );
520
- try {
521
- const availableWMSEntries = await getWMSEntries(
522
- this._layer.url,
523
- this._layer.parameters,
524
- );
525
- // check if the layer still exists, it can happen that the layer was removed while fetching the capabilities.
526
- if (!this._layer) {
527
- return;
528
- }
529
- this._availableWMSEntries = availableWMSEntries.filter((wmsEntry) => {
530
- return this._allowedWMSLayers
531
- ? this._allowedWMSLayers.includes(wmsEntry.name)
532
- : true;
533
- });
534
- const childItems = this._availableWMSEntries.map((wmsEntry) => {
535
- return createWMSChildContentTreeItem(
536
- this._app,
537
- wmsEntry,
538
- this.name,
539
- this._hideStyleSelector,
540
- );
541
- });
542
- childItems.forEach((childItem) => {
543
- this._app.contentTree.add(childItem);
544
- childItem.disabled = this.disabled;
545
- this._listeners.push(
546
- childItem.clickedEvent.addEventListener(() => {
547
- this._handleChildClickedEvent(childItem);
548
- }),
549
- childItem.styleSelected.addEventListener((style) => {
550
- this._handleStyleSelectedEvent(childItem, style);
551
- }),
552
- );
553
- });
554
- this._childItems = childItems;
555
- // check if we do have a legend already configured, if yes we set a flag, that we do not need to set the legend.
556
- if (this._layer.properties.legend) {
557
- this._legendSet = true;
558
- }
559
- // we need to get the Initial State from the Layer, to set the correct State to the children.
560
- this._setStateFromLayer();
561
- // the layer State maybe incomplete or does not fit to the wmsGroupContentTreeItem, so we need to set the State to the Layer.
562
- this._setState();
563
- this._setLegend();
564
- } catch (e) {
565
- // if the layer is not there it has been removed while fetching the capabilities.
566
- if (this._layer) {
567
- this._layer.deactivate();
568
- this.visible = false;
569
- this._invalid = true;
570
- }
571
- getLogger(this.className).error(
572
- `An error occured while fetching the ${this._layerName} capabilities:`,
573
- e,
574
- );
714
+
715
+ if (this._loadOnStartup) {
716
+ await this._loadWMSChildren();
575
717
  }
576
718
  }
577
719
  }
578
720
 
579
721
  async clicked() {
580
722
  await super.clicked();
723
+ if (!this._childrenLoaded) {
724
+ await this._loadWMSChildren();
725
+ return;
726
+ }
581
727
  if (this.state === StateActionState.NONE || this._setWMSLayersExclusive) {
582
728
  return;
583
729
  }
@@ -591,12 +737,28 @@ class WMSGroupContentTreeItem extends VcsObjectContentTreeItem {
591
737
  await this._setStateToLayer();
592
738
  }
593
739
 
740
+ /**
741
+ * Returns a readonly TreeViewItem used for rendering the current item.
742
+ * @returns {import('./contentTreeItem.js').TreeViewItem}
743
+ */
744
+ getTreeViewItem() {
745
+ const item = super.getTreeViewItem();
746
+ item.forceNodeDisplay = !this._loadOnStartup;
747
+ return item;
748
+ }
594
749
  /**
595
750
  * @returns {WMSGroupContentTreeItemOptions}
596
751
  */
597
752
  toJSON() {
598
753
  const config = super.toJSON();
599
754
  config.layerName = this._layerName;
755
+ const defaultInitOpen = !this._loadOnStartup;
756
+ if (this.initOpen !== defaultInitOpen) {
757
+ config.initOpen = this.initOpen;
758
+ }
759
+ if (this._loadOnStartup) {
760
+ config.loadOnStartup = this._loadOnStartup;
761
+ }
600
762
  if (this._showWhenNotSupported) {
601
763
  config.showWhenNotSupported = this._showWhenNotSupported;
602
764
  }
package/src/i18n/de.d.ts CHANGED
@@ -527,6 +527,7 @@ declare namespace messages {
527
527
  export let select: string;
528
528
  let placeholder_1: string;
529
529
  export { placeholder_1 as placeholder };
530
+ export let hideWindow: string;
530
531
  export let zoomToFeatureAction: string;
531
532
  export let zoomToAll: string;
532
533
  export let zoomToAllMobile: string;
package/src/i18n/de.js CHANGED
@@ -372,6 +372,7 @@ const messages = {
372
372
  tooltip: 'Suche',
373
373
  select: 'Suchergebnis auswählen',
374
374
  placeholder: 'Suche nach Adresse oder Ort/Sehenswürdigkeit',
375
+ hideWindow: 'Suche ausblenden',
375
376
  zoomToFeatureAction: 'Auf Ergebnis zoomen',
376
377
  zoomToAll: 'Auf alle Ergebnisse zoomen',
377
378
  zoomToAllMobile: 'Auf alle zoomen',
package/src/i18n/en.d.ts CHANGED
@@ -527,6 +527,7 @@ declare namespace messages {
527
527
  export let select: string;
528
528
  let placeholder_1: string;
529
529
  export { placeholder_1 as placeholder };
530
+ export let hideWindow: string;
530
531
  export let zoomToFeatureAction: string;
531
532
  export let zoomToAllMobile: string;
532
533
  export let zoomToAll: string;
package/src/i18n/en.js CHANGED
@@ -372,6 +372,7 @@ const messages = {
372
372
  tooltip: 'Search',
373
373
  select: 'Select result item',
374
374
  placeholder: 'Search for address or landmark/point of interest',
375
+ hideWindow: 'Hide search',
375
376
  zoomToFeatureAction: 'Zoom to result',
376
377
  zoomToAllMobile: 'Zoom to all',
377
378
  zoomToAll: 'Zoom to all',
@@ -9,9 +9,9 @@
9
9
  :show-title="false"
10
10
  @item-moved="move"
11
11
  />
12
- <v-sheet v-if="page && pageSize && totalCount && items.length !== 0">
12
+ <v-sheet v-if="page && pageSize && totalCount > pageSize">
13
13
  <v-pagination
14
- class="px-2"
14
+ class="px-4"
15
15
  v-model="page"
16
16
  :length="Math.ceil(totalCount / pageSize)"
17
17
  density="compact"
@@ -35,7 +35,7 @@
35
35
  import { createSelectionActions } from '../../components/lists/listHelper.js';
36
36
  import VcsList from '../../components/lists/VcsList.vue';
37
37
  import VcsButton from '../../components/buttons/VcsButton.vue';
38
- import { moveItem } from './CollectionComponentList.vue';
38
+ import { moveItem } from '../../components/lists/dragHelper.js';
39
39
 
40
40
  /**
41
41
  * @description
@@ -137,7 +137,7 @@
137
137
  return actions.value;
138
138
  }),
139
139
  move(event) {
140
- moveItem(collectionComponent, event);
140
+ moveItem(collectionComponent.collection, event);
141
141
  },
142
142
  openCollectionComponentList() {
143
143
  emit('openList', collectionComponent.id);
@@ -36,34 +36,12 @@
36
36
 
37
37
  <script>
38
38
  import { computed, inject } from 'vue';
39
- import { IndexedCollection } from '@vcmap/core';
40
39
  import { VSheet } from 'vuetify/components';
41
40
  import { createSelectionActions } from '../../components/lists/listHelper.js';
42
41
  import VcsList from '../../components/lists/VcsList.vue';
43
42
  import VcsActionButtonList from '../../components/buttons/VcsActionButtonList.vue';
44
43
  import VcsButton from '../../components/buttons/VcsButton.vue';
45
-
46
- /**
47
- * Moves an item to a new position.
48
- * New position is derived from a target item in the collection.
49
- * This ensures correct movement, if rendered list is only a subset of the collection.
50
- * @param {import("./collectionComponentClass.js").default<Object>} collectionComponent
51
- * @param {import("../../components/lists/dragHelper.js").ItemMovedEvent} event
52
- */
53
- export function moveItem(
54
- collectionComponent,
55
- { item, targetItem, position },
56
- ) {
57
- const { collection } = collectionComponent;
58
- if (collection instanceof IndexedCollection) {
59
- const collectionItem = collection.getByKey(item.name);
60
- const keyProperty = collection.uniqueKey;
61
- const targetIndexCol = [...collection].findIndex(
62
- (i) => i[keyProperty] === targetItem.name,
63
- );
64
- collection.moveTo(collectionItem, targetIndexCol + position);
65
- }
66
- }
44
+ import { moveItem } from '../../components/lists/dragHelper.js';
67
45
 
68
46
  /**
69
47
  * @description
@@ -124,7 +102,7 @@
124
102
  return actions.value;
125
103
  }),
126
104
  move(event) {
127
- moveItem(collectionComponent, event);
105
+ moveItem(collectionComponent.collection, event);
128
106
  },
129
107
  closeList() {
130
108
  emit('closeList', collectionComponent.id);