@vcmap/ui 5.0.0-rc.14 → 5.0.0-rc.15
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 +33 -31
- package/build/build.js +9 -0
- package/build/buildHelpers.js +12 -10
- package/build/commonViteConfig.js +3 -10
- package/config/base.config.json +26 -24
- package/config/dev.config.json +8 -0
- package/config/www.config.json +102 -17
- package/dist/assets/cesium.2e288a.js +137226 -0
- package/dist/assets/cesium.js +1 -1
- package/dist/assets/core.8014d3.js +14473 -0
- package/dist/assets/core.js +1 -1
- package/dist/assets/index.3f74fa92.js +1 -0
- package/dist/assets/ol.31c3a5.js +44279 -0
- package/dist/assets/ol.js +1 -1
- package/dist/assets/ui.36f84f.css +1 -0
- package/dist/assets/ui.36f84f.js +16101 -0
- package/dist/assets/ui.js +1 -1
- package/dist/assets/vue.a39c10.js +4675 -0
- package/dist/assets/vue.js +5 -2
- package/dist/assets/{vuetify.202322.css → vuetify.378637.css} +1 -1
- package/dist/assets/vuetify.378637.js +21019 -0
- package/dist/assets/vuetify.js +5 -2
- package/dist/index.html +1 -1
- package/index.js +4 -1
- package/package.json +10 -10
- package/plugins/@vcmap/pluginExample/index.js +14 -0
- package/plugins/@vcmap/pluginExample/pluginExampleComponent.vue +93 -67
- package/plugins/@vcmap/project-selector/ContextsListComponent.vue +8 -1
- package/plugins/@vcmap/project-selector/ProjectSelectorComponent.vue +27 -1
- package/plugins/@vcmap/search-nominatim/LICENSE.md +14 -0
- package/plugins/@vcmap/search-nominatim/README.md +2 -0
- package/plugins/@vcmap/search-nominatim/config.json +4 -0
- package/plugins/@vcmap/search-nominatim/index.js +26 -0
- package/plugins/@vcmap/search-nominatim/nominatim.js +170 -0
- package/plugins/@vcmap/search-nominatim/package.json +43 -0
- package/plugins/@vcmap/theme-changer/ThemeChangerComponent.vue +24 -0
- package/plugins/buttonExamples/ButtonExamples.vue +28 -1
- package/plugins/categoryTest/Categories.vue +16 -0
- package/plugins/categoryTest/Category.vue +30 -4
- package/plugins/example/mySuperComponent.vue +12 -1
- package/plugins/package.json +2 -1
- package/plugins/simple-graph/SimpleGraphComponent.vue +5 -11
- package/plugins/test/allIconsComponent.vue +16 -0
- package/plugins/test/editor.vue +3 -0
- package/plugins/test/emptyComponent.vue +3 -0
- package/plugins/test/vcsContent.vue +3 -0
- package/src/actions/actionHelper.js +103 -2
- package/src/actions/styleSelector.vue +9 -0
- package/src/application/VcsApp.vue +77 -9
- package/src/application/VcsAttributions.vue +63 -0
- package/src/application/VcsAttributionsFooter.vue +87 -0
- package/src/application/{Navbar.vue → VcsNavbar.vue} +35 -2
- package/src/application/VcsSettings.vue +4 -0
- package/src/application/attributionsHelper.js +150 -0
- package/src/application/vcsAppWrapper.vue +5 -1
- package/src/components/buttons/VcsActionButtonList.vue +8 -1
- package/src/components/buttons/VcsButton.vue +7 -1
- package/src/components/form-inputs-controls/VcsCheckbox.vue +7 -2
- package/src/components/form-inputs-controls/VcsColorPicker.vue +4 -0
- package/src/components/form-inputs-controls/VcsFormSection.vue +48 -2
- package/src/components/form-inputs-controls/VcsRadio.vue +7 -1
- package/src/components/form-inputs-controls/VcsSelect.vue +5 -1
- package/src/components/form-inputs-controls/VcsTextArea.vue +2 -0
- package/src/components/form-inputs-controls/VcsTextField.vue +6 -2
- package/src/components/lists/VcsActionList.vue +12 -1
- package/src/components/lists/VcsTreeview.vue +6 -1
- package/src/components/lists/VcsTreeviewLeaf.vue +5 -1
- package/src/components/lists/VcsTreeviewSearchbar.vue +5 -0
- package/src/components/notification/VcsTooltip.vue +14 -9
- package/src/components/tables/VcsTable.vue +117 -38
- package/src/featureInfo/AddressBalloonComponent.vue +17 -1
- package/src/featureInfo/BalloonComponent.vue +57 -23
- package/src/featureInfo/balloonFeatureInfoView.js +2 -2
- package/src/featureInfo/featureInfo.js +10 -2
- package/src/i18n/de.js +15 -0
- package/src/i18n/en.js +15 -0
- package/src/legend/legendHelper.js +18 -12
- package/src/legend/styleLegendItem.vue +20 -1
- package/src/legend/vcsLegend.vue +29 -3
- package/src/manager/toolbox/GroupToolboxComponent.vue +13 -1
- package/src/manager/toolbox/SelectToolboxComponent.vue +13 -1
- package/src/manager/toolbox/ToolboxManager.vue +3 -0
- package/src/manager/window/WindowComponent.vue +6 -0
- package/src/manager/window/WindowComponentHeader.vue +6 -1
- package/src/navigation/mapNavigation.vue +15 -36
- package/src/navigation/orientationToolsButton.vue +6 -1
- package/src/navigation/overviewMap.js +10 -39
- package/src/navigation/tiltSlider.vue +3 -0
- package/src/navigation/vcsCompass.vue +2 -0
- package/src/search/resultItem.vue +89 -0
- package/src/search/resultsComponent.vue +98 -0
- package/src/search/search.js +326 -0
- package/src/search/searchComponent.vue +90 -0
- package/src/styles/_typography.scss +3 -0
- package/src/styles/utils/_cursor.scss +4 -0
- package/src/styles/variables.scss +4 -1
- package/src/vcsUiApp.js +16 -0
- package/dist/assets/cesium.9489f8.js +0 -8699
- package/dist/assets/core.aa346a.js +0 -4
- package/dist/assets/index.3cd4fffa.js +0 -1
- package/dist/assets/ol.39651b.js +0 -439
- package/dist/assets/ui.15ef6a.css +0 -1
- package/dist/assets/ui.15ef6a.js +0 -71
- package/dist/assets/vue.cbe9d8.js +0 -9
- package/dist/assets/vuetify.202322.js +0 -148
@@ -0,0 +1,87 @@
|
|
1
|
+
<template>
|
2
|
+
<span class="attribution-wrap">
|
3
|
+
<span v-for="attribution in mergedAttributions" class="attribution-span" :key="attribution.provider">
|
4
|
+
<a
|
5
|
+
:href="attribution.url"
|
6
|
+
target="_blank"
|
7
|
+
class="text--secondary"
|
8
|
+
>{{ $t(attribution.provider) }} <span>{{ attribution.years }}</span></a>
|
9
|
+
</span>
|
10
|
+
<VcsButton
|
11
|
+
class="d-flex text--secondary"
|
12
|
+
small
|
13
|
+
:key="attributionAction.name"
|
14
|
+
:tooltip="attributionAction.title"
|
15
|
+
:icon="attributionAction.icon"
|
16
|
+
:active="attributionAction.active"
|
17
|
+
@click.stop="attributionAction.callback($event)"
|
18
|
+
/>
|
19
|
+
</span>
|
20
|
+
</template>
|
21
|
+
|
22
|
+
<style lang="scss" scoped>
|
23
|
+
.attribution-wrap{
|
24
|
+
white-space: nowrap;
|
25
|
+
margin-right: 40px;
|
26
|
+
overflow: hidden;
|
27
|
+
text-overflow: ellipsis;
|
28
|
+
|
29
|
+
.vcs-button-wrap{
|
30
|
+
position: absolute;
|
31
|
+
right: 4px;
|
32
|
+
bottom: 3px;
|
33
|
+
}
|
34
|
+
}
|
35
|
+
a:before {
|
36
|
+
content: '\00a9\00a0';
|
37
|
+
}
|
38
|
+
.attribution-span {
|
39
|
+
font-size: smaller;
|
40
|
+
&:before {
|
41
|
+
content: '\00a0\007c\00a0';
|
42
|
+
}
|
43
|
+
&:first-child::before{
|
44
|
+
content: '';
|
45
|
+
}
|
46
|
+
span{
|
47
|
+
font-size: inherit;
|
48
|
+
}
|
49
|
+
}
|
50
|
+
|
51
|
+
</style>
|
52
|
+
|
53
|
+
<script >
|
54
|
+
|
55
|
+
import { computed } from 'vue';
|
56
|
+
import { mergeAttributions } from './attributionsHelper.js';
|
57
|
+
import VcsButton from '../components/buttons/VcsButton.vue';
|
58
|
+
|
59
|
+
/**
|
60
|
+
* Lists attributions of maps, layers and oblique collections within the footer
|
61
|
+
* @vue-prop {import("vue").Ref<Array<AttributionEntry>} entries - array with one entry per active VcsObject
|
62
|
+
* @vue-prop {VcsAction} attributionAction - action to open attribution window
|
63
|
+
* @vue-computed {Array<{provider: string, years: string, url: URL}>} mergedAttributions - array with one entry per provider
|
64
|
+
*/
|
65
|
+
export default {
|
66
|
+
name: 'VcsAttributionsFooter',
|
67
|
+
components: {
|
68
|
+
VcsButton,
|
69
|
+
},
|
70
|
+
props: {
|
71
|
+
entries: {
|
72
|
+
type: Array,
|
73
|
+
required: true,
|
74
|
+
},
|
75
|
+
attributionAction: {
|
76
|
+
type: Object,
|
77
|
+
required: true,
|
78
|
+
},
|
79
|
+
},
|
80
|
+
setup(props) {
|
81
|
+
const mergedAttributions = computed(() => mergeAttributions(props.entries));
|
82
|
+
return {
|
83
|
+
mergedAttributions,
|
84
|
+
};
|
85
|
+
},
|
86
|
+
};
|
87
|
+
</script>
|
@@ -86,6 +86,17 @@
|
|
86
86
|
:show-icon="true"
|
87
87
|
/>
|
88
88
|
</v-menu>
|
89
|
+
<VcsButton
|
90
|
+
class="d-flex"
|
91
|
+
v-if="searchAction"
|
92
|
+
large
|
93
|
+
:key="searchAction.name"
|
94
|
+
:tooltip="searchAction.title"
|
95
|
+
:icon="searchAction.icon"
|
96
|
+
:active="searchAction.active"
|
97
|
+
@click.stop="searchAction.callback($event)"
|
98
|
+
v-bind="{...$attrs}"
|
99
|
+
/>
|
89
100
|
<v-menu
|
90
101
|
offset-y
|
91
102
|
v-if="menuActions.length > 0"
|
@@ -124,15 +135,30 @@
|
|
124
135
|
</style>
|
125
136
|
|
126
137
|
<script>
|
127
|
-
import { inject, ref, computed } from 'vue';
|
138
|
+
import { inject, ref, computed, onUnmounted } from 'vue';
|
139
|
+
import {
|
140
|
+
VCol, VContainer, VDivider, VMenu, VRow, VToolbar, VToolbarItems,
|
141
|
+
} from 'vuetify/lib';
|
128
142
|
import { ButtonLocation, getActionsByLocation } from '../manager/navbarManager.js';
|
129
143
|
import VcsActionButtonList from '../components/buttons/VcsActionButtonList.vue';
|
130
144
|
import VcsActionList from '../components/lists/VcsActionList.vue';
|
131
145
|
import VcsButton from '../components/buttons/VcsButton.vue';
|
146
|
+
import { createSearchButtonAction } from '../actions/actionHelper.js';
|
132
147
|
|
133
148
|
export default {
|
134
149
|
name: 'VcsNavbar',
|
135
|
-
components: {
|
150
|
+
components: {
|
151
|
+
VcsActionButtonList,
|
152
|
+
VcsActionList,
|
153
|
+
VcsButton,
|
154
|
+
VToolbar,
|
155
|
+
VContainer,
|
156
|
+
VRow,
|
157
|
+
VCol,
|
158
|
+
VToolbarItems,
|
159
|
+
VDivider,
|
160
|
+
VMenu,
|
161
|
+
},
|
136
162
|
setup() {
|
137
163
|
const app = inject('vcsApp');
|
138
164
|
|
@@ -142,12 +168,19 @@
|
|
142
168
|
() => getActionsByLocation(buttonComponents.value, location, [...app.plugins].map(p => p.name)),
|
143
169
|
);
|
144
170
|
|
171
|
+
const { searchAction, destroy: destroySearchAction } = createSearchButtonAction(app);
|
172
|
+
|
173
|
+
onUnmounted(() => {
|
174
|
+
destroySearchAction();
|
175
|
+
});
|
176
|
+
|
145
177
|
return {
|
146
178
|
mapActions: getActions(ButtonLocation.MAP),
|
147
179
|
contentActions: getActions(ButtonLocation.CONTENT),
|
148
180
|
toolActions: getActions(ButtonLocation.TOOL),
|
149
181
|
projectActions: getActions(ButtonLocation.PROJECT),
|
150
182
|
shareActions: getActions(ButtonLocation.SHARE),
|
183
|
+
searchAction,
|
151
184
|
menuActions: getActions(ButtonLocation.MENU),
|
152
185
|
config: app.uiConfig.config,
|
153
186
|
};
|
@@ -34,6 +34,7 @@
|
|
34
34
|
import {
|
35
35
|
ref, inject, onUnmounted, getCurrentInstance, computed,
|
36
36
|
} from 'vue';
|
37
|
+
import { VCol, VContainer, VRow } from 'vuetify/lib';
|
37
38
|
import VcsLabel from '../components/form-inputs-controls/VcsLabel.vue';
|
38
39
|
import VcsSelect from '../components/form-inputs-controls/VcsSelect.vue';
|
39
40
|
|
@@ -42,6 +43,9 @@
|
|
42
43
|
components: {
|
43
44
|
VcsSelect,
|
44
45
|
VcsLabel,
|
46
|
+
VContainer,
|
47
|
+
VRow,
|
48
|
+
VCol,
|
45
49
|
},
|
46
50
|
setup() {
|
47
51
|
const app = inject('vcsApp');
|
@@ -0,0 +1,150 @@
|
|
1
|
+
import { ref } from 'vue';
|
2
|
+
import { ObliqueMap } from '@vcmap/core';
|
3
|
+
|
4
|
+
/**
|
5
|
+
* @typedef {Object} Attribution.Options
|
6
|
+
* @property {string} provider - name of the data provider
|
7
|
+
* @property {number} [year] - year of dataset
|
8
|
+
* @property {URL} url - link to data provider
|
9
|
+
*/
|
10
|
+
|
11
|
+
/**
|
12
|
+
* @typedef {Object} AttributionEntry
|
13
|
+
* @property {string} key - name of the VcsObject the attribution applies to
|
14
|
+
* @property {string} title - title of the VcsObject the attribution applies to
|
15
|
+
* @property {Attribution.Options|Array<Attribution.Options>} attributions - attributions of a map, layer or oblique collection
|
16
|
+
*/
|
17
|
+
|
18
|
+
/**
|
19
|
+
* merges attribution entries of same providers
|
20
|
+
* @param {Array<AttributionEntry>} entries
|
21
|
+
* @returns {Array<{provider: string, years: string, url: URL}>}
|
22
|
+
*/
|
23
|
+
export function mergeAttributions(entries) {
|
24
|
+
const providers = {};
|
25
|
+
entries.forEach(({ attributions }) => {
|
26
|
+
attributions.forEach(({ provider, year, url }) => {
|
27
|
+
const providerObject = providers[provider];
|
28
|
+
if (providerObject) {
|
29
|
+
if (year) {
|
30
|
+
const index = providerObject.years.indexOf(year);
|
31
|
+
if (url && index === -1) {
|
32
|
+
if (providerObject.years.every(y => Number(y) < Number(year))) {
|
33
|
+
providerObject.url = url;
|
34
|
+
}
|
35
|
+
if (year) {
|
36
|
+
const set = new Set([...providerObject.years, Number(year)]);
|
37
|
+
providerObject.years = [...set].sort((a, b) => a - b);
|
38
|
+
}
|
39
|
+
}
|
40
|
+
}
|
41
|
+
} else {
|
42
|
+
providers[provider] = {
|
43
|
+
years: year ? [Number(year)] : [],
|
44
|
+
url,
|
45
|
+
};
|
46
|
+
}
|
47
|
+
});
|
48
|
+
});
|
49
|
+
return Object.keys(providers).map(provider => ({
|
50
|
+
provider,
|
51
|
+
years: providers[provider].years.join(', '),
|
52
|
+
url: providers[provider].url,
|
53
|
+
}));
|
54
|
+
}
|
55
|
+
|
56
|
+
/**
|
57
|
+
* Gets attributions of all active maps, layers and oblique collections and returns an array of entries.
|
58
|
+
* Each entry is defined by a key derived from the object's className and name, and it's associated attributions.
|
59
|
+
* Listens to state changes of maps, layers and oblique collections and synchronizes the entries array correspondingly.
|
60
|
+
* Returns a destroy function to clear listeners.
|
61
|
+
* @param {import("ui").VcsUiApp} app
|
62
|
+
* @returns {{entries: import("vue").Ref<Array<AttributionEntry>>, destroy: function():void}}
|
63
|
+
*/
|
64
|
+
export function getAttributions(app) {
|
65
|
+
/**
|
66
|
+
* @type {import("vue").Ref<Array<AttributionEntry>>}
|
67
|
+
*/
|
68
|
+
const entries = ref([]);
|
69
|
+
/**
|
70
|
+
* @type {function():void}
|
71
|
+
*/
|
72
|
+
let obliqueListener = () => {};
|
73
|
+
|
74
|
+
/**
|
75
|
+
* Adds an entry for an object using a combination of the object's className and name as key.
|
76
|
+
* @param {import("@vcmap/core").VcsMap|import("@vcmap/core").Layer|import("@vcmap/core").ObliqueCollection} object
|
77
|
+
*/
|
78
|
+
function addAttributions(object) {
|
79
|
+
const { attributions } = object.properties;
|
80
|
+
if (!attributions) { return; }
|
81
|
+
const key = `${object.className}_${object.name}`;
|
82
|
+
const idx = entries.value.findIndex(e => e.key === key);
|
83
|
+
if (idx < 0) {
|
84
|
+
entries.value.push({
|
85
|
+
key,
|
86
|
+
title: object.properties?.title ?? `${object.className}: ${object.name}`,
|
87
|
+
attributions: Array.isArray(attributions) ? attributions : [attributions],
|
88
|
+
});
|
89
|
+
}
|
90
|
+
}
|
91
|
+
|
92
|
+
/**
|
93
|
+
* @param {import("@vcmap/core").VcsMap|import("@vcmap/core").Layer|import("@vcmap/core").ObliqueCollection} object
|
94
|
+
*/
|
95
|
+
function removeAttributions(object) {
|
96
|
+
const idx = entries.value.findIndex(e => e.key === `${object.className}_${object.name}`);
|
97
|
+
if (idx >= 0) {
|
98
|
+
entries.value.splice(idx, 1);
|
99
|
+
}
|
100
|
+
}
|
101
|
+
|
102
|
+
/**
|
103
|
+
* adds or removes a AttributionEntry on layer state changes
|
104
|
+
* @param {import("@vcmap/core").VcsMap|import("@vcmap/core").Layer|import("@vcmap/core").ObliqueCollection} object
|
105
|
+
*/
|
106
|
+
function syncAttributions(object) {
|
107
|
+
if (object?.properties?.attributions === undefined) { return; }
|
108
|
+
if (object.active || object.loaded) {
|
109
|
+
addAttributions(object);
|
110
|
+
} else {
|
111
|
+
removeAttributions(object);
|
112
|
+
}
|
113
|
+
}
|
114
|
+
|
115
|
+
/**
|
116
|
+
*
|
117
|
+
* @param {import("@vcmap/core").VcsMap} map
|
118
|
+
*/
|
119
|
+
function initAttributions(map) {
|
120
|
+
if (!map) { return; }
|
121
|
+
obliqueListener();
|
122
|
+
entries.value.splice(0);
|
123
|
+
syncAttributions(map);
|
124
|
+
[...map.layerCollection].forEach((layer) => {
|
125
|
+
if (layer.isSupported(map)) {
|
126
|
+
syncAttributions(layer);
|
127
|
+
}
|
128
|
+
});
|
129
|
+
if (map instanceof ObliqueMap) {
|
130
|
+
syncAttributions(map.collection);
|
131
|
+
obliqueListener = map.collectionChanged.addEventListener(syncAttributions);
|
132
|
+
}
|
133
|
+
}
|
134
|
+
|
135
|
+
const listeners = [
|
136
|
+
app.maps.mapActivated.addEventListener(initAttributions),
|
137
|
+
app.layers.stateChanged.addEventListener(syncAttributions),
|
138
|
+
app.layers.removed.addEventListener(removeAttributions),
|
139
|
+
app.maps.removed.addEventListener(removeAttributions),
|
140
|
+
];
|
141
|
+
|
142
|
+
initAttributions(app.maps.activeMap);
|
143
|
+
|
144
|
+
const destroy = () => {
|
145
|
+
listeners.forEach(cb => cb());
|
146
|
+
obliqueListener();
|
147
|
+
};
|
148
|
+
|
149
|
+
return { entries, destroy };
|
150
|
+
}
|
@@ -5,6 +5,7 @@
|
|
5
5
|
</template>
|
6
6
|
|
7
7
|
<script>
|
8
|
+
import { VApp } from 'vuetify/lib';
|
8
9
|
import VcsApp from './VcsApp.vue';
|
9
10
|
|
10
11
|
/**
|
@@ -21,7 +22,10 @@
|
|
21
22
|
required: true,
|
22
23
|
},
|
23
24
|
},
|
24
|
-
components: {
|
25
|
+
components: {
|
26
|
+
VcsApp,
|
27
|
+
VApp,
|
28
|
+
},
|
25
29
|
};
|
26
30
|
</script>
|
27
31
|
|
@@ -38,6 +38,7 @@
|
|
38
38
|
</style>
|
39
39
|
<script>
|
40
40
|
|
41
|
+
import { VIcon, VMenu, VSpacer } from 'vuetify/lib';
|
41
42
|
import VcsButton from './VcsButton.vue';
|
42
43
|
import VcsActionList, { validateActions } from '../lists/VcsActionList.vue';
|
43
44
|
|
@@ -54,7 +55,13 @@
|
|
54
55
|
*/
|
55
56
|
export default {
|
56
57
|
name: 'VcsActionButtonList',
|
57
|
-
components: {
|
58
|
+
components: {
|
59
|
+
VcsActionList,
|
60
|
+
VcsButton,
|
61
|
+
VMenu,
|
62
|
+
VIcon,
|
63
|
+
VSpacer,
|
64
|
+
},
|
58
65
|
props: {
|
59
66
|
actions: {
|
60
67
|
type: Array,
|
@@ -94,6 +94,7 @@
|
|
94
94
|
</style>
|
95
95
|
|
96
96
|
<script>
|
97
|
+
import { VBtn, VIcon } from 'vuetify/lib';
|
97
98
|
import VcsBadge from '../notification/VcsBadge.vue';
|
98
99
|
import VcsTooltip from '../notification/VcsTooltip.vue';
|
99
100
|
|
@@ -118,7 +119,12 @@
|
|
118
119
|
*/
|
119
120
|
export default {
|
120
121
|
name: 'VcsButton',
|
121
|
-
components: {
|
122
|
+
components: {
|
123
|
+
VcsTooltip,
|
124
|
+
VcsBadge,
|
125
|
+
VBtn,
|
126
|
+
VIcon,
|
127
|
+
},
|
122
128
|
inheritAttrs: false,
|
123
129
|
props: {
|
124
130
|
active: {
|
@@ -47,6 +47,7 @@
|
|
47
47
|
}
|
48
48
|
</style>
|
49
49
|
<script>
|
50
|
+
import { VCheckbox } from 'vuetify/lib';
|
50
51
|
import VcsLabel from './VcsLabel.vue';
|
51
52
|
import VcsTooltip from '../notification/VcsTooltip.vue';
|
52
53
|
import validate from '../notification/validation.js';
|
@@ -58,11 +59,15 @@
|
|
58
59
|
* - if dense is set false, height is 32 px
|
59
60
|
* Provides VcsTooltip to show error messages
|
60
61
|
* @vue-prop {('bottom' | 'left' | 'top' | 'right')} [tooltipPosition='right'] - Position of the error tooltip.
|
61
|
-
* @vue-prop {string} label Label to be displayed, will be translated.
|
62
|
+
* @vue-prop {string} label - Label to be displayed, will be translated.
|
62
63
|
*/
|
63
64
|
export default {
|
64
65
|
name: 'VcsCheckbox',
|
65
|
-
components: {
|
66
|
+
components: {
|
67
|
+
VcsTooltip,
|
68
|
+
VcsLabel,
|
69
|
+
VCheckbox,
|
70
|
+
},
|
66
71
|
props: {
|
67
72
|
tooltipPosition: {
|
68
73
|
type: String,
|
@@ -31,6 +31,7 @@
|
|
31
31
|
} from 'vue';
|
32
32
|
import { Subject } from 'rxjs';
|
33
33
|
import { debounceTime, takeUntil } from 'rxjs/operators';
|
34
|
+
import { VColorPicker } from 'vuetify/lib';
|
34
35
|
|
35
36
|
/**
|
36
37
|
* @description
|
@@ -38,6 +39,9 @@
|
|
38
39
|
*/
|
39
40
|
export default {
|
40
41
|
name: 'VcsColorPicker',
|
42
|
+
components: {
|
43
|
+
VColorPicker,
|
44
|
+
},
|
41
45
|
props: {
|
42
46
|
width: {
|
43
47
|
type: Number,
|
@@ -5,12 +5,23 @@
|
|
5
5
|
<div class="form-section-header d-flex justify-space-between align-center">
|
6
6
|
<strong class="caption">{{ $t(title) }}</strong>
|
7
7
|
<VcsActionButtonList
|
8
|
-
:actions="
|
8
|
+
:actions="actions"
|
9
9
|
small
|
10
10
|
/>
|
11
11
|
</div>
|
12
12
|
</article>
|
13
13
|
</slot>
|
14
|
+
<v-alert
|
15
|
+
:value="showHelp"
|
16
|
+
dense
|
17
|
+
text
|
18
|
+
color="secondary"
|
19
|
+
class="ma-0"
|
20
|
+
>
|
21
|
+
<slot name="help">
|
22
|
+
<span>{{ $t(helpText) }}</span>
|
23
|
+
</slot>
|
24
|
+
</v-alert>
|
14
25
|
<article class="section-content">
|
15
26
|
<slot />
|
16
27
|
</article>
|
@@ -19,6 +30,8 @@
|
|
19
30
|
|
20
31
|
|
21
32
|
<script>
|
33
|
+
import { computed, ref } from 'vue';
|
34
|
+
import { VAlert } from 'vuetify/lib';
|
22
35
|
import VcsActionButtonList from '../buttons/VcsActionButtonList.vue';
|
23
36
|
|
24
37
|
/**
|
@@ -26,12 +39,18 @@
|
|
26
39
|
* Stylized form section with action buttons
|
27
40
|
* @vue-data {slot} [#title] - slot to override form section header
|
28
41
|
* @vue-data {slot} [#default] - slot with the section content
|
42
|
+
* @vue-data {slot} [#help] - Slot to specify html based help. Gets precedence over helpText prop.
|
29
43
|
* @vue-prop {string} title - Title to be displayed, will be translated.
|
30
44
|
* @vue-prop {Array<VcsAction>} titleActions - Icons to be displayed on the right side
|
45
|
+
* @vue-prop {string} [helpText] - Optional help text. Must be plain string. Use 'help' slot for html based help texts. Help slot has precedence over helpText prop.
|
46
|
+
* @vue-computed {Array<VcsAction>} actions - Returns title actions extended by a help action, if help prop is passed or help slot is used.
|
31
47
|
*/
|
32
48
|
export default {
|
33
49
|
name: 'VcsFormSection',
|
34
|
-
components: {
|
50
|
+
components: {
|
51
|
+
VcsActionButtonList,
|
52
|
+
VAlert,
|
53
|
+
},
|
35
54
|
props: {
|
36
55
|
title: {
|
37
56
|
type: String,
|
@@ -41,6 +60,33 @@
|
|
41
60
|
type: Array,
|
42
61
|
default: () => ([]),
|
43
62
|
},
|
63
|
+
helpText: {
|
64
|
+
type: String,
|
65
|
+
default: undefined,
|
66
|
+
},
|
67
|
+
},
|
68
|
+
setup(props, { slots }) {
|
69
|
+
const showHelp = ref(false);
|
70
|
+
const helpAction = {
|
71
|
+
name: 'help',
|
72
|
+
title: 'components.vcsFormSection.help',
|
73
|
+
icon: 'mdi-help-circle',
|
74
|
+
callback: () => { showHelp.value = !showHelp.value; },
|
75
|
+
};
|
76
|
+
/**
|
77
|
+
* @type {ComputedRef<VcsAction>}
|
78
|
+
*/
|
79
|
+
const actions = computed(() => {
|
80
|
+
if (props.helpText || (slots.help && slots.help().length > 0)) {
|
81
|
+
return [helpAction, ...props.titleActions];
|
82
|
+
}
|
83
|
+
return props.titleActions;
|
84
|
+
});
|
85
|
+
|
86
|
+
return {
|
87
|
+
showHelp,
|
88
|
+
actions,
|
89
|
+
};
|
44
90
|
},
|
45
91
|
};
|
46
92
|
</script>
|
@@ -70,6 +70,7 @@
|
|
70
70
|
}
|
71
71
|
</style>
|
72
72
|
<script>
|
73
|
+
import { VRadio, VRadioGroup } from 'vuetify/lib';
|
73
74
|
import VcsTooltip from '../notification/VcsTooltip.vue';
|
74
75
|
import VcsLabel from './VcsLabel.vue';
|
75
76
|
import validate from '../notification/validation.js';
|
@@ -94,7 +95,12 @@
|
|
94
95
|
*/
|
95
96
|
export default {
|
96
97
|
name: 'VcsRadio',
|
97
|
-
components: {
|
98
|
+
components: {
|
99
|
+
VcsTooltip,
|
100
|
+
VcsLabel,
|
101
|
+
VRadioGroup,
|
102
|
+
VRadio,
|
103
|
+
},
|
98
104
|
props: {
|
99
105
|
tooltipPosition: {
|
100
106
|
type: String,
|
@@ -49,6 +49,7 @@
|
|
49
49
|
</style>
|
50
50
|
<script>
|
51
51
|
|
52
|
+
import { VSelect } from 'vuetify/lib';
|
52
53
|
import VcsTooltip from '../notification/VcsTooltip.vue';
|
53
54
|
import validate from '../notification/validation.js';
|
54
55
|
|
@@ -64,7 +65,10 @@
|
|
64
65
|
*/
|
65
66
|
export default {
|
66
67
|
name: 'VcsSelect',
|
67
|
-
components: {
|
68
|
+
components: {
|
69
|
+
VcsTooltip,
|
70
|
+
VSelect,
|
71
|
+
},
|
68
72
|
props: {
|
69
73
|
tooltipPosition: {
|
70
74
|
type: String,
|
@@ -51,6 +51,7 @@
|
|
51
51
|
</style>
|
52
52
|
|
53
53
|
<script>
|
54
|
+
import { VTextarea } from 'vuetify/lib';
|
54
55
|
import VcsTooltip from '../notification/VcsTooltip.vue';
|
55
56
|
|
56
57
|
/**
|
@@ -73,6 +74,7 @@
|
|
73
74
|
name: 'VcsTextArea',
|
74
75
|
components: {
|
75
76
|
VcsTooltip,
|
77
|
+
VTextarea,
|
76
78
|
},
|
77
79
|
props: {
|
78
80
|
tooltipPosition: {
|
@@ -51,10 +51,11 @@
|
|
51
51
|
</style>
|
52
52
|
|
53
53
|
<script>
|
54
|
+
import { VTextField } from 'vuetify/lib';
|
54
55
|
import VcsTooltip from '../notification/VcsTooltip.vue';
|
55
56
|
|
56
57
|
/**
|
57
|
-
* @description extends API of {@link https://vuetifyjs.com/en/api/v-text-field
|
58
|
+
* @description extends API of {@link https://vuetifyjs.com/en/api/v-text-field v-text-field}.
|
58
59
|
* Provides two height options depending on "dense" property:
|
59
60
|
* - if dense is set true (default), height is 24 px
|
60
61
|
* - if dense is set false, height is 32 px
|
@@ -72,6 +73,7 @@
|
|
72
73
|
name: 'VcsTextField',
|
73
74
|
components: {
|
74
75
|
VcsTooltip,
|
76
|
+
VTextField,
|
75
77
|
},
|
76
78
|
props: {
|
77
79
|
tooltipPosition: {
|
@@ -101,7 +103,7 @@
|
|
101
103
|
return this.joinedErrorBucket.length > 0 && (this.firstInput || !this.neverBlurred);
|
102
104
|
},
|
103
105
|
isOutlined() {
|
104
|
-
return (this.hover || this.focus || this.isError) && !(this.$attrs.disabled || this.$attrs.disabled === '');
|
106
|
+
return (this.$attrs.outlined || this.hover || this.focus || this.isError) && !(this.$attrs.disabled || this.$attrs.disabled === '');
|
105
107
|
},
|
106
108
|
joinedErrorBucket() {
|
107
109
|
if (!this.isMounted) {
|
@@ -124,6 +126,8 @@
|
|
124
126
|
},
|
125
127
|
mounted() {
|
126
128
|
this.isMounted = true;
|
129
|
+
// fix for autofocus
|
130
|
+
this.focus = this.$attrs.autofocus != null;
|
127
131
|
},
|
128
132
|
};
|
129
133
|
</script>
|
@@ -40,6 +40,9 @@
|
|
40
40
|
</style>
|
41
41
|
<script>
|
42
42
|
import { is } from '@vcsuite/check';
|
43
|
+
import {
|
44
|
+
VIcon, VList, VListItem, VListItemContent, VListItemIcon, VListItemTitle,
|
45
|
+
} from 'vuetify/lib';
|
43
46
|
import VcsTooltip from '../notification/VcsTooltip.vue';
|
44
47
|
|
45
48
|
/**
|
@@ -91,7 +94,15 @@
|
|
91
94
|
*/
|
92
95
|
export default {
|
93
96
|
name: 'VcsActionList',
|
94
|
-
components: {
|
97
|
+
components: {
|
98
|
+
VcsTooltip,
|
99
|
+
VList,
|
100
|
+
VListItem,
|
101
|
+
VListItemIcon,
|
102
|
+
VIcon,
|
103
|
+
VListItemTitle,
|
104
|
+
VListItemContent,
|
105
|
+
},
|
95
106
|
props: {
|
96
107
|
actions: {
|
97
108
|
type: Array,
|
@@ -56,6 +56,7 @@
|
|
56
56
|
|
57
57
|
<script>
|
58
58
|
import { getCurrentInstance, ref } from 'vue';
|
59
|
+
import { VTreeview } from 'vuetify/lib';
|
59
60
|
import VcsTreeviewLeaf from './VcsTreeviewLeaf.vue';
|
60
61
|
import VcsTreeviewSearchbar from './VcsTreeviewSearchbar.vue';
|
61
62
|
|
@@ -68,7 +69,11 @@
|
|
68
69
|
*/
|
69
70
|
export default {
|
70
71
|
name: 'VcsTreeview',
|
71
|
-
components: {
|
72
|
+
components: {
|
73
|
+
VcsTreeviewSearchbar,
|
74
|
+
VcsTreeviewLeaf,
|
75
|
+
VTreeview,
|
76
|
+
},
|
72
77
|
props: {
|
73
78
|
showSearchbar: {
|
74
79
|
type: Boolean,
|
@@ -46,6 +46,7 @@
|
|
46
46
|
ref,
|
47
47
|
} from 'vue';
|
48
48
|
|
49
|
+
import { VIcon } from 'vuetify/lib';
|
49
50
|
import VcsActionButtonList from '../buttons/VcsActionButtonList.vue';
|
50
51
|
|
51
52
|
|
@@ -62,7 +63,10 @@
|
|
62
63
|
* @vue-computed {boolean} leaf - Whether the item is a leaf item or not
|
63
64
|
*/
|
64
65
|
export default {
|
65
|
-
components: {
|
66
|
+
components: {
|
67
|
+
VcsActionButtonList,
|
68
|
+
VIcon,
|
69
|
+
},
|
66
70
|
props: {
|
67
71
|
item: {
|
68
72
|
type: Object,
|