@vcmap/ui 5.0.0-rc.14 → 5.0.0-rc.16
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 +30 -24
- package/config/dev.config.json +13 -1
- package/config/www.config.json +104 -17
- package/dist/assets/cesium.430460.js +137226 -0
- package/dist/assets/cesium.js +1 -1
- package/dist/assets/core.5089ba.js +16024 -0
- package/dist/assets/core.js +1 -1
- package/dist/assets/index.854f8e2b.js +1 -0
- package/dist/assets/ol.9be53a.js +44279 -0
- package/dist/assets/ol.js +1 -1
- package/dist/assets/{ui.15ef6a.css → ui.49010a.css} +1 -1
- package/dist/assets/ui.49010a.js +16776 -0
- package/dist/assets/ui.js +1 -1
- package/dist/assets/vue.247c1c.js +4675 -0
- package/dist/assets/vue.js +5 -2
- package/dist/assets/{vuetify.202322.css → vuetify.735e58.css} +1 -1
- package/dist/assets/vuetify.735e58.js +21019 -0
- package/dist/assets/vuetify.js +5 -2
- package/dist/index.html +1 -1
- package/index.html +77 -0
- package/index.js +8 -1
- package/package.json +12 -10
- package/plugins/@vcmap/create-link/fallbackCreateLink.vue +4 -1
- package/plugins/@vcmap/create-link/index.js +4 -1
- package/plugins/@vcmap/pluginExample/exampleActions.js +45 -0
- package/plugins/@vcmap/pluginExample/index.js +38 -1
- package/plugins/@vcmap/pluginExample/pluginExampleComponent.vue +152 -98
- 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 +26 -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/notifier/index.js +31 -0
- package/plugins/notifier/notifierTester.vue +88 -0
- 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/index.js +22 -0
- package/plugins/test/myCustomHeader.vue +9 -1
- package/plugins/test/testList.vue +287 -0
- package/plugins/test/vcsContent.vue +3 -0
- package/plugins/test/windowManagerExample.vue +3 -0
- package/plugins/wizardExample/index.js +41 -0
- package/plugins/wizardExample/wizardExample.vue +77 -0
- package/src/actions/actionHelper.js +103 -2
- package/src/actions/styleSelector.vue +9 -0
- package/src/application/VcsApp.vue +95 -17
- 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 +55 -9
- package/src/components/form-inputs-controls/VcsRadio.vue +7 -1
- package/src/components/form-inputs-controls/VcsSelect.vue +38 -2
- package/src/components/form-inputs-controls/VcsTextArea.vue +2 -0
- package/src/components/form-inputs-controls/VcsTextField.vue +16 -4
- package/src/components/form-inputs-controls/VcsWizard.vue +133 -0
- package/src/components/imageElementInjector.vue +22 -0
- package/src/components/lists/VcsActionList.vue +12 -1
- package/src/components/lists/VcsList.vue +466 -0
- package/src/components/lists/VcsTreeview.vue +7 -3
- package/src/components/lists/VcsTreeviewLeaf.vue +23 -51
- package/src/components/lists/VcsTreeviewSearchbar.vue +6 -23
- package/src/components/notification/VcsTooltip.vue +14 -9
- package/src/components/tables/VcsTable.vue +129 -38
- package/src/contentTree/LayerTree.vue +1 -1
- package/src/contentTree/contentTreeItem.js +13 -13
- package/src/contentTree/subContentTreeItem.js +1 -1
- package/src/contentTree/vcsObjectContentTreeItem.js +1 -1
- package/src/featureInfo/AddressBalloonComponent.vue +17 -1
- package/src/featureInfo/BalloonComponent.vue +63 -27
- package/src/featureInfo/balloonFeatureInfoView.js +14 -14
- package/src/featureInfo/balloonHelper.js +4 -0
- package/src/featureInfo/featureInfo.js +23 -2
- package/src/featureInfo/featureInfoInteraction.js +1 -1
- package/src/i18n/de.js +22 -0
- package/src/i18n/en.js +22 -0
- package/src/icons/+all.js +4 -0
- package/src/icons/WandIcon.vue +63 -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 +15 -2
- package/src/manager/window/WindowComponentHeader.vue +38 -7
- package/src/manager/window/WindowManager.vue +1 -0
- package/src/manager/window/windowManager.js +11 -1
- package/src/navigation/mapNavigation.vue +15 -36
- package/src/navigation/orientationToolsButton.vue +6 -1
- package/src/navigation/overviewMap.js +19 -47
- package/src/navigation/tiltSlider.vue +3 -0
- package/src/navigation/vcsCompass.vue +2 -0
- package/src/notifier/notifier.js +121 -0
- package/src/notifier/notifierComponent.vue +84 -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 +23 -4
- package/src/vcsUiApp.js +35 -1
- package/src/vuePlugins/vuetify.js +2 -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.js +0 -71
- package/dist/assets/vue.cbe9d8.js +0 -9
- package/dist/assets/vuetify.202322.js +0 -148
@@ -0,0 +1,287 @@
|
|
1
|
+
<template>
|
2
|
+
<v-sheet>
|
3
|
+
<v-sheet class="pa-2">
|
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.title"
|
37
|
+
label="Title"
|
38
|
+
:rules="required"
|
39
|
+
/>
|
40
|
+
<v-switch label="visible" v-model="newItem.visible" />
|
41
|
+
<v-switch label="disabled" v-model="newItem.disabled" />
|
42
|
+
<v-switch label="random icon" v-model="newItem.icon" />
|
43
|
+
<v-switch label="console.log action" v-model="newItem.action" />
|
44
|
+
<v-switch label="console.log on clicked" v-model="newItem.clicked" />
|
45
|
+
<v-switch label="console.log selected state" v-model="newItem.selected" />
|
46
|
+
<vcs-button
|
47
|
+
type="submit"
|
48
|
+
>
|
49
|
+
Add
|
50
|
+
</vcs-button>
|
51
|
+
</v-form>
|
52
|
+
</v-card>
|
53
|
+
</v-dialog>
|
54
|
+
<v-divider class="ma-2" />
|
55
|
+
<v-switch
|
56
|
+
v-model="showTitle"
|
57
|
+
label="Show Title"
|
58
|
+
/>
|
59
|
+
<vcs-text-field v-model="title" placeholder="Title" />
|
60
|
+
<v-switch
|
61
|
+
v-model="titleActions"
|
62
|
+
label="Title Actions"
|
63
|
+
/>
|
64
|
+
<v-switch
|
65
|
+
v-model="titleIcon"
|
66
|
+
label="Title Icon"
|
67
|
+
/>
|
68
|
+
<v-divider class="ma-2" />
|
69
|
+
<template v-if="selectable">
|
70
|
+
<vcs-button
|
71
|
+
@click="selected = []"
|
72
|
+
>
|
73
|
+
Clear Selection
|
74
|
+
</vcs-button>
|
75
|
+
<v-switch v-model="showSelection" label="Show Selection" />
|
76
|
+
<ul v-if="showSelection">
|
77
|
+
<li
|
78
|
+
v-for="(i, index) in selected"
|
79
|
+
:key="`item-${index}`"
|
80
|
+
>
|
81
|
+
{{ i.title }}
|
82
|
+
</li>
|
83
|
+
</ul>
|
84
|
+
</template>
|
85
|
+
<v-divider class="ma-2" />
|
86
|
+
</v-sheet>
|
87
|
+
|
88
|
+
<vcs-list
|
89
|
+
:items="items"
|
90
|
+
:selectable="selectable"
|
91
|
+
:single-select="selectSingle"
|
92
|
+
:searchable="searchable"
|
93
|
+
:show-title="showTitle"
|
94
|
+
:icon="titleIconSrc"
|
95
|
+
:actions="titleActionsArray"
|
96
|
+
:title="title"
|
97
|
+
v-model="selected"
|
98
|
+
/>
|
99
|
+
</v-sheet>
|
100
|
+
</template>
|
101
|
+
|
102
|
+
<script>
|
103
|
+
import { VcsList, VcsButton, VcsTextField, Icons } from '@vcmap/ui';
|
104
|
+
import {
|
105
|
+
VSwitch,
|
106
|
+
VDivider,
|
107
|
+
VSheet,
|
108
|
+
VDialog,
|
109
|
+
VCard,
|
110
|
+
VForm,
|
111
|
+
} from 'vuetify/lib';
|
112
|
+
import { computed, ref } from 'vue';
|
113
|
+
|
114
|
+
function getRandomIcon() {
|
115
|
+
const keys = Object.keys(Icons);
|
116
|
+
const index = Math.floor(keys.length * Math.random());
|
117
|
+
return `$${keys[index]}`;
|
118
|
+
}
|
119
|
+
|
120
|
+
const defaultItems = [
|
121
|
+
{
|
122
|
+
name: 'foo',
|
123
|
+
title: 'Foo',
|
124
|
+
tooltip: 'this is the foo',
|
125
|
+
icon: 'mdi-pen',
|
126
|
+
},
|
127
|
+
{
|
128
|
+
name: 'bar',
|
129
|
+
title: 'Bar',
|
130
|
+
tooltip: 'just a bar',
|
131
|
+
actions: [
|
132
|
+
{
|
133
|
+
name: 'console.log',
|
134
|
+
callback() {
|
135
|
+
console.log('bar action');
|
136
|
+
},
|
137
|
+
},
|
138
|
+
],
|
139
|
+
},
|
140
|
+
{
|
141
|
+
name: 'bar',
|
142
|
+
title: 'Baz',
|
143
|
+
tooltip: 'special baz',
|
144
|
+
},
|
145
|
+
];
|
146
|
+
|
147
|
+
export default {
|
148
|
+
name: 'TestList',
|
149
|
+
components: {
|
150
|
+
VcsList,
|
151
|
+
VcsButton,
|
152
|
+
VcsTextField,
|
153
|
+
VSwitch,
|
154
|
+
VDivider,
|
155
|
+
VSheet,
|
156
|
+
VDialog,
|
157
|
+
VCard,
|
158
|
+
VForm,
|
159
|
+
},
|
160
|
+
setup() {
|
161
|
+
const selectable = ref(true);
|
162
|
+
const searchable = ref(true);
|
163
|
+
const selectSingle = ref(false);
|
164
|
+
const showSelection = ref(false);
|
165
|
+
const showTitle = ref(true);
|
166
|
+
const title = ref('Title');
|
167
|
+
const titleActionsArray = ref([]);
|
168
|
+
const titleIconSrc = ref(null);
|
169
|
+
const selected = ref([]);
|
170
|
+
const items = ref(defaultItems);
|
171
|
+
const newItem = ref({
|
172
|
+
name: 'foo',
|
173
|
+
title: 'foo',
|
174
|
+
disabled: false,
|
175
|
+
visible: true,
|
176
|
+
icon: false,
|
177
|
+
action: false,
|
178
|
+
clicked: false,
|
179
|
+
selected: false,
|
180
|
+
});
|
181
|
+
const dialog = ref(false);
|
182
|
+
|
183
|
+
return {
|
184
|
+
selectable,
|
185
|
+
searchable,
|
186
|
+
selectSingle,
|
187
|
+
selected,
|
188
|
+
showSelection,
|
189
|
+
showTitle,
|
190
|
+
title,
|
191
|
+
titleActionsArray,
|
192
|
+
titleIconSrc,
|
193
|
+
items,
|
194
|
+
newItem,
|
195
|
+
dialog,
|
196
|
+
required: [
|
197
|
+
v => !!v || 'Input may not be null',
|
198
|
+
v => v.length > 0 || 'Input must have a length',
|
199
|
+
],
|
200
|
+
add() {
|
201
|
+
const item = {
|
202
|
+
name: newItem.value.name,
|
203
|
+
title: newItem.value.title,
|
204
|
+
disabled: newItem.value.disabled,
|
205
|
+
visible: newItem.value.visible,
|
206
|
+
};
|
207
|
+
|
208
|
+
if (newItem.value.icon) {
|
209
|
+
item.icon = getRandomIcon();
|
210
|
+
}
|
211
|
+
|
212
|
+
if (newItem.value.action) {
|
213
|
+
item.actions = [
|
214
|
+
{
|
215
|
+
name: 'console.log',
|
216
|
+
callback() {
|
217
|
+
console.log('hi, i\'m: ', item.name);
|
218
|
+
},
|
219
|
+
},
|
220
|
+
];
|
221
|
+
}
|
222
|
+
|
223
|
+
if (newItem.value.clicked) {
|
224
|
+
item.clicked = () => {
|
225
|
+
console.log(`${item.name} just got clicked`);
|
226
|
+
};
|
227
|
+
}
|
228
|
+
|
229
|
+
if (newItem.value.selected) {
|
230
|
+
item.selectionChanged = (selected) => {
|
231
|
+
if (selected) {
|
232
|
+
console.log(`${item.name} is selected`);
|
233
|
+
} else {
|
234
|
+
console.log(`${item.name} is no longer selected`);
|
235
|
+
}
|
236
|
+
};
|
237
|
+
}
|
238
|
+
items.value.push(item);
|
239
|
+
newItem.value = {
|
240
|
+
name: 'foo',
|
241
|
+
title: 'foo',
|
242
|
+
disabled: false,
|
243
|
+
visible: true,
|
244
|
+
icon: false,
|
245
|
+
action: false,
|
246
|
+
clicked: false,
|
247
|
+
selected: false,
|
248
|
+
};
|
249
|
+
dialog.value = false;
|
250
|
+
},
|
251
|
+
titleActions: computed({
|
252
|
+
get() {
|
253
|
+
return titleActionsArray.value.length > 0;
|
254
|
+
},
|
255
|
+
set(value) {
|
256
|
+
if (value) {
|
257
|
+
titleActionsArray.value = [{
|
258
|
+
name: 'console.log foo',
|
259
|
+
callback() {
|
260
|
+
console.log('foo');
|
261
|
+
},
|
262
|
+
}];
|
263
|
+
} else {
|
264
|
+
titleActionsArray.value = [];
|
265
|
+
}
|
266
|
+
},
|
267
|
+
}),
|
268
|
+
titleIcon: computed({
|
269
|
+
get() {
|
270
|
+
return !!titleIconSrc.value;
|
271
|
+
},
|
272
|
+
set(value) {
|
273
|
+
if (value) {
|
274
|
+
titleIconSrc.value = getRandomIcon();
|
275
|
+
} else {
|
276
|
+
titleIconSrc.value = null;
|
277
|
+
}
|
278
|
+
},
|
279
|
+
}),
|
280
|
+
};
|
281
|
+
},
|
282
|
+
};
|
283
|
+
</script>
|
284
|
+
|
285
|
+
<style lang="scss" scoped>
|
286
|
+
|
287
|
+
</style>
|
@@ -0,0 +1,41 @@
|
|
1
|
+
import { createToggleAction, ButtonLocation, WindowSlot } from '@vcmap/ui';
|
2
|
+
import WizardExample from './wizardExample.vue';
|
3
|
+
|
4
|
+
export default async () => {
|
5
|
+
return {
|
6
|
+
name: 'wizardExample',
|
7
|
+
onVcsAppMounted(app) {
|
8
|
+
const { action, destroy } = createToggleAction(
|
9
|
+
{
|
10
|
+
name: 'wizardExample',
|
11
|
+
icon: '$vcsLegend',
|
12
|
+
title: 'VCS Wizard Example',
|
13
|
+
},
|
14
|
+
{
|
15
|
+
id: 'wizard-example',
|
16
|
+
component: WizardExample,
|
17
|
+
slot: WindowSlot.DYNAMIC_LEFT,
|
18
|
+
state: {
|
19
|
+
headerTitle: 'VCS Wizard',
|
20
|
+
headerIcon: '$vcsWand',
|
21
|
+
styles: { width: '350px', height: 'auto' },
|
22
|
+
},
|
23
|
+
},
|
24
|
+
app.windowManager,
|
25
|
+
'wizardExample',
|
26
|
+
);
|
27
|
+
app.navbarManager.add(
|
28
|
+
{ id: 'wizard-example', action },
|
29
|
+
'wizardExample',
|
30
|
+
ButtonLocation.TOOL,
|
31
|
+
);
|
32
|
+
this._destroyAction = destroy;
|
33
|
+
},
|
34
|
+
destroy() {
|
35
|
+
if (this._destroyAction) {
|
36
|
+
this._destroyAction();
|
37
|
+
this._destroyAction = null;
|
38
|
+
}
|
39
|
+
},
|
40
|
+
};
|
41
|
+
};
|
@@ -0,0 +1,77 @@
|
|
1
|
+
<template>
|
2
|
+
<VcsWizard
|
3
|
+
v-model="step"
|
4
|
+
>
|
5
|
+
<v-stepper-step
|
6
|
+
step="1"
|
7
|
+
editable
|
8
|
+
:complete="step > 1"
|
9
|
+
>
|
10
|
+
This is the first step
|
11
|
+
</v-stepper-step>
|
12
|
+
<v-stepper-content
|
13
|
+
step="1"
|
14
|
+
>
|
15
|
+
<v-sheet>
|
16
|
+
This is the content of the first step.
|
17
|
+
</v-sheet>
|
18
|
+
<VcsButton
|
19
|
+
@click="increaseStep()"
|
20
|
+
class="my-2"
|
21
|
+
>
|
22
|
+
Next
|
23
|
+
</VcsButton>
|
24
|
+
</v-stepper-content>
|
25
|
+
<v-stepper-step
|
26
|
+
:rules="[() => false]"
|
27
|
+
step="2"
|
28
|
+
editable
|
29
|
+
>
|
30
|
+
This is the second step
|
31
|
+
</v-stepper-step>
|
32
|
+
<v-stepper-content
|
33
|
+
step="2"
|
34
|
+
>
|
35
|
+
<VcsSelect
|
36
|
+
:items="['this', 'is', 'a', 'test']"
|
37
|
+
label="Select"
|
38
|
+
class="my-2"
|
39
|
+
/>
|
40
|
+
<VcsButton
|
41
|
+
@click="decreaseStep()"
|
42
|
+
>
|
43
|
+
Back
|
44
|
+
</VcsButton>
|
45
|
+
</v-stepper-content>
|
46
|
+
</VcsWizard>
|
47
|
+
</template>
|
48
|
+
|
49
|
+
<script>
|
50
|
+
import { VcsWizard, VcsButton, VcsSelect } from '@vcmap/ui';
|
51
|
+
import { VStepperStep, VStepperContent, VSheet } from 'vuetify/lib';
|
52
|
+
import { ref } from 'vue';
|
53
|
+
|
54
|
+
export default {
|
55
|
+
name: 'WizardExample',
|
56
|
+
components: {
|
57
|
+
VcsWizard,
|
58
|
+
VStepperStep,
|
59
|
+
VStepperContent,
|
60
|
+
VSheet,
|
61
|
+
VcsButton,
|
62
|
+
VcsSelect,
|
63
|
+
},
|
64
|
+
setup() {
|
65
|
+
const step = ref(1);
|
66
|
+
return {
|
67
|
+
step,
|
68
|
+
increaseStep() { step.value += 1; },
|
69
|
+
decreaseStep() { step.value -= 1; },
|
70
|
+
};
|
71
|
+
},
|
72
|
+
};
|
73
|
+
</script>
|
74
|
+
|
75
|
+
<style scoped>
|
76
|
+
|
77
|
+
</style>
|
@@ -1,8 +1,11 @@
|
|
1
1
|
import { v4 as uuid } from 'uuid';
|
2
2
|
import { check } from '@vcsuite/check';
|
3
|
-
import { Collection, MapCollection, Viewpoint } from '@vcmap/core';
|
3
|
+
import { Collection, Extent, MapCollection, mercatorProjection, Viewpoint } from '@vcmap/core';
|
4
|
+
import { Feature } from 'ol';
|
5
|
+
import { reactive, ref } from 'vue';
|
4
6
|
import { vcsAppSymbol } from '../pluginHelper.js';
|
5
|
-
import { getWindowPositionOptions } from '../manager/window/windowManager.js';
|
7
|
+
import { getWindowPositionOptions, WindowSlot } from '../manager/window/windowManager.js';
|
8
|
+
import SearchComponent from '../search/searchComponent.vue';
|
6
9
|
|
7
10
|
/**
|
8
11
|
* @typedef {Object} ActionOptions
|
@@ -88,6 +91,60 @@ export function createToggleAction(actionOptions, windowComponent, windowManager
|
|
88
91
|
return { action, destroy };
|
89
92
|
}
|
90
93
|
|
94
|
+
/**
|
95
|
+
* Creates a toggle button for the search tool, which is only available, if at least one search implementation is registered.
|
96
|
+
* @param {VcsUiApp} app
|
97
|
+
* @returns {{ searchAction: import("vue").Ref<import("vue").UnwrapRef<VcsAction>|null>, destroy: function():void }}
|
98
|
+
*/
|
99
|
+
export function createSearchButtonAction(app) {
|
100
|
+
let destroyAction = () => {};
|
101
|
+
const searchAction = ref(null);
|
102
|
+
const determineAction = () => {
|
103
|
+
if (app.windowManager.has('searchId')) {
|
104
|
+
app.windowManager.remove('searchId');
|
105
|
+
}
|
106
|
+
if (app.search.size > 0 && searchAction.value === null) {
|
107
|
+
const action = createToggleAction(
|
108
|
+
{
|
109
|
+
name: 'search.title',
|
110
|
+
icon: '$vcsSearch',
|
111
|
+
title: 'search.tooltip',
|
112
|
+
},
|
113
|
+
{
|
114
|
+
id: 'searchId',
|
115
|
+
component: SearchComponent,
|
116
|
+
state: { hideHeader: true },
|
117
|
+
slot: WindowSlot.DETACHED,
|
118
|
+
position: {
|
119
|
+
right: 0,
|
120
|
+
top: 0,
|
121
|
+
width: 440,
|
122
|
+
},
|
123
|
+
},
|
124
|
+
app.windowManager,
|
125
|
+
vcsAppSymbol,
|
126
|
+
);
|
127
|
+
destroyAction = action.destroy;
|
128
|
+
searchAction.value = reactive(action.action);
|
129
|
+
} else if (searchAction.value !== null) {
|
130
|
+
destroyAction();
|
131
|
+
destroyAction = () => {};
|
132
|
+
searchAction.value = null;
|
133
|
+
}
|
134
|
+
};
|
135
|
+
determineAction();
|
136
|
+
const listeners = [
|
137
|
+
app.search.added.addEventListener(determineAction),
|
138
|
+
app.search.removed.addEventListener(determineAction),
|
139
|
+
];
|
140
|
+
const destroy = () => {
|
141
|
+
destroyAction();
|
142
|
+
listeners.forEach((cb) => { cb(); });
|
143
|
+
};
|
144
|
+
|
145
|
+
return { searchAction, destroy };
|
146
|
+
}
|
147
|
+
|
91
148
|
/**
|
92
149
|
* Creates an action which will toggle the overview map (opening & closing the window and activating/ deactivating the overview map).
|
93
150
|
* @param {OverviewMap} overviewMap
|
@@ -260,3 +317,47 @@ export function createGoToViewpointAction(actionOptions, viewpoint, viewpointCol
|
|
260
317
|
},
|
261
318
|
};
|
262
319
|
}
|
320
|
+
|
321
|
+
/**
|
322
|
+
* calculates and returns a viewpoint using feature's extent
|
323
|
+
* @param {import("ol").Feature<import("ol/geom/Geometry").default>} feature
|
324
|
+
* @returns {Viewpoint|null}
|
325
|
+
*/
|
326
|
+
export function getViewpointFromFeature(feature) {
|
327
|
+
const extent = new Extent({
|
328
|
+
coordinates: feature.getGeometry()?.getExtent?.(),
|
329
|
+
projection: mercatorProjection,
|
330
|
+
});
|
331
|
+
|
332
|
+
if (!extent || !extent.isValid()) {
|
333
|
+
return null;
|
334
|
+
}
|
335
|
+
return Viewpoint.createViewpointFromExtent(extent);
|
336
|
+
}
|
337
|
+
|
338
|
+
/**
|
339
|
+
* Creates an action, which when clicked, zooms to the provided feature
|
340
|
+
* @param {ActionOptions} actionOptions
|
341
|
+
* @param {import("ol").Feature<import("ol/geom/Geometry").default>} feature
|
342
|
+
* @param {import("@vcmap/core").MapCollection} mapCollection
|
343
|
+
* @returns {VcsAction|null} returns null if the feature does not have a geometry with a valid extent
|
344
|
+
*/
|
345
|
+
export function createZoomToFeatureAction(actionOptions, feature, mapCollection) {
|
346
|
+
check(actionOptions, {
|
347
|
+
name: String,
|
348
|
+
icon: [undefined, String],
|
349
|
+
title: [undefined, String],
|
350
|
+
});
|
351
|
+
check(feature, Feature);
|
352
|
+
check(mapCollection, MapCollection);
|
353
|
+
|
354
|
+
const viewpoint = getViewpointFromFeature(feature);
|
355
|
+
|
356
|
+
return {
|
357
|
+
title: 'search.zoomToFeatureAction',
|
358
|
+
...actionOptions,
|
359
|
+
async callback() {
|
360
|
+
await mapCollection.activeMap.gotoViewpoint(viewpoint);
|
361
|
+
},
|
362
|
+
};
|
363
|
+
}
|
@@ -20,12 +20,21 @@
|
|
20
20
|
|
21
21
|
<script>
|
22
22
|
import { computed, inject, onUnmounted, ref } from 'vue';
|
23
|
+
import {
|
24
|
+
VChip, VList, VListItem, VListItemContent, VListItemIcon, VSheet,
|
25
|
+
} from 'vuetify/lib';
|
23
26
|
import VcsSelect from '../components/form-inputs-controls/VcsSelect.vue';
|
24
27
|
|
25
28
|
export default {
|
26
29
|
name: 'StyleSelector',
|
27
30
|
components: {
|
28
31
|
VcsSelect,
|
32
|
+
VSheet,
|
33
|
+
VList,
|
34
|
+
VListItem,
|
35
|
+
VListItemIcon,
|
36
|
+
VChip,
|
37
|
+
VListItemContent,
|
29
38
|
},
|
30
39
|
props: {
|
31
40
|
availableStyles: {
|