@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
package/src/i18n/de.js
CHANGED
@@ -55,18 +55,26 @@ const messages = {
|
|
55
55
|
vcsTable: {
|
56
56
|
key: 'Name',
|
57
57
|
value: 'Wert',
|
58
|
+
},
|
59
|
+
vcsDataTable: {
|
58
60
|
searchbarPlaceholder: 'Name, Wert, ...',
|
59
61
|
itemsPerPage: 'pro Seite',
|
60
62
|
ofItems: 'von',
|
61
63
|
nextPage: 'Nächste Seite',
|
62
64
|
formerPage: 'Vorherige Seite',
|
65
|
+
noDataPlaceholder: 'Keine Daten verfügbar',
|
66
|
+
noResultsPlaceholder: 'Keine übereinstimmenden Einträge gefunden',
|
63
67
|
},
|
64
68
|
},
|
65
69
|
settings: {
|
66
70
|
title: 'Einstellungen',
|
67
71
|
tooltip: 'Einstellungen',
|
68
|
-
languageTitle: 'Spracheinstellungen',
|
69
72
|
languageSelector: 'Sprache',
|
73
|
+
theme: {
|
74
|
+
title: 'Farbschema',
|
75
|
+
dark: 'Dunkel',
|
76
|
+
light: 'Hell',
|
77
|
+
},
|
70
78
|
},
|
71
79
|
featureInfo: {
|
72
80
|
activateToolTitle: 'Informationstool aktivieren',
|
@@ -85,6 +93,7 @@ const messages = {
|
|
85
93
|
select: 'Suchergebnis selektieren',
|
86
94
|
placeholder: 'Suche nach Straße, Adresse, Ort, POI',
|
87
95
|
zoomToFeatureAction: 'Auf Ergebnis zoomen',
|
96
|
+
zoomToAll: 'Zu allen Ergebnissen zoomen',
|
88
97
|
},
|
89
98
|
toolbox: {
|
90
99
|
flight: 'Flug',
|
@@ -103,6 +112,9 @@ const messages = {
|
|
103
112
|
information: 'Information',
|
104
113
|
success: 'Erfolg',
|
105
114
|
},
|
115
|
+
datePicker: {
|
116
|
+
today: 'Heute',
|
117
|
+
},
|
106
118
|
};
|
107
119
|
|
108
120
|
export default messages;
|
package/src/i18n/en.js
CHANGED
@@ -55,18 +55,26 @@ const messages = {
|
|
55
55
|
vcsTable: {
|
56
56
|
key: 'Name',
|
57
57
|
value: 'Value',
|
58
|
+
},
|
59
|
+
vcsDataTable: {
|
58
60
|
searchbarPlaceholder: 'Name, Value, ...',
|
59
61
|
itemsPerPage: 'per page',
|
60
62
|
ofItems: 'of',
|
61
63
|
nextPage: 'Next page',
|
62
64
|
formerPage: 'Former page',
|
65
|
+
noDataPlaceholder: 'No data available',
|
66
|
+
noResultsPlaceholder: 'No matching records found',
|
63
67
|
},
|
64
68
|
},
|
65
69
|
settings: {
|
66
70
|
title: 'Settings',
|
67
71
|
tooltip: 'Settings',
|
68
|
-
languageTitle: 'Language settings',
|
69
72
|
languageSelector: 'Language',
|
73
|
+
theme: {
|
74
|
+
title: 'Color theme',
|
75
|
+
dark: 'Dark',
|
76
|
+
light: 'Light',
|
77
|
+
},
|
70
78
|
},
|
71
79
|
featureInfo: {
|
72
80
|
activateToolTitle: 'Activate Infotool',
|
@@ -85,6 +93,7 @@ const messages = {
|
|
85
93
|
select: 'Select result item',
|
86
94
|
placeholder: 'Search for Street, Address, Landmark, POI',
|
87
95
|
zoomToFeatureAction: 'Zoom to result',
|
96
|
+
zoomToAll: 'Zoom to all',
|
88
97
|
},
|
89
98
|
toolbox: {
|
90
99
|
flight: 'flight',
|
@@ -103,6 +112,9 @@ const messages = {
|
|
103
112
|
information: 'Information',
|
104
113
|
success: 'Success',
|
105
114
|
},
|
115
|
+
datePicker: {
|
116
|
+
today: 'Today',
|
117
|
+
},
|
106
118
|
};
|
107
119
|
|
108
120
|
export default messages;
|
@@ -1,5 +1,5 @@
|
|
1
1
|
// eslint-disable-next-line max-classes-per-file
|
2
|
-
import {
|
2
|
+
import { moduleIdSymbol, IndexedCollection } from '@vcmap/core';
|
3
3
|
import { getLogger } from '@vcsuite/logger';
|
4
4
|
|
5
5
|
/**
|
@@ -51,59 +51,59 @@ export function mergeDeep(...sources) {
|
|
51
51
|
*/
|
52
52
|
class I18nCollection extends IndexedCollection {
|
53
53
|
/**
|
54
|
-
* @param {function():string}
|
54
|
+
* @param {function():string} getDynamicModuleId - function to get the current dynamic module id
|
55
55
|
*/
|
56
|
-
constructor(
|
56
|
+
constructor(getDynamicModuleId) {
|
57
57
|
super(false);
|
58
58
|
/**
|
59
59
|
* @type {function(): string}
|
60
60
|
* @private
|
61
61
|
*/
|
62
|
-
this.
|
62
|
+
this._getDynamicModuleId = getDynamicModuleId;
|
63
63
|
}
|
64
64
|
|
65
65
|
/**
|
66
66
|
* @inheritDoc
|
67
67
|
*/
|
68
68
|
add(item) {
|
69
|
-
if (!item[
|
70
|
-
item[
|
69
|
+
if (!item[moduleIdSymbol]) {
|
70
|
+
item[moduleIdSymbol] = this._getDynamicModuleId();
|
71
71
|
}
|
72
72
|
super.add(item);
|
73
73
|
}
|
74
74
|
|
75
75
|
/**
|
76
76
|
* @param {Array<Object>} configArray
|
77
|
-
* @param {string}
|
77
|
+
* @param {string} moduleId
|
78
78
|
* @returns {Promise<void>}
|
79
79
|
*/
|
80
|
-
async parseItems(configArray,
|
80
|
+
async parseItems(configArray, moduleId) {
|
81
81
|
if (Array.isArray(configArray)) {
|
82
82
|
configArray.forEach((item) => {
|
83
|
-
item[
|
83
|
+
item[moduleIdSymbol] = moduleId;
|
84
84
|
this.add(item);
|
85
85
|
});
|
86
86
|
}
|
87
87
|
}
|
88
88
|
|
89
89
|
/**
|
90
|
-
* @param {string}
|
90
|
+
* @param {string} moduleId
|
91
91
|
*/
|
92
|
-
async
|
92
|
+
async removeModule(moduleId) {
|
93
93
|
[...this]
|
94
|
-
.filter(item => item[
|
94
|
+
.filter(item => item[moduleIdSymbol] === moduleId)
|
95
95
|
.forEach((item) => {
|
96
96
|
this.remove(item);
|
97
97
|
});
|
98
98
|
}
|
99
99
|
|
100
100
|
/**
|
101
|
-
* @param {string}
|
101
|
+
* @param {string} moduleId
|
102
102
|
* @returns {Array<Object>}
|
103
103
|
*/
|
104
|
-
|
104
|
+
serializeModule(moduleId) {
|
105
105
|
return [...this]
|
106
|
-
.filter(item => item[
|
106
|
+
.filter(item => item[moduleIdSymbol] === moduleId)
|
107
107
|
.filter(item => !item[i18nPluginSymbol])
|
108
108
|
.map(item => JSON.parse(JSON.stringify(item)));
|
109
109
|
}
|
@@ -112,12 +112,12 @@ class I18nCollection extends IndexedCollection {
|
|
112
112
|
* This method adds plugin messages to the collection. It is no necessary to call this function
|
113
113
|
* from within a plugin. Use the i18n property on your plugin.
|
114
114
|
* @param {string} plugin Name of the plugin
|
115
|
-
* @param {string}
|
115
|
+
* @param {string} moduleId
|
116
116
|
* @param {Object} messages
|
117
117
|
*/
|
118
|
-
addPluginMessages(plugin,
|
118
|
+
addPluginMessages(plugin, moduleId, messages) {
|
119
119
|
messages[i18nPluginSymbol] = plugin;
|
120
|
-
messages[
|
120
|
+
messages[moduleIdSymbol] = moduleId;
|
121
121
|
this.add(messages);
|
122
122
|
}
|
123
123
|
|
@@ -125,11 +125,11 @@ class I18nCollection extends IndexedCollection {
|
|
125
125
|
* This method removes plugin messages from the collection. It is no necessary to call this function
|
126
126
|
* from within a plugin. Once your plugin is removed, the VcsUiApp will call this for you.
|
127
127
|
* @param {string} pluginName
|
128
|
-
* @param {string}
|
128
|
+
* @param {string} moduleId
|
129
129
|
*/
|
130
|
-
removePluginMessages(pluginName,
|
130
|
+
removePluginMessages(pluginName, moduleId) {
|
131
131
|
[...this]
|
132
|
-
.filter(item => item[i18nPluginSymbol] === pluginName && item[
|
132
|
+
.filter(item => item[i18nPluginSymbol] === pluginName && item[moduleIdSymbol] === moduleId)
|
133
133
|
.forEach((item) => {
|
134
134
|
this.remove(item);
|
135
135
|
});
|
@@ -147,7 +147,7 @@ class I18nCollection extends IndexedCollection {
|
|
147
147
|
* @inheritDoc
|
148
148
|
*/
|
149
149
|
destroy() {
|
150
|
-
this.
|
150
|
+
this._getDynamicModuleId = null;
|
151
151
|
super.destroy();
|
152
152
|
}
|
153
153
|
}
|
package/src/init.js
CHANGED
@@ -1,20 +1,49 @@
|
|
1
1
|
import Vue from 'vue';
|
2
|
-
import { check, checkMaybe } from '@vcsuite/check';
|
3
|
-
import {
|
2
|
+
import { check, checkMaybe, is } from '@vcsuite/check';
|
3
|
+
import { VcsModule } from '@vcmap/core';
|
4
4
|
import VcsAppComponentWrapper from './application/vcsAppWrapper.vue';
|
5
5
|
import { vuetify } from './vuePlugins/vuetify.js';
|
6
6
|
import { createVueI18n, setupI18n } from './vuePlugins/i18n.js';
|
7
7
|
import VcsUiApp from './vcsUiApp.js';
|
8
8
|
|
9
|
+
/**
|
10
|
+
* Base pattern to check VcsObjects
|
11
|
+
* @type {import("vcsuite/check").PatternFor<import("@vcmap/core").VcsObject>}
|
12
|
+
*/
|
13
|
+
const VcsObjectPattern = {
|
14
|
+
type: String,
|
15
|
+
name: String,
|
16
|
+
};
|
17
|
+
|
18
|
+
/**
|
19
|
+
* Base pattern to check VcsUiAppConfig
|
20
|
+
* @type {import("vcsuite/check").PatternFor<VcsUiAppConfig>}
|
21
|
+
*/
|
22
|
+
export const VcsUiAppConfigPattern = {
|
23
|
+
id: [undefined, String],
|
24
|
+
layers: [undefined, [VcsObjectPattern]],
|
25
|
+
maps: [undefined, [VcsObjectPattern]],
|
26
|
+
styles: [undefined, [VcsObjectPattern]],
|
27
|
+
viewpoints: [undefined, [VcsObjectPattern]],
|
28
|
+
startingViewpointName: [undefined, String],
|
29
|
+
startingMapName: [undefined, String],
|
30
|
+
projection: [undefined, Object],
|
31
|
+
categories: [undefined, [{ name: String, items: [Object] }]],
|
32
|
+
obliqueCollections: [undefined, [VcsObjectPattern]],
|
33
|
+
plugins: [undefined, [Object]],
|
34
|
+
contentTree: [undefined, [Object]],
|
35
|
+
uiConfig: [undefined, [Object]],
|
36
|
+
featureInfo: [undefined, [VcsObjectPattern]],
|
37
|
+
i18n: [undefined, [Object]],
|
38
|
+
};
|
39
|
+
|
9
40
|
/**
|
10
41
|
* creates and mounts a vcsApp
|
11
42
|
* @param {string} mountTarget
|
12
|
-
* @param {string=} configUrl optional config
|
13
43
|
* @returns {Promise<VcsUiApp>}
|
14
44
|
*/
|
15
|
-
export default async function initApp(mountTarget
|
45
|
+
export default async function initApp(mountTarget) {
|
16
46
|
check(mountTarget, String);
|
17
|
-
checkMaybe(configUrl, String);
|
18
47
|
const app = new VcsUiApp();
|
19
48
|
const i18n = createVueI18n();
|
20
49
|
new Vue({
|
@@ -28,11 +57,65 @@ export default async function initApp(mountTarget, configUrl) {
|
|
28
57
|
}).$mount(mountTarget);
|
29
58
|
|
30
59
|
setupI18n(app, i18n);
|
60
|
+
return app;
|
61
|
+
}
|
62
|
+
|
63
|
+
/**
|
64
|
+
* Initializes app with an optional single config
|
65
|
+
* @param {string} mountTarget
|
66
|
+
* @param {string=} configUrl optional config
|
67
|
+
* @returns {Promise<VcsUiApp>}
|
68
|
+
*/
|
69
|
+
export async function initAppFromModule(mountTarget, configUrl) {
|
70
|
+
check(mountTarget, String);
|
71
|
+
checkMaybe(configUrl, String);
|
72
|
+
|
73
|
+
const app = await initApp(mountTarget);
|
31
74
|
if (configUrl) {
|
32
75
|
const config = await fetch(configUrl)
|
33
76
|
.then(response => response.json());
|
34
|
-
const
|
35
|
-
await app.
|
77
|
+
const module = new VcsModule(config);
|
78
|
+
await app.addModule(module);
|
36
79
|
}
|
80
|
+
|
37
81
|
return app;
|
38
82
|
}
|
83
|
+
|
84
|
+
/**
|
85
|
+
* Initializes app with a map config containing a set of config urls
|
86
|
+
* @param {string} mountTarget
|
87
|
+
* @param {string} appUrl app config containing further modules to be loaded
|
88
|
+
* @returns {Promise<VcsUiApp>}
|
89
|
+
*/
|
90
|
+
export async function initAppFromAppConfig(mountTarget, appUrl) {
|
91
|
+
check(mountTarget, String);
|
92
|
+
check(appUrl, String);
|
93
|
+
|
94
|
+
const app = await initApp(mountTarget);
|
95
|
+
/**
|
96
|
+
* @type {{modules: Array<string|VcsUiAppConfig>}}
|
97
|
+
*/
|
98
|
+
const appConfig = await fetch(appUrl)
|
99
|
+
.then(response => response.json());
|
100
|
+
|
101
|
+
check(appConfig.modules, [String, Object]);
|
102
|
+
|
103
|
+
const modules = await Promise.all(appConfig.modules.map(async (c) => {
|
104
|
+
if (is(c, VcsUiAppConfigPattern)) {
|
105
|
+
return new VcsModule(/** @type{import("@vcmap/core").VcsAppConfig} */ c);
|
106
|
+
} else if (is(c, String)) {
|
107
|
+
const response = await fetch(c);
|
108
|
+
if (response.ok) {
|
109
|
+
const config = await response.json();
|
110
|
+
return new VcsModule(config);
|
111
|
+
}
|
112
|
+
}
|
113
|
+
return null;
|
114
|
+
}));
|
115
|
+
// eslint-disable-next-line no-restricted-syntax
|
116
|
+
for await (const module of modules) {
|
117
|
+
if (module) {
|
118
|
+
await app.addModule(module);
|
119
|
+
}
|
120
|
+
}
|
121
|
+
}
|
@@ -6,7 +6,11 @@
|
|
6
6
|
:key="idx"
|
7
7
|
:class="{ 'w-full': item.colNr === 1, 'w-half': item.colNr !== 1 }"
|
8
8
|
>
|
9
|
-
<v-list-item
|
9
|
+
<v-list-item
|
10
|
+
dense
|
11
|
+
class="pa-0"
|
12
|
+
:class="determineInnerPadding(idx)"
|
13
|
+
>
|
10
14
|
<v-list-item-icon class="pr-2">
|
11
15
|
<v-img
|
12
16
|
v-if="row.type === StyleRowType.Icon || row.type === StyleRowType.Shape"
|
@@ -126,7 +130,24 @@
|
|
126
130
|
required: true,
|
127
131
|
},
|
128
132
|
},
|
129
|
-
setup() {
|
133
|
+
setup(props) {
|
134
|
+
/**
|
135
|
+
* Determines if a list item has padding right or left, so it has correct spacing to second row.
|
136
|
+
* @param {number} index The index of the list item. Starts with 0.
|
137
|
+
* @returns {string} Vuetify padding helper.
|
138
|
+
*/
|
139
|
+
function determineInnerPadding(index) {
|
140
|
+
// check if there are more than two columns
|
141
|
+
if (props.item.colNr !== 1) {
|
142
|
+
// check if even number. If so, it is located in the left column and needs padding on the right.
|
143
|
+
if (index % 2 === 0) {
|
144
|
+
return 'pr-2';
|
145
|
+
} else {
|
146
|
+
return 'pl-2';
|
147
|
+
}
|
148
|
+
}
|
149
|
+
return '';
|
150
|
+
}
|
130
151
|
return {
|
131
152
|
StyleRowType,
|
132
153
|
getImageSrcFromShape,
|
@@ -136,6 +157,7 @@
|
|
136
157
|
}
|
137
158
|
return null;
|
138
159
|
},
|
160
|
+
determineInnerPadding,
|
139
161
|
};
|
140
162
|
},
|
141
163
|
};
|
package/src/legend/vcsLegend.vue
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
<template>
|
2
|
-
<v-
|
2
|
+
<v-sheet
|
3
3
|
class="overflow-y-auto"
|
4
4
|
>
|
5
5
|
<v-expansion-panels
|
@@ -7,47 +7,48 @@
|
|
7
7
|
multiple
|
8
8
|
v-if="entries.length > 0"
|
9
9
|
v-model="panels"
|
10
|
+
class="rounded-0"
|
10
11
|
>
|
11
12
|
<v-expansion-panel
|
12
13
|
v-for="(entry,i) in entries"
|
13
14
|
:key="i"
|
14
|
-
class="
|
15
|
+
class="px-2"
|
15
16
|
@change="entry.open = !entry.open"
|
16
17
|
>
|
17
18
|
<v-expansion-panel-header hide-actions>
|
18
|
-
{{ $t(entry.title) }}
|
19
19
|
<template #default="{ open }">
|
20
|
-
<div class="d-flex">
|
21
|
-
<
|
22
|
-
|
23
|
-
|
24
|
-
|
20
|
+
<div class="d-flex justify-space-between">
|
21
|
+
<div class="d-flex align-center">
|
22
|
+
<v-icon class="mr-1" :class="{ 'rotate': !open }">
|
23
|
+
mdi-chevron-down
|
24
|
+
</v-icon>
|
25
|
+
{{ $t(entry.title) }}
|
26
|
+
</div>
|
27
|
+
<VcsActionButtonList small :actions="entry.actions" />
|
25
28
|
</div>
|
26
29
|
</template>
|
27
30
|
</v-expansion-panel-header>
|
28
|
-
<v-expansion-panel-content>
|
31
|
+
<v-expansion-panel-content class="pl-6 pb-2">
|
29
32
|
<v-list dense>
|
30
33
|
<div v-for="(item, idx) in entry.legend" :key="idx">
|
31
|
-
<div v-if="item.type === LegendType.Image"
|
34
|
+
<div v-if="item.type === LegendType.Image">
|
32
35
|
<img
|
33
36
|
:src="$t(item.src)"
|
34
|
-
|
35
|
-
max-height="auto"
|
36
|
-
class="mx-2 legend-image"
|
37
|
+
class="legend-image"
|
37
38
|
:title="item.tooltip"
|
38
39
|
>
|
39
40
|
</div>
|
40
|
-
<div v-else-if="item.type === LegendType.Iframe"
|
41
|
+
<div v-else-if="item.type === LegendType.Iframe">
|
41
42
|
<iframe
|
42
43
|
:id="`legendIframe${idx}`"
|
43
44
|
:src="$t(item.src)"
|
44
45
|
scrolling="no"
|
45
|
-
|
46
|
+
style="width: 100%; height: 100%;"
|
46
47
|
frameBorder="0"
|
47
48
|
@load="setIframeHeight(`legendIframe${idx}`)"
|
48
49
|
/>
|
49
50
|
</div>
|
50
|
-
<style-legend-item v-else :item="item"
|
51
|
+
<style-legend-item v-else :item="item" />
|
51
52
|
</div>
|
52
53
|
</v-list>
|
53
54
|
</v-expansion-panel-content>
|
@@ -56,13 +57,12 @@
|
|
56
57
|
<v-sheet v-else class="ma-2">
|
57
58
|
{{ $t('legend.empty') }}
|
58
59
|
</v-sheet>
|
59
|
-
</v-
|
60
|
+
</v-sheet>
|
60
61
|
</template>
|
61
62
|
|
62
63
|
<script>
|
63
64
|
|
64
65
|
import {
|
65
|
-
VCard,
|
66
66
|
VExpansionPanels,
|
67
67
|
VExpansionPanel,
|
68
68
|
VExpansionPanelHeader,
|
@@ -74,7 +74,7 @@
|
|
74
74
|
import { computed } from 'vue';
|
75
75
|
import { LegendType } from './legendHelper.js';
|
76
76
|
import StyleLegendItem from './styleLegendItem.vue';
|
77
|
-
import
|
77
|
+
import VcsActionButtonList from '../components/buttons/VcsActionButtonList.vue';
|
78
78
|
|
79
79
|
/**
|
80
80
|
* @description A component rendering configured legend information for active layers.
|
@@ -84,9 +84,8 @@
|
|
84
84
|
export default {
|
85
85
|
name: 'VcsLegend',
|
86
86
|
components: {
|
87
|
-
|
87
|
+
VcsActionButtonList,
|
88
88
|
StyleLegendItem,
|
89
|
-
VCard,
|
90
89
|
VExpansionPanels,
|
91
90
|
VExpansionPanel,
|
92
91
|
VExpansionPanelHeader,
|
@@ -130,17 +129,11 @@
|
|
130
129
|
</script>
|
131
130
|
|
132
131
|
<style lang="scss" scoped>
|
133
|
-
.v-list-item--dense {
|
134
|
-
height: 32px;
|
135
|
-
}
|
136
|
-
::v-deep {
|
137
|
-
.treeview-label {
|
138
|
-
max-width: 189px;
|
139
|
-
}
|
140
|
-
}
|
141
132
|
.legend-image {
|
142
|
-
max-width:
|
133
|
+
max-width: 100%;
|
143
134
|
height: auto;
|
144
|
-
|
135
|
+
}
|
136
|
+
.rotate {
|
137
|
+
transform: rotate(-90deg);
|
145
138
|
}
|
146
139
|
</style>
|
@@ -1,48 +1,54 @@
|
|
1
1
|
<template>
|
2
|
-
<v-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
:selectable="category.selectable"
|
21
|
-
:single-select="category.singleSelect"
|
22
|
-
v-model="selection"
|
23
|
-
:show-title="false"
|
2
|
+
<v-expansion-panel
|
3
|
+
class="px-2"
|
4
|
+
@change="active = !active"
|
5
|
+
>
|
6
|
+
<v-expansion-panel-header hide-actions>
|
7
|
+
<template #default="{ open }">
|
8
|
+
<div class="d-flex justify-space-between">
|
9
|
+
<div class="d-flex align-center">
|
10
|
+
<v-icon class="mr-1" :class="{ 'rotate': !open }">
|
11
|
+
mdi-chevron-down
|
12
|
+
</v-icon>
|
13
|
+
{{ $t(category.title) }}
|
14
|
+
</div>
|
15
|
+
<VcsActionButtonList
|
16
|
+
v-if="category.actions?.length > 0"
|
17
|
+
:actions="category.actions"
|
18
|
+
small
|
19
|
+
class="float-end"
|
24
20
|
/>
|
25
|
-
</
|
26
|
-
</
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
21
|
+
</div>
|
22
|
+
</template>
|
23
|
+
</v-expansion-panel-header>
|
24
|
+
<v-expansion-panel-content class="pb-1">
|
25
|
+
<vcs-list
|
26
|
+
:items="category.items.slice(0, 10)"
|
27
|
+
:selectable="category.selectable"
|
28
|
+
:single-select="category.singleSelect"
|
29
|
+
v-model="selection"
|
30
|
+
:show-title="false"
|
31
|
+
/>
|
32
|
+
<v-sheet v-if="category.items.length > 10" class="ma-2 pl-2">
|
33
|
+
<VcsButton @click="openCategoryItemWindow" small>
|
34
|
+
{{ $t('categoryManager.more') }}
|
35
|
+
</VcsButton>
|
36
|
+
</v-sheet>
|
37
|
+
<v-sheet v-else-if="category.items.length === 0" class="ma-2 pl-2">
|
38
|
+
{{ $t('categoryManager.empty') }}
|
39
|
+
</v-sheet>
|
40
|
+
</v-expansion-panel-content>
|
41
|
+
</v-expansion-panel>
|
41
42
|
</template>
|
42
43
|
|
43
44
|
<script>
|
44
45
|
import { computed, inject, ref } from 'vue';
|
45
|
-
import {
|
46
|
+
import {
|
47
|
+
VIcon, VExpansionPanel,
|
48
|
+
VExpansionPanelHeader,
|
49
|
+
VExpansionPanelContent,
|
50
|
+
VSheet,
|
51
|
+
} from 'vuetify/lib';
|
46
52
|
import VcsList from '../../components/lists/VcsList.vue';
|
47
53
|
import VcsActionButtonList from '../../components/buttons/VcsActionButtonList.vue';
|
48
54
|
import VcsButton from '../../components/buttons/VcsButton.vue';
|
@@ -54,11 +60,12 @@
|
|
54
60
|
name: 'CategoryComponent',
|
55
61
|
components: {
|
56
62
|
VcsActionButtonList,
|
57
|
-
VcsList,
|
58
|
-
VContainer,
|
59
|
-
VRow,
|
60
63
|
VcsButton,
|
61
|
-
|
64
|
+
VcsList,
|
65
|
+
VExpansionPanel,
|
66
|
+
VExpansionPanelHeader,
|
67
|
+
VExpansionPanelContent,
|
68
|
+
VSheet,
|
62
69
|
VIcon,
|
63
70
|
},
|
64
71
|
props: {
|
@@ -72,7 +79,7 @@
|
|
72
79
|
/** @type {VcsUiApp} */
|
73
80
|
const app = inject('vcsApp');
|
74
81
|
const windowId = `${category.id}-category-list`;
|
75
|
-
const
|
82
|
+
const active = ref(false);
|
76
83
|
|
77
84
|
const selection = computed({
|
78
85
|
get() { return category.selection; },
|
@@ -84,7 +91,7 @@
|
|
84
91
|
|
85
92
|
return {
|
86
93
|
selection,
|
87
|
-
|
94
|
+
active,
|
88
95
|
openCategoryItemWindow() {
|
89
96
|
if (app.windowManager.has(windowId)) {
|
90
97
|
setTimeout(() => {
|
@@ -110,6 +117,8 @@
|
|
110
117
|
};
|
111
118
|
</script>
|
112
119
|
|
113
|
-
<style scoped>
|
114
|
-
|
120
|
+
<style lang="scss" scoped>
|
121
|
+
.rotate {
|
122
|
+
transform: rotate(-90deg);
|
123
|
+
}
|
115
124
|
</style>
|