@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.
- package/README.md +2 -2
- package/app.config.json +5 -0
- package/build/buildHelpers.js +1 -0
- package/build/buildPreview.js +2 -2
- package/build/commonViteConfig.js +1 -0
- package/config/aerowest.config.json +2 -0
- package/config/base.config.json +1 -0
- package/config/codes.config.json +2 -0
- package/config/dev.config.json +6 -0
- package/config/graphFeatureInfo.config.json +3 -1
- package/config/projects.config.json +27 -0
- package/config/www.config.json +27 -14
- package/dist/assets/cesium.js +1 -1
- package/dist/assets/{core.59d4d1.js → core.9342a1.js} +7912 -5474
- package/dist/assets/core.js +1 -1
- package/dist/assets/favicon.decf54cc.svg +10 -0
- package/dist/assets/index.fd041928.js +1 -0
- package/dist/assets/{ol.c1c512.js → ol.d2cba3.js} +12406 -12152
- package/dist/assets/ol.js +1 -1
- package/dist/assets/ui.c27597.css +5 -0
- package/dist/assets/{ui.80175f.js → ui.c27597.js} +6508 -5169
- package/dist/assets/ui.js +1 -1
- package/dist/assets/vue.js +2 -2
- package/dist/assets/vuetify.2f1432.css +5 -0
- package/dist/assets/{vuetify.efc158.js → vuetify.2f1432.js} +1 -1
- package/dist/assets/vuetify.js +2 -2
- package/dist/index.html +6 -1
- package/index.html +5 -0
- package/index.js +7 -3
- package/lib/olLib.js +15 -1
- package/package.json +5 -4
- package/plugins/@vcmap/project-selector/{ContextsListComponent.vue → ModulesListComponent.vue} +10 -10
- package/plugins/@vcmap/project-selector/ProjectSelectorComponent.vue +16 -16
- package/plugins/@vcmap/project-selector/README.md +15 -21
- package/plugins/@vcmap/project-selector/config.json +3 -3
- package/plugins/@vcmap/project-selector/de.json +3 -0
- package/plugins/@vcmap/project-selector/en.json +3 -0
- package/plugins/@vcmap/project-selector/index.js +76 -101
- package/plugins/@vcmap/simple-graph/index.js +1 -1
- package/plugins/@vcmap/theme-changer/ThemeChangerComponent.vue +10 -4
- package/plugins/@vcmap-show-case/category-tester/Categories.vue +2 -2
- package/plugins/@vcmap-show-case/category-tester/Category.vue +1 -4
- package/plugins/@vcmap-show-case/config-editor/editor.vue +14 -14
- package/plugins/@vcmap-show-case/form-inputs-example/FormInputsExample.vue +92 -81
- package/plugins/@vcmap-show-case/form-inputs-example/index.js +8 -3
- package/plugins/@vcmap-show-case/form-inputs-example/validation.js +1 -1
- package/plugins/@vcmap-show-case/list-example/ListExample.vue +5 -2
- package/plugins/@vcmap-show-case/table-example/DataTableExample.vue +202 -0
- package/plugins/@vcmap-show-case/table-example/README.md +3 -0
- package/plugins/@vcmap-show-case/table-example/index.js +47 -0
- package/plugins/@vcmap-show-case/table-example/package.json +5 -0
- package/plugins/@vcmap-show-case/wizard-example/wizardExample.vue +57 -23
- package/plugins/package.json +2 -1
- package/src/actions/actionHelper.js +16 -27
- package/src/actions/styleSelector.vue +26 -19
- package/src/application/VcsApp.vue +13 -5
- package/src/application/VcsAttributions.vue +2 -3
- package/src/application/VcsAttributionsFooter.vue +10 -16
- package/src/application/VcsNavbar.vue +1 -2
- package/src/application/VcsSettings.vue +21 -8
- package/src/assets/favicon-128.png +0 -0
- package/src/assets/favicon-180.png +0 -0
- package/src/assets/favicon-192.png +0 -0
- package/src/assets/favicon-32.png +0 -0
- package/src/assets/favicon.svg +10 -0
- package/src/components/buttons/VcsButton.vue +2 -3
- package/src/components/form-inputs-controls/VcsCheckbox.vue +46 -26
- package/src/components/form-inputs-controls/VcsDatePicker.vue +111 -0
- package/src/components/form-inputs-controls/VcsFormSection.vue +15 -13
- package/src/components/form-inputs-controls/VcsLabel.vue +10 -1
- package/src/components/form-inputs-controls/VcsRadio.vue +38 -18
- package/src/components/form-inputs-controls/VcsSelect.vue +117 -59
- package/src/components/form-inputs-controls/VcsTextArea.vue +101 -60
- package/src/components/form-inputs-controls/VcsTextField.vue +182 -69
- package/src/components/form-inputs-controls/VcsWizard.vue +23 -15
- package/src/components/form-inputs-controls/VcsWizardStep.vue +18 -16
- package/src/components/form-inputs-controls/composables.js +26 -0
- package/src/components/form-output/VcsFormattedNumber.vue +1 -1
- package/src/components/icons/2DDistanceIcon.vue +0 -3
- package/src/components/icons/3DDistanceIcon.vue +0 -3
- package/src/components/icons/3DHeightIcon.vue +0 -3
- package/src/components/icons/CheckboxCheckedIcon.vue +4 -11
- package/src/components/icons/CheckboxIcon.vue +9 -2
- package/src/components/icons/CheckboxIndeterminateIcon.vue +4 -21
- package/src/components/icons/CommentIcon.vue +1 -5
- package/src/components/icons/LegendIcon.vue +10 -60
- package/src/components/icons/ObliqueViewIcon.vue +6 -8
- package/src/components/icons/SimpleCircleOutlinedIcon.vue +1 -1
- package/src/components/icons/SplitViewIcon.vue +0 -4
- package/src/components/icons/ToolsIcon.vue +2 -4
- package/src/components/lists/VcsActionList.vue +0 -1
- package/src/components/lists/VcsList.vue +30 -30
- package/src/components/lists/VcsTreeview.vue +2 -2
- package/src/components/lists/VcsTreeviewLeaf.vue +3 -9
- package/src/components/lists/VcsTreeviewSearchbar.vue +4 -4
- package/src/components/notification/VcsBadge.vue +6 -2
- package/src/components/notification/VcsHelp.vue +39 -0
- package/src/components/tables/VcsDataTable.vue +386 -0
- package/src/components/tables/VcsTable.vue +55 -254
- package/src/contentTree/contentTreeCollection.js +1 -1
- package/src/contentTree/layerContentTreeItem.js +3 -0
- package/src/downloadHelper.js +49 -0
- package/src/featureInfo/AddressBalloonComponent.vue +1 -1
- package/src/featureInfo/BalloonComponent.vue +21 -15
- package/src/featureInfo/abstractFeatureInfoView.js +1 -1
- package/src/featureInfo/featureInfo.js +27 -9
- package/src/featureInfo/tableFeatureInfoView.js +4 -0
- package/src/i18n/de.js +13 -1
- package/src/i18n/en.js +13 -1
- package/src/i18n/i18nCollection.js +22 -22
- package/src/init.js +90 -7
- package/src/legend/styleLegendItem.vue +24 -2
- package/src/legend/vcsLegend.vue +24 -31
- package/src/manager/categoryManager/CategoryComponent.vue +56 -47
- package/src/manager/categoryManager/CategoryManager.vue +23 -10
- package/src/manager/categoryManager/categoryManager.js +11 -11
- package/src/manager/navbarManager.js +18 -0
- package/src/manager/toolbox/GroupToolboxComponent.vue +2 -3
- package/src/manager/toolbox/SelectToolboxComponent.vue +11 -5
- package/src/manager/toolbox/ToolboxManager.vue +0 -7
- package/src/manager/window/WindowComponent.vue +10 -16
- package/src/manager/window/WindowComponentHeader.vue +6 -4
- package/src/manager/window/WindowManager.vue +14 -15
- package/src/manager/window/windowHelper.js +1 -1
- package/src/manager/window/windowManager.js +18 -7
- package/src/navigation/mapNavCompass.vue +1 -1
- package/src/navigation/mapNavigation.vue +6 -6
- package/src/navigation/obliqueRotation.vue +36 -13
- package/src/navigation/orientationToolsButton.vue +0 -1
- package/src/navigation/overviewMap.js +11 -20
- package/src/navigation/tiltSlider.vue +30 -6
- package/src/navigation/vcsZoomButton.vue +37 -11
- package/src/pluginHelper.js +20 -0
- package/src/search/resultsComponent.vue +0 -1
- package/src/search/search.js +19 -20
- package/src/search/searchComponent.vue +21 -7
- package/src/state.js +6 -6
- package/src/styles/_theming.scss +72 -3
- package/src/styles/_typography.scss +0 -5
- package/src/styles/main.scss +1 -0
- package/src/styles/shades.scss +2 -0
- package/src/styles/variables.scss +40 -4
- package/src/uiConfig.js +4 -3
- package/src/vcsUiApp.js +49 -40
- package/src/vuePlugins/i18n.js +1 -0
- package/src/vuePlugins/vuetify.js +59 -13
- package/start.js +8 -2
- package/dist/assets/index.a3861d4e.js +0 -1
- package/dist/assets/ui.80175f.css +0 -1
- package/dist/assets/vuetify.efc158.css +0 -5
- package/map.config.json +0 -44
- /package/dist/assets/{cesium.49585c.js → cesium.166f91.js} +0 -0
- /package/dist/assets/{vue.a08ab1.js → vue.5d00e9.js} +0 -0
@@ -1,108 +1,37 @@
|
|
1
1
|
<template>
|
2
|
-
<
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
>
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
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
|
-
</
|
31
|
-
</
|
32
|
-
|
33
|
-
|
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 {
|
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
|
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
|
-
|
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
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
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.
|
309
|
+
() => app.dynamicModuleId,
|
310
310
|
null,
|
311
311
|
config => getObjectFromClassRegistry(app.contentTreeClassRegistry, config, app),
|
312
312
|
ContentTreeItem,
|
@@ -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
|
+
}
|
@@ -1,23 +1,25 @@
|
|
1
1
|
<template>
|
2
2
|
<v-card
|
3
|
-
class="mx-auto
|
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
|
8
|
+
<v-list-item class="px-2 align-center">
|
9
9
|
<v-list-item-avatar
|
10
10
|
tile
|
11
|
-
size="
|
12
|
-
class="mr-2
|
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="
|
19
|
-
<v-list-item-title
|
20
|
-
|
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: -
|
167
|
+
bottom: -12px;
|
163
168
|
left: 40px;
|
164
|
-
border-width:
|
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
|
-
.
|
170
|
-
border-color:
|
175
|
+
.theme--light .balloon:after {
|
176
|
+
border-color: map-get($shades, 'white') transparent;
|
171
177
|
}
|
172
|
-
.
|
173
|
-
border-color:
|
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
|
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 {
|
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.
|
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.
|
270
|
-
|
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
|
-
|
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 ??
|
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 ??
|
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.
|
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
|
|