@vcmap/ui 6.2.0-rc.2 → 6.2.0-rc.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 (58) hide show
  1. package/build/postInstall.js +32 -0
  2. package/config/dev.config.json +12 -0
  3. package/dist/assets/cesium.js +1 -1
  4. package/dist/assets/{core-6b5c0363.js → core-640eba41.js} +6965 -6565
  5. package/dist/assets/core-workers/panoramaImageWorker.js +1 -1
  6. package/dist/assets/core.js +1 -1
  7. package/dist/assets/{ol-f58f403b.js → ol-2b44b2a9.js} +1 -1
  8. package/dist/assets/ol.js +1 -1
  9. package/dist/assets/ui-8896bb2c.css +1 -0
  10. package/dist/assets/{ui-aadb7707.js → ui-8896bb2c.js} +9668 -9247
  11. package/dist/assets/ui.js +1 -1
  12. package/dist/assets/vue.js +1 -1
  13. package/dist/assets/{vuetify-533fb61b.js → vuetify-45cc2bff.js} +1 -1
  14. package/dist/assets/vuetify.js +1 -1
  15. package/index.d.ts +8 -6
  16. package/index.js +5 -7
  17. package/package.json +3 -2
  18. package/plugins/package.json +8 -7
  19. package/src/actions/actionHelper.d.ts +16 -11
  20. package/src/actions/actionHelper.js +50 -61
  21. package/src/actions/flightActions.d.ts +10 -0
  22. package/src/actions/flightActions.js +103 -13
  23. package/src/application/VcsApp.vue +1 -1
  24. package/src/application/VcsMainMap.vue +40 -2
  25. package/src/application/VcsMainMap.vue.d.ts +4 -0
  26. package/src/application/VcsMap.vue +0 -9
  27. package/src/components/flight/VcsFlightAnchorsComponent.vue +1 -0
  28. package/src/components/flight/VcsFlightPlayer.vue +31 -17
  29. package/src/components/flight/VcsFlightPlayer.vue.d.ts +1 -0
  30. package/src/components/plugins/VcsLoadingOverlay.vue +138 -0
  31. package/src/components/plugins/VcsLoadingOverlay.vue.d.ts +2 -0
  32. package/src/components/plugins/{AbstractWorkspaceItemCreator.vue → VcsWorkspaceWrapper.vue} +3 -3
  33. package/src/components/vector-properties/VcsFeatureEditingWindow.vue +20 -1
  34. package/src/components/vector-properties/VcsFeatureEditingWindow.vue.d.ts +11 -0
  35. package/src/components/vector-properties/VcsFeatureInputEditor.vue +166 -0
  36. package/src/components/vector-properties/VcsFeatureInputEditor.vue.d.ts +17 -0
  37. package/src/contentTree/contentTreeCollection.d.ts +5 -0
  38. package/src/contentTree/contentTreeCollection.js +11 -3
  39. package/src/contentTree/contentTreeItem.d.ts +2 -2
  40. package/src/contentTree/wmsGroupContentTreeItem.js +10 -3
  41. package/src/featureInfo/iframeFeatureInfoView.d.ts +16 -3
  42. package/src/featureInfo/iframeFeatureInfoView.js +19 -2
  43. package/src/featureInfo/iframeWmsFeatureInfoView.d.ts +3 -1
  44. package/src/featureInfo/iframeWmsFeatureInfoView.js +1 -1
  45. package/src/i18n/de.d.ts +21 -7
  46. package/src/i18n/de.js +11 -0
  47. package/src/i18n/en.d.ts +21 -7
  48. package/src/i18n/en.js +11 -0
  49. package/src/navigation/MapNavigation.vue +22 -27
  50. package/src/navigation/MapNavigation.vue.d.ts +2 -34
  51. package/src/navigation/overviewMap.d.ts +23 -13
  52. package/src/navigation/overviewMap.js +73 -72
  53. package/dist/assets/ui-aadb7707.css +0 -1
  54. /package/dist/assets/{cesium-8dd00805.js → cesium-8502542e.js} +0 -0
  55. /package/dist/assets/core-workers/{panoramaImageWorker.js-0ce7d2f3.js → panoramaImageWorker.js-70e7fc33.js} +0 -0
  56. /package/dist/assets/{vue-d7691a29.js → vue-461b4f1b.js} +0 -0
  57. /package/dist/assets/{vuetify-533fb61b.css → vuetify-45cc2bff.css} +0 -0
  58. /package/src/components/plugins/{AbstractWorkspaceItemCreator.vue.d.ts → VcsWorkspaceWrapper.vue.d.ts} +0 -0
@@ -58,6 +58,7 @@
58
58
  </v-container>
59
59
  </VcsFormSection>
60
60
  </template>
61
+
61
62
  <script>
62
63
  import { computed, inject, onMounted, onUnmounted, ref } from 'vue';
63
64
  import { VContainer, VSheet, VSpacer } from 'vuetify/components';
@@ -1,6 +1,15 @@
1
1
  <template>
2
2
  <v-container class="py-0 px-1 vcs-flight-player">
3
- <VcsLabel html-for="player">{{ $t('flight.player') }}</VcsLabel>
3
+ <v-row no-gutters class="d-flex align-center">
4
+ <VcsLabel html-for="player">{{ $t('flight.player') }}</VcsLabel>
5
+ <v-row class="d-flex justify-end px-1 gc-2" no-gutters>
6
+ <VcsActionButtonList
7
+ overflow-icon="$vcsShare"
8
+ :actions="recordingActions"
9
+ :disabled="!isCurrentPlayer || disabled"
10
+ />
11
+ </v-row>
12
+ </v-row>
4
13
  <VcsSlider
5
14
  v-if="clock"
6
15
  type="number"
@@ -32,22 +41,22 @@
32
41
  </div>
33
42
  </v-container>
34
43
  </template>
44
+
35
45
  <script>
36
46
  import { inject, onMounted, onUnmounted, ref } from 'vue';
37
- import { VContainer } from 'vuetify/components';
47
+ import { VContainer, VRow } from 'vuetify/components';
38
48
  import VcsSlider from '../form-inputs-controls/VcsSlider.vue';
39
49
  import VcsLabel from '../form-inputs-controls/VcsLabel.vue';
40
50
  import VcsButton from '../buttons/VcsButton.vue';
41
- import { createFlightPlayerActions } from '../../actions/flightActions.js';
51
+ import VcsActionButtonList from '../buttons/VcsActionButtonList.vue';
52
+ import {
53
+ createFlightMovieActions,
54
+ createFlightPlayerActions,
55
+ } from '../../actions/flightActions.js';
42
56
  import { getProvidedFlightInstance } from './composables.js';
43
57
 
44
58
  function getDefaultClock() {
45
- return {
46
- startTime: 0,
47
- endTime: 0,
48
- currentTime: 0,
49
- times: [],
50
- };
59
+ return { startTime: 0, endTime: 0, currentTime: 0, times: [] };
51
60
  }
52
61
 
53
62
  /**
@@ -70,18 +79,18 @@
70
79
  export default {
71
80
  name: 'VcsFlightPlayer',
72
81
  components: {
73
- VcsLabel,
74
- VcsButton,
75
82
  VContainer,
83
+ VRow,
84
+ VcsActionButtonList,
85
+ VcsButton,
86
+ VcsLabel,
76
87
  VcsSlider,
77
88
  },
78
- props: {
79
- disabled: {
80
- type: Boolean,
81
- default: false,
82
- },
83
- },
89
+ props: { disabled: { type: Boolean, default: false } },
84
90
  setup() {
91
+ /**
92
+ * @type {import("../../vcsUiApp.js").default}
93
+ */
85
94
  const app = inject('vcsApp');
86
95
  const flightInstance = getProvidedFlightInstance();
87
96
  const clock = ref(getDefaultClock());
@@ -113,6 +122,9 @@
113
122
  }
114
123
  }
115
124
 
125
+ const { actions: recordingActions, destroy: destroyRecordingActions } =
126
+ createFlightMovieActions(app, flightInstance);
127
+
116
128
  onMounted(async () => {
117
129
  flightInstancePlayer =
118
130
  await app.flights.setPlayerForFlight(flightInstance);
@@ -129,12 +141,14 @@
129
141
  onUnmounted(() => {
130
142
  destroy();
131
143
  playerChangedListener();
144
+ destroyRecordingActions();
132
145
  });
133
146
 
134
147
  return {
135
148
  clock,
136
149
  actions,
137
150
  isCurrentPlayer,
151
+ recordingActions,
138
152
  clockTime(seconds) {
139
153
  const mins = Math.floor(seconds / 60);
140
154
  const secs = Math.floor(seconds % 60);
@@ -12,6 +12,7 @@ declare const _default: import("vue").DefineComponent<{
12
12
  }>;
13
13
  actions: import("../../actions/actionHelper.js", { with: { "resolution-mode": "import" } }).VcsAction[];
14
14
  isCurrentPlayer: import("vue").Ref<boolean>;
15
+ recordingActions: import("../../actions/actionHelper.js", { with: { "resolution-mode": "import" } }).VcsAction[];
15
16
  clockTime(seconds: any): string;
16
17
  setTime(seconds: any): void;
17
18
  }, any, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
@@ -0,0 +1,138 @@
1
+ <template>
2
+ <v-dialog
3
+ v-model="show"
4
+ class="vcs-loading-overlay"
5
+ :max-width="maxWidth"
6
+ :persistent="persistent"
7
+ >
8
+ <v-card class="pa-1">
9
+ <v-card-title v-if="title" class="title loading">
10
+ {{ $t(title) }}
11
+ </v-card-title>
12
+ <v-card-text v-if="text" class="px-4">
13
+ {{ $t(text) }}
14
+ </v-card-text>
15
+ <div class="d-flex justify-end px-4" v-if="hasProgress">
16
+ {{ localProgress }}%
17
+ </div>
18
+ <div class="px-4 pb-1 pt-2">
19
+ <v-progress-linear
20
+ :model-value="localProgress"
21
+ :indeterminate="!hasProgress"
22
+ rounded
23
+ />
24
+ </div>
25
+ <template #actions v-if="cancellable">
26
+ <div class="pa-2">
27
+ <VcsFormButton @click="show = false">
28
+ {{ $t('components.cancel') }}
29
+ </VcsFormButton>
30
+ </div>
31
+ </template>
32
+ </v-card>
33
+ </v-dialog>
34
+ </template>
35
+
36
+ <script>
37
+ import {
38
+ VDialog,
39
+ VCard,
40
+ VCardText,
41
+ VProgressLinear,
42
+ VCardTitle,
43
+ } from 'vuetify/components';
44
+ import { computed, ref, watch } from 'vue';
45
+ import VcsFormButton from '../buttons/VcsFormButton.vue';
46
+
47
+ /**
48
+ * @description Basic overlay to display a progress bar on a VCard, with optional text and cancel button.
49
+ * @vue-prop {import("vue").Ref<number>|undefined} [progress] - The current progress value, between 0 and 1.
50
+ * @vue-prop {string} [title] - The title of the overlay. Will be translated.
51
+ * @vue-prop {string} [text=''] - Optional text to display in the overlay. Will be translated.
52
+ * @vue-prop {boolean} [cancellable=true] - Whether the overlay can be cancelled by the user.
53
+ * @vue-prop {string|number} [maxWidth='500'] - Optional max-width for the dialog.
54
+ * @vue-prop {boolean} [persistent=true] - Whether the dialog should be persistent (not dismissible by clicking outside).
55
+ */
56
+ export default {
57
+ name: 'VcsLoadingOverlay',
58
+ components: {
59
+ VDialog,
60
+ VCard,
61
+ VCardTitle,
62
+ VCardText,
63
+ VProgressLinear,
64
+ VcsFormButton,
65
+ },
66
+ props: {
67
+ progress: {
68
+ type: [Object, Number, undefined],
69
+ default: undefined,
70
+ },
71
+ title: {
72
+ type: String,
73
+ default: '',
74
+ },
75
+ text: {
76
+ type: String,
77
+ default: '',
78
+ },
79
+ cancellable: {
80
+ type: Boolean,
81
+ default: true,
82
+ },
83
+ maxWidth: {
84
+ type: [String, Number],
85
+ default: '500px',
86
+ },
87
+ persistent: {
88
+ type: Boolean,
89
+ default: true,
90
+ },
91
+ },
92
+ emits: ['cancel'],
93
+ setup(props, { emit }) {
94
+ const show = ref(true);
95
+ watch(show, () => {
96
+ if (!show.value) {
97
+ emit('cancel');
98
+ }
99
+ });
100
+ return {
101
+ show,
102
+ hasProgress: props.progress !== undefined,
103
+ localProgress: computed(() => {
104
+ if (props.progress && props.progress.value !== undefined) {
105
+ return Math.round(props.progress.value * 100);
106
+ }
107
+ return 0;
108
+ }),
109
+ };
110
+ },
111
+ };
112
+ </script>
113
+
114
+ <style scoped lang="scss">
115
+ .title {
116
+ font-size: calc(var(--v-vcs-font-size) * 1.2);
117
+ }
118
+
119
+ .loading:after {
120
+ content: ' .';
121
+ animation: dots 2s steps(4, end) infinite;
122
+ }
123
+ @keyframes dots {
124
+ 0%,
125
+ 100% {
126
+ content: '';
127
+ }
128
+ 25% {
129
+ content: '.';
130
+ }
131
+ 50% {
132
+ content: '..';
133
+ }
134
+ 75% {
135
+ content: '...';
136
+ }
137
+ }
138
+ </style>
@@ -0,0 +1,2 @@
1
+ declare const _default: import("vue").DefineSetupFnComponent<Record<string, any>, {}, {}, Record<string, any> & {}, import("vue").PublicProps>;
2
+ export default _default;
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <v-container class="pa-0 abstract-workspace-item-creator">
2
+ <v-container class="pa-0 vcs-workspace-wrapper">
3
3
  <slot />
4
4
  <div v-if="showFooter">
5
5
  <v-divider class="mt-3" />
@@ -42,7 +42,7 @@
42
42
  * @vue-prop {boolean} [disableAdd=false] - Flag to render add button disabled.
43
43
  * @vue-prop {boolean} [tooltipAdd='components.addToMyWorkspace'] - Option to change the add button tooltip.
44
44
  * @vue-prop {boolean} [disableNew=false] - Flag to render new button disabled.
45
- * @vue-prop {boolean} [tooltipNew''] - Option to change the add a tooltip to the new button.
45
+ * @vue-prop {boolean} [tooltipNew=''] - Option to change the add a tooltip to the new button.
46
46
  * @vue-prop {Array<VcsAction>} [actions] - Optional actions rendered as ActionButtonList in the footer.
47
47
  * @vue-prop {string} [newButtonTitle='components.new'] - Option to change the new button title, e.g. to 'components.apply'.
48
48
  * @vue-event {Event} addClicked - Event fired on clicking the reset button.
@@ -50,7 +50,7 @@
50
50
  * @vue-slot secondaryButton An optionnal named slot to add a secondary button to the footer, rendered filled on the left of the new button.
51
51
  */
52
52
  export default {
53
- name: 'AbstractWorkspaceItemCreator',
53
+ name: 'VcsWorkspaceWrapper',
54
54
  components: {
55
55
  VContainer,
56
56
  VDivider,
@@ -13,7 +13,12 @@
13
13
  :feature-properties="featureProperties"
14
14
  :allow-z-input="is3D"
15
15
  />
16
- <div v-else class="px-1 py-1">
16
+ <div v-else-if="showInputs" class="py-1">
17
+ <VcsFeatureInputEditor
18
+ :is3-d="is3D && featureProperties.altitudeMode === 'absolute'"
19
+ />
20
+ </div>
21
+ <div v-else class="py-1">
17
22
  {{ $t('components.editor.modifyInfo') }}
18
23
  </div>
19
24
  </div>
@@ -67,6 +72,7 @@
67
72
  } from './VcsVectorPropertiesComponent.vue';
68
73
  import VcsFormSection from '../section/VcsFormSection.vue';
69
74
  import VcsSnapTo from './VcsSnapTo.vue';
75
+ import VcsFeatureInputEditor from './VcsFeatureInputEditor.vue';
70
76
 
71
77
  /**
72
78
  * @typedef {Object} EditorManager
@@ -150,6 +156,7 @@
150
156
  VSheet,
151
157
  VcsFormSection,
152
158
  VcsVectorPropertiesComponent,
159
+ VcsFeatureInputEditor,
153
160
  VcsFeatureStyleComponent,
154
161
  },
155
162
  props: {
@@ -186,6 +193,10 @@
186
193
  type: Boolean,
187
194
  default: true,
188
195
  },
196
+ showInputEditor: {
197
+ type: Boolean,
198
+ default: false,
199
+ },
189
200
  },
190
201
  setup(props) {
191
202
  const vcsApp = inject('vcsApp');
@@ -463,8 +474,16 @@
463
474
  availableVectorProperties,
464
475
  is3D,
465
476
  is2DFeature,
477
+ isGeometryEditing,
466
478
  updateFeatureProperties,
467
479
  defaultVectorProperties: VectorProperties.getDefaultOptions(),
480
+ showInputs: computed(
481
+ () =>
482
+ !currentTransformationMode.value &&
483
+ props.showInputEditor &&
484
+ features.value.length === 1 &&
485
+ features.value[0]?.getGeometry()?.getType() === 'Point',
486
+ ),
468
487
  };
469
488
  },
470
489
  };
@@ -42,6 +42,10 @@ declare const _default: import("vue").DefineComponent<{
42
42
  type: BooleanConstructor;
43
43
  default: boolean;
44
44
  };
45
+ showInputEditor: {
46
+ type: BooleanConstructor;
47
+ default: boolean;
48
+ };
45
49
  }, {
46
50
  featureProperties: import("vue").ShallowRef<any>;
47
51
  session: import("vue").ShallowRef<import("@vcmap/core", { with: { "resolution-mode": "import" } }).SelectFeaturesSession | import("@vcmap/core", { with: { "resolution-mode": "import" } }).CreateFeatureSession<GeometryType> | undefined>;
@@ -53,8 +57,10 @@ declare const _default: import("vue").DefineComponent<{
53
57
  availableVectorProperties: import("vue").ShallowRef<never[]>;
54
58
  is3D: import("vue").Ref<boolean>;
55
59
  is2DFeature: import("vue").ComputedRef<boolean>;
60
+ isGeometryEditing: import("vue").ComputedRef<boolean>;
56
61
  updateFeatureProperties: (update: import("@vcmap/core").VectorPropertiesOptions) => void;
57
62
  defaultVectorProperties: import("@vcmap/core", { with: { "resolution-mode": "import" } }).VectorPropertiesOptions;
63
+ showInputs: import("vue").ComputedRef<boolean>;
58
64
  }, any, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
59
65
  allowedVectorProperties: {
60
66
  type: ArrayConstructor;
@@ -84,6 +90,10 @@ declare const _default: import("vue").DefineComponent<{
84
90
  type: BooleanConstructor;
85
91
  default: boolean;
86
92
  };
93
+ showInputEditor: {
94
+ type: BooleanConstructor;
95
+ default: boolean;
96
+ };
87
97
  }>>, {
88
98
  altitudeModes: unknown[];
89
99
  allowedVectorProperties: unknown[];
@@ -92,6 +102,7 @@ declare const _default: import("vue").DefineComponent<{
92
102
  showResetVectorProperties: boolean;
93
103
  showStyle: boolean;
94
104
  showSnapping: boolean;
105
+ showInputEditor: boolean;
95
106
  }, {}>;
96
107
  export default _default;
97
108
  export type EditorManager = {
@@ -0,0 +1,166 @@
1
+ <template>
2
+ <div class="vcs-point-input-editor">
3
+ <v-row no-gutters>
4
+ <v-col>
5
+ <VcsLabel html-for="posX">
6
+ {{ $t('components.editor.position.x') }}
7
+ </VcsLabel>
8
+ </v-col>
9
+ <v-col>
10
+ <VcsTextField
11
+ id="posX"
12
+ type="number"
13
+ v-model.number="coordinates[0]"
14
+ @update:model-value="isEdited = true"
15
+ />
16
+ </v-col>
17
+ </v-row>
18
+ <v-row no-gutters>
19
+ <v-col>
20
+ <VcsLabel html-for="posY">
21
+ {{ $t('components.editor.position.y') }}
22
+ </VcsLabel>
23
+ </v-col>
24
+ <v-col>
25
+ <VcsTextField
26
+ id="posY"
27
+ type="number"
28
+ v-model.number="coordinates[1]"
29
+ @update:model-value="isEdited = true"
30
+ />
31
+ </v-col>
32
+ </v-row>
33
+ <v-row no-gutters v-if="is3D">
34
+ <v-col>
35
+ <VcsLabel html-for="posZ">
36
+ {{ $t('components.editor.position.z') }}
37
+ </VcsLabel>
38
+ </v-col>
39
+ <v-col>
40
+ <VcsTextField
41
+ id="posZ"
42
+ type="number"
43
+ v-model.number="coordinates[2]"
44
+ @update:model-value="isEdited = true"
45
+ />
46
+ </v-col>
47
+ </v-row>
48
+ <v-row no-gutters v-if="isEdited" class="d-flex justify-end gc-1">
49
+ <VcsToolButton @click="cancel">
50
+ {{ $t('components.cancel') }}
51
+ </VcsToolButton>
52
+ <VcsToolButton @click="apply">
53
+ {{ $t('components.apply') }}
54
+ </VcsToolButton>
55
+ </v-row>
56
+ </div>
57
+ </template>
58
+
59
+ <script>
60
+ import { VCol, VRow } from 'vuetify/components';
61
+ import { inject, onUnmounted, ref } from 'vue';
62
+ import {
63
+ getDefaultProjection,
64
+ mercatorProjection,
65
+ Projection,
66
+ } from '@vcmap/core';
67
+ import { getLogger } from '@vcsuite/logger';
68
+ import VcsLabel from '../form-inputs-controls/VcsLabel.vue';
69
+ import VcsTextField from '../form-inputs-controls/VcsTextField.vue';
70
+ import VcsToolButton from '../buttons/VcsToolButton.vue';
71
+
72
+ /**
73
+ * @description Component to edit the position of a feature in a vector layer. Currently
74
+ * only supports point features, which need to be the currently selected feature in the manager.
75
+ * @vue-prop {boolean} is3D - Whether the feature is in 3D.
76
+ */
77
+ export default {
78
+ name: 'VcsFeatureEditingWindow',
79
+ components: {
80
+ VCol,
81
+ VRow,
82
+ VcsLabel,
83
+ VcsTextField,
84
+ VcsToolButton,
85
+ },
86
+ props: {
87
+ is3D: {
88
+ type: Boolean,
89
+ required: true,
90
+ },
91
+ },
92
+ setup() {
93
+ const { currentFeatures: features } = inject('manager');
94
+
95
+ if (
96
+ features.value.length !== 1 ||
97
+ features.value[0]?.getGeometry()?.getType() !== 'Point'
98
+ ) {
99
+ getLogger('VcsFeatureEditingWindow').error(
100
+ 'This component only supports editing a single point feature.',
101
+ );
102
+ }
103
+
104
+ const isEdited = ref(false);
105
+ /** @type {import("ol").Feature} */
106
+ const feature = features.value[0];
107
+ const defaultProjection = getDefaultProjection();
108
+ const decimalPlaces = defaultProjection.epsg.includes('4326') ? 6 : 2;
109
+
110
+ function transform(coordinates) {
111
+ return mercatorProjection
112
+ .transformTo(defaultProjection, coordinates)
113
+ .map((c, i) => +c.toFixed(i === 2 ? 2 : decimalPlaces));
114
+ }
115
+ const coordinates = ref(
116
+ transform(feature.getGeometry().getFlatCoordinates()),
117
+ );
118
+
119
+ function updateFromFeature() {
120
+ coordinates.value = transform(
121
+ feature.getGeometry().getFlatCoordinates(),
122
+ );
123
+ }
124
+ feature.on('change', updateFromFeature);
125
+ onUnmounted(() => {
126
+ feature.un('change', updateFromFeature);
127
+ });
128
+
129
+ function updateFromInput() {
130
+ let updatedCoordinates;
131
+ try {
132
+ updatedCoordinates = Projection.transform(
133
+ mercatorProjection,
134
+ defaultProjection,
135
+ coordinates.value,
136
+ );
137
+ feature.getGeometry().setCoordinates(updatedCoordinates);
138
+ } catch (error) {
139
+ getLogger('VcsFeatureEditingWindow').error(
140
+ 'Invalid coordinates input',
141
+ error,
142
+ );
143
+ }
144
+ }
145
+
146
+ return {
147
+ isEdited,
148
+ coordinates,
149
+ apply: () => {
150
+ updateFromInput();
151
+ isEdited.value = false;
152
+ },
153
+ cancel: () => {
154
+ updateFromFeature();
155
+ isEdited.value = false;
156
+ },
157
+ };
158
+ },
159
+ };
160
+ </script>
161
+
162
+ <style scoped>
163
+ :deep(.v-btn__content):hover {
164
+ color: rgb(var(--v-theme-primary));
165
+ }
166
+ </style>
@@ -0,0 +1,17 @@
1
+ declare const _default: import("vue").DefineComponent<{
2
+ is3D: {
3
+ type: BooleanConstructor;
4
+ required: true;
5
+ };
6
+ }, {
7
+ isEdited: import("vue").Ref<boolean>;
8
+ coordinates: import("vue").Ref<number[]>;
9
+ apply: () => void;
10
+ cancel: () => void;
11
+ }, any, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
12
+ is3D: {
13
+ type: BooleanConstructor;
14
+ required: true;
15
+ };
16
+ }>>, {}, {}>;
17
+ export default _default;
@@ -23,6 +23,11 @@ declare class ContentTreeCollection extends IndexedCollection<ContentTreeItem> {
23
23
  * @param {import("@src/vcsUiApp.js").default} app
24
24
  */
25
25
  constructor(app: import("@src/vcsUiApp.js").default);
26
+ /**
27
+ * @type {string|undefined}
28
+ * @private
29
+ */
30
+ private _removedListenerTimeoutId;
26
31
  /**
27
32
  * @type {import("@src/vcsUiApp.js").default}
28
33
  * @private
@@ -31,6 +31,11 @@ export const defaultContentTreeComponentId = 'Content';
31
31
  * @extends {IndexedCollection<ContentTreeItem>}
32
32
  */
33
33
  class ContentTreeCollection extends IndexedCollection {
34
+ /**
35
+ * @type {string|undefined}
36
+ * @private
37
+ */
38
+ _removedListenerTimeoutId;
34
39
  /**
35
40
  * @param {import("@src/vcsUiApp.js").default} app
36
41
  */
@@ -75,13 +80,13 @@ class ContentTreeCollection extends IndexedCollection {
75
80
  'contentTreeActiveOnStartup',
76
81
  );
77
82
  if (
78
- contentTreeActiveOnStartup?.value &&
83
+ contentTreeActiveOnStartup?.value != null &&
79
84
  contentTreeActiveOnStartup[moduleIdSymbol] !== this._app.dynamicModuleId
80
85
  ) {
81
86
  const action = this._app.navbarManager.get(
82
87
  defaultContentTreeComponentId,
83
88
  )?.action;
84
- if (action && !action.active) {
89
+ if (action && action.active !== contentTreeActiveOnStartup.value) {
85
90
  action.callback();
86
91
  }
87
92
  }
@@ -107,7 +112,10 @@ class ContentTreeCollection extends IndexedCollection {
107
112
  }
108
113
  }),
109
114
  this.removed.addEventListener((child) => {
110
- recreateTree();
115
+ clearTimeout(this._removedListenerTimeoutId);
116
+ this._removedListenerTimeoutId = setTimeout(() => {
117
+ recreateTree();
118
+ }, 0);
111
119
  if (this._weightListeners.has(child.name)) {
112
120
  this._weightListeners.get(child.name)();
113
121
  this._weightListeners.delete(child.name);
@@ -272,11 +272,11 @@ declare class ContentTreeItem {
272
272
  /**
273
273
  * @param {(string|HTMLCanvasElement|HTMLImageElement)=} icon
274
274
  */
275
- set icon(icon: string | HTMLImageElement | HTMLCanvasElement | undefined);
275
+ set icon(icon: string | HTMLCanvasElement | HTMLImageElement | undefined);
276
276
  /**
277
277
  * @type {string|HTMLCanvasElement|HTMLImageElement|undefined}
278
278
  */
279
- get icon(): string | HTMLImageElement | HTMLCanvasElement | undefined;
279
+ get icon(): string | HTMLCanvasElement | HTMLImageElement | undefined;
280
280
  /**
281
281
  * @param {number} weight
282
282
  */
@@ -522,6 +522,10 @@ class WMSGroupContentTreeItem extends VcsObjectContentTreeItem {
522
522
  this._layer.url,
523
523
  this._layer.parameters,
524
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
+ }
525
529
  this._availableWMSEntries = availableWMSEntries.filter((wmsEntry) => {
526
530
  return this._allowedWMSLayers
527
531
  ? this._allowedWMSLayers.includes(wmsEntry.name)
@@ -558,9 +562,12 @@ class WMSGroupContentTreeItem extends VcsObjectContentTreeItem {
558
562
  this._setState();
559
563
  this._setLegend();
560
564
  } catch (e) {
561
- this._layer.deactivate();
562
- this.visible = false;
563
- this._invalid = true;
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
+ }
564
571
  getLogger(this.className).error(
565
572
  `An error occured while fetching the ${this._layerName} capabilities:`,
566
573
  e,