@vcmap/ui 5.0.0-rc.26 → 5.0.0-rc.27
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/build/buildCesium.js +7 -0
- package/config/dev.config.json +4 -0
- package/dist/assets/cesium/ThirdParty/Workers/basis_transcoder.js +21 -0
- package/dist/assets/cesium/ThirdParty/Workers/draco_decoder_nodejs.js +117 -0
- package/dist/assets/cesium/ThirdParty/Workers/package.json +1 -0
- package/dist/assets/cesium/ThirdParty/Workers/pako_deflate.min.js +2 -0
- package/dist/assets/cesium/ThirdParty/Workers/pako_inflate.min.js +2 -0
- package/dist/assets/cesium/ThirdParty/Workers/z-worker-pako.js +1 -0
- package/dist/assets/cesium/ThirdParty/basis_transcoder.wasm +0 -0
- package/dist/assets/cesium/ThirdParty/draco_decoder.wasm +0 -0
- package/dist/assets/cesium/ThirdParty/google-earth-dbroot-parser.js +8337 -0
- package/dist/assets/{cesium.305b7c.js → cesium.82fdbe.js} +4 -4
- package/dist/assets/cesium.js +1 -1
- package/dist/assets/{core.f3d6d4.js → core.df069a.js} +2 -2
- package/dist/assets/core.js +1 -1
- package/dist/assets/index-1cff371d.js +1 -0
- package/dist/assets/ol.js +1 -1
- package/dist/assets/style/icon-marker-blue.534e37.png +0 -0
- package/dist/assets/style/icon-marker-green.0b6a92.png +0 -0
- package/dist/assets/style/icon-marker-o-blue.7b6d62.png +0 -0
- package/dist/assets/style/icon-marker-o-green.c863c0.png +0 -0
- package/dist/assets/style/icon-marker-o-red.93ff58.png +0 -0
- package/dist/assets/style/icon-marker-o.036477.png +0 -0
- package/dist/assets/style/icon-marker-red.313d03.png +0 -0
- package/dist/assets/style/icon-marker.70960f.png +0 -0
- package/dist/assets/style/icon-pin-blue.7be369.png +0 -0
- package/dist/assets/style/icon-pin-green.cbb935.png +0 -0
- package/dist/assets/style/icon-pin-red.3f25b2.png +0 -0
- package/dist/assets/style/icon-pin.b7ce77.png +0 -0
- package/dist/assets/{ui.74022f.css → ui.3ed7ff.css} +2 -2
- package/dist/assets/ui.3ed7ff.js +14763 -0
- package/dist/assets/ui.js +1 -1
- package/dist/assets/vue.js +2 -2
- package/dist/assets/{vuetify.30486f.js → vuetify.614278.js} +1 -1
- package/dist/assets/vuetify.js +2 -2
- package/dist/index.html +1 -1
- package/index.js +17 -1
- package/package.json +1 -1
- package/plugins/@vcmap/create-link/index.js +8 -8
- package/plugins/@vcmap-show-case/collection-manager-example/index.js +6 -1
- package/plugins/@vcmap-show-case/form-inputs-example/FormInputsExample.vue +36 -8
- package/plugins/@vcmap-show-case/form-inputs-example/exampleActions.js +0 -19
- package/plugins/@vcmap-show-case/form-inputs-example/index.js +1 -2
- package/plugins/@vcmap-show-case/style-input-example/README.md +4 -0
- package/plugins/@vcmap-show-case/style-input-example/index.js +42 -0
- package/plugins/@vcmap-show-case/style-input-example/package.json +5 -0
- package/plugins/@vcmap-show-case/style-input-example/styleExample.vue +191 -0
- package/plugins/@vcmap-show-case/window-tester/WindowExample.vue +12 -13
- package/plugins/@vcmap-show-case/window-tester/windowExampleToggleChild.vue +44 -0
- package/public/assets/style/icon-marker-blue.png +0 -0
- package/public/assets/style/icon-marker-green.png +0 -0
- package/public/assets/style/icon-marker-o-blue.png +0 -0
- package/public/assets/style/icon-marker-o-green.png +0 -0
- package/public/assets/style/icon-marker-o-red.png +0 -0
- package/public/assets/style/icon-marker-o.png +0 -0
- package/public/assets/style/icon-marker-red.png +0 -0
- package/public/assets/style/icon-marker.png +0 -0
- package/public/assets/style/icon-pin-blue.png +0 -0
- package/public/assets/style/icon-pin-green.png +0 -0
- package/public/assets/style/icon-pin-red.png +0 -0
- package/public/assets/style/icon-pin.png +0 -0
- package/src/actions/actionHelper.js +1 -0
- package/src/application/VcsApp.vue +7 -1
- package/src/components/buttons/VcsActionButtonList.vue +1 -0
- package/src/components/form-inputs-controls/VcsCheckbox.vue +3 -2
- package/src/components/form-inputs-controls/VcsFormSection.vue +59 -9
- package/src/components/form-inputs-controls/VcsLabel.vue +10 -0
- package/src/components/form-inputs-controls/VcsRadioGrid.vue +175 -0
- package/src/components/form-inputs-controls/VcsSelect.vue +3 -0
- package/src/components/form-inputs-controls/VcsTextField.vue +12 -0
- package/src/components/icons/+all.js +4 -0
- package/src/components/icons/EditVerticesIcon.vue +39 -0
- package/src/components/lists/VcsActionList.vue +2 -0
- package/src/components/style/MenuWrapper.vue +138 -0
- package/src/components/style/VcsFillMenu.vue +61 -0
- package/src/components/style/VcsFillSelector.vue +45 -0
- package/src/components/style/VcsImageMenu.vue +84 -0
- package/src/components/style/VcsImageSelector.vue +609 -0
- package/src/components/style/VcsStrokeMenu.vue +73 -0
- package/src/components/style/VcsStrokeSelector.vue +87 -0
- package/src/components/style/VcsTextMenu.vue +81 -0
- package/src/components/style/VcsTextSelector.vue +271 -0
- package/src/components/style/VcsVectorStyleComponent.vue +119 -0
- package/src/components/style/composables.js +84 -0
- package/src/contentTree/contentTreeCollection.js +1 -0
- package/src/i18n/de.js +51 -17
- package/src/i18n/en.js +56 -22
- package/src/legend/vcsLegend.vue +7 -5
- package/src/manager/collectionManager/CollectionComponent.vue +9 -17
- package/src/manager/collectionManager/CollectionComponentList.vue +22 -9
- package/src/manager/collectionManager/CollectionManager.vue +20 -1
- package/src/manager/collectionManager/collectionComponent.js +11 -0
- package/src/manager/window/WindowComponent.vue +2 -1
- package/src/manager/window/WindowManager.vue +23 -9
- package/src/manager/window/windowHelper.js +76 -4
- package/src/manager/window/windowManager.js +38 -6
- package/src/vcsUiApp.js +1 -0
- package/dist/assets/index-f94d5be3.js +0 -1
- package/dist/assets/ui.74022f.js +0 -13466
- /package/dist/assets/{ol.39cc05.js → ol.90a5d0.js} +0 -0
- /package/dist/assets/{vue.9b8c6e.js → vue.537ff3.js} +0 -0
- /package/dist/assets/{vuetify.30486f.css → vuetify.614278.css} +0 -0
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -154,6 +154,11 @@
|
|
154
154
|
CesiumMap: '$vcs3d',
|
155
155
|
ObliqueMap: '$vcsObliqueView',
|
156
156
|
};
|
157
|
+
const mapBtnWeight = {
|
158
|
+
OpenlayersMap: 3,
|
159
|
+
CesiumMap: 2,
|
160
|
+
ObliqueMap: 1,
|
161
|
+
};
|
157
162
|
|
158
163
|
const mapButtonActionDestroy = {};
|
159
164
|
const setupMap = ({ className, name }) => {
|
@@ -173,6 +178,7 @@
|
|
173
178
|
{
|
174
179
|
id: `mapButton-${name}`,
|
175
180
|
action,
|
181
|
+
weight: mapBtnWeight[className],
|
176
182
|
},
|
177
183
|
vcsAppSymbol,
|
178
184
|
ButtonLocation.MAP,
|
@@ -342,7 +348,7 @@
|
|
342
348
|
provides: {
|
343
349
|
collectionManager: app.categoryManager,
|
344
350
|
},
|
345
|
-
slot: WindowSlot.
|
351
|
+
slot: WindowSlot.DYNAMIC_LEFT,
|
346
352
|
},
|
347
353
|
app.windowManager,
|
348
354
|
vcsAppSymbol,
|
@@ -1,29 +1,49 @@
|
|
1
1
|
<template>
|
2
2
|
<section class="vcs-form-section">
|
3
3
|
<slot name="header" :heading="heading" :actions="actions">
|
4
|
-
<
|
5
|
-
<div
|
6
|
-
class="
|
7
|
-
|
8
|
-
|
4
|
+
<div class="vcs-form-section-header d-flex base lighten-3">
|
5
|
+
<div class="d-flex justify-space-between w-full">
|
6
|
+
<div class="d-flex align-center" :class="{ 'px-2': !expandable }">
|
7
|
+
<v-btn
|
8
|
+
:ripple="false"
|
9
|
+
dense
|
10
|
+
plain
|
11
|
+
icon
|
12
|
+
small
|
13
|
+
text
|
14
|
+
:disabled="disabled"
|
15
|
+
elevation="0"
|
16
|
+
@click="open = !open"
|
17
|
+
v-if="expandable"
|
18
|
+
>
|
19
|
+
<v-icon>{{
|
20
|
+
open ? 'mdi-chevron-down' : 'mdi-chevron-right'
|
21
|
+
}}</v-icon>
|
22
|
+
</v-btn>
|
23
|
+
<strong :class="{ 'text--disabled': disabled }">{{
|
24
|
+
$t(heading)
|
25
|
+
}}</strong>
|
26
|
+
</div>
|
9
27
|
<VcsActionButtonList
|
10
28
|
:actions="actions"
|
11
29
|
:overflow-count="actionButtonListOverflowCount"
|
30
|
+
class="pa-2"
|
12
31
|
/>
|
13
32
|
</div>
|
14
|
-
</
|
33
|
+
</div>
|
15
34
|
</slot>
|
16
35
|
<VcsHelp :text="helpText" :show="showHelp" class="base lighten-4">
|
17
36
|
<slot name="help" />
|
18
37
|
</VcsHelp>
|
19
|
-
<article class="section-content">
|
38
|
+
<article class="section-content" v-if="showContent">
|
20
39
|
<slot />
|
21
40
|
</article>
|
22
41
|
</section>
|
23
42
|
</template>
|
24
43
|
|
25
44
|
<script>
|
26
|
-
import { computed, reactive } from 'vue';
|
45
|
+
import { computed, reactive, ref } from 'vue';
|
46
|
+
import { VBtn, VIcon } from 'vuetify/lib';
|
27
47
|
import VcsActionButtonList from '../buttons/VcsActionButtonList.vue';
|
28
48
|
import VcsHelp from '../notification/VcsHelp.vue';
|
29
49
|
|
@@ -34,6 +54,9 @@
|
|
34
54
|
* @vue-data {slot} [#default] - slot with the section content
|
35
55
|
* @vue-data {slot} [#help] - Slot to specify html based help. Gets precedence over helpText prop.
|
36
56
|
* @vue-prop {string} heading - Title of the section to be displayed, will be translated.
|
57
|
+
* @vue-prop {boolean} [expandable=false] - If true, section can be toggled.
|
58
|
+
* @vue-prop {boolean} [startOpen=false] - If section starts open.
|
59
|
+
* @vue-prop {boolean} [disabled=false] - If expansion is disabled. Title is rendered in disabled style.
|
37
60
|
* @vue-prop {Array<VcsAction>} headerActions - Icons to be displayed on the right side
|
38
61
|
* @vue-prop {number} [actionButtonListOverflowCount] - overflow count to use for action lists in the title and items
|
39
62
|
* @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.
|
@@ -42,6 +65,8 @@
|
|
42
65
|
export default {
|
43
66
|
name: 'VcsFormSection',
|
44
67
|
components: {
|
68
|
+
VBtn,
|
69
|
+
VIcon,
|
45
70
|
VcsActionButtonList,
|
46
71
|
VcsHelp,
|
47
72
|
},
|
@@ -50,6 +75,18 @@
|
|
50
75
|
type: String,
|
51
76
|
default: undefined,
|
52
77
|
},
|
78
|
+
expandable: {
|
79
|
+
type: Boolean,
|
80
|
+
default: false,
|
81
|
+
},
|
82
|
+
startOpen: {
|
83
|
+
type: Boolean,
|
84
|
+
default: false,
|
85
|
+
},
|
86
|
+
disabled: {
|
87
|
+
type: Boolean,
|
88
|
+
default: false,
|
89
|
+
},
|
53
90
|
headerActions: {
|
54
91
|
type: Array,
|
55
92
|
default: () => [],
|
@@ -65,6 +102,13 @@
|
|
65
102
|
},
|
66
103
|
},
|
67
104
|
setup(props, { slots }) {
|
105
|
+
const open = ref(props.startOpen);
|
106
|
+
const showContent = computed(() => {
|
107
|
+
if (props.expandable) {
|
108
|
+
return open.value;
|
109
|
+
}
|
110
|
+
return true;
|
111
|
+
});
|
68
112
|
const helpAction = reactive({
|
69
113
|
name: 'help',
|
70
114
|
title: 'components.vcsFormSection.help',
|
@@ -86,6 +130,8 @@
|
|
86
130
|
});
|
87
131
|
|
88
132
|
return {
|
133
|
+
open,
|
134
|
+
showContent,
|
89
135
|
showHelp,
|
90
136
|
actions,
|
91
137
|
};
|
@@ -93,7 +139,11 @@
|
|
93
139
|
};
|
94
140
|
</script>
|
95
141
|
|
96
|
-
<style scoped>
|
142
|
+
<style lang="scss" scoped>
|
143
|
+
@import '../../styles/shades.scss';
|
144
|
+
.vcs-form-section-header {
|
145
|
+
height: 40px;
|
146
|
+
}
|
97
147
|
.v-alert--text:before {
|
98
148
|
background-color: transparent;
|
99
149
|
}
|
@@ -4,6 +4,7 @@
|
|
4
4
|
class="vcs-label"
|
5
5
|
:class="{
|
6
6
|
'vcs-label-dense': dense,
|
7
|
+
'vcs-label-required': required,
|
7
8
|
'px-1': dense,
|
8
9
|
'px-2': !dense,
|
9
10
|
}"
|
@@ -22,6 +23,10 @@
|
|
22
23
|
.vcs-label-dense {
|
23
24
|
line-height: $line-height-dense;
|
24
25
|
}
|
26
|
+
.vcs-label-required:after {
|
27
|
+
content: ' *';
|
28
|
+
color: var(--v-error-base);
|
29
|
+
}
|
25
30
|
</style>
|
26
31
|
<script>
|
27
32
|
/**
|
@@ -29,6 +34,7 @@
|
|
29
34
|
* pass the label text as innerHtml
|
30
35
|
* @vue-prop {string} htmlFor - an id reference the label is meant for
|
31
36
|
* @vue-prop {boolean} [dense=true] - default line height is 32px (dense). If set false, height is 40px.
|
37
|
+
* @vue-prop {boolean} [required=false] - Marks an input field as required by adding an asterisk after the label.
|
32
38
|
*/
|
33
39
|
export default {
|
34
40
|
name: 'VcsLabel',
|
@@ -41,6 +47,10 @@
|
|
41
47
|
type: Boolean,
|
42
48
|
default: true,
|
43
49
|
},
|
50
|
+
required: {
|
51
|
+
type: Boolean,
|
52
|
+
default: false,
|
53
|
+
},
|
44
54
|
},
|
45
55
|
};
|
46
56
|
</script>
|
@@ -0,0 +1,175 @@
|
|
1
|
+
<template>
|
2
|
+
<VcsTooltip
|
3
|
+
:tooltip-position="tooltipPosition"
|
4
|
+
:tooltip="errorMessage"
|
5
|
+
color="error"
|
6
|
+
:max-width="200"
|
7
|
+
>
|
8
|
+
<template #activator="{ on, attrs }">
|
9
|
+
<v-container v-on="on" class="py-0" :class="isDense ? 'px-1' : 'px-2'">
|
10
|
+
<v-radio-group
|
11
|
+
ref="radioGroup"
|
12
|
+
hide-details
|
13
|
+
class="vcs-radio-group"
|
14
|
+
:ripple="false"
|
15
|
+
:dense="isDense"
|
16
|
+
v-bind="{ ...$attrs, ...attrs }"
|
17
|
+
v-on="{ ...$listeners, ...on }"
|
18
|
+
>
|
19
|
+
<v-row no-gutters class="justify-center">
|
20
|
+
<v-col
|
21
|
+
v-for="(item, idx) in items"
|
22
|
+
:key="idx"
|
23
|
+
cols="1"
|
24
|
+
class="mx-2"
|
25
|
+
>
|
26
|
+
<v-row no-gutters>
|
27
|
+
<v-col>
|
28
|
+
<div
|
29
|
+
class="d-flex justify-center label-wrapper pt-1"
|
30
|
+
:class="$attrs.disabled ? 'disabled' : ''"
|
31
|
+
>
|
32
|
+
<slot name="label" :value="item[itemValue]" :src="item.src">
|
33
|
+
<img
|
34
|
+
:src="item.src"
|
35
|
+
:alt="item[itemValue]"
|
36
|
+
class="image"
|
37
|
+
/>
|
38
|
+
</slot>
|
39
|
+
</div>
|
40
|
+
</v-col>
|
41
|
+
</v-row>
|
42
|
+
<v-row no-gutters>
|
43
|
+
<v-col>
|
44
|
+
<v-radio
|
45
|
+
:value="item[itemValue]"
|
46
|
+
:ripple="false"
|
47
|
+
class="ma-0"
|
48
|
+
:class="isDense ? 'vcs-radio-dense' : 'vcs-radio'"
|
49
|
+
:dense="isDense"
|
50
|
+
/>
|
51
|
+
</v-col>
|
52
|
+
</v-row>
|
53
|
+
</v-col>
|
54
|
+
</v-row>
|
55
|
+
</v-radio-group>
|
56
|
+
</v-container>
|
57
|
+
</template>
|
58
|
+
</VcsTooltip>
|
59
|
+
</template>
|
60
|
+
|
61
|
+
<script>
|
62
|
+
import { computed, ref } from 'vue';
|
63
|
+
import { VContainer, VRow, VCol, VRadioGroup, VRadio } from 'vuetify/lib';
|
64
|
+
import { VcsTooltip } from '@vcmap/ui';
|
65
|
+
import { useErrorSync } from './composables.js';
|
66
|
+
|
67
|
+
/**
|
68
|
+
* @description Stylized wrapper around {@link https://vuetifyjs.com/en/api/v-radio-group/ |vuetify radio group} which places icons or raster src files above the radio buttons as labels and arranges them in a grid.
|
69
|
+
* @vue-prop {{value: string, src: string}[]} items - The items to be displayed in the grid. The src is the path to the raster image.
|
70
|
+
* @vue-prop {('bottom' | 'left' | 'top' | 'right')} [tooltipPosition='right'] - Position of the error tooltip.
|
71
|
+
* @vue-prop {string} itemValue - The key of the provided item objects that contains the value.
|
72
|
+
* @vue-data {slot} [#label] - slot to display labels where the src does not contain a path to an img but e.g. the name of an icon. Then an v-icon can be used in the slot.
|
73
|
+
*/
|
74
|
+
export default {
|
75
|
+
name: 'VcsRadioGrid',
|
76
|
+
components: {
|
77
|
+
VContainer,
|
78
|
+
VRow,
|
79
|
+
VCol,
|
80
|
+
VRadioGroup,
|
81
|
+
VRadio,
|
82
|
+
VcsTooltip,
|
83
|
+
},
|
84
|
+
props: {
|
85
|
+
items: {
|
86
|
+
type: Array,
|
87
|
+
required: true,
|
88
|
+
},
|
89
|
+
tooltipPosition: {
|
90
|
+
type: String,
|
91
|
+
default: 'right',
|
92
|
+
},
|
93
|
+
itemValue: {
|
94
|
+
type: String,
|
95
|
+
default: 'value',
|
96
|
+
},
|
97
|
+
},
|
98
|
+
setup(props, { attrs }) {
|
99
|
+
const radioGroup = ref();
|
100
|
+
|
101
|
+
const errorMessage = useErrorSync(radioGroup);
|
102
|
+
return {
|
103
|
+
isDense: computed(() => attrs.dense !== false),
|
104
|
+
radioGroup,
|
105
|
+
errorMessage,
|
106
|
+
};
|
107
|
+
},
|
108
|
+
model: {
|
109
|
+
event: 'change',
|
110
|
+
},
|
111
|
+
};
|
112
|
+
</script>
|
113
|
+
|
114
|
+
<style lang="scss" scoped>
|
115
|
+
// TODO: scss for radio buttons should be moved to own file.
|
116
|
+
@import '../../styles/vcsFont.scss';
|
117
|
+
@import '../../styles/shades.scss';
|
118
|
+
.v-input--radio-group--column .v-radio:not(:last-child):not(:only-child) {
|
119
|
+
margin-bottom: 0;
|
120
|
+
}
|
121
|
+
.v-input {
|
122
|
+
&.vcs-radio-group {
|
123
|
+
::v-deep {
|
124
|
+
margin-top: 0;
|
125
|
+
padding-top: 0;
|
126
|
+
label.v-label,
|
127
|
+
.v-icon.v-icon {
|
128
|
+
font-size: $vcs-font-size;
|
129
|
+
color: inherit;
|
130
|
+
&.theme--light {
|
131
|
+
color: map-get($shades, 'black') !important;
|
132
|
+
&.error--text {
|
133
|
+
color: var(--v-error-base) !important;
|
134
|
+
}
|
135
|
+
}
|
136
|
+
&.theme--dark {
|
137
|
+
color: map-get($shades, 'white') !important;
|
138
|
+
&.error--text {
|
139
|
+
color: var(--v-error-base) !important;
|
140
|
+
}
|
141
|
+
}
|
142
|
+
}
|
143
|
+
.v-radio:not(:last-child):not(:only-child) {
|
144
|
+
margin-bottom: 0;
|
145
|
+
}
|
146
|
+
.v-input--selection-controls__input {
|
147
|
+
margin: 0;
|
148
|
+
}
|
149
|
+
label.v-label.error--text {
|
150
|
+
animation: none;
|
151
|
+
}
|
152
|
+
}
|
153
|
+
}
|
154
|
+
}
|
155
|
+
.vcs-radio {
|
156
|
+
height: 40px;
|
157
|
+
align-items: center;
|
158
|
+
}
|
159
|
+
.vcs-radio-dense {
|
160
|
+
height: 32px;
|
161
|
+
align-items: center;
|
162
|
+
}
|
163
|
+
.image {
|
164
|
+
max-height: 24px;
|
165
|
+
max-width: 24px;
|
166
|
+
height: auto;
|
167
|
+
width: auto;
|
168
|
+
}
|
169
|
+
.label-wrapper {
|
170
|
+
width: 24px;
|
171
|
+
}
|
172
|
+
.disabled {
|
173
|
+
opacity: 0.3;
|
174
|
+
}
|
175
|
+
</style>
|
@@ -24,6 +24,7 @@
|
|
24
24
|
v-bind="{ ...$attrs, ...attrs }"
|
25
25
|
v-on="{ ...$listeners, ...on }"
|
26
26
|
:height="isDense ? 24 : 32"
|
27
|
+
:rules="rules"
|
27
28
|
class="py-1 primary--placeholder align-center"
|
28
29
|
:class="{
|
29
30
|
'remove-outline': !isOutlined,
|
@@ -244,6 +245,16 @@
|
|
244
245
|
}
|
245
246
|
});
|
246
247
|
|
248
|
+
const rules = computed(() => {
|
249
|
+
if (attrs.type === 'number' && Array.isArray(attrs.rules)) {
|
250
|
+
return attrs.rules.map((rule) => {
|
251
|
+
return (value) => rule(parseFloat(value));
|
252
|
+
});
|
253
|
+
} else {
|
254
|
+
return attrs.rules;
|
255
|
+
}
|
256
|
+
});
|
257
|
+
|
247
258
|
function onEscape(event) {
|
248
259
|
textFieldRef.value.blur();
|
249
260
|
emit('input', textFieldRef.value.initialValue);
|
@@ -268,6 +279,7 @@
|
|
268
279
|
isOutlined,
|
269
280
|
visibleValue,
|
270
281
|
type,
|
282
|
+
rules,
|
271
283
|
onEscape,
|
272
284
|
textFieldRef,
|
273
285
|
errorMessage,
|
@@ -22,6 +22,7 @@ import ComponentsIcon from './ComponentsIcon.vue';
|
|
22
22
|
import ConeIcon from './ConeIcon.vue';
|
23
23
|
import DimensionsHouseIcon from './DimensionsHouseIcon.vue';
|
24
24
|
import EditIcon from './EditIcon.vue';
|
25
|
+
import EditVerticesIcon from './EditVerticesIcon.vue';
|
25
26
|
import ElevationProfileIcon from './ElevationProfileIcon.vue';
|
26
27
|
import ExportAreaIcon from './ExportAreaIcon.vue';
|
27
28
|
import ExportFlightIcon from './ExportFlightIcon.vue';
|
@@ -204,6 +205,9 @@ const IconMap = {
|
|
204
205
|
edit: {
|
205
206
|
component: EditIcon,
|
206
207
|
},
|
208
|
+
editVertices: {
|
209
|
+
component: EditVerticesIcon,
|
210
|
+
},
|
207
211
|
elevationProfile: {
|
208
212
|
component: ElevationProfileIcon,
|
209
213
|
},
|
@@ -0,0 +1,39 @@
|
|
1
|
+
<template>
|
2
|
+
<svg
|
3
|
+
xmlns="http://www.w3.org/2000/svg"
|
4
|
+
width="23.907"
|
5
|
+
height="24"
|
6
|
+
viewBox="0 0 23.907 24"
|
7
|
+
>
|
8
|
+
<g id="icon-16-edit_vertex" transform="translate(0 0)">
|
9
|
+
<path
|
10
|
+
id="Path_840"
|
11
|
+
data-name="Path 840"
|
12
|
+
d="M-5.217-90.456l1.376,1.3,6.355-6.38L1.138-96.81Z"
|
13
|
+
transform="translate(5.217 109.281)"
|
14
|
+
fill="currentColor"
|
15
|
+
/>
|
16
|
+
<path
|
17
|
+
id="Path_841"
|
18
|
+
data-name="Path 841"
|
19
|
+
d="M2.9-100.708A2.818,2.818,0,0,0-.074-97.655,2.827,2.827,0,0,0,2.9-94.778,2.8,2.8,0,0,0,5.88-97.655,2.853,2.853,0,0,0,2.9-100.708Z"
|
20
|
+
transform="translate(7.204 107.775)"
|
21
|
+
fill="currentColor"
|
22
|
+
/>
|
23
|
+
<path
|
24
|
+
id="Path_842"
|
25
|
+
data-name="Path 842"
|
26
|
+
d="M3.806-99.513l1.5,1.426,6.3-6.355-1.363-1.363Z"
|
27
|
+
transform="translate(8.703 105.805)"
|
28
|
+
fill="currentColor"
|
29
|
+
/>
|
30
|
+
<path
|
31
|
+
id="Path_843"
|
32
|
+
data-name="Path 843"
|
33
|
+
d="M4.221-96.244,8.771-85.5l1.871-4.384,4.4-1.958Z"
|
34
|
+
transform="translate(8.863 109.5)"
|
35
|
+
fill="currentColor"
|
36
|
+
/>
|
37
|
+
</g>
|
38
|
+
</svg>
|
39
|
+
</template>
|
@@ -53,6 +53,7 @@
|
|
53
53
|
* @property {string} [icon] - icon rendered on the button. If no icon provided, item is rendered in overflow
|
54
54
|
* @property {Function} callback - callback function is triggered when the button is clicked
|
55
55
|
* @property {boolean} [active=false] - optional state of button. If active, button is rendered in primary color
|
56
|
+
* @property {boolean} [hasUpdate=false] - optional hasUpdate of button. If true, a yellow notification is rendered next to the button
|
56
57
|
* @property {boolean} [background=false] - optional background state. If active and background, button is rendered in primary color outlined
|
57
58
|
* @property {boolean} [disabled=false] - optional flag to indicate that the action is disabled
|
58
59
|
*/
|
@@ -68,6 +69,7 @@
|
|
68
69
|
callback: Function,
|
69
70
|
active: [undefined, Boolean],
|
70
71
|
background: [undefined, Boolean],
|
72
|
+
hasUpdate: [undefined, Boolean],
|
71
73
|
disabled: [undefined, Boolean],
|
72
74
|
};
|
73
75
|
|
@@ -0,0 +1,138 @@
|
|
1
|
+
<template>
|
2
|
+
<v-sheet>
|
3
|
+
<div class="d-flex align-center py-1">
|
4
|
+
<VcsCheckbox
|
5
|
+
:value="!!value"
|
6
|
+
@change="handleCheckbox"
|
7
|
+
:disabled="disabled"
|
8
|
+
/>
|
9
|
+
<v-menu
|
10
|
+
:close-on-content-click="false"
|
11
|
+
:close-on-click="false"
|
12
|
+
v-model="isMenuOpen"
|
13
|
+
:absolute="true"
|
14
|
+
:disabled="!value || disabled"
|
15
|
+
min-width="300"
|
16
|
+
max-width="300"
|
17
|
+
>
|
18
|
+
<template #activator="{ on, attrs }">
|
19
|
+
<VcsTooltip :tooltip="name">
|
20
|
+
<template #activator="{ on: tooltipOn, attrs: tooltipAttrs }">
|
21
|
+
<v-card
|
22
|
+
rounded
|
23
|
+
height="24px"
|
24
|
+
width="32px"
|
25
|
+
v-bind="{ ...attrs, ...tooltipAttrs }"
|
26
|
+
v-on="{ ...on, ...tooltipOn }"
|
27
|
+
class="tiled-background"
|
28
|
+
>
|
29
|
+
<slot name="preview" />
|
30
|
+
</v-card>
|
31
|
+
</template>
|
32
|
+
</VcsTooltip>
|
33
|
+
</template>
|
34
|
+
<VcsFormSection
|
35
|
+
:heading="name"
|
36
|
+
:header-actions="[
|
37
|
+
{
|
38
|
+
name: 'reset',
|
39
|
+
title: 'components.style.reset',
|
40
|
+
icon: '$vcsReturn',
|
41
|
+
callback: () => {
|
42
|
+
reset();
|
43
|
+
},
|
44
|
+
},
|
45
|
+
{
|
46
|
+
name: 'close',
|
47
|
+
title: 'components.close',
|
48
|
+
icon: 'mdi-close-thick',
|
49
|
+
callback: () => {
|
50
|
+
close();
|
51
|
+
},
|
52
|
+
},
|
53
|
+
]"
|
54
|
+
>
|
55
|
+
<slot name="content" />
|
56
|
+
</VcsFormSection>
|
57
|
+
</v-menu>
|
58
|
+
<span class="ml-2">{{ $t(name) }}</span>
|
59
|
+
</div>
|
60
|
+
</v-sheet>
|
61
|
+
</template>
|
62
|
+
|
63
|
+
<script>
|
64
|
+
import { ref } from 'vue';
|
65
|
+
import { VSheet, VMenu, VCard } from 'vuetify/lib';
|
66
|
+
import { VcsFormSection, VcsTooltip, VcsCheckbox } from '@vcmap/ui';
|
67
|
+
|
68
|
+
/**
|
69
|
+
* @description A wrapper for style components, that provides:
|
70
|
+
* - a 32 x 24 px preview
|
71
|
+
* - a checkbox that emits null when unchecked and the value of the valueDefault prop when checked again. If the vauleDefault is undefined or null, the valueFallback will be emitted.
|
72
|
+
* - a menu that pops up when clicking the preview. It has also a reset button that emits the value of the valueDefault prop when clicked
|
73
|
+
* @vue-prop {Object} [value] - Style options that are modelled by the checkbox.
|
74
|
+
* @vue-prop {string} name - The name that is displayed in the header of the menu and in the tooltip of the preview.
|
75
|
+
* @vue-prop {Object} [valueDefault] - The default Options, that are applied when clicking reset or setting the checkbox from null to true.
|
76
|
+
* @vue-prop {Object} valueFallback - The fallback Options, in case the valueDefault is null or undefined. These are applied when the checkbox is checked again and the default value is null. The fallback value must not be null or undefined.
|
77
|
+
*/
|
78
|
+
export default {
|
79
|
+
name: 'MenuWrapper',
|
80
|
+
components: {
|
81
|
+
VSheet,
|
82
|
+
VMenu,
|
83
|
+
VCard,
|
84
|
+
VcsFormSection,
|
85
|
+
VcsTooltip,
|
86
|
+
VcsCheckbox,
|
87
|
+
},
|
88
|
+
props: {
|
89
|
+
value: {
|
90
|
+
default: undefined,
|
91
|
+
required: false,
|
92
|
+
type: Object,
|
93
|
+
},
|
94
|
+
valueDefault: {
|
95
|
+
default: undefined,
|
96
|
+
type: Object,
|
97
|
+
},
|
98
|
+
valueFallback: {
|
99
|
+
required: true,
|
100
|
+
type: Object,
|
101
|
+
},
|
102
|
+
name: {
|
103
|
+
required: true,
|
104
|
+
type: String,
|
105
|
+
},
|
106
|
+
disabled: {
|
107
|
+
default: false,
|
108
|
+
type: Boolean,
|
109
|
+
},
|
110
|
+
},
|
111
|
+
setup(props, { emit }) {
|
112
|
+
const isMenuOpen = ref(false);
|
113
|
+
|
114
|
+
return {
|
115
|
+
isMenuOpen,
|
116
|
+
reset() {
|
117
|
+
emit('input', props.valueDefault);
|
118
|
+
},
|
119
|
+
close() {
|
120
|
+
isMenuOpen.value = false;
|
121
|
+
},
|
122
|
+
handleCheckbox(value) {
|
123
|
+
emit(
|
124
|
+
'input',
|
125
|
+
value ? props.valueDefault || props.valueFallback : null,
|
126
|
+
);
|
127
|
+
},
|
128
|
+
};
|
129
|
+
},
|
130
|
+
};
|
131
|
+
</script>
|
132
|
+
|
133
|
+
<style scoped>
|
134
|
+
.tiled-background {
|
135
|
+
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAGElEQVQYlWNgYGCQwoKxgqGgcJA5h3yFAAs8BRWVSwooAAAAAElFTkSuQmCC)
|
136
|
+
repeat;
|
137
|
+
}
|
138
|
+
</style>
|