@vcmap/ui 5.0.0-rc.21 → 5.0.0-rc.23

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 (153) hide show
  1. package/README.md +2 -2
  2. package/app.config.json +5 -0
  3. package/build/buildHelpers.js +1 -0
  4. package/build/buildPreview.js +2 -2
  5. package/build/commonViteConfig.js +1 -0
  6. package/config/aerowest.config.json +2 -0
  7. package/config/base.config.json +1 -0
  8. package/config/codes.config.json +2 -0
  9. package/config/dev.config.json +6 -0
  10. package/config/graphFeatureInfo.config.json +3 -1
  11. package/config/projects.config.json +27 -0
  12. package/config/www.config.json +27 -14
  13. package/dist/assets/cesium.js +1 -1
  14. package/dist/assets/{core.59d4d1.js → core.9342a1.js} +7912 -5474
  15. package/dist/assets/core.js +1 -1
  16. package/dist/assets/favicon.decf54cc.svg +10 -0
  17. package/dist/assets/index.fd041928.js +1 -0
  18. package/dist/assets/{ol.c1c512.js → ol.d2cba3.js} +12406 -12152
  19. package/dist/assets/ol.js +1 -1
  20. package/dist/assets/ui.c27597.css +5 -0
  21. package/dist/assets/{ui.80175f.js → ui.c27597.js} +6508 -5169
  22. package/dist/assets/ui.js +1 -1
  23. package/dist/assets/vue.js +2 -2
  24. package/dist/assets/vuetify.2f1432.css +5 -0
  25. package/dist/assets/{vuetify.efc158.js → vuetify.2f1432.js} +1 -1
  26. package/dist/assets/vuetify.js +2 -2
  27. package/dist/index.html +6 -1
  28. package/index.html +5 -0
  29. package/index.js +7 -3
  30. package/lib/olLib.js +15 -1
  31. package/package.json +5 -4
  32. package/plugins/@vcmap/project-selector/{ContextsListComponent.vue → ModulesListComponent.vue} +10 -10
  33. package/plugins/@vcmap/project-selector/ProjectSelectorComponent.vue +16 -16
  34. package/plugins/@vcmap/project-selector/README.md +15 -21
  35. package/plugins/@vcmap/project-selector/config.json +3 -3
  36. package/plugins/@vcmap/project-selector/de.json +3 -0
  37. package/plugins/@vcmap/project-selector/en.json +3 -0
  38. package/plugins/@vcmap/project-selector/index.js +76 -101
  39. package/plugins/@vcmap/simple-graph/index.js +1 -1
  40. package/plugins/@vcmap/theme-changer/ThemeChangerComponent.vue +10 -4
  41. package/plugins/@vcmap-show-case/category-tester/Categories.vue +2 -2
  42. package/plugins/@vcmap-show-case/category-tester/Category.vue +1 -4
  43. package/plugins/@vcmap-show-case/config-editor/editor.vue +14 -14
  44. package/plugins/@vcmap-show-case/form-inputs-example/FormInputsExample.vue +92 -81
  45. package/plugins/@vcmap-show-case/form-inputs-example/index.js +8 -3
  46. package/plugins/@vcmap-show-case/form-inputs-example/validation.js +1 -1
  47. package/plugins/@vcmap-show-case/list-example/ListExample.vue +5 -2
  48. package/plugins/@vcmap-show-case/table-example/DataTableExample.vue +202 -0
  49. package/plugins/@vcmap-show-case/table-example/README.md +3 -0
  50. package/plugins/@vcmap-show-case/table-example/index.js +47 -0
  51. package/plugins/@vcmap-show-case/table-example/package.json +5 -0
  52. package/plugins/@vcmap-show-case/wizard-example/wizardExample.vue +57 -23
  53. package/plugins/package.json +2 -1
  54. package/src/actions/actionHelper.js +16 -27
  55. package/src/actions/styleSelector.vue +26 -19
  56. package/src/application/VcsApp.vue +13 -5
  57. package/src/application/VcsAttributions.vue +2 -3
  58. package/src/application/VcsAttributionsFooter.vue +10 -16
  59. package/src/application/VcsNavbar.vue +1 -2
  60. package/src/application/VcsSettings.vue +21 -8
  61. package/src/assets/favicon-128.png +0 -0
  62. package/src/assets/favicon-180.png +0 -0
  63. package/src/assets/favicon-192.png +0 -0
  64. package/src/assets/favicon-32.png +0 -0
  65. package/src/assets/favicon.svg +10 -0
  66. package/src/components/buttons/VcsButton.vue +2 -3
  67. package/src/components/form-inputs-controls/VcsCheckbox.vue +46 -26
  68. package/src/components/form-inputs-controls/VcsDatePicker.vue +111 -0
  69. package/src/components/form-inputs-controls/VcsFormSection.vue +15 -13
  70. package/src/components/form-inputs-controls/VcsLabel.vue +10 -1
  71. package/src/components/form-inputs-controls/VcsRadio.vue +38 -18
  72. package/src/components/form-inputs-controls/VcsSelect.vue +117 -59
  73. package/src/components/form-inputs-controls/VcsTextArea.vue +101 -60
  74. package/src/components/form-inputs-controls/VcsTextField.vue +182 -69
  75. package/src/components/form-inputs-controls/VcsWizard.vue +23 -15
  76. package/src/components/form-inputs-controls/VcsWizardStep.vue +18 -16
  77. package/src/components/form-inputs-controls/composables.js +26 -0
  78. package/src/components/form-output/VcsFormattedNumber.vue +1 -1
  79. package/src/components/icons/2DDistanceIcon.vue +0 -3
  80. package/src/components/icons/3DDistanceIcon.vue +0 -3
  81. package/src/components/icons/3DHeightIcon.vue +0 -3
  82. package/src/components/icons/CheckboxCheckedIcon.vue +4 -11
  83. package/src/components/icons/CheckboxIcon.vue +9 -2
  84. package/src/components/icons/CheckboxIndeterminateIcon.vue +4 -21
  85. package/src/components/icons/CommentIcon.vue +1 -5
  86. package/src/components/icons/LegendIcon.vue +10 -60
  87. package/src/components/icons/ObliqueViewIcon.vue +6 -8
  88. package/src/components/icons/SimpleCircleOutlinedIcon.vue +1 -1
  89. package/src/components/icons/SplitViewIcon.vue +0 -4
  90. package/src/components/icons/ToolsIcon.vue +2 -4
  91. package/src/components/lists/VcsActionList.vue +0 -1
  92. package/src/components/lists/VcsList.vue +30 -30
  93. package/src/components/lists/VcsTreeview.vue +2 -2
  94. package/src/components/lists/VcsTreeviewLeaf.vue +3 -9
  95. package/src/components/lists/VcsTreeviewSearchbar.vue +4 -4
  96. package/src/components/notification/VcsBadge.vue +6 -2
  97. package/src/components/notification/VcsHelp.vue +39 -0
  98. package/src/components/tables/VcsDataTable.vue +386 -0
  99. package/src/components/tables/VcsTable.vue +55 -254
  100. package/src/contentTree/contentTreeCollection.js +1 -1
  101. package/src/contentTree/layerContentTreeItem.js +3 -0
  102. package/src/downloadHelper.js +49 -0
  103. package/src/featureInfo/AddressBalloonComponent.vue +1 -1
  104. package/src/featureInfo/BalloonComponent.vue +21 -15
  105. package/src/featureInfo/abstractFeatureInfoView.js +1 -1
  106. package/src/featureInfo/featureInfo.js +27 -9
  107. package/src/featureInfo/tableFeatureInfoView.js +4 -0
  108. package/src/i18n/de.js +13 -1
  109. package/src/i18n/en.js +13 -1
  110. package/src/i18n/i18nCollection.js +22 -22
  111. package/src/init.js +90 -7
  112. package/src/legend/styleLegendItem.vue +24 -2
  113. package/src/legend/vcsLegend.vue +24 -31
  114. package/src/manager/categoryManager/CategoryComponent.vue +56 -47
  115. package/src/manager/categoryManager/CategoryManager.vue +23 -10
  116. package/src/manager/categoryManager/categoryManager.js +11 -11
  117. package/src/manager/navbarManager.js +18 -0
  118. package/src/manager/toolbox/GroupToolboxComponent.vue +2 -3
  119. package/src/manager/toolbox/SelectToolboxComponent.vue +11 -5
  120. package/src/manager/toolbox/ToolboxManager.vue +0 -7
  121. package/src/manager/window/WindowComponent.vue +10 -16
  122. package/src/manager/window/WindowComponentHeader.vue +6 -4
  123. package/src/manager/window/WindowManager.vue +14 -15
  124. package/src/manager/window/windowHelper.js +1 -1
  125. package/src/manager/window/windowManager.js +18 -7
  126. package/src/navigation/mapNavCompass.vue +1 -1
  127. package/src/navigation/mapNavigation.vue +6 -6
  128. package/src/navigation/obliqueRotation.vue +36 -13
  129. package/src/navigation/orientationToolsButton.vue +0 -1
  130. package/src/navigation/overviewMap.js +11 -20
  131. package/src/navigation/tiltSlider.vue +30 -6
  132. package/src/navigation/vcsZoomButton.vue +37 -11
  133. package/src/pluginHelper.js +20 -0
  134. package/src/search/resultsComponent.vue +0 -1
  135. package/src/search/search.js +19 -20
  136. package/src/search/searchComponent.vue +21 -7
  137. package/src/state.js +6 -6
  138. package/src/styles/_theming.scss +72 -3
  139. package/src/styles/_typography.scss +0 -5
  140. package/src/styles/main.scss +1 -0
  141. package/src/styles/shades.scss +2 -0
  142. package/src/styles/variables.scss +40 -4
  143. package/src/uiConfig.js +4 -3
  144. package/src/vcsUiApp.js +49 -40
  145. package/src/vuePlugins/i18n.js +1 -0
  146. package/src/vuePlugins/vuetify.js +59 -13
  147. package/start.js +8 -2
  148. package/dist/assets/index.a3861d4e.js +0 -1
  149. package/dist/assets/ui.80175f.css +0 -1
  150. package/dist/assets/vuetify.efc158.css +0 -5
  151. package/map.config.json +0 -44
  152. /package/dist/assets/{cesium.49585c.js → cesium.166f91.js} +0 -0
  153. /package/dist/assets/{vue.a08ab1.js → vue.5d00e9.js} +0 -0
@@ -1,17 +1,26 @@
1
1
  <template>
2
- <div
3
- v-if="categories.length > 0"
4
- >
5
- <category-component
6
- v-for="category in categories"
7
- :category="category"
8
- :key="category.categoryName"
9
- />
10
- </div>
2
+ <v-sheet>
3
+ <v-expansion-panels
4
+ accordion
5
+ multiple
6
+ v-if="categories.length > 0"
7
+ class="rounded-0"
8
+ >
9
+ <category-component
10
+ v-for="category in categories"
11
+ :category="category"
12
+ :key="category.categoryName"
13
+ />
14
+ </v-expansion-panels>
15
+ </v-sheet>
11
16
  </template>
12
17
 
13
18
  <script>
14
19
  import { inject, ref, computed } from 'vue';
20
+ import {
21
+ VExpansionPanels,
22
+ VSheet,
23
+ } from 'vuetify/lib';
15
24
  import CategoryComponent from './CategoryComponent.vue';
16
25
 
17
26
  /**
@@ -21,7 +30,11 @@
21
30
  */
22
31
  export default {
23
32
  name: 'CategoryManager',
24
- components: { CategoryComponent },
33
+ components: {
34
+ VExpansionPanels,
35
+ VSheet,
36
+ CategoryComponent,
37
+ },
25
38
  setup() {
26
39
  const app = inject('vcsApp');
27
40
  const categoryIds = ref(app.categoryManager.componentIds);
@@ -1,5 +1,5 @@
1
1
  import { reactive } from 'vue';
2
- import { contextIdSymbol, IndexedCollection, VcsEvent } from '@vcmap/core';
2
+ import { moduleIdSymbol, IndexedCollection, VcsEvent } from '@vcmap/core';
3
3
  import { check } from '@vcsuite/check';
4
4
  import { sortByOwner } from '../navbarManager.js';
5
5
  import { validateAction, validateActions } from '../../components/lists/VcsActionList.vue';
@@ -145,8 +145,8 @@ class CategoryManager {
145
145
  * @type {function():void}
146
146
  * @private
147
147
  */
148
- this._dynamicContextIdListener = this._app.dynamicContextIdChanged.addEventListener((id) => {
149
- this._dynamicContextId = id;
148
+ this._dynamicModuleIdListener = this._app.dynamicModuleIdChanged.addEventListener((id) => {
149
+ this._dynamicModuleId = id;
150
150
  this._resetManagedCategories();
151
151
  });
152
152
 
@@ -162,7 +162,7 @@ class CategoryManager {
162
162
  * @type {string}
163
163
  * @private
164
164
  */
165
- this._dynamicContextId = this._app.dynamicContextId;
165
+ this._dynamicModuleId = this._app.dynamicModuleId;
166
166
 
167
167
  /**
168
168
  * @type {Array<ItemMapping<*>>}
@@ -250,7 +250,7 @@ class CategoryManager {
250
250
  }
251
251
 
252
252
  /**
253
- * removes all items from all categories and rebuilds the item tree depending on the ContextId
253
+ * removes all items from all categories and rebuilds the item tree depending on the ModuleId
254
254
  * @private
255
255
  */
256
256
  _resetManagedCategories() {
@@ -281,7 +281,7 @@ class CategoryManager {
281
281
  });
282
282
  managedCategory.items = [...category.collection]
283
283
  .filter((item) => {
284
- return item[contextIdSymbol] === this._dynamicContextId;
284
+ return item[moduleIdSymbol] === this._dynamicModuleId;
285
285
  })
286
286
  .map((item) => {
287
287
  return transformItem(item, category, itemMappings);
@@ -306,17 +306,17 @@ class CategoryManager {
306
306
 
307
307
  const listeners = [
308
308
  category.collection.added.addEventListener((item) => {
309
- if (item[contextIdSymbol] === this._dynamicContextId) {
309
+ if (item[moduleIdSymbol] === this._dynamicModuleId) {
310
310
  this._handleItemAdded(item, category);
311
311
  }
312
312
  }),
313
313
  category.collection.removed.addEventListener((item) => {
314
- if (item[contextIdSymbol] === this._dynamicContextId) {
314
+ if (item[moduleIdSymbol] === this._dynamicModuleId) {
315
315
  this._handleItemRemoved(item, category);
316
316
  }
317
317
  }),
318
318
  category.collection.replaced.addEventListener((replacedEvent) => {
319
- if (replacedEvent.old[contextIdSymbol] === this._dynamicContextId) {
319
+ if (replacedEvent.old[moduleIdSymbol] === this._dynamicModuleId) {
320
320
  this._handleItemRemoved(replacedEvent.old, category);
321
321
  }
322
322
  }),
@@ -324,7 +324,7 @@ class CategoryManager {
324
324
 
325
325
  if (category.collection instanceof IndexedCollection) {
326
326
  listeners.push(category.collection.moved.addEventListener((item) => {
327
- if (item[contextIdSymbol] === this._dynamicContextId) {
327
+ if (item[moduleIdSymbol] === this._dynamicModuleId) {
328
328
  this._handleItemMoved(item, category);
329
329
  }
330
330
  }));
@@ -572,7 +572,7 @@ class CategoryManager {
572
572
  * destroys the categoryManager, removes all Listeners and clears all Managed Categories
573
573
  */
574
574
  destroy() {
575
- this._dynamicContextIdListener();
575
+ this._dynamicModuleIdListener();
576
576
  this._appCategoriesRemovedListener();
577
577
  this.componentIds = [];
578
578
  this._managedCategories.forEach((item) => {
@@ -84,6 +84,24 @@ class NavbarManager extends ButtonManager {
84
84
  buttonComponent[locationSymbol] = location;
85
85
  return buttonComponent;
86
86
  }
87
+
88
+ /**
89
+ * Toggles a button of provided id by executing its callback.
90
+ * Use active flag to force a state to be applied.
91
+ * @param {string} id
92
+ * @param {boolean} [active]
93
+ */
94
+ toggle(id, active = undefined) {
95
+ check(id, String);
96
+ const { action } = this.get(id);
97
+ if (active !== undefined) {
98
+ if (action?.active !== active) {
99
+ action.callback();
100
+ }
101
+ } else if (action) {
102
+ action.callback();
103
+ }
104
+ }
87
105
  }
88
106
 
89
107
  export default NavbarManager;
@@ -14,12 +14,12 @@
14
14
  :icon="group.icon"
15
15
  :tooltip="group.title"
16
16
  :active="open || hasActiveAction"
17
- :color="hasActiveAction ? 'primary' : 'basic'"
17
+ :color="hasActiveAction ? 'primary' : ''"
18
18
  v-bind="attrs"
19
19
  v-on="on"
20
20
  large
21
21
  >
22
- <v-icon v-text="open ? 'mdi-chevron-up' : 'mdi-chevron-down'" color="accent" class="text--darken-3" />
22
+ <v-icon v-text="open ? 'mdi-chevron-up' : 'mdi-chevron-down'" />
23
23
  </VcsButton>
24
24
  </template>
25
25
 
@@ -28,7 +28,6 @@
28
28
  class="vcs-toolbox-2 toolbar__secondary mx-auto v-sheet marginToTop"
29
29
  :height="40"
30
30
  width="fit-content"
31
- color="basic"
32
31
  dense
33
32
  >
34
33
  <v-toolbar-items class="w-full">
@@ -33,7 +33,7 @@
33
33
  :width="16"
34
34
  large
35
35
  >
36
- <v-icon v-text="open ? 'mdi-chevron-up' : 'mdi-chevron-down'" color="accent" class="text--darken-3" />
36
+ <v-icon v-text="open ? 'mdi-chevron-up' : 'mdi-chevron-down'" />
37
37
  </VcsButton>
38
38
  </template>
39
39
 
@@ -41,7 +41,6 @@
41
41
  class="vcs-toolbox-2 toolbar__secondary mx-auto v-sheet marginToTop justify-center"
42
42
  :height="40"
43
43
  width="fit-content"
44
- color="basic"
45
44
  dense
46
45
  >
47
46
  <v-toolbar-items class="w-full">
@@ -62,6 +61,8 @@
62
61
  </div>
63
62
  </template>
64
63
  <style lang="scss">
64
+ @import '../../styles/shades.scss';
65
+
65
66
  .vcs-toolbox-action-selected > .v-btn.vcs-button--large {
66
67
  max-width: 40px;
67
68
  }
@@ -71,9 +72,14 @@
71
72
  }
72
73
 
73
74
  .vcs-toolbox-action-select-button--active {
74
- //border: 2px solid var(--v-basic-base);
75
- border-radius: 5px;
76
- background: var(--v-basic-base);
75
+ //border: 2px solid var(--v-shades-base);
76
+ border-radius: 4px;
77
+ }
78
+ .theme--light .vcs-toolbox-action-select-button--active {
79
+ background: map-get($shades, 'white');
80
+ }
81
+ .theme--dark .vcs-toolbox-action-select-button--active {
82
+ background: map-get($shades, 'black');
77
83
  }
78
84
 
79
85
  .vcs-toolbox-2 {
@@ -50,13 +50,6 @@
50
50
  padding: 0;
51
51
  }
52
52
  }
53
-
54
- &.theme--light.v-toolbar.v-sheet {
55
- background-color: #ffffffda;
56
- }
57
- &.theme--dark.v-toolbar.v-sheet {
58
- background-color: #000000da;
59
- }
60
53
  }
61
54
 
62
55
  .marginToTop {
@@ -2,7 +2,7 @@
2
2
  <v-sheet
3
3
  :id="`window-component--${windowState.id}`"
4
4
  class="elevation-3 position-absolute d-flex flex-column"
5
- @click="clicked"
5
+ v-on="{ ...$listeners }"
6
6
  @dragstart="dragStart"
7
7
  @dragend="dragEnd"
8
8
  :draggable="isDraggable"
@@ -20,14 +20,18 @@
20
20
  class="pa-2"
21
21
  :class="{
22
22
  'cursor-grab': isDynamic,
23
- 'grey--text': !isOnTop,
24
23
  }"
25
24
  >
26
25
  <slot name="headerComponent" :props="$attrs" />
27
26
  </div>
28
- <v-divider />
27
+ <v-divider
28
+ v-if="!windowState.hideHeader"
29
+ />
29
30
  <div
30
31
  class="overflow-x-hidden mb-1"
32
+ :class="{
33
+ 'rounded': !isDocked,
34
+ }"
31
35
  >
32
36
  <slot />
33
37
  </div>
@@ -54,7 +58,8 @@
54
58
  * @vue-prop {WindowState} windowState
55
59
  * @vue-prop {boolean} isOnTop - Whether the component is focused
56
60
  * @vue-prop {Object} slotWindow - slot ref of the window
57
- * @vue-event {PointerEvent} clicked - raised when the component is clicked
61
+ * @vue-event {PointerEvent} click - raised when the component is clicked
62
+ * @vue-event {MouseEvent} mousedown - raised when the component is mousedown
58
63
  * @vue-event {{dx: number, dy: number}} move - raised when the component is moved (dragged)
59
64
  * @vue-data {slot} [#default] - slot with the window content
60
65
  * @vue-data {slot} [#headerComponent] - slot to override the default header
@@ -95,21 +100,14 @@
95
100
  });
96
101
  const isDockedRight = computed(() => props.slotWindow === WindowSlot.DYNAMIC_RIGHT);
97
102
  const isDraggable = ref(false);
98
- /**
99
- * @param {PointerEvent} e
100
- */
101
- const clicked = (e) => {
102
- emit('click', e);
103
- };
104
103
  /**
105
104
  * Sets window as draggable on mousedown on header.
106
105
  * Stops bubbling of header action buttons.
107
106
  * @param {MouseEvent} e
108
107
  */
109
108
  const mousedown = (e) => {
109
+ emit('mousedown', e);
110
110
  if (e.target.closest('button')) {
111
- e.preventDefault();
112
- e.stopPropagation();
113
111
  return;
114
112
  }
115
113
  isDraggable.value = isDynamic.value;
@@ -129,9 +127,6 @@
129
127
  startEvent = e;
130
128
  // set mouse cursor to move
131
129
  e.dataTransfer.effectAllowed = 'move';
132
- const preventDefaultDragover = dragOverEvent => dragOverEvent.preventDefault();
133
- e.target.parentElement.ondragover = preventDefaultDragover;
134
- app.maps.target.ondragover = preventDefaultDragover;
135
130
  };
136
131
  /**
137
132
  * @param {DragEvent} endEvent
@@ -154,7 +149,6 @@
154
149
  isDynamicLeft: isDockedLeft,
155
150
  isDynamicRight: isDockedRight,
156
151
  isDraggable,
157
- clicked,
158
152
  dragStart,
159
153
  dragEnd,
160
154
  mousedown,
@@ -4,11 +4,12 @@
4
4
  <v-icon
5
5
  v-if="windowState.headerIcon"
6
6
  class="mr-2"
7
- :class="{ 'text--primary': isOnTop }"
7
+ :class="{ 'primary--text': isOnTop }"
8
8
  v-text="windowState.headerIcon"
9
+ size="16"
9
10
  />
10
11
  <h3
11
- class="font-size-14 d-inline-block user-select-none font-weight-bold"
12
+ class="d-inline-block user-select-none font-weight-bold"
12
13
  :class="{ 'text--primary': isOnTop }"
13
14
  >
14
15
  {{ $t(windowState.headerTitle) }}
@@ -33,7 +34,7 @@
33
34
  small
34
35
  :icon="infoAction.icon"
35
36
  :tooltip="infoAction.title"
36
- class="px-1"
37
+ class="px-1 d-flex"
37
38
  />
38
39
  <VcsButton
39
40
  v-if="isDockable"
@@ -41,13 +42,14 @@
41
42
  small
42
43
  icon="mdi-pin"
43
44
  tooltip="components.pin"
44
- class="px-1"
45
+ class="px-1 d-flex"
45
46
  />
46
47
  <VcsButton
47
48
  @click.stop="close"
48
49
  small
49
50
  icon="mdi-close-thick"
50
51
  tooltip="components.close"
52
+ class="d-flex"
51
53
  />
52
54
  </div>
53
55
  </span>
@@ -3,16 +3,16 @@
3
3
  :class="{ 'win-container-mobile' : $vuetify.breakpoint.xs }"
4
4
  >
5
5
  <WindowComponent
6
- v-for="(id, zIndex) in componentIds"
6
+ v-for="id in componentIds"
7
7
  :key="id"
8
8
  :window-state="getState(id)"
9
9
  :slot-window="getSlot(id)"
10
- :z-index="zIndex"
10
+ :z-index="getComponent(id).zIndex"
11
11
  @moved="move(id, $event)"
12
- @click="clicked(id)"
13
- :style="getStyles(id, zIndex).value"
12
+ @mousedown="bringWindowToTop(id)"
13
+ :style="getStyles(id).value"
14
14
  :class="getState(id).classes"
15
- :is-on-top="isOnTop(zIndex)"
15
+ :is-on-top="isOnTop(id)"
16
16
  >
17
17
  <component
18
18
  :is="getComponent(id)"
@@ -23,7 +23,7 @@
23
23
  <component
24
24
  :is="getHeaderComponent(id)"
25
25
  :window-state="getState(id)"
26
- :is-on-top="isOnTop(zIndex)"
26
+ :is-on-top="isOnTop(id)"
27
27
  :slot-window="getSlot(id)"
28
28
  v-bind="getProps(id)"
29
29
  @close="close(id)"
@@ -84,23 +84,22 @@
84
84
  return windowManager.get(id)?.props ?? {};
85
85
  };
86
86
  /**
87
- * @param {number} zIndex
87
+ * @param {string} id
88
88
  * @returns {boolean}
89
89
  */
90
- const isOnTop = (zIndex) => {
91
- return zIndex === componentIds.length - 1;
90
+ const isOnTop = (id) => {
91
+ return windowManager.get(id)?.zIndex.value === componentIds.length - 1;
92
92
  };
93
93
  /**
94
94
  * @param {string} id
95
- * @param {number} zIndex
96
95
  * @returns {import("vue").ComputedRef<Object>}
97
96
  */
98
- const getStyles = (id, zIndex) => computed(() => {
97
+ const getStyles = id => computed(() => {
99
98
  const windowComponent = windowManager.get(id);
100
99
  const state = windowComponent?.state;
101
100
  const position = applyPositionOnTarget(windowComponent?.position, targetSize.value);
102
101
  return {
103
- zIndex,
102
+ zIndex: windowComponent.zIndex.value,
104
103
  ...position,
105
104
  ...(state.styles || {}),
106
105
  };
@@ -108,8 +107,8 @@
108
107
  /**
109
108
  * @param {string} id
110
109
  */
111
- const clicked = (id) => {
112
- if (windowManager.has(id)) {
110
+ const bringWindowToTop = (id) => {
111
+ if (windowManager.has(id) && !isOnTop(id)) {
113
112
  windowManager.bringWindowToTop(id);
114
113
  }
115
114
  };
@@ -143,7 +142,7 @@
143
142
  getSlot: id => windowManager.get(id).slot,
144
143
  close: (id) => { windowManager.remove(id); },
145
144
  pin: (id) => { windowManager.pinWindow(id); },
146
- clicked,
145
+ bringWindowToTop,
147
146
  move,
148
147
  };
149
148
  },
@@ -304,7 +304,7 @@ export function clipToTargetSize(windowPositionOptions, targetSize) {
304
304
  clippedPosition.height = windowPositionOptions.height;
305
305
  }
306
306
  clippedPosition.maxWidth = targetWidth;
307
- clippedPosition.maxHeight = targetHeight;
307
+ clippedPosition.maxHeight = targetHeight - 4; // 2px space plus 2px due to margin bottom
308
308
  if (windowPositionOptions.maxWidth !== undefined) {
309
309
  clippedPosition.maxWidth = Math.min(windowPositionOptions.maxWidth, targetWidth);
310
310
  }
@@ -1,4 +1,4 @@
1
- import { reactive, ref } from 'vue';
1
+ import { computed, reactive, ref } from 'vue';
2
2
  import { VcsEvent } from '@vcmap/core';
3
3
  import { v4 as uuidv4 } from 'uuid';
4
4
  import { parseEnumValue } from '@vcsuite/parsers';
@@ -137,6 +137,7 @@ export function isSlotPosition(windowPosition) {
137
137
  * @property {WindowSlot} initialSlot
138
138
  * @property {Object} props
139
139
  * @property {Object} provides
140
+ * @property {import("vue").ComputedGetter<number>} zIndex
140
141
  */
141
142
 
142
143
  /**
@@ -238,6 +239,11 @@ class WindowManager {
238
239
  * @type {Array<string>}
239
240
  */
240
241
  this.componentIds = [];
242
+ /**
243
+ * reactive ordered array of ids, defining the zIndex of a component
244
+ * @type {import("vue").Ref<Array<string>>}
245
+ */
246
+ this._zIndices = ref([]);
241
247
 
242
248
  /**
243
249
  * @type {Map<string, WindowComponent>}
@@ -277,8 +283,8 @@ class WindowManager {
277
283
  const windowComponent = this._windowComponents.get(id);
278
284
  if (windowComponent) {
279
285
  this._cachePosition(windowComponent);
280
- const index = this.componentIds.indexOf(id);
281
- this.componentIds.splice(index, 1);
286
+ this.componentIds.splice(this.componentIds.indexOf(id), 1);
287
+ this._zIndices.value.splice(this._zIndices.value.indexOf(id), 1);
282
288
  this._windowComponents.delete(id);
283
289
  this._handleSlotsChanged(windowComponent.slot.value);
284
290
  this.removed.raiseEvent(windowComponent);
@@ -453,6 +459,7 @@ class WindowManager {
453
459
 
454
460
  const position = reactive(windowPosition);
455
461
  const initialPosition = { ...windowPositionOptions };
462
+ const zIndex = computed(() => this._zIndices.value.indexOf(id));
456
463
  /**
457
464
  * @type {WindowComponent}
458
465
  */
@@ -487,6 +494,9 @@ class WindowManager {
487
494
  get provides() {
488
495
  return provides;
489
496
  },
497
+ get zIndex() {
498
+ return zIndex;
499
+ },
490
500
  };
491
501
  const cached = this._assignCachedPosition(windowComponent);
492
502
  if (!cached) {
@@ -494,6 +504,7 @@ class WindowManager {
494
504
  }
495
505
  this._windowComponents.set(id, windowComponent);
496
506
  this.componentIds.push(id);
507
+ this._zIndices.value.push(id);
497
508
  this._handleSlotsChanged(slot);
498
509
  this.added.raiseEvent(windowComponent);
499
510
  return windowComponent;
@@ -505,10 +516,10 @@ class WindowManager {
505
516
  */
506
517
  bringWindowToTop(id) {
507
518
  if (this.has(id)) {
508
- const index = this.componentIds.indexOf(id);
509
- if (index >= 0 && index !== this.componentIds.length - 1) {
510
- this.componentIds.push(id);
511
- this.componentIds.splice(index, 1);
519
+ const index = this._zIndices.value.indexOf(id);
520
+ if (index >= 0 && index !== this._zIndices.value.length - 1) {
521
+ this._zIndices.value.push(id);
522
+ this._zIndices.value.splice(index, 1);
512
523
  }
513
524
  }
514
525
  }
@@ -162,6 +162,6 @@
162
162
  }
163
163
 
164
164
  svg path:hover {
165
- fill: var(--v-base-lighten5) !important;
165
+ fill: var(--v-primary-lighten1) !important;
166
166
  }
167
167
  </style>
@@ -58,7 +58,7 @@
58
58
  import OrientationToolsButton from './orientationToolsButton.vue';
59
59
 
60
60
  /**
61
- * Creates a go-to viewpoint action from a startingViewpointName defined in a context
61
+ * Creates a go-to viewpoint action from a startingViewpointName defined in a module
62
62
  * @param {VcsUiApp} app
63
63
  * @returns {{action: import("vue").Reactive<{}>, destroy: function():void}}
64
64
  */
@@ -66,13 +66,13 @@
66
66
  const initialAction = { icon: undefined, title: undefined, active: undefined, callback: undefined };
67
67
  const action = reactive({ ...initialAction });
68
68
  /**
69
- * Gets the starting viewpoint of the last added context, where a startingViewpointName was defined
69
+ * Gets the starting viewpoint of the last added module, where a startingViewpointName was defined
70
70
  * and sets it on the home button action.
71
71
  */
72
72
  const updateStartingViewpoint = () => {
73
73
  let viewpoint = null;
74
- for (let idx = app.contexts.length - 1; idx >= 0; idx--) {
75
- const { startingViewpointName } = app.contexts[idx].config;
74
+ for (let idx = app.modules.length - 1; idx >= 0; idx--) {
75
+ const { startingViewpointName } = app.modules[idx].config;
76
76
  if (startingViewpointName && app.viewpoints.hasKey(startingViewpointName)) {
77
77
  viewpoint = app.viewpoints.getByKey(startingViewpointName);
78
78
  break;
@@ -95,8 +95,8 @@
95
95
  };
96
96
 
97
97
  const listener = [
98
- app.contextAdded.addEventListener(updateStartingViewpoint),
99
- app.contextRemoved.addEventListener(updateStartingViewpoint),
98
+ app.moduleAdded.addEventListener(updateStartingViewpoint),
99
+ app.moduleRemoved.addEventListener(updateStartingViewpoint),
100
100
  ];
101
101
 
102
102
  const destroy = () => { listener.forEach(cb => cb()); };
@@ -1,15 +1,19 @@
1
1
  <template>
2
- <div class="d-inline-flex">
3
- <OrientationToolsButton
4
- @click="input(-90)"
5
- icon="$vcsRotateLeft"
6
- tooltip="navigation.obliqueLeftTooltip"
7
- />
8
- <OrientationToolsButton
9
- @click="input(90)"
10
- icon="$vcsRotateRight"
11
- tooltip="navigation.obliqueRightTooltip"
12
- />
2
+ <div class="d-inline-flex rounded vcs-oblique-orientation">
3
+ <div class="d-inline-flex rounded inner">
4
+ <OrientationToolsButton
5
+ @click="input(-90)"
6
+ icon="$vcsRotateLeft"
7
+ tooltip="navigation.obliqueLeftTooltip"
8
+ elevation="0"
9
+ />
10
+ <OrientationToolsButton
11
+ @click="input(90)"
12
+ icon="$vcsRotateRight"
13
+ tooltip="navigation.obliqueRightTooltip"
14
+ elevation="0"
15
+ />
16
+ </div>
13
17
  </div>
14
18
  </template>
15
19
 
@@ -43,6 +47,25 @@
43
47
  };
44
48
  </script>
45
49
 
46
- <style scoped>
47
-
50
+ <style lang="scss" scoped>
51
+ .vcs-oblique-orientation {
52
+ box-shadow: rgba(0, 0, 0, 0.15) 0 2px 2px 0;
53
+ .inner{
54
+ box-shadow: rgba(0, 0, 0, 0.25) 0 -2px 2px 0 inset;
55
+ }
56
+ ::v-deep {
57
+ .btn-orientation-tools{
58
+ &:first-child{
59
+ box-shadow: rgba(0, 0, 0, 0.25) 2px 2px 1px -2px,
60
+ rgba(0, 0, 0, 0.02) -3px 2px 2px 0,
61
+ rgba(0, 0, 0, 0.12) 0 1px 1px 0 !important;
62
+ }
63
+ &:last-child{
64
+ box-shadow: rgba(0, 0, 0, 0.02) 1px 4px 1px -2px,
65
+ rgba(0, 0, 0, 0.02) 1px 2px 1px 0,
66
+ rgba(0, 0, 0, 0.1) 1px 1px 1px 0 !important;
67
+ }
68
+ }
69
+ }
70
+ }
48
71
  </style>
@@ -5,7 +5,6 @@
5
5
  >
6
6
  <template #activator="{ on, attrs }">
7
7
  <v-card
8
- elevation="0"
9
8
  class="h-8 w-8 d-flex align-center justify-center text-center btn-orientation-tools"
10
9
  v-bind="{ ...$attrs, ...attrs }"
11
10
  v-on="{ ...$listeners, ...on }"