@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,108 +1,37 @@
1
1
  <template>
2
- <v-card>
3
- <VcsTreeviewSearchbar
4
- v-if="showSearchbar"
5
- :placeholder="$t(searchbarPlaceholder)"
6
- v-model="search"
7
- />
8
- <v-data-table
9
- dense
10
- item-key="key"
11
- :headers="translatedHeaders"
12
- :items="items"
13
- :items-per-page.sync="itemsPerPageRef"
14
- :page.sync="page"
15
- :search="search"
16
- :custom-filter="handleFilter"
17
- hide-default-footer
18
- class="vcs-table"
19
- >
20
- <!-- eslint-disable-next-line -->
21
- <template #item.key="{ item }">
22
- <td class="vcs-table px-2 overflow-max-width" :title="$t(item.key)">
23
- {{ $t(item.key) }}
24
- </td>
25
- </template>
26
- <!-- eslint-disable-next-line -->
27
- <template #item.value="{ item }">
28
- <td class="vcs-table px-2 overflow-max-width" :title="$t(item.value)">
2
+ <VcsDataTable
3
+ :items="items"
4
+ :headers="headers"
5
+ item-key="key"
6
+ v-bind="$attrs"
7
+ >
8
+ <!-- eslint-disable-next-line -->
9
+ <template #item.key="{ item }">
10
+ <td
11
+ :title="$t(item.key)"
12
+ class="vcs-table px-2 overflow-max-width rounded-0 noBorder"
13
+ :style="{'max-width': headers[0].width }"
14
+ >
15
+ {{ $t(item.key) }}
16
+ </td>
17
+ </template>
18
+ <!-- eslint-disable-next-line -->
19
+ <template #item.value="{ item }">
20
+ <td
21
+ :title="$t(item.value)"
22
+ class="vcs-table px-2 overflow-max-width rounded-0 noBorder"
23
+ :style="{'max-width': headers[1].width }"
24
+ >
25
+ <span :class="{ 'single-line': !/\s/.test(item.value), 'multi-line': /\s/.test(item.value), }">
29
26
  {{ $t(item.value) }}
30
- </td>
31
- </template>
32
- <template #footer>
33
- <v-divider />
34
- <v-container class="pa-2 vcs-pagination-bar accent" v-if="items.length > itemsPerPageRef">
35
- <v-row
36
- dense
37
- no-gutters
38
- align="center"
39
- justify="center"
40
- >
41
- <v-menu offset-y dense>
42
- <template #activator="{ on, attrs }">
43
- <VcsButton
44
- small
45
- color="primary"
46
- v-bind="attrs"
47
- v-on="on"
48
- >
49
- {{ itemsPerPageRef }}
50
- <v-icon>mdi-chevron-down</v-icon>
51
- </VcsButton>
52
- </template>
53
- <v-list>
54
- <v-list-item
55
- v-for="(number, index) in itemsPerPageArray"
56
- :key="index"
57
- @click="updateItemsPerPage(number)"
58
- style="min-height: auto; height: 24px; text-align: right;"
59
- >
60
- <v-list-item-title>{{ number }}</v-list-item-title>
61
- </v-list-item>
62
- </v-list>
63
- </v-menu>
64
- <span class="mx-2">{{ $t('components.vcsTable.itemsPerPage') }}</span>
65
- <span class="mx-2">
66
- {{ itemsFrom }} - {{ itemsTo }} {{ $t('components.vcsTable.ofItems') }} {{ numberOfItems }}
67
- </span>
68
- <VcsButton
69
- small
70
- icon="mdi-chevron-left"
71
- @click="formerPage"
72
- tooltip="components.vcsTable.formerPage"
73
- :disabled="page < 2"
74
- class="ml-1"
75
- />
76
- <VcsButton
77
- small
78
- icon="mdi-chevron-right"
79
- @click="nextPage"
80
- tooltip="components.vcsTable.nextPage"
81
- :disabled="page > numberOfPages - 1"
82
- class="ml-1"
83
- />
84
- </v-row>
85
- </v-container>
86
- </template>
87
- </v-data-table>
88
- </v-card>
27
+ </span>
28
+ </td>
29
+ </template>
30
+ </VcsDataTable>
89
31
  </template>
90
32
  <script>
91
- import { getCurrentInstance, ref, computed } from 'vue';
92
- import {
93
- VCard,
94
- VDivider,
95
- VContainer,
96
- VDataTable,
97
- VList,
98
- VListItem,
99
- VListItemTitle,
100
- VMenu,
101
- VIcon,
102
- VRow,
103
- } from 'vuetify/lib';
104
- import VcsTreeviewSearchbar from '../lists/VcsTreeviewSearchbar.vue';
105
- import VcsButton from '../buttons/VcsButton.vue';
33
+ import { computed } from 'vue';
34
+ import VcsDataTable from './VcsDataTable.vue';
106
35
 
107
36
  /**
108
37
  * @typedef {Object} TableItem
@@ -131,34 +60,16 @@
131
60
  }
132
61
 
133
62
  /**
134
- * @description A table view for feature attributes using {@link https://vuetifyjs.com/en/api/v-data-table/#props v-data-table }
63
+ * @description A table view for feature attributes using VcsDataTable
135
64
  * @vue-prop {string} featureId - feature's id
136
65
  * @vue-prop {Object} attributes - feature's attributes
137
66
  * @vue-prop {Array<{text: string, value: string}>} [headers] - optional array defining column names
138
- * @vue-prop {boolean} [showSearchbar=true] - whether to show searchbar
139
- * @vue-prop {string} [searchbarPlaceholder='Search'] - placeholder for searchbar
140
67
  * @vue-computed {Array<TableItem>} items - from attributes derived table items
141
- * @vue-computed {Array<TableItem>} filteredItems - array of items with search filter applied on. If search string is empty, same as items array.
142
- * @vue-computed {number} numberOfItems - number of filtered items (depending on search).
143
- * @vue-computed {number} numberOfPages - number of pages depending on number of items, search and itemsPerPage.
144
- * @vue-computed {number} itemsFrom - index of first item shown on current page.
145
- * @vue-computed {number} itemsTo - index of last item shown on current page.
146
68
  */
147
69
  export default {
148
70
  name: 'VcsTable',
149
71
  components: {
150
- VcsButton,
151
- VcsTreeviewSearchbar,
152
- VCard,
153
- VDataTable,
154
- VContainer,
155
- VDivider,
156
- VRow,
157
- VMenu,
158
- VIcon,
159
- VList,
160
- VListItem,
161
- VListItemTitle,
72
+ VcsDataTable,
162
73
  },
163
74
  props: {
164
75
  featureId: {
@@ -176,29 +87,8 @@
176
87
  { text: 'components.vcsTable.value', value: 'value', width: '160px' },
177
88
  ],
178
89
  },
179
- itemsPerPage: {
180
- type: Number,
181
- default: 10,
182
- },
183
- itemsPerPageArray: {
184
- type: Array,
185
- default: () => [5, 10, 15],
186
- },
187
- showSearchbar: {
188
- type: Boolean,
189
- default: true,
190
- },
191
- searchbarPlaceholder: {
192
- type: String,
193
- default: 'components.vcsTable.searchbarPlaceholder',
194
- },
195
90
  },
196
91
  setup(props) {
197
- const vm = getCurrentInstance().proxy;
198
- /**
199
- * @type {Ref<UnwrapRef<string>>}
200
- */
201
- const search = ref('');
202
92
  /**
203
93
  * @type {ComputedRef<Array<TableItem>>}
204
94
  */
@@ -209,128 +99,39 @@
209
99
  });
210
100
  });
211
101
 
212
- /**
213
- * @param {any} value
214
- * @param {string|undefined} filter
215
- * @param {TableItem} item
216
- * @returns {boolean}
217
- */
218
- const handleFilter = (value, filter, item) => {
219
- if (filter) {
220
- const q = filter.toLocaleLowerCase();
221
- return [item.key, item.value].some((i) => {
222
- const content = i.toString();
223
- const translated = vm.$t(content);
224
- return translated.toLowerCase().includes(q) || content.toLowerCase().includes(q);
225
- });
226
- }
227
- return true;
228
- };
229
-
230
- /**
231
- * @type {ComputedRef<TableItem[]>}
232
- */
233
- const filteredItems = computed(() => items.value.filter(item => handleFilter(item.value, search.value, item)));
234
- const numberOfItems = computed(() => filteredItems.value.length);
235
-
236
- /**
237
- * @type {ComputedRef<Array<{text: string, value: string}>>}
238
- */
239
- const translatedHeaders = computed(() => {
240
- return props.headers.map((hd) => {
241
- hd.text = vm.$t(hd.text);
242
- return hd;
243
- });
244
- });
245
-
246
- /**
247
- * @type {Ref<UnwrapRef<number>>}
248
- */
249
- const itemsPerPageRef = ref(props.itemsPerPage);
250
- const numberOfPages = computed(() => {
251
- return Math.ceil(numberOfItems.value / itemsPerPageRef.value);
252
- });
253
- /**
254
- * @type {Ref<UnwrapRef<number>>}
255
- */
256
- const page = ref(1);
257
- const itemsFrom = computed(() => ((page.value - 1) * itemsPerPageRef.value) + 1);
258
- const itemsTo = computed(() => {
259
- const last = page.value * itemsPerPageRef.value;
260
- return last < numberOfItems.value ? last : numberOfItems.value;
261
- });
262
-
263
102
  return {
264
- search,
265
- page,
266
103
  items,
267
- filteredItems,
268
- itemsPerPageRef,
269
- itemsFrom,
270
- itemsTo,
271
- numberOfPages,
272
- numberOfItems,
273
- nextPage() {
274
- if (page.value + 1 <= numberOfPages.value) {
275
- page.value += 1;
276
- }
277
- },
278
- formerPage() {
279
- if (page.value - 1 >= 1) {
280
- page.value -= 1;
281
- }
282
- },
283
- updateItemsPerPage(number) {
284
- itemsPerPageRef.value = number;
285
- },
286
- handleFilter,
287
- translatedHeaders,
288
104
  };
289
105
  },
290
106
  };
291
107
  </script>
292
108
 
293
109
  <style lang="scss" scoped>
294
- ::v-deep{
295
- .vcs-table {
296
- td {
297
- overflow: hidden;
298
- text-overflow: ellipsis;
299
- white-space: nowrap;
300
- &.overflow-max-width{
301
- max-width: 160px;
302
- }
303
- &.v-data-table__mobile-row{
304
- justify-content: left;
305
- height: 27px;
306
- min-height: auto;
307
- }
308
- }
309
- th.sortable{
310
- padding: 0 8px;
311
- span{
312
- vertical-align: middle;
313
- padding: 0 4px 0 0;
314
- }
315
- }
316
- }
317
- .v-data-table__mobile-row__cell{
318
- td.vcs-table.overflow-max-width{
110
+
111
+ .single-line {
112
+ display: block;
113
+ white-space: nowrap;
114
+ overflow: hidden;
115
+ text-overflow: ellipsis;
116
+ }
117
+ .multi-line {
118
+ display: -webkit-box;
119
+ -webkit-box-orient: vertical;
120
+ -webkit-line-clamp: 3;
121
+ overflow: hidden;
122
+ height: auto;
123
+ max-height: 96px;
124
+ }
125
+
126
+ .noBorder {
127
+ border-bottom: none !important;
128
+ }
129
+
130
+ ::v-deep {
131
+ .v-data-table__mobile-row__cell {
132
+ td.vcs-table.overflow-max-width {
319
133
  max-width: 260px;
320
134
  }
321
135
  }
322
- .v-btn.vcs-button--small{
323
- height: 100% !important;
324
- display: block;
325
- }
326
- }
327
- .vcs-pagination-bar{
328
- .vcs-button-wrap{
329
- height: 25px;
330
- border: 1px solid lightgrey;
331
- padding: 0 4px;
332
- background-color: var(--v-basic-base);
333
- border-radius: 4px;
334
- }
335
136
  }
336
137
  </style>
@@ -306,7 +306,7 @@ export function createContentTreeCollection(app) {
306
306
 
307
307
  const overrideCollection = makeOverrideCollection(
308
308
  collection,
309
- () => app.dynamicContextId,
309
+ () => app.dynamicModuleId,
310
310
  null,
311
311
  config => getObjectFromClassRegistry(app.contentTreeClassRegistry, config, app),
312
312
  ContentTreeItem,
@@ -122,6 +122,9 @@ class LayerContentTreeItem extends VcsObjectContentTreeItem {
122
122
  },
123
123
  {
124
124
  component,
125
+ position: {
126
+ width: 200,
127
+ },
125
128
  props: reactive({
126
129
  availableStyles: availableStyles.slice(),
127
130
  layerName: this._layerName,
@@ -0,0 +1,49 @@
1
+ import { hasSameOrigin } from '@vcmap/core';
2
+
3
+ /**
4
+ * Download a blob
5
+ * @param {string} uri
6
+ * @param {string} fileName
7
+ * @api
8
+ * @export
9
+ */
10
+ export function downloadURI(uri, fileName) {
11
+ const link = document.createElement('a');
12
+ link.download = fileName;
13
+ link.href = uri;
14
+ if (!hasSameOrigin(uri)) {
15
+ link.target = '_blank';
16
+ }
17
+ link.click();
18
+ link.remove();
19
+ }
20
+
21
+ /**
22
+ * Download a blob
23
+ * @param {Blob} blob
24
+ * @param {string} fileName
25
+ */
26
+ export function downloadBlob(blob, fileName) {
27
+ downloadURI(URL.createObjectURL(blob), fileName);
28
+ }
29
+
30
+ /**
31
+ * Download a text as UTF-8
32
+ * @param {string} text
33
+ * @param {string} fileName
34
+ */
35
+ export function downloadText(text, fileName) {
36
+ downloadURI(`data:text/plain;charset=utf-8,${encodeURIComponent(text)}`, fileName);
37
+ }
38
+
39
+ /**
40
+ * Download a canvas as an image
41
+ * @param {HTMLCanvasElement} canvas
42
+ * @param {string} fileName
43
+ * @param {string=} mimeType
44
+ */
45
+ export function downloadCanvas(canvas, fileName, mimeType) {
46
+ canvas.toBlob((blob) => {
47
+ downloadBlob(blob, fileName);
48
+ }, mimeType);
49
+ }
@@ -8,7 +8,7 @@
8
8
  tile
9
9
  size="40"
10
10
  >
11
- <v-icon size="20" color="secondary">
11
+ <v-icon size="20">
12
12
  $vcsHomePoint
13
13
  </v-icon>
14
14
  </v-list-item-avatar>
@@ -1,23 +1,25 @@
1
1
  <template>
2
2
  <v-card
3
- class="mx-auto mb-1 elevation-0"
3
+ class="mx-auto elevation-0"
4
4
  max-width="400"
5
5
  v-if="position"
6
6
  >
7
7
  <slot name="balloon-header" :attrs="{...$props, ...$attrs}">
8
- <v-list-item class="px-2 pr-1 align-start">
8
+ <v-list-item class="px-2 align-center">
9
9
  <v-list-item-avatar
10
10
  tile
11
- size="20"
12
- class="mr-2 align-self-start"
11
+ size="16"
12
+ class="mr-2"
13
13
  >
14
14
  <v-icon color="primary">
15
15
  $vcsInfo
16
16
  </v-icon>
17
17
  </v-list-item-avatar>
18
- <v-list-item-content class="py-2 pr-1 align-self-start">
19
- <v-list-item-title class="text-h6">
20
- {{ $t(balloonTitle) }}
18
+ <v-list-item-content class="pr-1">
19
+ <v-list-item-title>
20
+ <h3 class="font-weight-bold">
21
+ {{ $t(balloonTitle) }}
22
+ </h3>
21
23
  </v-list-item-title>
22
24
  <v-list-item-subtitle v-if="balloonSubtitle">
23
25
  {{ $t(balloonSubtitle) }}
@@ -28,15 +30,16 @@
28
30
  small
29
31
  icon="mdi-close-thick"
30
32
  tooltip="components.close"
33
+ class="d-flex"
31
34
  />
32
35
  </v-list-item>
33
36
  </slot>
34
37
 
35
38
  <v-divider />
36
39
 
37
- <v-card class="overflow-y-auto py-2 elevation-0" max-height="250">
40
+ <v-card class="overflow-y-auto py-2 elevation-0" max-height="250" color="transparent">
38
41
  <slot :attrs="{...$props, ...$attrs}">
39
- <v-list v-for="(value, name, index) in attributes" :key="`attribute-${index}`">
42
+ <v-list v-for="(value, name, index) in attributes" :key="`attribute-${index}`" color="transparent">
40
43
  <v-list-item class="px-2">
41
44
  <v-list-item-content>
42
45
  <v-list-item-title>
@@ -150,6 +153,8 @@
150
153
  </script>
151
154
 
152
155
  <style lang="scss">
156
+ @import '../styles/shades.scss';
157
+
153
158
  .balloon {
154
159
  z-index: 0 !important;
155
160
  }
@@ -159,18 +164,19 @@
159
164
  .balloon:after {
160
165
  content: "";
161
166
  position: absolute;
162
- bottom: -20px;
167
+ bottom: -12px;
163
168
  left: 40px;
164
- border-width: 20px 20px 0;
169
+ border-width: 12px 10px 0;
165
170
  border-style: solid;
166
171
  display: block;
167
172
  width: 0;
173
+ filter: drop-shadow(1px 2px 1px rgba(0, 0, 0, 0.3));
168
174
  }
169
- .v-sheet.theme--light.balloon:after{
170
- border-color: #FFFFFF transparent;
175
+ .theme--light .balloon:after {
176
+ border-color: map-get($shades, 'white') transparent;
171
177
  }
172
- .v-sheet.theme--dark.balloon:after{
173
- border-color: #1E1E1E transparent;
178
+ .theme--dark .balloon:after {
179
+ border-color: map-get($shades, 'black') transparent;
174
180
  }
175
181
  .balloon .v-list-item .v-list-item__title,
176
182
  .balloon .v-list-item .v-list-item__subtitle {
@@ -217,7 +217,7 @@ class AbstractFeatureInfoView extends VcsObject {
217
217
  }
218
218
 
219
219
  /**
220
- * window options, configured in a context, used only internally by AbstractFeatureInfoView or subclass
220
+ * window options, configured in a module, used only internally by AbstractFeatureInfoView or subclass
221
221
  * @type {WindowComponentOptions|Object}
222
222
  * @readonly
223
223
  */
@@ -33,7 +33,7 @@ import TableFeatureInfoView from './tableFeatureInfoView.js';
33
33
  import IframeFeatureInfoView from './iframeFeatureInfoView.js';
34
34
  import AddressBalloonFeatureInfoView from './addressBalloonFeatureInfoView.js';
35
35
  import BalloonFeatureInfoView from './balloonFeatureInfoView.js';
36
- import { defaultPrimaryColor } from '../vuePlugins/vuetify.js';
36
+ import { getDefaultPrimaryColor } from '../vuePlugins/vuetify.js';
37
37
  import { ToolboxType } from '../manager/toolbox/toolboxManager.js';
38
38
 
39
39
  /** @typedef {import("ol").Feature<import("ol/geom/Geometry").default>|import("@vcmap-cesium/engine").Cesium3DTileFeature|import("@vcmap-cesium/engine").Cesium3DTilePointFeature|import("@vcmap-cesium/engine").Entity} FeatureType */
@@ -126,6 +126,7 @@ export function createFeatureInfoSession(app) {
126
126
 
127
127
  /**
128
128
  * @param {VcsUiApp} app
129
+ * @returns {function():void}
129
130
  */
130
131
  function setupFeatureInfoTool(app) {
131
132
  /** @type {FeatureInfoSession|null} */
@@ -153,6 +154,9 @@ function setupFeatureInfoTool(app) {
153
154
  },
154
155
  };
155
156
 
157
+ if (app.uiConfig.getByKey('startingFeatureInfo')?.value !== false) {
158
+ action.callback();
159
+ }
156
160
  app.toolboxManager.add(
157
161
  {
158
162
  id: 'featureInfo',
@@ -161,6 +165,13 @@ function setupFeatureInfoTool(app) {
161
165
  },
162
166
  vcsAppSymbol,
163
167
  );
168
+
169
+ return () => {
170
+ if (session) {
171
+ session.stop();
172
+ }
173
+ app.toolboxManager.remove('featureInfo');
174
+ };
164
175
  }
165
176
 
166
177
  /**
@@ -200,7 +211,7 @@ class FeatureInfo {
200
211
  */
201
212
  this._collection = makeOverrideCollection(
202
213
  new Collection(),
203
- () => this._app.dynamicContextId,
214
+ () => this._app.dynamicModuleId,
204
215
  null,
205
216
  config => getObjectFromClassRegistry(this._featureInfoClassRegistry, config),
206
217
  AbstractFeatureInfoView,
@@ -266,8 +277,12 @@ class FeatureInfo {
266
277
  this.clear();
267
278
  }
268
279
  }),
269
- this._app.contextAdded.addEventListener(() => this.clear()),
270
- this._app.contextRemoved.addEventListener(() => this.clear()),
280
+ this._app.moduleAdded.addEventListener(() => {
281
+ this.clear();
282
+ this._destroyFeatureInfoTool();
283
+ this._destroyFeatureInfoTool = setupFeatureInfoTool(this._app);
284
+ }),
285
+ this._app.moduleRemoved.addEventListener(() => this.clear()),
271
286
  ];
272
287
  /**
273
288
  * A vector layer to render provided features on
@@ -275,8 +290,11 @@ class FeatureInfo {
275
290
  * @private
276
291
  */
277
292
  this._scratchLayer = null;
278
-
279
- setupFeatureInfoTool(this._app);
293
+ /**
294
+ * @type {function():void}
295
+ * @private
296
+ */
297
+ this._destroyFeatureInfoTool = setupFeatureInfoTool(this._app);
280
298
  }
281
299
 
282
300
  /**
@@ -386,7 +404,7 @@ class FeatureInfo {
386
404
  [featureId]: getHighlightStyle(
387
405
  feature,
388
406
  layer,
389
- this._app.uiConfig.config.value.primaryColor ?? defaultPrimaryColor,
407
+ this._app.uiConfig.config.value.primaryColor ?? getDefaultPrimaryColor(),
390
408
  ),
391
409
  });
392
410
  this._clearHighlightingCb = () => this._scratchLayer.featureVisibility.unHighlight([featureId]);
@@ -396,7 +414,7 @@ class FeatureInfo {
396
414
  [featureId]: getHighlightStyle(
397
415
  feature,
398
416
  layer,
399
- this._app.uiConfig.config.value.primaryColor ?? defaultPrimaryColor,
417
+ this._app.uiConfig.config.value.primaryColor ?? getDefaultPrimaryColor(),
400
418
  ),
401
419
  });
402
420
  this._clearHighlightingCb = () => layer.featureVisibility.unHighlight([featureId]);
@@ -458,7 +476,7 @@ class FeatureInfo {
458
476
  destroy() {
459
477
  this._clearInternal();
460
478
  this._featureChanged.destroy();
461
- this._app.toolboxManager.remove('featureInfo');
479
+ this._destroyFeatureInfoTool();
462
480
  if (this._scratchLayer) {
463
481
  this._app.layers.remove(this._scratchLayer);
464
482
  this._scratchLayer.destroy();
@@ -77,6 +77,10 @@ class TableFeatureInfoView extends AbstractFeatureInfoView {
77
77
  itemsPerPageArray: this.itemsPerPageArray,
78
78
  showSearchbar: this.showSearchbar,
79
79
  searchbarPlaceholder: this.searchbarPlaceholder,
80
+ headers: [
81
+ { text: 'components.vcsTable.key', value: 'key', width: '128px' },
82
+ { text: 'components.vcsTable.value', value: 'value', width: '192px' },
83
+ ],
80
84
  };
81
85
  }
82
86