@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
package/dist/assets/ui.js CHANGED
@@ -1 +1 @@
1
- export * from "./ui-b13e28a1.js";
1
+ export * from "./ui-f33a5ee2.js";
@@ -1 +1 @@
1
- export * from "./vue-6a295c0b.js";
1
+ export * from "./vue-004523e0.js";
@@ -10,7 +10,7 @@ function loadCss(href) {
10
10
  elem.onerror = reject;
11
11
  document.head.appendChild(elem);
12
12
  });
13
- } await loadCss('./assets/vuetify-a1930526.css');import { watch as Q, onScopeDispose as Ze, effectScope as Zl, shallowRef as K, Fragment as ie, reactive as it, computed as b, watchEffect as Fe, toRefs as Yt, capitalize as Nn, isVNode as Rc, Comment as Nc, unref as ot, warn as ja, getCurrentInstance as Hc, ref as j, provide as De, inject as ye, defineComponent as zc, camelize as Ir, h as Gt, toRaw as Be, createVNode as r, mergeProps as O, onBeforeUnmount as Qe, readonly as Ql, onDeactivated as _r, onActivated as Wc, onMounted as Ye, nextTick as we, TransitionGroup as Jl, Transition as jt, isRef as Tn, toRef as $, onBeforeMount as ra, withDirectives as $e, resolveDirective as gt, vShow as Ct, onUpdated as jc, Text as Uc, resolveDynamicComponent as Yc, markRaw as Gc, Teleport as Kc, cloneVNode as qc, createTextVNode as Tt, onUnmounted as Tr, onBeforeUpdate as Xc, withModifiers as Tl, toDisplayString as Zc, vModelText as Qc, resolveComponent as Jc, render as Ar } from "./vue-6a295c0b.js";
13
+ } await loadCss('./assets/vuetify-2fc014c4.css');import { watch as Q, onScopeDispose as Ze, effectScope as Zl, shallowRef as K, Fragment as ie, reactive as it, computed as b, watchEffect as Fe, toRefs as Yt, capitalize as Nn, isVNode as Rc, Comment as Nc, unref as ot, warn as ja, getCurrentInstance as Hc, ref as j, provide as De, inject as ye, defineComponent as zc, camelize as Ir, h as Gt, toRaw as Be, createVNode as r, mergeProps as O, onBeforeUnmount as Qe, readonly as Ql, onDeactivated as _r, onActivated as Wc, onMounted as Ye, nextTick as we, TransitionGroup as Jl, Transition as jt, isRef as Tn, toRef as $, onBeforeMount as ra, withDirectives as $e, resolveDirective as gt, vShow as Ct, onUpdated as jc, Text as Uc, resolveDynamicComponent as Yc, markRaw as Gc, Teleport as Kc, cloneVNode as qc, createTextVNode as Tt, onUnmounted as Tr, onBeforeUpdate as Xc, withModifiers as Tl, toDisplayString as Zc, vModelText as Qc, resolveComponent as Jc, render as Ar } from "./vue-004523e0.js";
14
14
  function rt(e, n) {
15
15
  let t;
16
16
  function a() {
@@ -1 +1 @@
1
- export * from "./vuetify-a1930526.js";
1
+ export * from "./vuetify-2fc014c4.js";
package/index.d.ts CHANGED
@@ -209,6 +209,8 @@ export * from "./src/components/modelHelper.js";
209
209
  export type * from "./src/components/modelHelper.d.ts";
210
210
  export * from "./src/components/composables.js";
211
211
  export type * from "./src/components/composables.d.ts";
212
+ export { moveDraggableItems } from "./src/components/lists/dragHelper.js";
213
+ export type * from "./src/components/lists/dragHelper.d.ts";
212
214
  export { default as VcsTreeview } from "./src/components/lists/VcsTreeview.vue";
213
215
  export type * from "./src/components/lists/VcsTreeview.vue.d.ts";
214
216
  export { default as VcsTreeNode } from "./src/components/lists/VcsTreeNode.vue";
@@ -277,13 +279,15 @@ export { default as VcsSplashScreen } from "./src/application/VcsSplashScreen.vu
277
279
  export type * from "./src/application/VcsSplashScreen.vue.d.ts";
278
280
  export { default as Search } from "./src/search/search.js";
279
281
  export type * from "./src/search/search.d.ts";
282
+ export { searchComponentId } from "./src/search/SearchComponent.vue";
283
+ export type * from "./src/search/SearchComponent.vue.d.ts";
280
284
  export { markText } from "./src/search/markText.js";
281
285
  export type * from "./src/search/markText.d.ts";
282
286
  export { default as ResultItemComponent } from "./src/search/ResultItem.vue";
283
287
  export type * from "./src/search/ResultItem.vue.d.ts";
284
288
  export { default as ResultsComponent } from "./src/search/ResultsComponent.vue";
285
289
  export type * from "./src/search/ResultsComponent.vue.d.ts";
286
- export { addLoadingOverlay, callSafeAction, createMapButtonAction, createToggleAction, createModalAction, createLinkAction, createGoToViewpointAction, createZoomToFeatureAction, searchComponentId } from "./src/actions/actionHelper.js";
290
+ export { addLoadingOverlay, callSafeAction, createMapButtonAction, createToggleAction, createModalAction, createLinkAction, createGoToViewpointAction, createZoomToFeatureAction } from "./src/actions/actionHelper.js";
287
291
  export type * from "./src/actions/actionHelper.d.ts";
288
292
  export { createDeepPickingAction, deepPickingWindowId } from "./src/actions/deepPickingAction.js";
289
293
  export type * from "./src/actions/deepPickingAction.d.ts";
package/index.js CHANGED
@@ -11,7 +11,6 @@ export {
11
11
  createLinkAction,
12
12
  createGoToViewpointAction,
13
13
  createZoomToFeatureAction,
14
- searchComponentId,
15
14
  } from './src/actions/actionHelper.js';
16
15
  export {
17
16
  createDeepPickingAction,
@@ -313,6 +312,7 @@ export { default as VcsList } from './src/components/lists/VcsList.vue';
313
312
  export { default as VcsListItemComponent } from './src/components/lists/VcsListItemComponent.vue';
314
313
  export { default as VcsGroupedList } from './src/components/lists/VcsGroupedList.vue';
315
314
  export * from './src/components/lists/listHelper.js';
315
+ export { moveDraggableItems } from './src/components/lists/dragHelper.js';
316
316
  export { default as VcsTreeview } from './src/components/lists/VcsTreeview.vue';
317
317
  export { default as VcsTreeNode } from './src/components/lists/VcsTreeNode.vue';
318
318
  export { default as VcsTreeviewTitle } from './src/components/lists/VcsTreeviewTitle.vue';
@@ -376,6 +376,7 @@ export {
376
376
  getLegendEntries,
377
377
  } from './src/legend/legendHelper.js';
378
378
  export { default as Search } from './src/search/search.js';
379
+ export { searchComponentId } from './src/search/SearchComponent.vue';
379
380
  export { markText } from './src/search/markText.js';
380
381
  export { default as ResultItemComponent } from './src/search/ResultItem.vue';
381
382
  export { default as ResultsComponent } from './src/search/ResultsComponent.vue';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vcmap/ui",
3
- "version": "6.2.2",
3
+ "version": "6.2.4",
4
4
  "author": "Virtual City Systems",
5
5
  "license": "MIT",
6
6
  "scripts": {
@@ -0,0 +1,28 @@
1
+ <template>
2
+ <v-container class="pa-0">
3
+ <VcsExtentEditor heading="Default WGS84 projection" v-model="wgs84Extent" />
4
+ <VcsExtentEditor
5
+ heading="Mercator projection example"
6
+ v-model="mercatorExtent"
7
+ />
8
+ </v-container>
9
+ </template>
10
+ <script>
11
+ import { VcsExtentEditor } from '@vcmap/ui';
12
+ import { VContainer } from 'vuetify/components';
13
+ import { Extent, mercatorProjection, wgs84Projection } from '@vcmap/core';
14
+
15
+ export default {
16
+ name: 'ExtentExample',
17
+ components: { VcsExtentEditor, VContainer },
18
+ setup() {
19
+ const wgs84Extent = new Extent({ projection: wgs84Projection }).toJSON();
20
+ const mercatorExtent = new Extent({
21
+ projection: mercatorProjection,
22
+ }).toJSON();
23
+
24
+ return { wgs84Extent, mercatorExtent };
25
+ },
26
+ };
27
+ </script>
28
+ <style lang="scss" scoped></style>
@@ -1,19 +1,11 @@
1
- import {
2
- ButtonLocation,
3
- createToggleAction,
4
- WindowSlot,
5
- VcsExtentEditor,
6
- } from '@vcmap/ui';
7
- import { Extent } from '@vcmap/core';
8
- import { reactive } from 'vue';
1
+ import { ButtonLocation, createToggleAction, WindowSlot } from '@vcmap/ui';
9
2
  import packageJSON from '../package.json';
3
+ import ExtentExample from './ExtentExample.vue';
10
4
 
11
5
  /**
12
6
  * @returns {VcsPlugin}
13
7
  */
14
8
  export default async function extentExample() {
15
- const modelValue = reactive(new Extent().toJSON());
16
-
17
9
  return {
18
10
  get name() {
19
11
  return packageJSON.name;
@@ -33,15 +25,12 @@ export default async function extentExample() {
33
25
  },
34
26
  {
35
27
  id: 'extent-example',
36
- component: VcsExtentEditor,
28
+ component: ExtentExample,
37
29
  slot: WindowSlot.DYNAMIC_LEFT,
38
30
  state: {
39
31
  headerTitle: 'Extent Example',
40
32
  headerIcon: '$vcsBoundingBox',
41
33
  },
42
- props: {
43
- modelValue,
44
- },
45
34
  },
46
35
  app.windowManager,
47
36
  packageJSON.name,
@@ -118,7 +118,6 @@ export function addLoadingOverlay(app: import("../vcsUiApp.js").default, owner:
118
118
  maxWidth?: string | number | undefined;
119
119
  persistent?: boolean | undefined;
120
120
  } | undefined): () => void;
121
- export const searchComponentId: "searchId";
122
121
  export type ActionOptions = Omit<VcsAction, 'callback'>;
123
122
  export type ActionCallback = (p?: PointerEvent) => (void | Promise<void>);
124
123
  export type VcsAction = {
@@ -18,7 +18,9 @@ import {
18
18
  getFittedWindowPositionOptions,
19
19
  getTargetSize,
20
20
  } from '../manager/window/windowHelper.js';
21
- import SearchComponent from '../search/SearchComponent.vue';
21
+ import SearchComponent, {
22
+ searchComponentId,
23
+ } from '../search/SearchComponent.vue';
22
24
  import VcsLoadingOverlay from '../components/plugins/VcsLoadingOverlay.vue';
23
25
 
24
26
  /**
@@ -215,8 +217,6 @@ export function createToggleAction(
215
217
  return { action, destroy };
216
218
  }
217
219
 
218
- export const searchComponentId = 'searchId';
219
-
220
220
  /**
221
221
  * @param {import("../vcsUiApp.js").default} app
222
222
  * @returns {{action: import("vue").UnwrapRef<VcsAction>, destroy: function():void}}
@@ -99,6 +99,10 @@
99
99
  };
100
100
  setupI18n();
101
101
  const setLocale = () => {
102
+ if (!languages.value.includes(app.locale)) {
103
+ localLanguage.value = 'en';
104
+ return;
105
+ }
102
106
  localLanguage.value = app.locale;
103
107
  };
104
108
  setLocale();
@@ -18,6 +18,7 @@
18
18
  hide-z
19
19
  v-model="min"
20
20
  :disabled="disabled"
21
+ :extent="extent"
21
22
  :axis-rules="[
22
23
  [(v) => checkInput(v, max[0])],
23
24
  [(v) => checkInput(v, max[1])],
@@ -35,6 +36,7 @@
35
36
  hide-z
36
37
  v-model="max"
37
38
  :disabled="disabled"
39
+ :extent="extent"
38
40
  :axis-rules="[
39
41
  [(v) => checkInput(min[0], v)],
40
42
  [(v) => checkInput(min[1], v)],
@@ -54,7 +56,7 @@
54
56
  <script>
55
57
  import { computed, toRaw } from 'vue';
56
58
  import { VCol, VContainer, VRow } from 'vuetify/components';
57
- import { Extent } from '@vcmap/core';
59
+ import { Extent, Projection } from '@vcmap/core';
58
60
  import VcsLabel from '../form-inputs-controls/VcsLabel.vue';
59
61
  import VcsTextField from '../form-inputs-controls/VcsTextField.vue';
60
62
  import VcsCoordinate from '../form-inputs-controls/VcsCoordinate.vue';
@@ -100,6 +102,14 @@
100
102
  setup(props, { emit }) {
101
103
  const localValue = useProxiedComplexModel(props, 'modelValue', emit);
102
104
 
105
+ const { proj } = new Projection(localValue.value.projection);
106
+ const extent = proj.getExtent() || [
107
+ -Infinity,
108
+ -Infinity,
109
+ Infinity,
110
+ Infinity,
111
+ ];
112
+
103
113
  const getCoordinate = (start, end = 4) =>
104
114
  computed({
105
115
  get() {
@@ -121,6 +131,7 @@
121
131
  min: getCoordinate(0, 2),
122
132
  max: getCoordinate(2),
123
133
  checkInput,
134
+ extent,
124
135
  cid,
125
136
  };
126
137
  },
@@ -15,6 +15,7 @@ declare const _default: import("vue").DefineComponent<{
15
15
  min: import("vue").WritableComputedRef<any>;
16
16
  max: import("vue").WritableComputedRef<any>;
17
17
  checkInput: typeof checkInput;
18
+ extent: import("ol/extent.js", { with: { "resolution-mode": "import" } }).Extent;
18
19
  cid: string;
19
20
  }, any, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, "update:modelValue"[], "update:modelValue", import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
20
21
  modelValue: {
@@ -73,7 +73,7 @@
73
73
  import VcsList from '../lists/VcsList.vue';
74
74
  import VcsTextField from '../form-inputs-controls/VcsTextField.vue';
75
75
  import VcsButton from '../buttons/VcsButton.vue';
76
- import { moveItem } from '../../manager/collectionManager/CollectionComponentList.vue';
76
+ import { moveItem } from '../lists/dragHelper.js';
77
77
  import CollectionComponentClass from '../../manager/collectionManager/collectionComponentClass.js';
78
78
  import { WindowSlot } from '../../manager/window/windowManager.js';
79
79
  import VcsViewpointEditor from '../viewpoint/VcsViewpointEditor.vue';
@@ -330,7 +330,7 @@
330
330
  draggable: collectionComponent.draggable,
331
331
  actions: collectionComponent.getActions(),
332
332
  move(event) {
333
- moveItem(collectionComponent, event);
333
+ moveItem(collectionComponent.collection, event);
334
334
  },
335
335
  durationRule,
336
336
  showDuration(index) {
@@ -46,7 +46,6 @@
46
46
  "
47
47
  @dragend="dragEnd($event)"
48
48
  @drop="drop($event, item)"
49
- @dragleave="dragLeave($event)"
50
49
  :class="{
51
50
  'v-list-item__selected': selected.includes(item),
52
51
  'v-list-item__lighten_even': lightenEven,
@@ -246,23 +245,16 @@
246
245
  return items;
247
246
  });
248
247
 
249
- const {
250
- dragging,
251
- isDraggable,
252
- dragStart,
253
- dragOver,
254
- dragLeave,
255
- dragEnd,
256
- drop,
257
- } = setupDraggableListOrTree(props, query, (e, value) =>
258
- emit(e, {
259
- ...value,
260
- // @deprecate: targetIndex will be removed on next mayor release
261
- targetIndex: props.items.findIndex(
262
- (i) => i.name === value.targetItem.name,
263
- ),
264
- }),
265
- );
248
+ const { dragging, isDraggable, dragStart, dragOver, dragEnd, drop } =
249
+ setupDraggableListOrTree(props, query, (e, value) =>
250
+ emit(e, {
251
+ ...value,
252
+ // @deprecate: targetIndex will be removed on next mayor release
253
+ targetIndex: props.items.findIndex(
254
+ (i) => i.name === value.targetItem.name,
255
+ ),
256
+ }),
257
+ );
266
258
 
267
259
  const { select, selected, selectionActions } = setupSelectableList(
268
260
  props,
@@ -14,12 +14,13 @@
14
14
  ref="treenodeRef"
15
15
  no-gutters
16
16
  class="treenode flex-nowrap text-truncate"
17
- :class="`level-${level} ${children.length ? 'group' : 'item'}`"
17
+ :class="`level-${level} ${isGroup ? 'group' : 'item'}`"
18
18
  >
19
19
  <VBtn
20
- v-if="children.length"
20
+ v-if="isGroup"
21
21
  class="chevron-btn"
22
22
  variant="text"
23
+ :disabled="item.children.length === 0"
23
24
  :icon="isOpen ? 'mdi-chevron-down' : 'mdi-chevron-right'"
24
25
  @click="bubbleItemToggled(item.name)"
25
26
  />
@@ -41,7 +42,7 @@
41
42
  <slot name="title" v-bind="{ item }">
42
43
  <VcsTreeviewTitle
43
44
  :item="item"
44
- :cursor-pointer="item.clickable || (openOnClick && !!children.length)"
45
+ :cursor-pointer="item.clickable || (openOnClick && isGroup)"
45
46
  @click="(event) => $emit('click', item, event)"
46
47
  />
47
48
  </slot>
@@ -134,6 +135,7 @@
134
135
  * @property {string|HTMLCanvasElement|HTMLImageElement|undefined} [icon] - An optional icon to display with this item. Can be a URL or HTMLElement.
135
136
  * @property {function(string):void} [clicked] - A callback called when the item is clicked.
136
137
  * @property {boolean} [blockOverflow=true] - Forwards the blockOverflow setting to the ActionButtonList, if true will reserve some space for an overflow.
138
+ * @property {boolean} [forceNodeDisplay] - Forces the item to display as a node (with chevron) even when it has no children.
137
139
  */
138
140
 
139
141
  /**
@@ -254,6 +256,9 @@
254
256
  forwardSlots,
255
257
  treenodeRef,
256
258
  isOpen,
259
+ isGroup: computed(
260
+ () => children.value.length > 0 || props.item.forceNodeDisplay,
261
+ ),
257
262
  matchFilter,
258
263
  iconSize,
259
264
  children,
@@ -32,4 +32,8 @@ export type VcsTreeNodeItem = {
32
32
  * - Forwards the blockOverflow setting to the ActionButtonList, if true will reserve some space for an overflow.
33
33
  */
34
34
  blockOverflow?: boolean | undefined;
35
+ /**
36
+ * - Forces the item to display as a node (with chevron) even when it has no children.
37
+ */
38
+ forceNodeDisplay?: boolean | undefined;
35
39
  };
@@ -36,7 +36,6 @@
36
36
  @dragover="dragOver"
37
37
  @dragend="dragEnd"
38
38
  @drop="drop"
39
- @dragleave="dragLeave"
40
39
  @item-toggled="itemToggled"
41
40
  @click="itemClicked"
42
41
  >
@@ -150,9 +149,7 @@
150
149
  localOpenedItems.value.push(...newItems);
151
150
  }
152
151
  },
153
- {
154
- immediate: true,
155
- },
152
+ { immediate: true },
156
153
  );
157
154
 
158
155
  function itemToggled(itemName) {
@@ -166,14 +163,13 @@
166
163
 
167
164
  const { xs } = useDisplay();
168
165
 
169
- const { isDraggable, dragStart, dragOver, dragLeave, dragEnd, drop } =
166
+ const { isDraggable, dragStart, dragOver, dragEnd, drop } =
170
167
  setupDraggableListOrTree(props, localSearchValue, emit);
171
168
 
172
169
  return {
173
170
  isDraggable,
174
171
  dragStart,
175
172
  dragOver,
176
- dragLeave,
177
173
  dragEnd,
178
174
  drop,
179
175
  localSearchValue,
@@ -51,7 +51,6 @@ declare const _default: import("vue").DefineComponent<{
51
51
  isDraggable: import("vue").ComputedRef<boolean>;
52
52
  dragStart: (e: MouseEvent, item: import("./dragHelper.js", { with: { "resolution-mode": "import" } }).VcsDraggableItem) => void;
53
53
  dragOver: (e: MouseEvent, item: import("./dragHelper.js", { with: { "resolution-mode": "import" } }).VcsDraggableItem, dropTarget: HTMLElement, dropTargetZones?: import("./dragHelper.js", { with: { "resolution-mode": "import" } }).DropZones | undefined, isOpen?: boolean | undefined) => void;
54
- dragLeave: (e: MouseEvent) => void;
55
54
  dragEnd: (e: MouseEvent) => void;
56
55
  drop: (e: MouseEvent, item: import("./dragHelper.js", { with: { "resolution-mode": "import" } }).VcsDraggableItem) => void;
57
56
  localSearchValue: import("vue").Ref<any>;
@@ -30,7 +30,6 @@
30
30
  * dropTargetZones?: DropZones,
31
31
  * isOpen?: boolean,
32
32
  * ) => void;
33
- * dragLeave: (e: MouseEvent) => void;
34
33
  * dragEnd: (e: MouseEvent) => void;
35
34
  * drop: (
36
35
  * e: MouseEvent,
@@ -78,6 +77,15 @@ export function setupDraggableListOrTree(props: Object & {
78
77
  * @param {ItemMovedEvent} event
79
78
  */
80
79
  export function moveDraggableItems(items: Array<VcsDraggableItem>, { item, targetItem, position }: ItemMovedEvent): void;
80
+ /**
81
+ * Moves an item to a new position.
82
+ * New position is derived from a target item in the collection.
83
+ * This ensures correct movement, if rendered list is only a subset of the collection.
84
+ * @template T
85
+ * @param {import("@vcmap/core").IndexedCollection<T>} collection
86
+ * @param {import("../../components/lists/dragHelper.js").ItemMovedEvent} event
87
+ */
88
+ export function moveItem<T>(collection: import("@vcmap/core").IndexedCollection<T>, event: import("../../components/lists/dragHelper.js").ItemMovedEvent): void;
81
89
  export type InsertMode = number;
82
90
  export namespace InsertMode {
83
91
  let BEFORE: number;
@@ -96,7 +104,6 @@ export type DraggableListOrTreeSetup = {
96
104
  isDraggable: import("vue").ComputedRef<boolean>;
97
105
  dragStart: (e: MouseEvent, item: VcsDraggableItem) => void;
98
106
  dragOver: (e: MouseEvent, item: VcsDraggableItem, dropTarget: HTMLElement, dropTargetZones?: DropZones, isOpen?: boolean) => void;
99
- dragLeave: (e: MouseEvent) => void;
100
107
  dragEnd: (e: MouseEvent) => void;
101
108
  drop: (e: MouseEvent, item: VcsDraggableItem) => void;
102
109
  };
@@ -43,7 +43,6 @@ export const InsertMode = {
43
43
  * dropTargetZones?: DropZones,
44
44
  * isOpen?: boolean,
45
45
  * ) => void;
46
- * dragLeave: (e: MouseEvent) => void;
47
46
  * dragEnd: (e: MouseEvent) => void;
48
47
  * drop: (
49
48
  * e: MouseEvent,
@@ -100,6 +99,11 @@ export function setupDraggableListOrTree(props, query, emit) {
100
99
  return !query.value && props.draggable;
101
100
  });
102
101
 
102
+ /**
103
+ * @type {HTMLElement | undefined}
104
+ */
105
+ let lastDropTarget;
106
+
103
107
  /**
104
108
  *
105
109
  * @param {HTMLElement} target
@@ -148,7 +152,7 @@ export function setupDraggableListOrTree(props, query, emit) {
148
152
  ) {
149
153
  dropPosition = InsertMode.AFTER;
150
154
  currentTarget.classList.add('drop-target-after');
151
- } else if (dropTargetZones === true || dropTargetZones.into === true) {
155
+ } else if (isIntoAllowed) {
152
156
  dropPosition = InsertMode.INTO;
153
157
  currentTarget.classList.add('drop-target-into');
154
158
  e.dataTransfer.dropEffect = 'copy';
@@ -158,7 +162,7 @@ export function setupDraggableListOrTree(props, query, emit) {
158
162
  }
159
163
 
160
164
  /**
161
- * @param {MouseEvent} e
165
+ * @param {DragEvent} e
162
166
  * @param {VcsDraggableItem} item
163
167
  */
164
168
  function drop(e, item) {
@@ -178,7 +182,7 @@ export function setupDraggableListOrTree(props, query, emit) {
178
182
  }
179
183
 
180
184
  /**
181
- * @param {MouseEvent} e
185
+ * @param {DragEvent} e
182
186
  * @param {VcsDraggableItem} item
183
187
  */
184
188
  function dragStart(e, item) {
@@ -191,7 +195,7 @@ export function setupDraggableListOrTree(props, query, emit) {
191
195
  }
192
196
 
193
197
  /**
194
- * @param {MouseEvent} e
198
+ * @param {DragEvent} e
195
199
  * @param {VcsDraggableItem} item
196
200
  * @param {HTMLElement} dropTarget
197
201
  * @param {DropZones} [dropTargetZones=true]
@@ -207,14 +211,22 @@ export function setupDraggableListOrTree(props, query, emit) {
207
211
  e.stopPropagation();
208
212
  e.preventDefault();
209
213
  if (
210
- !isDraggable.value ||
211
- !dragging.value ||
212
- draggedItem?.name === item.name
214
+ (!isDraggable.value ||
215
+ !dragging.value ||
216
+ draggedItem?.name === item.name) &&
217
+ e.dataTransfer
213
218
  ) {
214
219
  e.dataTransfer.dropEffect = 'none';
215
220
  return;
216
221
  }
217
222
 
223
+ if (lastDropTarget !== e.currentTarget) {
224
+ if (lastDropTarget) {
225
+ clearDropTargetClasses(lastDropTarget);
226
+ }
227
+ lastDropTarget = e.currentTarget;
228
+ }
229
+
218
230
  clearDropTargetClasses(e.currentTarget);
219
231
  addDropTargetClasses(
220
232
  e,
@@ -227,22 +239,16 @@ export function setupDraggableListOrTree(props, query, emit) {
227
239
  }
228
240
 
229
241
  /**
230
- * @param {MouseEvent} e
231
- */
232
- function dragLeave(e) {
233
- e.stopPropagation();
234
- e.preventDefault();
235
- dropPosition = null;
236
- clearDropTargetClasses(e.currentTarget);
237
- }
238
-
239
- /**
240
- * @param {MouseEvent} e
242
+ * @param {DragEvent} e
241
243
  */
242
244
  function dragEnd(e) {
243
245
  e.stopPropagation();
244
246
  dropPosition = null;
245
247
  dragging.value = false;
248
+ if (lastDropTarget) {
249
+ clearDropTargetClasses(lastDropTarget);
250
+ lastDropTarget = null;
251
+ }
246
252
  }
247
253
 
248
254
  return {
@@ -250,7 +256,6 @@ export function setupDraggableListOrTree(props, query, emit) {
250
256
  isDraggable,
251
257
  dragStart,
252
258
  dragOver,
253
- dragLeave,
254
259
  dragEnd,
255
260
  drop,
256
261
  };
@@ -272,7 +277,7 @@ function findAndSplice(
272
277
  insertPosition,
273
278
  ...itemsToInsert
274
279
  ) {
275
- const index = array.findIndex((i) => i === item);
280
+ const index = array.indexOf(item);
276
281
 
277
282
  if (index !== -1) {
278
283
  if (insertPosition === InsertMode.AFTER) {
@@ -323,3 +328,24 @@ export function moveDraggableItems(items, { item, targetItem, position }) {
323
328
  findAndSplice(items, item, 1);
324
329
  findAndSplice(items, targetItem, 0, position, item);
325
330
  }
331
+
332
+ /**
333
+ * Moves an item to a new position.
334
+ * New position is derived from a target item in the collection.
335
+ * This ensures correct movement, if rendered list is only a subset of the collection.
336
+ * @template T
337
+ * @param {import("@vcmap/core").IndexedCollection<T>} collection
338
+ * @param {import("../../components/lists/dragHelper.js").ItemMovedEvent} event
339
+ */
340
+ export function moveItem(collection, event) {
341
+ if (collection.moveTo) {
342
+ const item = collection.getByKey(event.item.name);
343
+ const target = collection.getByKey(event.targetItem.name);
344
+
345
+ const itemIndex = collection.indexOf(item);
346
+ const targetIndex = collection.indexOf(target);
347
+ const relativePosition = itemIndex < targetIndex ? -1 : 1;
348
+ const offset = relativePosition === event.position ? event.position : 0;
349
+ collection.moveTo(item, targetIndex + offset);
350
+ }
351
+ }
@@ -29,6 +29,10 @@
29
29
  import VcsHelp from '../components/notification/VcsHelp.vue';
30
30
  import VcsTreeview from '../components/lists/VcsTreeview.vue';
31
31
  import WMSGroupContentTreeItem from './wmsGroupContentTreeItem.js';
32
+ import {
33
+ moveItem,
34
+ moveDraggableItems,
35
+ } from '../components/lists/dragHelper.js';
32
36
 
33
37
  export const layerSwapId = 'layer-swap-window';
34
38
 
@@ -143,16 +147,23 @@
143
147
  }
144
148
  return { into: false };
145
149
  },
146
- move({ item, targetItem }) {
150
+ /**
151
+ * @param {import("../components/lists/dragHelper.js").ItemMovedEvent} event
152
+ */
153
+ move(event) {
154
+ const { item, targetItem, position } = event;
147
155
  const layer = app.layers.getByKey(item.name);
148
156
  if (layer && !targetItem[vcsLayerName]) {
149
- app.layers.moveTo(layer, targetItem.index);
157
+ moveItem(app.layers, event);
150
158
  } else if (item[vcsLayerName] === targetItem[vcsLayerName]) {
151
159
  const wmsLayer = app.layers.getByKey(item[vcsLayerName]);
152
160
  if (wmsLayer instanceof WMSLayer) {
153
161
  const newLayerNames = wmsLayer.getLayers();
154
- newLayerNames.splice(item.index, 1);
155
- newLayerNames.splice(targetItem.index, 0, item[wmsLayerName]);
162
+ moveDraggableItems(newLayerNames, {
163
+ item: item[wmsLayerName],
164
+ targetItem: targetItem[wmsLayerName],
165
+ position,
166
+ });
156
167
  wmsLayer
157
168
  .setLayers(newLayerNames)
158
169
  .catch((e) => getLogger('LayerSwap.vue').error(e));
@@ -31,10 +31,10 @@ declare const _default: import("vue").DefineComponent<{}, {
31
31
  dropTargetZones(item: any, targetItem: any): false | {
32
32
  into: boolean;
33
33
  };
34
- move({ item, targetItem }: {
35
- item: any;
36
- targetItem: any;
37
- }): void;
34
+ /**
35
+ * @param {import("../components/lists/dragHelper.js").ItemMovedEvent} event
36
+ */
37
+ move(event: import("../components/lists/dragHelper.js").ItemMovedEvent): void;
38
38
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{}>>, {}, {}>;
39
39
  export default _default;
40
40
  declare const wmsLayerName: unique symbol;
@@ -436,7 +436,7 @@ class ContentTreeItem {
436
436
  removeAction(actionName) {
437
437
  const index = this._getActionIndex(actionName);
438
438
  if (index > -1) {
439
- this._actions.value.splice(index, 1);
439
+ this._actions.value = this._actions.value.filter((_, i) => i !== index);
440
440
  }
441
441
  }
442
442