@vcmap/ui 5.0.0-rc.22 → 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/buildPreview.js +2 -2
- 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 +2 -0
- package/dist/assets/cesium.js +1 -1
- package/dist/assets/{core.a66593.js → core.9342a1.js} +7804 -5352
- package/dist/assets/core.js +1 -1
- package/dist/assets/index.fd041928.js +1 -0
- package/dist/assets/ol.js +1 -1
- package/dist/assets/ui.c27597.css +5 -0
- package/dist/assets/{ui.d760e4.js → ui.c27597.js} +5055 -4694
- package/dist/assets/ui.js +1 -1
- package/dist/assets/vue.js +2 -2
- package/dist/assets/{vuetify.427322.js → vuetify.2f1432.js} +1 -1
- package/dist/assets/vuetify.js +2 -2
- package/dist/index.html +1 -1
- package/index.js +5 -2
- package/package.json +3 -3
- package/plugins/@vcmap/project-selector/{ContextsListComponent.vue → ModulesListComponent.vue} +10 -10
- package/plugins/@vcmap/project-selector/ProjectSelectorComponent.vue +15 -15
- 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-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 +18 -1
- package/plugins/@vcmap-show-case/form-inputs-example/index.js +1 -0
- 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/src/actions/actionHelper.js +16 -27
- package/src/actions/styleSelector.vue +26 -19
- package/src/components/form-inputs-controls/VcsDatePicker.vue +111 -0
- package/src/components/form-inputs-controls/VcsTextField.vue +18 -7
- package/src/components/form-inputs-controls/VcsWizard.vue +3 -1
- package/src/components/icons/CheckboxCheckedIcon.vue +1 -1
- package/src/components/icons/LegendIcon.vue +10 -60
- package/src/components/lists/VcsList.vue +25 -6
- package/src/components/tables/VcsDataTable.vue +386 -0
- package/src/components/tables/VcsTable.vue +33 -278
- package/src/contentTree/contentTreeCollection.js +1 -1
- package/src/contentTree/layerContentTreeItem.js +3 -0
- package/src/downloadHelper.js +49 -0
- package/src/featureInfo/BalloonComponent.vue +9 -8
- package/src/featureInfo/abstractFeatureInfoView.js +1 -1
- package/src/featureInfo/featureInfo.js +3 -3
- package/src/i18n/de.js +8 -0
- package/src/i18n/en.js +8 -0
- package/src/i18n/i18nCollection.js +22 -22
- package/src/init.js +90 -7
- 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/window/WindowComponent.vue +10 -15
- package/src/manager/window/WindowComponentHeader.vue +4 -2
- 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 +5 -5
- package/src/navigation/vcsZoomButton.vue +37 -11
- package/src/pluginHelper.js +20 -0
- package/src/search/search.js +12 -3
- package/src/search/searchComponent.vue +15 -0
- package/src/state.js +6 -6
- package/src/uiConfig.js +3 -3
- package/src/vcsUiApp.js +44 -40
- package/src/vuePlugins/i18n.js +1 -0
- package/start.js +8 -2
- package/dist/assets/index.8b833ead.js +0 -1
- package/dist/assets/ui.d760e4.css +0 -5
- package/map.config.json +0 -44
- /package/dist/assets/{cesium.88cffd.js → cesium.166f91.js} +0 -0
- /package/dist/assets/{ol.d4539f.js → ol.d2cba3.js} +0 -0
- /package/dist/assets/{vue.db5102.js → vue.5d00e9.js} +0 -0
- /package/dist/assets/{vuetify.427322.css → vuetify.2f1432.css} +0 -0
@@ -66,14 +66,12 @@
|
|
66
66
|
VCard,
|
67
67
|
VForm,
|
68
68
|
VTextarea,
|
69
|
-
VBtn,
|
70
69
|
} from 'vuetify/lib';
|
71
70
|
|
72
71
|
export default {
|
73
72
|
name: 'CategoryComponent',
|
74
73
|
components: {
|
75
74
|
VcsButton,
|
76
|
-
VSheet,
|
77
75
|
VVirtualScroll,
|
78
76
|
VListItem,
|
79
77
|
VListItemContent,
|
@@ -84,7 +82,6 @@
|
|
84
82
|
VForm,
|
85
83
|
VTextarea,
|
86
84
|
VSheet,
|
87
|
-
VBtn,
|
88
85
|
},
|
89
86
|
props: {
|
90
87
|
categoryName: {
|
@@ -129,7 +126,7 @@
|
|
129
126
|
dialog.value = false;
|
130
127
|
},
|
131
128
|
download() {
|
132
|
-
const stringObject = JSON.stringify(categoryObject.
|
129
|
+
const stringObject = JSON.stringify(categoryObject.serializeModule(app.dynamicModuleId), null, 2);
|
133
130
|
downloadLink.value = `data:text/json;charset=utf-8,${encodeURIComponent(stringObject)}`;
|
134
131
|
if (downloadLink.value) {
|
135
132
|
nextTick(() => {
|
@@ -8,10 +8,10 @@
|
|
8
8
|
v-else
|
9
9
|
/>
|
10
10
|
|
11
|
-
<VcsButton @click="
|
11
|
+
<VcsButton @click="replaceModule">
|
12
12
|
Apply
|
13
13
|
</VcsButton>
|
14
|
-
<VcsButton @click="
|
14
|
+
<VcsButton @click="removeModule">
|
15
15
|
Remove
|
16
16
|
</VcsButton>
|
17
17
|
</div>
|
@@ -20,10 +20,10 @@
|
|
20
20
|
<script>
|
21
21
|
import { ref, inject } from 'vue';
|
22
22
|
import { VcsButton } from '@vcmap/ui';
|
23
|
-
import {
|
23
|
+
import { VcsModule } from '@vcmap/core';
|
24
24
|
import { VProgressCircular, VTextarea } from 'vuetify/lib';
|
25
25
|
|
26
|
-
const
|
26
|
+
const moduleId = 'foo';
|
27
27
|
|
28
28
|
export default {
|
29
29
|
name: 'Editor',
|
@@ -35,25 +35,25 @@
|
|
35
35
|
setup() {
|
36
36
|
/** @type {VcsUiApp} */
|
37
37
|
const app = inject('vcsApp');
|
38
|
-
const
|
39
|
-
const configString = ref(JSON.stringify(
|
38
|
+
const module = app.getModuleById(moduleId);
|
39
|
+
const configString = ref(JSON.stringify(module ? module.config : {}, null, 2));
|
40
40
|
const loading = ref(false);
|
41
41
|
|
42
42
|
return {
|
43
43
|
configString,
|
44
44
|
loading,
|
45
|
-
async
|
45
|
+
async replaceModule() {
|
46
46
|
loading.value = true;
|
47
47
|
const config = JSON.parse(configString.value);
|
48
|
-
config.id =
|
49
|
-
const
|
50
|
-
await this.
|
51
|
-
await app.
|
48
|
+
config.id = moduleId;
|
49
|
+
const newModule = new VcsModule(config);
|
50
|
+
await this.removeModule();
|
51
|
+
await app.addModule(newModule);
|
52
52
|
loading.value = false;
|
53
53
|
},
|
54
|
-
async
|
55
|
-
if (app.
|
56
|
-
await app.
|
54
|
+
async removeModule() {
|
55
|
+
if (app.getModuleById(moduleId)) {
|
56
|
+
await app.removeModule(moduleId);
|
57
57
|
}
|
58
58
|
},
|
59
59
|
};
|
@@ -143,6 +143,19 @@
|
|
143
143
|
/>
|
144
144
|
</v-col>
|
145
145
|
</v-row>
|
146
|
+
<v-row
|
147
|
+
no-gutters
|
148
|
+
align="center"
|
149
|
+
>
|
150
|
+
<v-col>
|
151
|
+
<VcsLabel html-for="dateInput" :dense="dense">
|
152
|
+
Date
|
153
|
+
</VcsLabel>
|
154
|
+
</v-col>
|
155
|
+
<v-col>
|
156
|
+
<VcsDatePicker id="dateInput" v-model="state.dateInput" />
|
157
|
+
</v-col>
|
158
|
+
</v-row>
|
146
159
|
</v-container>
|
147
160
|
</template>
|
148
161
|
</VcsFormSection>
|
@@ -254,7 +267,9 @@
|
|
254
267
|
</v-row>
|
255
268
|
<v-row no-gutters>
|
256
269
|
<v-col>
|
257
|
-
<VcsLabel :dense="dense">
|
270
|
+
<VcsLabel :dense="dense">
|
271
|
+
Text
|
272
|
+
</VcsLabel>
|
258
273
|
</v-col>
|
259
274
|
</v-row>
|
260
275
|
<v-row
|
@@ -370,6 +385,7 @@
|
|
370
385
|
VcsFormSection,
|
371
386
|
VcsLabel,
|
372
387
|
VcsTextArea,
|
388
|
+
VcsDatePicker,
|
373
389
|
} from '@vcmap/ui';
|
374
390
|
import { VCol, VContainer, VForm, VRow } from 'vuetify/lib';
|
375
391
|
import packageJSON from './package.json';
|
@@ -391,6 +407,7 @@
|
|
391
407
|
VRow,
|
392
408
|
VCol,
|
393
409
|
VContainer,
|
410
|
+
VcsDatePicker,
|
394
411
|
},
|
395
412
|
props: {
|
396
413
|
actions: {
|
@@ -0,0 +1,202 @@
|
|
1
|
+
<template>
|
2
|
+
<v-sheet>
|
3
|
+
<v-sheet class="px-2 d-grid">
|
4
|
+
<v-switch
|
5
|
+
v-model="selectable"
|
6
|
+
label="Selectable"
|
7
|
+
/>
|
8
|
+
<v-switch
|
9
|
+
:disabled="!selectable"
|
10
|
+
v-model="selectSingle"
|
11
|
+
label=" Single Select"
|
12
|
+
/>
|
13
|
+
<v-switch
|
14
|
+
v-model="searchable"
|
15
|
+
label="Searchable"
|
16
|
+
/>
|
17
|
+
<v-dialog
|
18
|
+
v-model="dialog"
|
19
|
+
width="400"
|
20
|
+
>
|
21
|
+
<template #activator="{ on }">
|
22
|
+
<vcs-button v-on="on">
|
23
|
+
Add An item
|
24
|
+
</vcs-button>
|
25
|
+
</template>
|
26
|
+
<v-card class="pa-2">
|
27
|
+
<v-form
|
28
|
+
@submit.prevent="add"
|
29
|
+
>
|
30
|
+
<vcs-text-field
|
31
|
+
v-model="newItem.name"
|
32
|
+
label="Name"
|
33
|
+
:rules="required"
|
34
|
+
/>
|
35
|
+
<vcs-text-field
|
36
|
+
v-model="newItem.type"
|
37
|
+
label="type"
|
38
|
+
:rules="required"
|
39
|
+
/>
|
40
|
+
<vcs-text-field
|
41
|
+
v-model="newItem.date"
|
42
|
+
type="date"
|
43
|
+
label="date"
|
44
|
+
/>
|
45
|
+
<vcs-button
|
46
|
+
type="submit"
|
47
|
+
>
|
48
|
+
Add
|
49
|
+
</vcs-button>
|
50
|
+
</v-form>
|
51
|
+
</v-card>
|
52
|
+
</v-dialog>
|
53
|
+
</v-sheet>
|
54
|
+
|
55
|
+
<vcs-data-table
|
56
|
+
:items="items"
|
57
|
+
item-key="id"
|
58
|
+
:headers="headers"
|
59
|
+
:show-select="selectable"
|
60
|
+
:single-select="selectSingle"
|
61
|
+
:show-searchbar="searchable"
|
62
|
+
v-model="selected"
|
63
|
+
>
|
64
|
+
<!-- eslint-disable-next-line -->
|
65
|
+
<template v-slot:item.actions="{ item }">
|
66
|
+
<VcsActionButtonList
|
67
|
+
v-if="item.actions"
|
68
|
+
:actions="item.actions"
|
69
|
+
:block-overflow="true"
|
70
|
+
:overflow-count="2"
|
71
|
+
small
|
72
|
+
/>
|
73
|
+
</template>
|
74
|
+
</vcs-data-table>
|
75
|
+
</v-sheet>
|
76
|
+
</template>
|
77
|
+
|
78
|
+
<script>
|
79
|
+
import { VcsDataTable, VcsButton, VcsTextField, VcsActionButtonList } from '@vcmap/ui';
|
80
|
+
import {
|
81
|
+
VSwitch,
|
82
|
+
VSheet,
|
83
|
+
VDialog,
|
84
|
+
VCard,
|
85
|
+
VForm,
|
86
|
+
} from 'vuetify/lib';
|
87
|
+
import { ref } from 'vue';
|
88
|
+
|
89
|
+
const defaultHeaders = [
|
90
|
+
{
|
91
|
+
text: 'Name',
|
92
|
+
value: 'name',
|
93
|
+
},
|
94
|
+
{
|
95
|
+
text: 'Type',
|
96
|
+
value: 'type',
|
97
|
+
},
|
98
|
+
{
|
99
|
+
text: 'Datum',
|
100
|
+
value: 'date',
|
101
|
+
sort: (a, b) => new Date(b) - new Date(a),
|
102
|
+
},
|
103
|
+
{ text: 'Actions', value: 'actions', sortable: false },
|
104
|
+
];
|
105
|
+
|
106
|
+
const defaultItems = [
|
107
|
+
{
|
108
|
+
id: 0,
|
109
|
+
name: 'foo',
|
110
|
+
type: 'Foo',
|
111
|
+
date: '8/3/2023 9:24',
|
112
|
+
actions: [
|
113
|
+
{
|
114
|
+
name: 'console.log',
|
115
|
+
icon: 'mdi-printer',
|
116
|
+
callback() {
|
117
|
+
console.log('foo action');
|
118
|
+
},
|
119
|
+
},
|
120
|
+
],
|
121
|
+
},
|
122
|
+
{
|
123
|
+
id: 1,
|
124
|
+
name: 'bar',
|
125
|
+
type: 'Bar',
|
126
|
+
date: '1/8/2022 19:54',
|
127
|
+
},
|
128
|
+
{
|
129
|
+
id: 2,
|
130
|
+
name: 'baz',
|
131
|
+
type: 'Baz',
|
132
|
+
date: '11/2/2012 14:03',
|
133
|
+
},
|
134
|
+
];
|
135
|
+
|
136
|
+
export default {
|
137
|
+
name: 'DataTableExample',
|
138
|
+
components: {
|
139
|
+
VcsDataTable,
|
140
|
+
VcsButton,
|
141
|
+
VcsTextField,
|
142
|
+
VcsActionButtonList,
|
143
|
+
VSwitch,
|
144
|
+
VSheet,
|
145
|
+
VDialog,
|
146
|
+
VCard,
|
147
|
+
VForm,
|
148
|
+
},
|
149
|
+
setup() {
|
150
|
+
const selectable = ref(true);
|
151
|
+
const searchable = ref(true);
|
152
|
+
const selectSingle = ref(false);
|
153
|
+
const selected = ref([]);
|
154
|
+
const items = ref(defaultItems);
|
155
|
+
const headers = ref(defaultHeaders);
|
156
|
+
const newItem = ref({
|
157
|
+
id: items.value.length,
|
158
|
+
name: 'foo',
|
159
|
+
type: 'foo',
|
160
|
+
date: new Date(),
|
161
|
+
});
|
162
|
+
const dialog = ref(false);
|
163
|
+
|
164
|
+
return {
|
165
|
+
selectable,
|
166
|
+
searchable,
|
167
|
+
selectSingle,
|
168
|
+
selected,
|
169
|
+
items,
|
170
|
+
headers,
|
171
|
+
newItem,
|
172
|
+
dialog,
|
173
|
+
required: [
|
174
|
+
v => !!v || 'Input may not be null',
|
175
|
+
v => v.length > 0 || 'Input must have a length',
|
176
|
+
],
|
177
|
+
add() {
|
178
|
+
const item = {
|
179
|
+
name: newItem.value.name,
|
180
|
+
type: newItem.value.type,
|
181
|
+
date: newItem.value.date,
|
182
|
+
};
|
183
|
+
|
184
|
+
items.value.push(item);
|
185
|
+
newItem.value = {
|
186
|
+
name: 'foo',
|
187
|
+
type: 'foo',
|
188
|
+
date: new Date(),
|
189
|
+
};
|
190
|
+
dialog.value = false;
|
191
|
+
},
|
192
|
+
};
|
193
|
+
},
|
194
|
+
};
|
195
|
+
</script>
|
196
|
+
|
197
|
+
<style lang="scss" scoped>
|
198
|
+
.d-grid{
|
199
|
+
display: grid;
|
200
|
+
grid-template-columns: 1fr 1fr;
|
201
|
+
}
|
202
|
+
</style>
|
@@ -0,0 +1,47 @@
|
|
1
|
+
import { ButtonLocation, createToggleAction, WindowSlot } from '@vcmap/ui';
|
2
|
+
import packageJSON from './package.json';
|
3
|
+
import DataTableExample from './DataTableExample.vue';
|
4
|
+
|
5
|
+
/**
|
6
|
+
* @returns {VcsPlugin}
|
7
|
+
*/
|
8
|
+
export default async function iconsExample() {
|
9
|
+
return {
|
10
|
+
get name() { return packageJSON.name; },
|
11
|
+
get version() { return packageJSON.version; },
|
12
|
+
get vcMapVersion() { return packageJSON.vcMapVersion; },
|
13
|
+
onVcsAppMounted(app) {
|
14
|
+
const { action, destroy } = createToggleAction(
|
15
|
+
{
|
16
|
+
name: 'Table Example',
|
17
|
+
title: 'Table Example Plugin',
|
18
|
+
},
|
19
|
+
{
|
20
|
+
id: 'table-example',
|
21
|
+
component: DataTableExample,
|
22
|
+
slot: WindowSlot.DYNAMIC_LEFT,
|
23
|
+
state: {
|
24
|
+
headerTitle: 'Table Example',
|
25
|
+
},
|
26
|
+
position: {
|
27
|
+
width: 500,
|
28
|
+
},
|
29
|
+
},
|
30
|
+
app.windowManager,
|
31
|
+
packageJSON.name,
|
32
|
+
);
|
33
|
+
app.navbarManager.add(
|
34
|
+
{ action },
|
35
|
+
packageJSON.name,
|
36
|
+
ButtonLocation.TOOL,
|
37
|
+
);
|
38
|
+
this._destroyAction = destroy;
|
39
|
+
},
|
40
|
+
destroy() {
|
41
|
+
if (this._destroyAction) {
|
42
|
+
this._destroyAction();
|
43
|
+
this._destroyAction = null;
|
44
|
+
}
|
45
|
+
},
|
46
|
+
};
|
47
|
+
}
|
@@ -203,29 +203,18 @@ export function createModalAction(actionOptions, modalComponent, app, owner) {
|
|
203
203
|
check(owner, [String, vcsAppSymbol]);
|
204
204
|
|
205
205
|
const id = uuid();
|
206
|
+
const { position: windowPositionOptions, ...component } = modalComponent;
|
207
|
+
let modalActivator = null;
|
206
208
|
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
bottom: 0,
|
217
|
-
left: 0,
|
218
|
-
right: 0,
|
219
|
-
});
|
220
|
-
elem.onclick = () => { app.windowManager.remove(id); };
|
221
|
-
document.body.appendChild(elem);
|
222
|
-
}
|
223
|
-
};
|
224
|
-
|
225
|
-
const removeModal = () => {
|
226
|
-
const child = document.getElementById(id);
|
227
|
-
if (child) {
|
228
|
-
child.parentElement.removeChild(child);
|
209
|
+
/**
|
210
|
+
* Closes the modal at mousedown on an app element
|
211
|
+
* Requires mousedown event bubbling on app elements (same behaviour as v-menu).
|
212
|
+
* @param {MouseEvent} e
|
213
|
+
*/
|
214
|
+
const handleMouseDown = (e) => {
|
215
|
+
const div = document.getElementById(`window-component--${id}`);
|
216
|
+
if (!div?.contains(e.target) && !modalActivator?.contains(e.target)) {
|
217
|
+
app.windowManager.remove(id);
|
229
218
|
}
|
230
219
|
};
|
231
220
|
|
@@ -236,10 +225,11 @@ export function createModalAction(actionOptions, modalComponent, app, owner) {
|
|
236
225
|
if (!this.active) {
|
237
226
|
this.active = true;
|
238
227
|
const { left, top, width } = event.currentTarget.getBoundingClientRect();
|
239
|
-
|
228
|
+
modalActivator = event.currentTarget;
|
229
|
+
const position = { ...getWindowPositionOptions(left + width, top, app.maps.target), ...windowPositionOptions };
|
240
230
|
const state = { ...modalComponent?.state, hideHeader: true };
|
241
|
-
app.windowManager.add({ position, ...
|
242
|
-
|
231
|
+
app.windowManager.add({ position, ...component, id, state }, owner);
|
232
|
+
document.addEventListener('mousedown', handleMouseDown);
|
243
233
|
} else {
|
244
234
|
this.active = false;
|
245
235
|
app.windowManager.remove(id);
|
@@ -252,10 +242,9 @@ export function createModalAction(actionOptions, modalComponent, app, owner) {
|
|
252
242
|
app.windowManager.removed.addEventListener(({ id: windowId }) => {
|
253
243
|
if (windowId === id) {
|
254
244
|
action.active = false;
|
255
|
-
|
245
|
+
document.removeEventListener('mousedown', handleMouseDown);
|
256
246
|
}
|
257
247
|
}),
|
258
|
-
removeModal,
|
259
248
|
];
|
260
249
|
|
261
250
|
const destroy = () => { listeners.forEach((cb) => { cb(); }); };
|
@@ -1,6 +1,16 @@
|
|
1
1
|
<template>
|
2
|
-
<v-sheet v-if="items" class="
|
3
|
-
<
|
2
|
+
<v-sheet v-if="items" class="pt-1 pb-0 px-0">
|
3
|
+
<v-list>
|
4
|
+
<v-list-item
|
5
|
+
v-for="(item, index) in items"
|
6
|
+
:key="index"
|
7
|
+
@click.stop="select(item.value)"
|
8
|
+
>
|
9
|
+
<v-list-item-title :class="{ 'primary--text': item.value === currentStyleName }">
|
10
|
+
{{ item.text }}
|
11
|
+
</v-list-item-title>
|
12
|
+
</v-list-item>
|
13
|
+
</v-list>
|
4
14
|
<v-list v-if="currentStyleLegend.length > 0">
|
5
15
|
<v-list-item
|
6
16
|
v-for="(entry, index) in currentStyleLegend"
|
@@ -21,18 +31,17 @@
|
|
21
31
|
<script>
|
22
32
|
import { computed, inject, onUnmounted, ref } from 'vue';
|
23
33
|
import {
|
24
|
-
VChip, VList, VListItem, VListItemContent, VListItemIcon, VSheet,
|
34
|
+
VChip, VList, VListItem, VListItemContent, VListItemIcon, VListItemTitle, VSheet,
|
25
35
|
} from 'vuetify/lib';
|
26
|
-
import VcsSelect from '../components/form-inputs-controls/VcsSelect.vue';
|
27
36
|
|
28
37
|
export default {
|
29
38
|
name: 'StyleSelector',
|
30
39
|
components: {
|
31
|
-
VcsSelect,
|
32
40
|
VSheet,
|
33
41
|
VList,
|
34
42
|
VListItem,
|
35
43
|
VListItemIcon,
|
44
|
+
VListItemTitle,
|
36
45
|
VChip,
|
37
46
|
VListItemContent,
|
38
47
|
},
|
@@ -46,8 +55,8 @@
|
|
46
55
|
required: true,
|
47
56
|
},
|
48
57
|
},
|
49
|
-
setup({ layerName, availableStyles }) {
|
50
|
-
/** @type {
|
58
|
+
setup({ layerName, availableStyles }, { attrs }) {
|
59
|
+
/** @type {VcsUiApp} */
|
51
60
|
const app = inject('vcsApp');
|
52
61
|
/** @type {import("@vcmap/core").FeatureLayer} */
|
53
62
|
const layer = app.layers.getByKey(layerName);
|
@@ -68,16 +77,6 @@
|
|
68
77
|
styleChangedListener();
|
69
78
|
});
|
70
79
|
|
71
|
-
const currentStyle = computed({
|
72
|
-
get() { return currentStyleName.value; },
|
73
|
-
set(styleName) {
|
74
|
-
const style = styleName === defaultStyle ?
|
75
|
-
layer.defaultStyle :
|
76
|
-
app.styles.getByKey(styleName);
|
77
|
-
layer.setStyle(style);
|
78
|
-
},
|
79
|
-
});
|
80
|
-
|
81
80
|
const items = computed(() => {
|
82
81
|
return [
|
83
82
|
{ text: 'Default', value: defaultStyle },
|
@@ -85,15 +84,23 @@
|
|
85
84
|
];
|
86
85
|
});
|
87
86
|
|
87
|
+
function select(styleName) {
|
88
|
+
const style = styleName === defaultStyle ?
|
89
|
+
layer.defaultStyle :
|
90
|
+
app.styles.getByKey(styleName);
|
91
|
+
layer.setStyle(style);
|
92
|
+
app.windowManager.remove(attrs['window-state'].id);
|
93
|
+
}
|
94
|
+
|
88
95
|
return {
|
89
|
-
|
96
|
+
currentStyleName,
|
90
97
|
currentStyleLegend,
|
91
98
|
items,
|
99
|
+
select,
|
92
100
|
};
|
93
101
|
},
|
94
102
|
};
|
95
103
|
</script>
|
96
104
|
|
97
105
|
<style scoped>
|
98
|
-
|
99
106
|
</style>
|
@@ -0,0 +1,111 @@
|
|
1
|
+
<template>
|
2
|
+
<v-menu
|
3
|
+
v-model="menuOpen"
|
4
|
+
:close-on-content-click="false"
|
5
|
+
transition="scale-transition"
|
6
|
+
offset-y
|
7
|
+
max-width="290px"
|
8
|
+
min-width="290px"
|
9
|
+
>
|
10
|
+
<template #activator="{ on, attrs }">
|
11
|
+
<v-text-field
|
12
|
+
v-model="formattedDate"
|
13
|
+
:placeholder="formatDate(new Date().toISOString())"
|
14
|
+
v-bind="{...$attrs, ...attrs}"
|
15
|
+
v-on="{...$listeners, ...on}"
|
16
|
+
:prepend-icon="icon"
|
17
|
+
readonly
|
18
|
+
hide-details
|
19
|
+
class="ma-0 py-1"
|
20
|
+
/>
|
21
|
+
</template>
|
22
|
+
<v-date-picker v-model="date" no-title @input="menuOpen = false" :locale="locale" color="primary">
|
23
|
+
<v-btn color="primary" @click="goToToday">
|
24
|
+
{{ $t('datePicker.today') }}
|
25
|
+
</v-btn>
|
26
|
+
</v-date-picker>
|
27
|
+
</v-menu>
|
28
|
+
</template>
|
29
|
+
<style lang="scss" scoped>
|
30
|
+
::v-deep {
|
31
|
+
.v-input__control{
|
32
|
+
padding: 0 8px;
|
33
|
+
}
|
34
|
+
}
|
35
|
+
</style>
|
36
|
+
<script>
|
37
|
+
import {
|
38
|
+
computed, ref, watch, inject, onUnmounted, onBeforeMount,
|
39
|
+
} from 'vue';
|
40
|
+
import {
|
41
|
+
VMenu, VTextField, VDatePicker, VBtn,
|
42
|
+
} from 'vuetify/lib';
|
43
|
+
/**
|
44
|
+
* @description stylized wrapper around {@link https://v15.vuetifyjs.com/en/components/date-pickers/#month-pickers-in-dialog-and-menu}.
|
45
|
+
* @vue-prop {string} value - value of the date picker in {@link https://tc39.es/ecma262/#sec-date-time-string-format | Date Time String Format}
|
46
|
+
* @vue-prop {string} icon - specify optional prepend icon, defaults to mdi-calendar
|
47
|
+
* @vue-event {string} input - raised when calendar date is selected
|
48
|
+
*/
|
49
|
+
export default {
|
50
|
+
name: 'VcsDatePicker',
|
51
|
+
props: {
|
52
|
+
value: {
|
53
|
+
type: String,
|
54
|
+
required: true,
|
55
|
+
},
|
56
|
+
icon: {
|
57
|
+
type: String,
|
58
|
+
default: 'mdi-calendar',
|
59
|
+
},
|
60
|
+
},
|
61
|
+
components: {
|
62
|
+
VMenu,
|
63
|
+
VTextField,
|
64
|
+
VDatePicker,
|
65
|
+
VBtn,
|
66
|
+
},
|
67
|
+
setup(props, context) {
|
68
|
+
/**
|
69
|
+
* @type {import("@vcmap/ui").VcsUiApp}
|
70
|
+
*/
|
71
|
+
const app = /** @type {import("@vcmap/ui").VcsUiApp} */ (inject('vcsApp'));
|
72
|
+
const localValue = ref(props.value);
|
73
|
+
const menuOpen = ref(false);
|
74
|
+
const locale = ref(app.locale);
|
75
|
+
|
76
|
+
const isValid = date => !Number.isNaN(Date.parse(date));
|
77
|
+
const setFromValue = () => {
|
78
|
+
if (isValid(localValue.value)) {
|
79
|
+
localValue.value = props.value;
|
80
|
+
} else {
|
81
|
+
// eslint-disable-next-line no-console
|
82
|
+
console.error('Invalid date provided: ', props.value);
|
83
|
+
}
|
84
|
+
};
|
85
|
+
onBeforeMount(() => setFromValue());
|
86
|
+
const destroyLocaleChanged = app.localeChanged.addEventListener(() => { locale.value = app.locale; });
|
87
|
+
onUnmounted(() => destroyLocaleChanged());
|
88
|
+
|
89
|
+
const formatDate = (date) => {
|
90
|
+
if (date) {
|
91
|
+
return new Intl.DateTimeFormat(locale.value, { dateStyle: 'short' }).format(Date.parse(date));
|
92
|
+
}
|
93
|
+
return '';
|
94
|
+
};
|
95
|
+
const goToToday = () => {
|
96
|
+
localValue.value = new Date(Date.now()).toISOString().substring(0, 10);
|
97
|
+
menuOpen.value = false;
|
98
|
+
};
|
99
|
+
watch(() => props.value, () => setFromValue());
|
100
|
+
const formattedDate = computed({
|
101
|
+
get: () => { return formatDate(localValue.value); },
|
102
|
+
set: () => {},
|
103
|
+
});
|
104
|
+
const date = computed({ get: () => localValue.value, set: (nv) => { localValue.value = nv; context.emit('input', localValue.value); } });
|
105
|
+
|
106
|
+
return {
|
107
|
+
formattedDate, date, menuOpen, formatDate, locale, goToToday,
|
108
|
+
};
|
109
|
+
},
|
110
|
+
};
|
111
|
+
</script>
|