@vcmap/ui 6.1.0-rc.6 → 6.1.0

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 (149) hide show
  1. package/config/base.config.json +7 -3
  2. package/config/cluster.config.json +5 -14
  3. package/config/dev.config.json +175 -56
  4. package/config/projects.config.json +2 -1
  5. package/config/splashscreen.config.json +6 -10
  6. package/config/vectorTile.config.json +42 -1
  7. package/dist/assets/{cesium-f5e8e354.js → cesium-664ad022.js} +53 -23
  8. package/dist/assets/cesium.js +1 -1
  9. package/dist/assets/{core-c134a524.js → core-841b71a4.js} +8458 -5828
  10. package/dist/assets/core.js +1 -1
  11. package/dist/assets/{ol-2752311f.js → ol-2e095c08.js} +87 -37
  12. package/dist/assets/ol.js +1 -1
  13. package/dist/assets/ui-2fd6f47d.css +1 -0
  14. package/dist/assets/{ui-83514586.js → ui-2fd6f47d.js} +21376 -20063
  15. package/dist/assets/ui.js +1 -1
  16. package/dist/assets/vue.js +1 -1
  17. package/dist/assets/{vuetify-5dbe2644.css → vuetify-4bc77ff7.css} +2 -2
  18. package/dist/assets/{vuetify-5dbe2644.js → vuetify-4bc77ff7.js} +7520 -7373
  19. package/dist/assets/vuetify.js +1 -1
  20. package/dist/index.html +1 -1
  21. package/index.d.ts +15 -5
  22. package/index.html +1 -1
  23. package/index.js +14 -5
  24. package/package.json +12 -8
  25. package/plugins/@vcmap-show-case/theming-example/src/index.js +1 -0
  26. package/plugins/@vcmap-show-case/vector-properties-example/src/LayerSettings.vue +39 -0
  27. package/plugins/@vcmap-show-case/vector-properties-example/src/VectorPropertiesExample.vue +3 -0
  28. package/plugins/@vcmap-show-case/vector-properties-example/src/lib.js +13 -0
  29. package/plugins/@vcmap-show-case/window-tester/src/WindowExample.vue +9 -0
  30. package/plugins/package.json +7 -5
  31. package/src/actions/actionHelper.d.ts +6 -0
  32. package/src/actions/actionHelper.js +22 -0
  33. package/src/actions/deepPickingAction.d.ts +23 -0
  34. package/src/actions/deepPickingAction.js +399 -0
  35. package/src/application/MapsGroupMobileMenu.vue +105 -0
  36. package/src/application/MapsGroupMobileMenu.vue.d.ts +7 -0
  37. package/src/application/VcsApp.vue +51 -24
  38. package/src/application/VcsApp.vue.d.ts +9 -2
  39. package/src/application/VcsAttributionsFooter.vue +1 -0
  40. package/src/application/VcsContainer.vue +36 -13
  41. package/src/application/VcsContainer.vue.d.ts +7 -0
  42. package/src/application/VcsMobileMenuList.vue +111 -0
  43. package/src/application/VcsMobileMenuList.vue.d.ts +2 -0
  44. package/src/application/VcsNavbar.vue +15 -3
  45. package/src/application/VcsNavbarMobile.vue +206 -0
  46. package/src/application/VcsNavbarMobile.vue.d.ts +42 -0
  47. package/src/application/VcsPositionDisplay.vue +1 -0
  48. package/src/application/VcsSplashScreen.vue +39 -7
  49. package/src/application/VcsSplashScreen.vue.d.ts +6 -0
  50. package/src/application/uiConfigHelper.d.ts +12 -0
  51. package/src/application/uiConfigHelper.js +37 -0
  52. package/src/components/buttons/VcsActionButtonList.vue +1 -0
  53. package/src/components/buttons/VcsToolButton.vue +8 -1
  54. package/src/components/buttons/VcsToolButton.vue.d.ts +1 -0
  55. package/src/components/form-inputs-controls/VcsSelect.vue +8 -6
  56. package/src/components/form-output/VcsTemplateMarkdown.vue +43 -0
  57. package/src/components/form-output/VcsTemplateMarkdown.vue.d.ts +9 -0
  58. package/src/components/icons/+all.d.ts +5 -0
  59. package/src/components/icons/+all.js +14 -0
  60. package/src/components/lists/VcsActionList.vue +1 -0
  61. package/src/components/lists/VcsGroupedList.vue +2 -1
  62. package/src/components/lists/VcsListItemComponent.vue +1 -0
  63. package/src/components/lists/VcsTreeNode.vue +11 -2
  64. package/src/components/lists/VcsTreeview.vue +40 -3
  65. package/src/components/lists/VcsTreeview.vue.d.ts +1 -0
  66. package/src/components/lists/VcsTreeviewTitle.vue +8 -1
  67. package/src/components/style/{MenuWrapper.vue → StyleMenuWrapper.vue} +2 -1
  68. package/src/components/style/VcsFillMenu.vue +4 -4
  69. package/src/components/style/VcsImageMenu.vue +4 -4
  70. package/src/components/style/VcsStrokeMenu.vue +4 -4
  71. package/src/components/style/VcsTextMenu.vue +4 -4
  72. package/src/contentTree/LayerTree.vue +8 -46
  73. package/src/contentTree/LayerTree.vue.d.ts +1 -3
  74. package/src/contentTree/contentTreeCollection.d.ts +7 -0
  75. package/src/contentTree/contentTreeCollection.js +31 -10
  76. package/src/contentTree/contentTreeItem.d.ts +4 -4
  77. package/src/contentTree/contentTreeItem.js +2 -2
  78. package/src/contentTree/flightContentTreeItem.d.ts +8 -1
  79. package/src/contentTree/flightContentTreeItem.js +26 -3
  80. package/src/contentTree/groupContentTreeItem.d.ts +21 -0
  81. package/src/contentTree/groupContentTreeItem.js +32 -2
  82. package/src/contentTree/layerContentTreeItem.d.ts +8 -1
  83. package/src/contentTree/layerContentTreeItem.js +26 -4
  84. package/src/contentTree/layerGroupContentTreeItem.d.ts +6 -0
  85. package/src/contentTree/layerGroupContentTreeItem.js +27 -3
  86. package/src/contentTree/nodeContentTreeItem.d.ts +21 -0
  87. package/src/contentTree/nodeContentTreeItem.js +31 -2
  88. package/src/contentTree/obliqueCollectionContentTreeItem.d.ts +6 -0
  89. package/src/contentTree/obliqueCollectionContentTreeItem.js +22 -2
  90. package/src/contentTree/wmsChildContentTreeItem.d.ts +56 -0
  91. package/src/contentTree/wmsChildContentTreeItem.js +159 -0
  92. package/src/contentTree/wmsGroupContentTreeItem.d.ts +171 -0
  93. package/src/contentTree/wmsGroupContentTreeItem.js +619 -0
  94. package/src/featureInfo/BalloonComponent.vue +6 -6
  95. package/src/featureInfo/ClusterFeatureComponent.vue +47 -11
  96. package/src/featureInfo/ClusterFeatureComponent.vue.d.ts +1 -0
  97. package/src/featureInfo/MarkdownBalloonComponent.vue +3 -9
  98. package/src/featureInfo/MarkdownBalloonComponent.vue.d.ts +1 -11
  99. package/src/featureInfo/balloonFeatureInfoView.d.ts +3 -0
  100. package/src/featureInfo/balloonFeatureInfoView.js +78 -11
  101. package/src/featureInfo/balloonHelper.js +9 -13
  102. package/src/featureInfo/featureInfo.d.ts +32 -7
  103. package/src/featureInfo/featureInfo.js +192 -93
  104. package/src/featureInfo/markdownBalloonFeatureInfoView.d.ts +0 -6
  105. package/src/featureInfo/markdownBalloonFeatureInfoView.js +5 -14
  106. package/src/featureInfo/markdownFeatureInfoView.d.ts +2 -8
  107. package/src/featureInfo/markdownFeatureInfoView.js +6 -15
  108. package/src/i18n/de.d.ts +64 -50
  109. package/src/i18n/de.js +9 -0
  110. package/src/i18n/en.d.ts +64 -50
  111. package/src/i18n/en.js +9 -0
  112. package/src/legend/VcsLegend.vue +21 -2
  113. package/src/legend/VcsLegend.vue.d.ts +1 -0
  114. package/src/legend/legendHelper.d.ts +0 -13
  115. package/src/legend/legendHelper.js +3 -27
  116. package/src/manager/navbarManager.d.ts +14 -1
  117. package/src/manager/navbarManager.js +22 -2
  118. package/src/manager/toolbox/GroupToolboxComponent.vue +17 -3
  119. package/src/manager/toolbox/GroupToolboxComponent.vue.d.ts +1 -0
  120. package/src/manager/toolbox/SelectToolboxComponent.vue +17 -3
  121. package/src/manager/toolbox/SelectToolboxComponent.vue.d.ts +1 -0
  122. package/src/manager/toolbox/ToolboxManagerComponent.vue +45 -14
  123. package/src/manager/toolbox/ToolboxManagerComponent.vue.d.ts +9 -0
  124. package/src/manager/toolbox/toolboxManager.d.ts +2 -1
  125. package/src/manager/toolbox/toolboxManager.js +13 -1
  126. package/src/manager/window/WindowComponent.vue +3 -2
  127. package/src/manager/window/WindowComponentHeader.vue +9 -1
  128. package/src/manager/window/WindowComponentHeader.vue.d.ts +1 -0
  129. package/src/manager/window/WindowManager.vue +175 -30
  130. package/src/manager/window/WindowManager.vue.d.ts +5 -0
  131. package/src/manager/window/windowManager.d.ts +2 -2
  132. package/src/manager/window/windowManager.js +12 -10
  133. package/src/navigation/MapNavigation.vue +29 -19
  134. package/src/navigation/MapNavigation.vue.d.ts +1 -0
  135. package/src/notifier/NotifierComponent.vue +1 -0
  136. package/src/search/ResultsComponent.vue +44 -17
  137. package/src/search/ResultsComponent.vue.d.ts +11 -1
  138. package/src/search/SearchComponent.vue +60 -9
  139. package/src/search/SearchComponent.vue.d.ts +2 -0
  140. package/src/search/search.js +3 -16
  141. package/src/state.d.ts +2 -1
  142. package/src/state.js +2 -1
  143. package/src/uiConfig.d.ts +9 -0
  144. package/src/uiConfig.js +1 -0
  145. package/src/vuePlugins/vuetify.d.ts +4 -0
  146. package/src/vuePlugins/vuetify.js +49 -3
  147. package/dist/assets/ui-83514586.css +0 -1
  148. /package/dist/assets/{vue-f8b1b5f8.js → vue-71fd14e8.js} +0 -0
  149. /package/src/components/style/{MenuWrapper.vue.d.ts → StyleMenuWrapper.vue.d.ts} +0 -0
@@ -107,31 +107,7 @@ export function getImageSrcFromShape(image) {
107
107
  * @property {string} title - layer or entry name
108
108
  * @property {boolean} [open=true] - panel state of entry
109
109
  * @property {Array<LegendItem>} legend - legend properties
110
- * @property {Array<import("../actions/actionHelper.js").VcsAction>} actions - popout actions
111
- */
112
-
113
- /**
114
- * creates a LegendEntry with title, options and optionally popout action to the entries array
115
- * @param {string} key - layerName
116
- * @param {string} title
117
- * @param {Array<LegendItem>} legend
118
- * @returns {LegendEntry}
119
- */
120
- export function createLegendEntry(key, title, legend) {
121
- const actions = [];
122
- legend.forEach((item) => {
123
- // XXX only one popout button allowed. Rethink if use case for multiple popout buttons comes up.
124
- if (item.src && item.popoutBtn && actions.length < 1) {
125
- actions.push({
126
- name: 'legendPopoutAction',
127
- icon: 'mdi-open-in-new',
128
- title: 'legend.openInNew',
129
- callback: () => window.open(item.src, '_blank'),
130
- });
131
- }
132
- });
133
- return { key, title, legend, actions, open: true };
134
- }
110
+ */
135
111
 
136
112
  /**
137
113
  *
@@ -176,7 +152,7 @@ export function getLegendEntries(app) {
176
152
  const legend =
177
153
  layer.style?.properties?.legend ?? layer.properties?.legend;
178
154
  if (legend) {
179
- const legendEntry = createLegendEntry(key, title, legend);
155
+ const legendEntry = { key, title, legend, open: true };
180
156
  entries.unshift(legendEntry);
181
157
  }
182
158
  if (layer.styleChanged) {
@@ -214,7 +190,7 @@ export function getLegendEntries(app) {
214
190
  const title = group.properties.title || group.name;
215
191
  const { legend } = group.properties;
216
192
  if (!entries.some(({ key }) => key === group.name)) {
217
- const legendEntry = createLegendEntry(group.name, title, legend);
193
+ const legendEntry = { key: group.name, title, legend, open: true };
218
194
  entries.unshift(legendEntry);
219
195
  }
220
196
  }
@@ -16,6 +16,7 @@ export function sortByOwner(ownerA: string | symbol, ownerB: string | symbol, or
16
16
  */
17
17
  export function getActionsByLocation(buttonComponents: Array<import("./buttonManager.js").ButtonComponent>, location: ButtonLocation, order?: string[] | undefined, compareFn?: ((arg0: import("./buttonManager.js").ButtonComponent, arg1: import("./buttonManager.js").ButtonComponent) => number) | undefined): Array<import("../actions/actionHelper.js").VcsAction>;
18
18
  export const locationSymbol: unique symbol;
19
+ export const deviceSymbol: unique symbol;
19
20
  /**
20
21
  * *
21
22
  */
@@ -30,9 +31,20 @@ export namespace ButtonLocation {
30
31
  }
31
32
  export default NavbarManager;
32
33
  export type INavbarManager = import("../vcsUiApp.js").VcsComponentManager<import("./buttonManager.js").ButtonComponent, import("./buttonManager.js").ButtonComponentOptions>;
34
+ export type DeviceOptions = {
35
+ desktop: boolean | null;
36
+ tablet: boolean | null;
37
+ mobile: boolean | null;
38
+ };
33
39
  /**
34
40
  * @typedef {import("../vcsUiApp.js").VcsComponentManager<import("./buttonManager.js").ButtonComponent,import("./buttonManager.js").ButtonComponentOptions>} INavbarManager
35
41
  */
42
+ /**
43
+ * @typedef {Object} DeviceOptions
44
+ * @property {boolean?} desktop
45
+ * @property {boolean?} tablet
46
+ * @property {boolean?} mobile
47
+ */
36
48
  /**
37
49
  * @class NavbarManager
38
50
  * @description Manages a set of Map Buttons in the Navbar
@@ -44,11 +56,12 @@ declare class NavbarManager extends ButtonManager implements INavbarManager {
44
56
  * @param {import("./buttonManager.js").ButtonComponentOptions} buttonComponentOptions
45
57
  * @param {string|symbol} owner pluginName or vcsAppSymbol
46
58
  * @param {ButtonLocation} location Button render position
59
+ * @param {DeviceOptions} [device={destop: true, tablet: true}] Device - optional device configuration
47
60
  * @throws {Error} if a buttonComponent with the same ID has already been added
48
61
  * @returns {import("./buttonManager.js").ButtonComponent}
49
62
  */
50
63
  // @ts-ignore
51
- add(buttonComponentOptions: import("./buttonManager.js").ButtonComponentOptions, owner: string | symbol, location: ButtonLocation): import("./buttonManager.js").ButtonComponent;
64
+ add(buttonComponentOptions: import("./buttonManager.js").ButtonComponentOptions, owner: string | symbol, location: ButtonLocation, device?: DeviceOptions | undefined): import("./buttonManager.js").ButtonComponent;
52
65
  /**
53
66
  * Toggles a button of provided id by executing its callback.
54
67
  * Use active flag to force a state to be applied.
@@ -1,8 +1,9 @@
1
- import { check, ofEnum } from '@vcsuite/check';
1
+ import { check, ofEnum, optional } from '@vcsuite/check';
2
2
  import ButtonManager, { sortByWeight } from './buttonManager.js';
3
3
  import { vcsAppSymbol } from '../pluginHelper.js';
4
4
 
5
5
  export const locationSymbol = Symbol('location');
6
+ export const deviceSymbol = Symbol('device');
6
7
 
7
8
  /**
8
9
  * sorts by owner and optionally plugin order
@@ -74,6 +75,13 @@ export const ButtonLocation = {
74
75
  * @typedef {import("../vcsUiApp.js").VcsComponentManager<import("./buttonManager.js").ButtonComponent,import("./buttonManager.js").ButtonComponentOptions>} INavbarManager
75
76
  */
76
77
 
78
+ /**
79
+ * @typedef {Object} DeviceOptions
80
+ * @property {boolean?} desktop
81
+ * @property {boolean?} tablet
82
+ * @property {boolean?} mobile
83
+ */
84
+
77
85
  /**
78
86
  * @class NavbarManager
79
87
  * @description Manages a set of Map Buttons in the Navbar
@@ -85,13 +93,25 @@ class NavbarManager extends ButtonManager {
85
93
  * @param {import("./buttonManager.js").ButtonComponentOptions} buttonComponentOptions
86
94
  * @param {string|symbol} owner pluginName or vcsAppSymbol
87
95
  * @param {ButtonLocation} location Button render position
96
+ * @param {DeviceOptions} [device={destop: true, tablet: true}] Device - optional device configuration
88
97
  * @throws {Error} if a buttonComponent with the same ID has already been added
89
98
  * @returns {import("./buttonManager.js").ButtonComponent}
90
99
  */
91
- add(buttonComponentOptions, owner, location) {
100
+ add(
101
+ buttonComponentOptions,
102
+ owner,
103
+ location,
104
+ device = { desktop: true, tablet: true },
105
+ ) {
92
106
  check(location, ofEnum(ButtonLocation));
107
+ check(device, {
108
+ desktop: optional(Boolean),
109
+ tablet: optional(Boolean),
110
+ mobile: optional(Boolean),
111
+ });
93
112
  const buttonComponent = super.add(buttonComponentOptions, owner);
94
113
  buttonComponent[locationSymbol] = location;
114
+ buttonComponent[deviceSymbol] = device;
95
115
  return buttonComponent;
96
116
  }
97
117
 
@@ -3,8 +3,8 @@
3
3
  <v-menu
4
4
  v-model="open"
5
5
  @update:model-value="$emit('toggle', open)"
6
- location="bottom center"
7
- z-index="0"
6
+ :location="xs ? 'top center' : 'bottom center'"
7
+ :z-index="xs ? 2 : undefined"
8
8
  >
9
9
  <template #activator="{ props }">
10
10
  <VcsToolButton
@@ -22,13 +22,20 @@
22
22
  </template>
23
23
 
24
24
  <v-toolbar
25
- class="vcs-toolbox-toolbar--secondary mx-auto marginToTop rounded-b elevation-4 opacity-80 px-1"
25
+ class="vcs-toolbox-toolbar--secondary mx-auto elevation-4 opacity-80 px-1"
26
+ :class="{
27
+ marginToTop: !xs,
28
+ marginToBottom: xs,
29
+ 'rounded-t': xs,
30
+ 'rounded-b': !xs,
31
+ }"
26
32
  :height="toolboxHeight"
27
33
  >
28
34
  <v-toolbar-items class="w-100">
29
35
  <div class="d-flex align-center justify-space-between gc-1 w-100">
30
36
  <VcsToolButton
31
37
  v-for="{ id, action } in orderedButtons"
38
+ :data-action-name="action.name"
32
39
  :key="id"
33
40
  :tooltip="action.title"
34
41
  :icon="action.icon"
@@ -52,10 +59,14 @@
52
59
  .marginToTop {
53
60
  margin-top: 3px;
54
61
  }
62
+ .marginToBottom {
63
+ margin-bottom: 3px;
64
+ }
55
65
  </style>
56
66
  <script>
57
67
  import { computed, ref } from 'vue';
58
68
  import { VMenu, VIcon, VToolbar, VToolbarItems } from 'vuetify/components';
69
+ import { useDisplay } from 'vuetify';
59
70
  import VcsToolButton from '../../components/buttons/VcsToolButton.vue';
60
71
  import { getComponentsByOrder } from './toolboxManager.js';
61
72
  import { useFontSize } from '../../vuePlugins/vuetify.js';
@@ -104,11 +115,14 @@
104
115
  return fontSize.value * 3 + 1;
105
116
  });
106
117
 
118
+ const { xs } = useDisplay();
119
+
107
120
  return {
108
121
  open,
109
122
  orderedButtons,
110
123
  hasActiveAction,
111
124
  toolboxHeight,
125
+ xs,
112
126
  };
113
127
  },
114
128
  };
@@ -8,6 +8,7 @@ declare const _default: import("vue").DefineComponent<{
8
8
  orderedButtons: import("vue").ComputedRef<(import("../buttonManager.js", { with: { "resolution-mode": "import" } }).ButtonComponent | import("./toolboxManager.js", { with: { "resolution-mode": "import" } }).ToolboxComponent)[]>;
9
9
  hasActiveAction: import("vue").ComputedRef<boolean>;
10
10
  toolboxHeight: import("vue").ComputedRef<number>;
11
+ xs: import("vue").Ref<boolean>;
11
12
  }, any, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
12
13
  group: {
13
14
  type: ObjectConstructor;
@@ -6,6 +6,7 @@
6
6
  >
7
7
  <VcsToolButton
8
8
  :key="group.action.tools[group.action.currentIndex].name"
9
+ :data-action-name="group.action.tools[group.action.currentIndex].name"
9
10
  :tooltip="group.action.tools[group.action.currentIndex].title"
10
11
  :icon="group.action.tools[group.action.currentIndex].icon"
11
12
  :active="group.action.active"
@@ -24,9 +25,9 @@
24
25
  />
25
26
  <v-menu
26
27
  v-model="open"
27
- location="bottom center"
28
+ :location="xs ? 'top center' : 'bottom center'"
28
29
  @update:model-value="$emit('toggle', open)"
29
- z-index="0"
30
+ :z-index="xs ? 2 : undefined"
30
31
  >
31
32
  <template #activator="{ props }">
32
33
  <VcsToolButton
@@ -42,13 +43,20 @@
42
43
  </template>
43
44
 
44
45
  <v-toolbar
45
- class="vcs-toolbox-2 mx-auto marginToTop rounded-b elevation-4 opacity-80 px-1"
46
+ class="vcs-toolbox-2 mx-auto elevation-4 opacity-80 px-1"
47
+ :class="{
48
+ marginToTop: !xs,
49
+ marginToBottom: xs,
50
+ 'rounded-t': xs,
51
+ 'rounded-b': !xs,
52
+ }"
46
53
  :height="toolboxHeight"
47
54
  >
48
55
  <v-toolbar-items class="w-100">
49
56
  <div class="d-flex align-center justify-space-between gc-1 w-100">
50
57
  <VcsToolButton
51
58
  v-for="(item, index) in group.action.tools"
59
+ :data-action-name="item.name"
52
60
  :key="`${item.name}-${index}`"
53
61
  :tooltip="item.title"
54
62
  :icon="item.icon"
@@ -66,10 +74,14 @@
66
74
  .marginToTop {
67
75
  margin-top: 3px;
68
76
  }
77
+ .marginToBottom {
78
+ margin-bottom: 3px;
79
+ }
69
80
  </style>
70
81
  <script>
71
82
  import { ref, computed } from 'vue';
72
83
  import { VMenu, VIcon, VToolbar, VToolbarItems } from 'vuetify/components';
84
+ import { useDisplay } from 'vuetify';
73
85
  import VcsToolButton from '../../components/buttons/VcsToolButton.vue';
74
86
  import { useFontSize } from '../../vuePlugins/vuetify.js';
75
87
 
@@ -99,9 +111,11 @@
99
111
  const toolboxHeight = computed(() => {
100
112
  return fontSize.value * 3 + 1;
101
113
  });
114
+ const { xs } = useDisplay();
102
115
  return {
103
116
  open,
104
117
  toolboxHeight,
118
+ xs,
105
119
  };
106
120
  },
107
121
  };
@@ -6,6 +6,7 @@ declare const _default: import("vue").DefineComponent<{
6
6
  }, {
7
7
  open: import("vue").Ref<boolean>;
8
8
  toolboxHeight: import("vue").ComputedRef<number>;
9
+ xs: import("vue").Ref<boolean>;
9
10
  }, any, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
10
11
  group: {
11
12
  type: ObjectConstructor;
@@ -1,32 +1,41 @@
1
1
  <template>
2
2
  <v-toolbar
3
- v-if="toolboxOpen && orderedGroups.length > 0 && smAndUp"
3
+ v-if="toolboxOpen && orderedGroups.length > 0"
4
4
  class="vcs-toolbox mx-auto elevation-4 opacity-80 toolbox-manager-component"
5
5
  :class="{
6
- 'rounded-b': !open,
6
+ 'rounded-b': !open && !xs,
7
+ 'rounded-t': xs,
7
8
  'vcs-toolbox__secondary': !isDefaultToolbox,
9
+ mobileToolbox: xs,
8
10
  }"
9
11
  :height="toolboxHeight"
10
- :style="{ zIndex }"
12
+ :style="{ zIndex: xs ? zIndexMobile : zIndex }"
11
13
  @click.stop="bringToTop"
12
14
  >
13
15
  <v-toolbar-items class="w-100 px-4 gc-1">
14
16
  <div
15
17
  class="d-flex align-center justify-space-between w-100"
16
18
  v-for="group in orderedGroups"
19
+ :data-toolbox-id="group.id"
17
20
  :key="group.id"
18
21
  >
19
22
  <ToolboxActionGroup
20
23
  v-if="group.type === ToolboxType.GROUP"
21
24
  :group="group"
22
25
  @toggle="openGroup"
23
- @click="bringToTop"
26
+ @click="
27
+ bringToTop;
28
+ xs && toolboxToggleAction.callback();
29
+ "
24
30
  />
25
31
  <ToolboxActionSelect
26
32
  v-else-if="group.type === ToolboxType.SELECT"
27
33
  :group="group"
28
34
  @toggle="openGroup"
29
- @click="bringToTop"
35
+ @click="
36
+ bringToTop;
37
+ xs && toolboxToggleAction.callback();
38
+ "
30
39
  />
31
40
  <VcsToolButton
32
41
  v-else
@@ -37,6 +46,7 @@
37
46
  :disabled="group.action.disabled"
38
47
  @click.stop="
39
48
  bringToTop();
49
+ xs && toolboxToggleAction.callback();
40
50
  group.action.callback($event);
41
51
  "
42
52
  v-bind="{ ...$attrs }"
@@ -61,10 +71,16 @@
61
71
  margin-top: 2px;
62
72
  width: fit-content;
63
73
  }
74
+ .mobileToolbox {
75
+ bottom: 0px !important;
76
+ position: absolute !important;
77
+ left: 50% !important;
78
+ transform: translateX(-50%) !important;
79
+ }
64
80
  </style>
65
81
 
66
82
  <script>
67
- import { inject, ref, computed, watch, onUnmounted } from 'vue';
83
+ import { inject, ref, computed, watch, onUnmounted, reactive } from 'vue';
68
84
  import { useDisplay } from 'vuetify';
69
85
  import { VToolbar, VToolbarItems } from 'vuetify/components';
70
86
  import {
@@ -76,7 +92,7 @@
76
92
  import ToolboxActionGroup from './GroupToolboxComponent.vue';
77
93
  import VcsToolButton from '../../components/buttons/VcsToolButton.vue';
78
94
  import { vcsAppSymbol } from '../../pluginHelper.js';
79
- import { ButtonLocation } from '../navbarManager.js';
95
+ import { ButtonLocation, deviceSymbol } from '../navbarManager.js';
80
96
  import { useFontSize } from '../../vuePlugins/vuetify.js';
81
97
 
82
98
  /**
@@ -114,6 +130,8 @@
114
130
  setup() {
115
131
  const app = inject('vcsApp');
116
132
 
133
+ const { smAndUp, xs, sm, mdAndUp } = useDisplay();
134
+
117
135
  const groups = computed(() => {
118
136
  return app.toolboxManager.componentIds.map((id) =>
119
137
  app.toolboxManager.get(id),
@@ -130,6 +148,8 @@
130
148
  toolboxComponentId,
131
149
  vcsAppSymbol,
132
150
  );
151
+ // The zIndex of the mobile toolbox is two higher than the desktop toolbox because it needs to be above the windows
152
+ const zIndexMobile = computed(() => zIndex.value + 2);
133
153
 
134
154
  /**
135
155
  * To be rendered in Toolbox components must meet certain conditions:
@@ -139,13 +159,18 @@
139
159
  * @param {SingleToolboxComponent|SelectToolboxComponent|GroupToolboxComponent} c
140
160
  * @returns {boolean}
141
161
  */
162
+
142
163
  function filterFunc(c) {
143
164
  return (
144
- c.type === ToolboxType.SINGLE ||
145
- c?.action?.tools?.length > 1 ||
146
- c.buttonManager?.componentIds?.length > 0
165
+ (c.type === ToolboxType.SINGLE ||
166
+ c?.action?.tools?.length > 1 ||
167
+ c.buttonManager?.componentIds?.length > 0) &&
168
+ ((xs.value === true && c[deviceSymbol]?.mobile === true) ||
169
+ (sm.value === true && c[deviceSymbol]?.tablet === true) ||
170
+ (mdAndUp.value === true && c[deviceSymbol]?.desktop === true))
147
171
  );
148
172
  }
173
+
149
174
  const orderedGroups = computed(() =>
150
175
  getComponentsByOrder(groups.value)
151
176
  .filter((comp) => comp.toolboxNames.includes(toolboxName.value))
@@ -153,16 +178,19 @@
153
178
  );
154
179
 
155
180
  const toolboxOpen = app.toolboxManager.open;
156
- const toolboxToggleAction = {
181
+ if (xs.value) {
182
+ toolboxOpen.value = false;
183
+ }
184
+ const toolboxToggleAction = reactive({
157
185
  name: 'toolboxToggleAction',
158
186
  icon: '$vcsTools',
159
187
  title: 'toolbox.title',
160
- active: true,
188
+ active: toolboxOpen.value,
161
189
  callback() {
162
190
  this.active = !this.active;
163
191
  toolboxOpen.value = this.active;
164
192
  },
165
- };
193
+ });
166
194
 
167
195
  function handleToolboxButton() {
168
196
  if (orderedGroups.value.length > 0) {
@@ -174,6 +202,7 @@
174
202
  },
175
203
  vcsAppSymbol,
176
204
  ButtonLocation.TOOL,
205
+ { desktop: true, tablet: true, mobile: true },
177
206
  );
178
207
  }
179
208
  } else {
@@ -201,7 +230,6 @@
201
230
  app.windowManager.bringWindowToTop(toolboxComponentId);
202
231
  };
203
232
 
204
- const { smAndUp } = useDisplay();
205
233
  const fontSize = useFontSize();
206
234
  const toolboxHeight = computed(() => {
207
235
  return fontSize.value * 3 + 1;
@@ -209,8 +237,10 @@
209
237
  return {
210
238
  smAndUp,
211
239
  toolboxOpen,
240
+ toolboxToggleAction,
212
241
  orderedGroups,
213
242
  zIndex,
243
+ zIndexMobile,
214
244
  isDefaultToolbox: computed(
215
245
  () => toolboxName.value === defaultToolboxName,
216
246
  ),
@@ -224,6 +254,7 @@
224
254
  }
225
255
  },
226
256
  toolboxHeight,
257
+ xs,
227
258
  };
228
259
  },
229
260
  };
@@ -12,8 +12,16 @@ export const toolboxComponentId: "toolbox";
12
12
  declare const _default: import("vue").DefineComponent<{}, {
13
13
  smAndUp: import("vue").Ref<boolean>;
14
14
  toolboxOpen: any;
15
+ toolboxToggleAction: {
16
+ name: string;
17
+ icon: string;
18
+ title: string;
19
+ active: any;
20
+ callback: () => void;
21
+ };
15
22
  orderedGroups: import("vue").ComputedRef<(import("../buttonManager.js", { with: { "resolution-mode": "import" } }).ButtonComponent | import("./toolboxManager.js", { with: { "resolution-mode": "import" } }).ToolboxComponent)[]>;
16
23
  zIndex: any;
24
+ zIndexMobile: import("vue").ComputedRef<any>;
17
25
  isDefaultToolbox: import("vue").ComputedRef<boolean>;
18
26
  ToolboxType: {
19
27
  SINGLE: number;
@@ -24,6 +32,7 @@ declare const _default: import("vue").DefineComponent<{}, {
24
32
  bringToTop: () => void;
25
33
  openGroup(group: any): void;
26
34
  toolboxHeight: import("vue").ComputedRef<number>;
35
+ xs: import("vue").Ref<boolean>;
27
36
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{}>>, {}, {}>;
28
37
  export default _default;
29
38
  export type ToolboxButtonGroup = {
@@ -159,11 +159,12 @@ declare class ToolboxManager implements IToolboxManager {
159
159
  * adds a ToolboxComponent
160
160
  * @param {SingleToolboxComponentOptions|SelectToolboxComponentOptions|GroupToolboxComponentOptions} toolboxComponentOptions
161
161
  * @param {string|symbol} owner pluginName or vcsAppSymbol
162
+ * @param {import('../navbarManager.js').DeviceOptions} [device={destop: true, tablet: true}] Device - optional device configuration
162
163
  * @throws {Error} if a toolboxComponent with the same ID has already been added
163
164
  * @returns {SingleToolboxComponent|SelectToolboxComponent|import("vue").ShallowReactive<GroupToolboxComponent>}
164
165
  */
165
166
  // @ts-ignore
166
- add(toolboxComponentOptions: SingleToolboxComponentOptions | SelectToolboxComponentOptions | GroupToolboxComponentOptions, owner: string | symbol): SingleToolboxComponent | SelectToolboxComponent | import("vue").ShallowReactive<GroupToolboxComponent>;
167
+ add(toolboxComponentOptions: SingleToolboxComponentOptions | SelectToolboxComponentOptions | GroupToolboxComponentOptions, owner: string | symbol, device?: import("../navbarManager.js").DeviceOptions | undefined): SingleToolboxComponent | SelectToolboxComponent | import("vue").ShallowReactive<GroupToolboxComponent>;
167
168
  /**
168
169
  * removes all {@link ToolboxComponent}s of a specific owner and fires removed Events
169
170
  * @param {string|vcsAppSymbol} owner
@@ -6,6 +6,7 @@ import { vcsAppSymbol } from '../../pluginHelper.js';
6
6
  import ButtonManager from '../buttonManager.js';
7
7
  import { ActionPattern } from '../../components/lists/VcsActionList.vue';
8
8
  import { getActionFromOptions } from '../../actions/actionHelper.js';
9
+ import { deviceSymbol } from '../navbarManager.js';
9
10
 
10
11
  /**
11
12
  * Possible group types. Define behaviour of group:
@@ -287,12 +288,22 @@ class ToolboxManager {
287
288
  * adds a ToolboxComponent
288
289
  * @param {SingleToolboxComponentOptions|SelectToolboxComponentOptions|GroupToolboxComponentOptions} toolboxComponentOptions
289
290
  * @param {string|symbol} owner pluginName or vcsAppSymbol
291
+ * @param {import('../navbarManager.js').DeviceOptions} [device={destop: true, tablet: true}] Device - optional device configuration
290
292
  * @throws {Error} if a toolboxComponent with the same ID has already been added
291
293
  * @returns {SingleToolboxComponent|SelectToolboxComponent|import("vue").ShallowReactive<GroupToolboxComponent>}
292
294
  */
293
- add(toolboxComponentOptions, owner) {
295
+ add(
296
+ toolboxComponentOptions,
297
+ owner,
298
+ device = { desktop: true, tablet: true },
299
+ ) {
294
300
  check(toolboxComponentOptions.id, maybe(String));
295
301
  check(toolboxComponentOptions.type, ofEnum(ToolboxType));
302
+ check(device, {
303
+ desktop: optional(Boolean),
304
+ tablet: optional(Boolean),
305
+ mobile: optional(Boolean),
306
+ });
296
307
  check(owner, oneOf(String, vcsAppSymbol));
297
308
 
298
309
  if (toolboxComponentOptions.id && this.has(toolboxComponentOptions.id)) {
@@ -322,6 +333,7 @@ class ToolboxManager {
322
333
  get toolboxNames() {
323
334
  return toolboxNames;
324
335
  },
336
+ [deviceSymbol]: device,
325
337
  };
326
338
 
327
339
  if (type === ToolboxType.SINGLE) {
@@ -9,7 +9,7 @@
9
9
  :class="{
10
10
  rounded: !isDocked,
11
11
  marginToTop: isDocked || !isChild,
12
- marginToTopTablet: isTabletWithOpenToolbar,
12
+ marginTablet: isTabletWithOpenToolbar,
13
13
  'rounded-be': isDynamicLeft,
14
14
  'rounded-bs': isDynamicRight,
15
15
  }"
@@ -42,8 +42,9 @@
42
42
  .marginToTop {
43
43
  margin-top: 2px;
44
44
  }
45
- .marginToTopTablet {
45
+ .marginTablet {
46
46
  margin-top: calc(var(--v-vcs-font-size) * 3 + 6px);
47
+ margin-bottom: 2px;
47
48
  }
48
49
  </style>
49
50
 
@@ -22,7 +22,10 @@
22
22
  {{ $st(headerTooltip) }}
23
23
  </v-tooltip>
24
24
  </h3>
25
- <div class="d-flex justify-space-between align-center">
25
+ <div
26
+ class="d-flex justify-space-between align-center"
27
+ :class="{ 'gc-4': xs, 'mr-2': xs }"
28
+ >
26
29
  <template v-if="windowState.headerActions?.length > 0">
27
30
  <VcsActionButtonList
28
31
  :actions="windowState.headerActions"
@@ -30,6 +33,7 @@
30
33
  />
31
34
  <v-divider vertical inset class="mx-1 my-1" />
32
35
  </template>
36
+
33
37
  <VcsButton
34
38
  v-if="infoAction"
35
39
  @click.stop="infoAction.callback()"
@@ -80,6 +84,7 @@
80
84
  <script>
81
85
  import { VIcon, VDivider, VTooltip } from 'vuetify/components';
82
86
  import { computed, getCurrentInstance, ref } from 'vue';
87
+ import { useDisplay } from 'vuetify';
83
88
  import { createEllipseTooltip } from '../../components/composables.js';
84
89
  import VcsButton from '../../components/buttons/VcsButton.vue';
85
90
  import VcsActionButtonList from '../../components/buttons/VcsActionButtonList.vue';
@@ -130,6 +135,8 @@
130
135
  () => !props.windowState.hidePin && props.windowState.dockable,
131
136
  );
132
137
 
138
+ const { xs } = useDisplay();
139
+
133
140
  const vm = getCurrentInstance().proxy;
134
141
 
135
142
  const translatedHeaderTitle = computed(() =>
@@ -166,6 +173,7 @@
166
173
  translatedHeaderTitle,
167
174
  ),
168
175
  infoAction,
176
+ xs,
169
177
  };
170
178
  },
171
179
  };
@@ -21,6 +21,7 @@ declare const _default: import("vue").DefineComponent<{
21
21
  iconSize: import("vue").ComputedRef<number>;
22
22
  headerTooltip: import("vue").ComputedRef<string>;
23
23
  infoAction: import("../../actions/actionHelper.js", { with: { "resolution-mode": "import" } }).VcsAction | undefined;
24
+ xs: import("vue").Ref<boolean>;
24
25
  }, any, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
25
26
  windowState: {
26
27
  type: ObjectConstructor;