@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
@@ -0,0 +1,206 @@
1
+ <template>
2
+ <v-toolbar
3
+ absolute
4
+ density="comfortable"
5
+ elevation="0"
6
+ class="px-4 vcs-navbar-mobile"
7
+ :height="toolbarHeight"
8
+ >
9
+ <v-container fluid class="pa-0">
10
+ <v-row no-gutters class="align-center">
11
+ <v-col>
12
+ <v-toolbar-items>
13
+ <div class="d-flex justify-space-between w-100">
14
+ <VcsToolButton
15
+ v-if="mobileMenuAction"
16
+ :key="mobileMenuAction.name"
17
+ :data-action-name="mobileMenuAction.name"
18
+ :tooltip="mobileMenuAction.title"
19
+ :icon="mobileMenuAction.icon"
20
+ :active="mobileMenuAction.active"
21
+ @click.stop="mobileMenuAction.callback($event)"
22
+ v-bind="{ ...$attrs }"
23
+ />
24
+ <VcsToolButton
25
+ v-if="searchAction"
26
+ :data-action-name="searchAction.name"
27
+ :key="searchAction.name"
28
+ :tooltip="searchAction.title"
29
+ :icon="searchAction.icon"
30
+ :active="searchAction.active"
31
+ @click.stop="searchAction.callback($event)"
32
+ v-bind="{ ...$attrs }"
33
+ />
34
+
35
+ <MapsGroupMobileMenu> </MapsGroupMobileMenu>
36
+
37
+ <template v-if="contentActions.length > 0">
38
+ <VcsToolButton
39
+ v-for="(action, index) in contentActions"
40
+ :key="action.name || index"
41
+ :tooltip="action.title"
42
+ :icon="action.icon"
43
+ :active="action.active"
44
+ @click.stop="action.callback($event)"
45
+ v-bind="{ ...$attrs }"
46
+ />
47
+ </template>
48
+ <VcsToolButton
49
+ v-if="toolboxToggleAction"
50
+ :key="toolboxToggleAction.name"
51
+ :tooltip="toolboxToggleAction.title"
52
+ :icon="toolboxToggleAction.icon"
53
+ :active="toolboxToggleAction.active"
54
+ @click.stop="toolboxToggleAction.callback($event)"
55
+ v-bind="{ ...$attrs }"
56
+ />
57
+ </div>
58
+ </v-toolbar-items>
59
+ </v-col>
60
+ </v-row>
61
+ </v-container>
62
+ </v-toolbar>
63
+ </template>
64
+
65
+ <style lang="scss" scoped>
66
+ .v-toolbar.v-toolbar--bottom {
67
+ bottom: 0;
68
+ position: fixed;
69
+ }
70
+ .flex-grow-2 {
71
+ flex-grow: 2;
72
+ }
73
+ .vcs-navbar-mobile {
74
+ bottom: 0;
75
+ padding-top: calc(var(--v-vcs-font-size) - 5px);
76
+ padding-bottom: calc(var(--v-vcs-font-size) - 5px);
77
+ }
78
+ </style>
79
+
80
+ <script>
81
+ import { computed, inject, onUnmounted, shallowRef } from 'vue';
82
+ import {
83
+ VCol,
84
+ VContainer,
85
+ VRow,
86
+ VToolbar,
87
+ VToolbarItems,
88
+ } from 'vuetify/components';
89
+ import {
90
+ ButtonLocation,
91
+ deviceSymbol,
92
+ getActionsByLocation,
93
+ } from '../manager/navbarManager.js';
94
+ import VcsToolButton from '../components/buttons/VcsToolButton.vue';
95
+ import { vcsAppSymbol } from '../pluginHelper.js';
96
+ import {
97
+ createSearchButtonAction,
98
+ createToggleAction,
99
+ } from '../actions/actionHelper.js';
100
+ import { useFontSize } from '../vuePlugins/vuetify.js';
101
+ import VcsMobileMenuList from './VcsMobileMenuList.vue';
102
+ import { WindowSlot } from '../manager/window/windowManager.js';
103
+ import MapsGroupMobileMenu from './MapsGroupMobileMenu.vue';
104
+ import { toolboxComponentId } from '../manager/toolbox/ToolboxManagerComponent.vue';
105
+
106
+ export const mobileMenuListId = 'mobileMenuList';
107
+
108
+ /**
109
+ * @description The menu bar of a VcsMap application in Mobile view.
110
+ * Consists of three sections (first: Menu & Search, second: Map & Content, third: Toolbox).
111
+ * They rearrange the buttons of the desktop view according to the new sections.
112
+ * The ButtonLocation of MENU & imprint/dataprotection buttons are now in the Mobile Menu, the MAP and CONTENT are now in the second section, and the Toolbox is in the third section.
113
+ */
114
+ export default {
115
+ name: 'VcsNavbarMobile',
116
+ components: {
117
+ VcsToolButton,
118
+ VToolbar,
119
+ VContainer,
120
+ VRow,
121
+ VCol,
122
+ VToolbarItems,
123
+ MapsGroupMobileMenu,
124
+ },
125
+ setup() {
126
+ const app = inject('vcsApp');
127
+
128
+ const mobileButtonComponents = computed(() =>
129
+ app.navbarManager.componentIds
130
+ .map((id) => app.navbarManager.get(id))
131
+ .filter((buttonComponent) => {
132
+ return buttonComponent[deviceSymbol].mobile;
133
+ }),
134
+ );
135
+ const getActions = (location) =>
136
+ computed(() =>
137
+ getActionsByLocation(
138
+ mobileButtonComponents.value,
139
+ location,
140
+ [...app.plugins].map((p) => p.name),
141
+ ),
142
+ );
143
+
144
+ const { searchAction, destroy: destroySearchAction } =
145
+ createSearchButtonAction(app);
146
+
147
+ onUnmounted(() => {
148
+ destroySearchAction();
149
+ });
150
+
151
+ const fontSize = useFontSize();
152
+ const toolbarHeight = computed(() => {
153
+ return fontSize.value * 3 + 1;
154
+ });
155
+
156
+ const mobileMenuList = {
157
+ id: mobileMenuListId,
158
+ component: VcsMobileMenuList,
159
+ slot: WindowSlot.DYNAMIC_LEFT,
160
+ state: {
161
+ headerIcon: '$vcsMenu',
162
+ headerTitle: 'Menu',
163
+ },
164
+ };
165
+
166
+ const { action: mobileMenuAction } = createToggleAction(
167
+ {
168
+ name: 'mobileMenuAction',
169
+ title: 'mobileMenu.title',
170
+ icon: '$vcsMenu',
171
+ },
172
+ mobileMenuList,
173
+ app.windowManager,
174
+ vcsAppSymbol,
175
+ );
176
+
177
+ // only show the first two actions, rest handled in VcsMobileMenuList
178
+ const contentActions = computed(() => {
179
+ return getActions(ButtonLocation.CONTENT)?.value?.slice(0, 2);
180
+ });
181
+
182
+ const toolboxToggleAction = shallowRef(
183
+ app.navbarManager.get(toolboxComponentId)?.action,
184
+ );
185
+ const navbarManagerAddedListener =
186
+ app.navbarManager.added.addEventListener(({ id }) => {
187
+ if (id === toolboxComponentId) {
188
+ toolboxToggleAction.value =
189
+ app.navbarManager.get(toolboxComponentId).action;
190
+ }
191
+ });
192
+
193
+ onUnmounted(() => {
194
+ navbarManagerAddedListener();
195
+ });
196
+
197
+ return {
198
+ mobileMenuAction,
199
+ contentActions,
200
+ toolboxToggleAction,
201
+ searchAction,
202
+ toolbarHeight,
203
+ };
204
+ },
205
+ };
206
+ </script>
@@ -0,0 +1,42 @@
1
+ export const mobileMenuListId: "mobileMenuList";
2
+ declare const _default: import("vue").DefineComponent<{}, {
3
+ mobileMenuAction: import("../actions/actionHelper.js", { with: { "resolution-mode": "import" } }).VcsAction;
4
+ contentActions: import("vue").ComputedRef<import("../actions/actionHelper.js", { with: { "resolution-mode": "import" } }).VcsAction[]>;
5
+ toolboxToggleAction: import("vue").ShallowRef<any>;
6
+ searchAction: import("vue").Ref<{
7
+ /**
8
+ * - reactive and translatable name rendered in overflow
9
+ */
10
+ name: string;
11
+ /**
12
+ * - reactive and translatable title rendered as tooltip
13
+ */
14
+ title?: string | undefined;
15
+ /**
16
+ * - icon rendered on the button. If no icon provided, item is rendered in overflow
17
+ */
18
+ icon?: string | undefined;
19
+ /**
20
+ * - callback function is triggered when the button is clicked
21
+ */
22
+ callback: import("../actions/actionHelper.js", { with: { "resolution-mode": "import" } }).ActionCallback;
23
+ /**
24
+ * - optional state of button. If active, button is rendered in primary color
25
+ */
26
+ active?: boolean | undefined;
27
+ /**
28
+ * - optional hasUpdate of button. If true, a yellow notification is rendered next to the button
29
+ */
30
+ hasUpdate?: boolean | undefined;
31
+ /**
32
+ * - optional background state. If active and background, button is rendered in primary color outlined
33
+ */
34
+ background?: boolean | undefined;
35
+ /**
36
+ * - optional flag to indicate that the action is disabled
37
+ */
38
+ disabled?: boolean | undefined;
39
+ } | null>;
40
+ toolbarHeight: import("vue").ComputedRef<number>;
41
+ }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{}>>, {}, {}>;
42
+ export default _default;
@@ -4,6 +4,7 @@
4
4
  :class="{ active: positionDisplayAction.active }"
5
5
  >
6
6
  <VcsButton
7
+ :data-action-name="positionDisplayAction.name"
7
8
  :tooltip="positionDisplayAction.title"
8
9
  :icon="positionDisplayAction.icon"
9
10
  @click.stop="positionDisplayAction.callback($event)"
@@ -10,7 +10,7 @@
10
10
  class="vcs-splash-screen"
11
11
  >
12
12
  <v-card>
13
- <v-card-text>
13
+ <v-card-text class="pb-0 overflow-y-auto">
14
14
  <VcsMarkdown :content="$st(options.content)" />
15
15
  <VcsCheckbox v-if="options.acceptInput" v-model="checkBox">
16
16
  <template #label>
@@ -34,7 +34,7 @@
34
34
  </VcsCheckbox>
35
35
  </v-card-text>
36
36
 
37
- <v-card-actions>
37
+ <v-card-actions class="vcs-splash-screen-actions">
38
38
  <div class="d-flex gc-2 w-100 justify-end">
39
39
  <VcsFormButton
40
40
  v-if="
@@ -69,7 +69,12 @@
69
69
  import { computed, ref, inject } from 'vue';
70
70
  import { moduleIdSymbol } from '@vcmap/core';
71
71
  import { v5 as uuidv5 } from 'uuid';
72
- import { hideSplashScreenKey, setToLocalStorage } from '../localStorage.js';
72
+ import {
73
+ hideSplashScreenKey,
74
+ getFromLocalStorage,
75
+ removeFromLocalStorage,
76
+ setToLocalStorage,
77
+ } from '../localStorage.js';
73
78
  import { executeCallbacks } from '../callback/vcsCallback.js';
74
79
  import VcsFormButton from '../components/buttons/VcsFormButton.vue';
75
80
  import VcsCheckbox from '../components/form-inputs-controls/VcsCheckbox.vue';
@@ -89,6 +94,25 @@
89
94
  return uuidv5(string, uuidv5.URL);
90
95
  }
91
96
 
97
+ /**
98
+ * Whether the splash screen should be shown.
99
+ * @param {import("../vcsUiApp.js").default} app
100
+ * @returns {boolean} - true if the SplashScreenConfigHash of the local storage is different from the current SplashScreenConfigHash
101
+ */
102
+ export function shouldShowSplashSceen(app) {
103
+ if (app.uiConfig.config.splashScreen) {
104
+ const config = app.uiConfig.getByKey('splashScreen');
105
+ const hash = getSplashScreenHash(app);
106
+ const moduleId = config[moduleIdSymbol];
107
+ const storedHash = getFromLocalStorage(
108
+ `${name}_${moduleId}`,
109
+ hideSplashScreenKey,
110
+ );
111
+ return hash !== storedHash;
112
+ }
113
+ return false;
114
+ }
115
+
92
116
  export default {
93
117
  name: 'VcsSplashScreen',
94
118
  components: {
@@ -115,16 +139,20 @@
115
139
  const localValue = useProxiedAtomicModel(props, 'modelValue', emit);
116
140
 
117
141
  const checkBox = ref(false);
118
- const dontShowAgain = ref(false);
142
+ const dontShowAgain = ref(!shouldShowSplashSceen(app));
119
143
 
120
144
  function exitScreen() {
121
145
  localValue.value = false;
122
146
  checkBox.value = false;
123
- if (dontShowAgain.value) {
147
+ if (props.options.enableDontShowAgain) {
124
148
  const config = app.uiConfig.getByKey('splashScreen');
125
149
  const hash = getSplashScreenHash(app);
126
150
  const moduleId = config[moduleIdSymbol];
127
- setToLocalStorage(`${name}_${moduleId}`, hideSplashScreenKey, hash);
151
+ if (dontShowAgain.value) {
152
+ setToLocalStorage(`${name}_${moduleId}`, hideSplashScreenKey, hash);
153
+ } else {
154
+ removeFromLocalStorage(`${name}_${moduleId}`, hideSplashScreenKey);
155
+ }
128
156
  }
129
157
  if (Array.isArray(props.options.exitCallbackOptions)) {
130
158
  executeCallbacks(app, props.options.exitCallbackOptions);
@@ -139,7 +167,7 @@
139
167
 
140
168
  const position = computed(() => ({
141
169
  width: props.options.position?.width || 800,
142
- height: props.options.position?.height || 500,
170
+ height: props.options.position?.height,
143
171
  maxWidth: props.options.position?.maxWidth,
144
172
  maxHeight: props.options.position?.maxHeight,
145
173
  }));
@@ -165,4 +193,8 @@
165
193
  .v-input {
166
194
  margin-left: -5px !important;
167
195
  }
196
+ .vcs-splash-screen-actions {
197
+ position: sticky !important;
198
+ bottom: 0;
199
+ }
168
200
  </style>
@@ -3,6 +3,12 @@
3
3
  * @returns {Promise<string>} The hash of the SplashScreen config.
4
4
  */
5
5
  export function getSplashScreenHash(app: import("@vcmap/ui").VcsUiApp): Promise<string>;
6
+ /**
7
+ * Whether the splash screen should be shown.
8
+ * @param {import("../vcsUiApp.js").default} app
9
+ * @returns {boolean} - true if the SplashScreenConfigHash of the local storage is different from the current SplashScreenConfigHash
10
+ */
11
+ export function shouldShowSplashSceen(app: import("../vcsUiApp.js").default): boolean;
6
12
  declare const _default: import("vue").DefineComponent<{
7
13
  modelValue: {
8
14
  type: BooleanConstructor;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Creates a computed property for data protection configuration.
3
+ * @param {import("../uiConfig.js").UiConfigObject} uiConfig - The UI configuration object from the app.
4
+ * @returns {import('vue').ComputedRef<import('../uiConfig.js').TextPageType|undefined>}
5
+ */
6
+ export function getDataProtection(uiConfig: import("../uiConfig.js").UiConfigObject): import('vue').ComputedRef<import('../uiConfig.js').TextPageType | undefined>;
7
+ /**
8
+ * Creates a computed property for imprint configuration.
9
+ * @param {import("../uiConfig.js").UiConfigObject} uiConfig - The UI configuration object from the app.
10
+ * @returns {import('vue').ComputedRef<import('../uiConfig.js').TextPageType|undefined>}
11
+ */
12
+ export function getImprint(uiConfig: import("../uiConfig.js").UiConfigObject): import('vue').ComputedRef<import('../uiConfig.js').TextPageType | undefined>;
@@ -0,0 +1,37 @@
1
+ import { computed } from 'vue';
2
+
3
+ /**
4
+ * Creates a computed property for data protection configuration.
5
+ * @param {import("../uiConfig.js").UiConfigObject} uiConfig - The UI configuration object from the app.
6
+ * @returns {import('vue').ComputedRef<import('../uiConfig.js').TextPageType|undefined>}
7
+ */
8
+ export function getDataProtection(uiConfig) {
9
+ return computed(() => {
10
+ if (uiConfig?.dataProtection) {
11
+ return {
12
+ title: 'footer.dataProtection.title',
13
+ tooltip: 'footer.dataProtection.tooltip',
14
+ ...uiConfig.dataProtection,
15
+ };
16
+ }
17
+ return undefined;
18
+ });
19
+ }
20
+
21
+ /**
22
+ * Creates a computed property for imprint configuration.
23
+ * @param {import("../uiConfig.js").UiConfigObject} uiConfig - The UI configuration object from the app.
24
+ * @returns {import('vue').ComputedRef<import('../uiConfig.js').TextPageType|undefined>}
25
+ */
26
+ export function getImprint(uiConfig) {
27
+ return computed(() => {
28
+ if (uiConfig?.imprint) {
29
+ return {
30
+ title: 'footer.imprint.title',
31
+ tooltip: 'footer.imprint.tooltip',
32
+ ...uiConfig.imprint,
33
+ };
34
+ }
35
+ return undefined;
36
+ });
37
+ }
@@ -10,6 +10,7 @@
10
10
  class="d-flex"
11
11
  v-for="(btn, index) in buttons"
12
12
  :key="`${btn.name}-${index}`"
13
+ :data-action-name="btn.name"
13
14
  :tooltip="btn.title"
14
15
  :tooltip-position="tooltipPosition"
15
16
  :icon="btn.icon"
@@ -20,7 +20,11 @@
20
20
  :text="$st(tooltip)"
21
21
  :location="tooltipPosition"
22
22
  />
23
- <v-icon :size="iconSize" v-if="icon" :class="{ 'mr-2': hasDefaultSlot }">
23
+ <v-icon
24
+ :size="iconSize"
25
+ v-if="icon"
26
+ :class="{ 'mr-2': hasDefaultSlot && !xs }"
27
+ >
24
28
  {{ icon }}
25
29
  </v-icon>
26
30
  <VcsBadge
@@ -68,6 +72,7 @@
68
72
  <script>
69
73
  import { computed } from 'vue';
70
74
  import { VBtn, VIcon, VTooltip } from 'vuetify/components';
75
+ import { useDisplay } from 'vuetify';
71
76
  import VcsBadge from '../notification/VcsBadge.vue';
72
77
  import { getForwardSlots } from '../composables.js';
73
78
  import { useFontSize } from '../../vuePlugins/vuetify.js';
@@ -147,6 +152,7 @@
147
152
  return 'text';
148
153
  });
149
154
 
155
+ const { xs } = useDisplay();
150
156
  const fontSize = useFontSize();
151
157
  const itemHeight = computed(() => {
152
158
  return fontSize.value * 2 + 6;
@@ -162,6 +168,7 @@
162
168
  forwardSlots,
163
169
  buttonVariant,
164
170
  hasDefaultSlot,
171
+ xs,
165
172
  };
166
173
  },
167
174
  };
@@ -38,6 +38,7 @@ declare const _default: import("vue").DefineComponent<{
38
38
  forwardSlots: string[];
39
39
  buttonVariant: import("vue").ComputedRef<"flat" | "text">;
40
40
  hasDefaultSlot: import("vue").ComputedRef<boolean>;
41
+ xs: import("vue").Ref<boolean>;
41
42
  }, any, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
42
43
  active: {
43
44
  type: BooleanConstructor;
@@ -15,12 +15,14 @@
15
15
  v-model="localModelValue"
16
16
  >
17
17
  <template #selection="{ item, index }">
18
- <span v-if="index === 0" class="text-truncate w-100">
19
- {{ $st(getTitle(item.raw)) }}
20
- </span>
21
- <span v-if="index === 1" class="text-no-wrap">
22
- (+{{ additionalItems }})
23
- </span>
18
+ <slot name="selection" v-bind="{ item, index }">
19
+ <span v-if="index === 0" class="text-truncate w-100">
20
+ {{ $st(getTitle(item.raw)) }}
21
+ </span>
22
+ <span v-if="index === 1" class="text-no-wrap">
23
+ (+{{ additionalItems }})
24
+ </span>
25
+ </slot>
24
26
  </template>
25
27
 
26
28
  <template #append-inner="scope">
@@ -0,0 +1,43 @@
1
+ <script setup>
2
+ import { computed, inject } from 'vue';
3
+ import { renderTemplate } from '@vcmap/core';
4
+ import VcsMarkdown from './VcsMarkdown.vue';
5
+
6
+ const app = inject('vcsApp');
7
+
8
+ const props = defineProps({
9
+ /**
10
+ * The template to render to markdown.
11
+ */
12
+ template: {
13
+ type: String,
14
+ default: '',
15
+ },
16
+ /**
17
+ * The context to render the template with.
18
+ * The context will get augmented with the currentVcsAppLocale.
19
+ * Template re-renders on locale change and uses vue18n.t for translation.
20
+ */
21
+ context: {
22
+ type: Object,
23
+ default: () => ({}),
24
+ },
25
+ });
26
+
27
+ const content = computed(() => {
28
+ return renderTemplate(
29
+ props.template,
30
+ {
31
+ ...props.context,
32
+ currentVcsAppLocale: app.vueI18n.locale.value,
33
+ },
34
+ (key) => app.vueI18n.t(key),
35
+ );
36
+ });
37
+ </script>
38
+
39
+ <template>
40
+ <vcs-markdown :content="content" />
41
+ </template>
42
+
43
+ <style scoped lang="scss"></style>
@@ -0,0 +1,9 @@
1
+ declare const _default: import("vue").DefineComponent<{}, {
2
+ template: string;
3
+ context: Record<string, any>;
4
+ $props: {
5
+ readonly template?: string | undefined;
6
+ readonly context?: Record<string, any> | undefined;
7
+ };
8
+ }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{}>>, {}, {}>;
9
+ export default _default;
@@ -1,3 +1,8 @@
1
+ /**
2
+ * @param {string} color
3
+ * @returns {import("ol/style/Icon").Options}
4
+ */
5
+ export function getColoredMapIcon(color: string): import("ol/style/Icon").Options;
1
6
  export const IconIds: string[];
2
7
  export const IconNames: string[];
3
8
  export default Icons;
@@ -497,3 +497,17 @@ export const IconNames = Object.keys(Icons).map((name) => {
497
497
  return `$${name}`;
498
498
  });
499
499
  export default Icons;
500
+
501
+ /**
502
+ * @param {string} color
503
+ * @returns {import("ol/style/Icon").Options}
504
+ */
505
+ export function getColoredMapIcon(color) {
506
+ return {
507
+ src: `data:image/svg+xml,%3Csvg xmlns:dc='http://purl.org/dc/elements/1.1/' xmlns:cc='http://creativecommons.org/ns%23' xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns%23' xmlns:svg='http://www.w3.org/2000/svg' xmlns='http://www.w3.org/2000/svg' xmlns:sodipodi='http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd' xmlns:inkscape='http://www.inkscape.org/namespaces/inkscape' id='icon_24_poi' width='24' height='23.994' viewBox='0 0 24 23.994' sodipodi:docname='mapIcon.svg'%3E%3Cg id='Gruppe_1972' transform='translate(-571 -609.477)'%3E%3Cpath id='Pfad_773' d='M583,611a8.009,8.009,0,0,0-8,8c0,5.314,6.952,13.32,7.248,13.658a1,1,0,0,0,1.5,0c.3-.338,7.248-8.344,7.248-13.658A8.009,8.009,0,0,0,583,611Zm0,19.444c-2.18-2.685-6-8.09-6-11.444a6,6,0,0,1,12,0C589,622.354,585.18,627.759,583,630.444Z' fill='currentColor' /%3E%3Cpath id='Pfad_774' d='M583,615a4,4,0,1,0,4,4A4,4,0,0,0,583,615Zm0,6a2,2,0,1,1,2-2A2,2,0,0,1,583,621Z' fill='currentColor' /%3E%3C/g%3E%3Cpath fill='${encodeURIComponent(
508
+ color,
509
+ )}' d='M 11.672998,20.526286 C 8.5115524,16.526958 6.4310003,12.714969 6.0702695,10.260963 6.0109099,9.8571482 6.0115821,9.1201807 6.0716855,8.7084104 6.4424582,6.1682348 8.3335069,4.1603103 10.828528,3.6575721 c 1.904966,-0.383844 3.881822,0.1903514 5.289639,1.5364231 0.993092,0.9495349 1.610829,2.1488769 1.810148,3.5144152 0.0601,0.4117703 0.06077,1.1487378 0.0014,1.5525526 -0.357076,2.429138 -2.337816,6.081898 -5.487559,10.119822 -0.224045,0.287223 -0.415188,0.530536 -0.424763,0.540696 -0.0096,0.01016 -0.16456,-0.167678 -0.344411,-0.395195 z m 0.990366,-7.047968 c 0.894914,-0.146674 1.762065,-0.627065 2.349286,-1.301476 0.86707,-0.995812 1.194989,-2.3427819 0.880571,-3.6170541 -0.379849,-1.5394474 -1.596396,-2.6842781 -3.173401,-2.9863277 -0.368703,-0.070619 -1.070937,-0.070619 -1.43964,0 C 9.7056173,5.875042 8.48604,7.0227247 8.1067793,8.5597879 7.8410265,9.6368274 8.0329903,10.787029 8.6317551,11.705317 c 0.5717674,0.876885 1.4205679,1.474277 2.4457369,1.721329 0.47704,0.114961 1.079877,0.134602 1.585872,0.05167 z' id='path1432' /%3E%3C/svg%3E`,
510
+ scale: 1,
511
+ color,
512
+ };
513
+ }
@@ -2,6 +2,7 @@
2
2
  <v-list v-if="actions.length > 0" rounded class="vcs-action-list">
3
3
  <v-list-item
4
4
  v-for="(action, index) in actions"
5
+ :data-action-name="action.name"
5
6
  :key="`${action.name}-${index}`"
6
7
  :class="action.active ? 'text-primary' : ''"
7
8
  :disabled="action.disabled || disabled"
@@ -142,7 +142,7 @@
142
142
  </script>
143
143
 
144
144
  <template>
145
- <div>
145
+ <div class="vcs-grouped-list">
146
146
  <VcsTreeviewSearchbar
147
147
  v-if="searchable"
148
148
  :placeholder="searchbarPlaceholder"
@@ -156,6 +156,7 @@
156
156
  >
157
157
  <vcs-expansion-panel
158
158
  v-for="(group, i) in groups"
159
+ :data-group-name="group.name"
159
160
  :key="i"
160
161
  :value="group.name"
161
162
  :disabled="group.disabled"
@@ -93,6 +93,7 @@
93
93
  :disabled="item.disabled"
94
94
  v-bind="$attrs"
95
95
  class="vcs-list-item-component"
96
+ :data-list-item-name="item.name"
96
97
  >
97
98
  <template #prepend="scope">
98
99
  <slot name="prepend" v-bind="scope">
@@ -1,5 +1,9 @@
1
1
  <template>
2
- <div class="vcs-tree-node" v-if="matchFilter">
2
+ <div
3
+ class="vcs-tree-node"
4
+ v-if="matchFilter"
5
+ :data-tree-item-name="item.name"
6
+ >
3
7
  <v-row
4
8
  no-gutters
5
9
  class="treenode flex-nowrap text-truncate"
@@ -13,7 +17,12 @@
13
17
  @click="bubbleItemToggled(item.name)"
14
18
  />
15
19
  <slot name="prepend" v-bind="{ item }">
16
- <span class="prepend">
20
+ <span
21
+ class="prepend"
22
+ :class="{
23
+ 'text-disabled': item.disabled,
24
+ }"
25
+ >
17
26
  <div v-if="item.icon">
18
27
  <v-icon v-if="typeof item?.icon === 'string'" :size="iconSize">
19
28
  {{ item.icon }}