@vcmap/ui 5.0.0-rc.15 → 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/config/base.config.json +4 -0
- package/config/dev.config.json +5 -1
- package/config/www.config.json +5 -3
- package/dist/assets/{cesium.2e288a.js → cesium.430460.js} +0 -0
- package/dist/assets/cesium.js +1 -1
- package/dist/assets/{core.8014d3.js → core.5089ba.js} +5925 -4374
- package/dist/assets/core.js +1 -1
- package/dist/assets/{index.3f74fa92.js → index.854f8e2b.js} +1 -1
- package/dist/assets/{ol.31c3a5.js → ol.9be53a.js} +0 -0
- package/dist/assets/ol.js +1 -1
- package/dist/assets/ui.49010a.css +1 -0
- package/dist/assets/{ui.36f84f.js → ui.49010a.js} +3907 -3232
- package/dist/assets/ui.js +1 -1
- package/dist/assets/{vue.a39c10.js → vue.247c1c.js} +0 -0
- package/dist/assets/vue.js +2 -2
- package/dist/assets/{vuetify.378637.css → vuetify.735e58.css} +1 -1
- package/dist/assets/{vuetify.378637.js → vuetify.735e58.js} +1 -1
- package/dist/assets/vuetify.js +2 -2
- package/dist/index.html +1 -1
- package/index.html +77 -0
- package/index.js +4 -0
- package/package.json +4 -2
- 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 +24 -1
- package/plugins/@vcmap/pluginExample/pluginExampleComponent.vue +70 -42
- package/plugins/@vcmap/search-nominatim/nominatim.js +1 -1
- package/plugins/@vcmap/theme-changer/ThemeChangerComponent.vue +4 -2
- package/plugins/notifier/index.js +31 -0
- package/plugins/notifier/notifierTester.vue +88 -0
- package/plugins/package.json +1 -1
- package/plugins/test/allIconsComponent.vue +2 -2
- package/plugins/test/emptyComponent.vue +1 -1
- package/plugins/test/index.js +22 -0
- package/plugins/test/myCustomHeader.vue +9 -1
- package/plugins/test/testList.vue +287 -0
- package/plugins/test/windowManagerExample.vue +3 -0
- package/plugins/wizardExample/index.js +41 -0
- package/plugins/wizardExample/wizardExample.vue +77 -0
- package/src/application/VcsApp.vue +18 -8
- package/src/components/form-inputs-controls/VcsFormSection.vue +10 -10
- package/src/components/form-inputs-controls/VcsSelect.vue +33 -1
- package/src/components/form-inputs-controls/VcsTextField.vue +11 -3
- package/src/components/form-inputs-controls/VcsWizard.vue +133 -0
- package/src/components/imageElementInjector.vue +22 -0
- package/src/components/lists/VcsList.vue +466 -0
- package/src/components/lists/VcsTreeview.vue +1 -2
- package/src/components/lists/VcsTreeviewLeaf.vue +18 -50
- package/src/components/lists/VcsTreeviewSearchbar.vue +1 -23
- package/src/components/tables/VcsTable.vue +13 -1
- 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/BalloonComponent.vue +10 -8
- package/src/featureInfo/balloonFeatureInfoView.js +14 -14
- package/src/featureInfo/balloonHelper.js +4 -0
- package/src/featureInfo/featureInfo.js +13 -0
- package/src/featureInfo/featureInfoInteraction.js +1 -1
- package/src/i18n/de.js +7 -0
- package/src/i18n/en.js +7 -0
- package/src/icons/+all.js +4 -0
- package/src/icons/WandIcon.vue +63 -0
- package/src/manager/window/WindowComponent.vue +9 -2
- package/src/manager/window/WindowComponentHeader.vue +33 -7
- package/src/manager/window/WindowManager.vue +1 -0
- package/src/manager/window/windowManager.js +11 -1
- package/src/navigation/overviewMap.js +10 -9
- package/src/notifier/notifier.js +121 -0
- package/src/notifier/notifierComponent.vue +84 -0
- package/src/styles/variables.scss +19 -3
- package/src/vcsUiApp.js +19 -1
- package/src/vuePlugins/vuetify.js +2 -0
- package/dist/assets/ui.36f84f.css +0 -1
@@ -7,30 +7,30 @@ import { createStateRefAction, StateActionState } from '../actions/stateRefActio
|
|
7
7
|
|
8
8
|
/**
|
9
9
|
* @typedef {Object} ContentTreeItemOptions
|
10
|
-
* @property {string} name
|
10
|
+
* @property {string} name - name of the item defining the structure within the tree using dot notation.
|
11
11
|
* @property {string} [title] - may be unset, if set from object properties later on. required otherwise
|
12
12
|
* @property {string} [tooltip] - may be unset or set from object properties later on.
|
13
|
-
* @property {string|HTMLCanvasElement|HTMLImageElement|undefined} icon - an icon URL or element to display
|
14
|
-
* @property {number} [weight]
|
15
|
-
* @property {string} [infoUrl]
|
16
|
-
* @property {boolean} [initOpen=false]
|
13
|
+
* @property {string|HTMLCanvasElement|HTMLImageElement|undefined} icon - an icon URL or element to display.
|
14
|
+
* @property {number} [weight] - optional weighting of the item. higher weights come first.
|
15
|
+
* @property {string} [infoUrl] - optional info url providing link with additional information.
|
16
|
+
* @property {boolean} [initOpen=false] - groups being initially open or not.
|
17
17
|
*/
|
18
18
|
|
19
19
|
/**
|
20
20
|
* A readonly rendering interface of a ContentTreeItem.
|
21
21
|
* @typedef {Object} TreeViewItem
|
22
22
|
* @property {string} name
|
23
|
-
* @property {boolean} visible
|
24
|
-
* @property {boolean} clickable
|
25
|
-
* @property {boolean} disabled
|
26
|
-
* @property {StateActionState} state
|
27
|
-
* @property {string} title
|
23
|
+
* @property {boolean} visible - Whether to display this item or not.
|
24
|
+
* @property {boolean} clickable - Whether this item reacts to click events, e.g. with visual feedback
|
25
|
+
* @property {boolean} disabled - Whether this item should be displayed as disabled.
|
26
|
+
* @property {StateActionState} state - The state of this item. NONE if this item cannot have a state.
|
27
|
+
* @property {string} title - The title to be displayed
|
28
28
|
* @property {string} [tooltip]
|
29
|
-
* @property {string|HTMLCanvasElement|HTMLImageElement|undefined} icon
|
29
|
+
* @property {string|HTMLCanvasElement|HTMLImageElement|undefined} [icon] - An optional icon to display with this item. Can be an URL or HTMLElement.
|
30
30
|
* @property {Array<VcsAction>} actions
|
31
31
|
* @property {Array<TreeViewItem>} children
|
32
32
|
* @property {Array<TreeViewItem>} visibleChildren - computed property
|
33
|
-
* @property {function():Promise<void>} clicked
|
33
|
+
* @property {function(PointerEvent):Promise<void>} clicked - A callback called once the item is clicked.
|
34
34
|
*/
|
35
35
|
|
36
36
|
/**
|
@@ -376,7 +376,7 @@ class ContentTreeItem {
|
|
376
376
|
* GoToExtent: 8
|
377
377
|
* The default weight is set to always push new actions past these.
|
378
378
|
* @param {VcsAction} action
|
379
|
-
* @param {number} [weight=
|
379
|
+
* @param {number} [weight=11]
|
380
380
|
*/
|
381
381
|
addAction(action, weight = 11) {
|
382
382
|
check(action.name, String);
|
@@ -6,7 +6,7 @@ import ContentTreeItem, { contentTreeClassRegistry } from './contentTreeItem.js'
|
|
6
6
|
export const subTreeSymbol = Symbol('SubTree');
|
7
7
|
|
8
8
|
/**
|
9
|
-
* A
|
9
|
+
* A subtree item. Subtrees are rendered in their own (not the main content tree).
|
10
10
|
* They will receive their own toggle button in the nav bar.
|
11
11
|
* Only toplevel items can be content tree items (with a name which does not have a .)
|
12
12
|
* @class
|
@@ -9,7 +9,7 @@ import ContentTreeItem, { contentTreeClassRegistry } from './contentTreeItem.js'
|
|
9
9
|
|
10
10
|
/**
|
11
11
|
* An abstract class for VcsObject based items.
|
12
|
-
* It
|
12
|
+
* It handles the overriding/setting of its own values based on
|
13
13
|
* the VcsObjects properties bag.
|
14
14
|
* @class
|
15
15
|
* @template {VcsObjectContentTreeItemProperties} T
|
@@ -17,16 +17,17 @@
|
|
17
17
|
</v-list-item-avatar>
|
18
18
|
<v-list-item-content class="py-2 pr-1 align-self-start">
|
19
19
|
<v-list-item-title class="text-h6">
|
20
|
-
{{ $t(
|
20
|
+
{{ $t(balloonTitle) }}
|
21
21
|
</v-list-item-title>
|
22
|
-
<v-list-item-subtitle v-if="
|
23
|
-
{{ $t(
|
22
|
+
<v-list-item-subtitle v-if="balloonSubtitle">
|
23
|
+
{{ $t(balloonSubtitle) }}
|
24
24
|
</v-list-item-subtitle>
|
25
25
|
</v-list-item-content>
|
26
26
|
<VcsButton
|
27
27
|
@click.stop="close"
|
28
28
|
small
|
29
29
|
icon="mdi-close-thick"
|
30
|
+
tooltip="components.close"
|
30
31
|
/>
|
31
32
|
</v-list-item>
|
32
33
|
</slot>
|
@@ -58,7 +59,8 @@
|
|
58
59
|
VList,
|
59
60
|
VListItem,
|
60
61
|
VListItemAvatar,
|
61
|
-
VListItemContent,
|
62
|
+
VListItemContent,
|
63
|
+
VListItemSubtitle,
|
62
64
|
VListItemTitle,
|
63
65
|
} from 'vuetify/lib';
|
64
66
|
import { setupBalloonPositionListener } from './balloonHelper.js';
|
@@ -68,8 +70,8 @@
|
|
68
70
|
* @description A balloon viewing feature attributes. Size dynamic dependent on number of attributes.
|
69
71
|
* Scrollable, if more than 6 attributes are provided.
|
70
72
|
* @vue-prop {string} featureId - feature's id
|
71
|
-
* @vue-prop {string}
|
72
|
-
* @vue-prop {string}
|
73
|
+
* @vue-prop {string} balloonTitle - balloon title
|
74
|
+
* @vue-prop {string} balloonSubtitle - balloon subtitle
|
73
75
|
* @vue-prop {Object} attributes - feature's attributes
|
74
76
|
* @vue-prop {Array<import("ol/coordinate").Coordinate>} position - clicked position balloon is rendered at
|
75
77
|
* @vue-data {slot} [#balloon-header] - slot to override balloon header, $props and $attrs are passed to `attrs`
|
@@ -94,11 +96,11 @@
|
|
94
96
|
type: String,
|
95
97
|
required: true,
|
96
98
|
},
|
97
|
-
|
99
|
+
balloonTitle: {
|
98
100
|
type: String,
|
99
101
|
required: true,
|
100
102
|
},
|
101
|
-
|
103
|
+
balloonSubtitle: {
|
102
104
|
type: String,
|
103
105
|
required: true,
|
104
106
|
},
|
@@ -26,14 +26,14 @@ export function extractNestedKey(key, attrs, defaultValue = null) {
|
|
26
26
|
|
27
27
|
/**
|
28
28
|
* @typedef {FeatureInfoViewOptions} BalloonFeatureInfoViewOptions
|
29
|
-
* @property {string} [
|
30
|
-
* @property {string} [
|
29
|
+
* @property {string} [balloonTitle] - optional title to overwrite default (layerName). Can be attribute key (nested key using '.'), i18n key or text
|
30
|
+
* @property {string} [balloonSubtitle] - optional window title to overwrite default (featureId). Can be attribute key (nested key using '.'), i18n key or text
|
31
31
|
*/
|
32
32
|
|
33
33
|
/**
|
34
34
|
* @typedef {FeatureInfoProps} BalloonFeatureInfoViewProps
|
35
|
-
* @property {string}
|
36
|
-
* @property {string}
|
35
|
+
* @property {string} balloonTitle
|
36
|
+
* @property {string} balloonSubtitle
|
37
37
|
* @property {import("ol/coordinate").Coordinate} position
|
38
38
|
*/
|
39
39
|
|
@@ -87,12 +87,12 @@ class BalloonFeatureInfoView extends AbstractFeatureInfoView {
|
|
87
87
|
/**
|
88
88
|
* @type {string}
|
89
89
|
*/
|
90
|
-
this.
|
90
|
+
this.balloonTitle = options.balloonTitle;
|
91
91
|
|
92
92
|
/**
|
93
93
|
* @type {string}
|
94
94
|
*/
|
95
|
-
this.
|
95
|
+
this.balloonSubtitle = options.balloonSubtitle;
|
96
96
|
}
|
97
97
|
|
98
98
|
/**
|
@@ -105,11 +105,11 @@ class BalloonFeatureInfoView extends AbstractFeatureInfoView {
|
|
105
105
|
return {
|
106
106
|
...properties,
|
107
107
|
position: featureInfo.position ?? getPositionFromFeature(featureInfo.feature),
|
108
|
-
|
109
|
-
extractNestedKey(this.
|
108
|
+
balloonTitle: this.balloonTitle != null ?
|
109
|
+
extractNestedKey(this.balloonTitle, properties.attributes, this.balloonTitle) :
|
110
110
|
properties.layerProperties.title,
|
111
|
-
|
112
|
-
extractNestedKey(this.
|
111
|
+
balloonSubtitle: this.balloonSubtitle != null ?
|
112
|
+
extractNestedKey(this.balloonSubtitle, properties.attributes, this.balloonSubtitle) :
|
113
113
|
properties.featureId,
|
114
114
|
};
|
115
115
|
}
|
@@ -138,11 +138,11 @@ class BalloonFeatureInfoView extends AbstractFeatureInfoView {
|
|
138
138
|
*/
|
139
139
|
toJSON() {
|
140
140
|
const config = super.toJSON();
|
141
|
-
if (this.
|
142
|
-
config.
|
141
|
+
if (this.balloonTitle) {
|
142
|
+
config.balloonTitle = this.balloonTitle;
|
143
143
|
}
|
144
|
-
if (this.
|
145
|
-
config.
|
144
|
+
if (this.balloonSubtitle) {
|
145
|
+
config.balloonSubtitle = this.balloonSubtitle;
|
146
146
|
}
|
147
147
|
return config;
|
148
148
|
}
|
@@ -99,6 +99,10 @@ export async function setupBalloonPositionListener(vcsApp, windowId, clickedPosi
|
|
99
99
|
|
100
100
|
const map = app.maps.activeMap;
|
101
101
|
if (map instanceof CesiumMap) {
|
102
|
+
if (!position[2]) {
|
103
|
+
const [position3D] = await map.getHeightFromTerrain([position]);
|
104
|
+
position[2] = position3D[2];
|
105
|
+
}
|
102
106
|
const wgs84Position = Projection.mercatorToWgs84(position);
|
103
107
|
const cartesian = Cartographic.toCartesian(Cartographic.fromDegrees(...wgs84Position));
|
104
108
|
listeners.push(map.getScene().postRender.addEventListener((scene) => {
|
@@ -231,6 +231,11 @@ class FeatureInfo {
|
|
231
231
|
* @private
|
232
232
|
*/
|
233
233
|
this._selectedFeature = null;
|
234
|
+
/**
|
235
|
+
* @type {string|null}
|
236
|
+
* @private
|
237
|
+
*/
|
238
|
+
this._selectedFeatureId = null;
|
234
239
|
/**
|
235
240
|
* @type {Array<function():void>}
|
236
241
|
* @private
|
@@ -299,6 +304,12 @@ class FeatureInfo {
|
|
299
304
|
*/
|
300
305
|
get selectedFeature() { return this._selectedFeature; }
|
301
306
|
|
307
|
+
/**
|
308
|
+
* @type {null|string}
|
309
|
+
* @readonly
|
310
|
+
*/
|
311
|
+
get selectedFeatureId() { return this._selectedFeatureId; }
|
312
|
+
|
302
313
|
/**
|
303
314
|
* The window id of the current features FeatureInfoView window
|
304
315
|
* @type {string|null}
|
@@ -404,6 +415,7 @@ class FeatureInfo {
|
|
404
415
|
);
|
405
416
|
|
406
417
|
this._selectedFeature = feature;
|
418
|
+
this._selectedFeatureId = feature.getId();
|
407
419
|
this._featureChanged.raiseEvent(this._selectedFeature);
|
408
420
|
} else {
|
409
421
|
this.clear();
|
@@ -436,6 +448,7 @@ class FeatureInfo {
|
|
436
448
|
this._clearInternal();
|
437
449
|
if (this._selectedFeature) {
|
438
450
|
this._selectedFeature = null;
|
451
|
+
this._selectedFeatureId = null;
|
439
452
|
this._featureChanged.raiseEvent(this._selectedFeature);
|
440
453
|
}
|
441
454
|
}
|
@@ -24,7 +24,7 @@ class FeatureInfoInteraction extends AbstractInteraction {
|
|
24
24
|
*/
|
25
25
|
async pipe(event) {
|
26
26
|
if (event.feature) {
|
27
|
-
if (!this._featureInfo.selectedFeature || event.feature.getId() !== this._featureInfo.
|
27
|
+
if (!this._featureInfo.selectedFeature || event.feature.getId() !== this._featureInfo.selectedFeatureId) {
|
28
28
|
event.stopPropagation = true;
|
29
29
|
await this._featureInfo.selectFeature(
|
30
30
|
event.feature,
|
package/src/i18n/de.js
CHANGED
@@ -44,6 +44,7 @@ const messages = {
|
|
44
44
|
components: {
|
45
45
|
title: 'Komponenten',
|
46
46
|
tooltip: 'Komponenten',
|
47
|
+
close: 'Fenster schließen.',
|
47
48
|
vcsFormSection: {
|
48
49
|
help: 'Hilfe anzeigen.',
|
49
50
|
},
|
@@ -91,6 +92,12 @@ const messages = {
|
|
91
92
|
tooltip: 'Öffne Attribution Fenster',
|
92
93
|
},
|
93
94
|
},
|
95
|
+
notification: {
|
96
|
+
error: 'Fehler',
|
97
|
+
warning: 'Warnung',
|
98
|
+
information: 'Information',
|
99
|
+
success: 'Erfolg',
|
100
|
+
},
|
94
101
|
};
|
95
102
|
|
96
103
|
export default messages;
|
package/src/i18n/en.js
CHANGED
@@ -44,6 +44,7 @@ const messages = {
|
|
44
44
|
components: {
|
45
45
|
title: 'Components',
|
46
46
|
tooltip: 'Components',
|
47
|
+
close: 'Close window.',
|
47
48
|
vcsFormSection: {
|
48
49
|
help: 'Show help.',
|
49
50
|
},
|
@@ -91,6 +92,12 @@ const messages = {
|
|
91
92
|
tooltip: 'Open Attributions Window',
|
92
93
|
},
|
93
94
|
},
|
95
|
+
notification: {
|
96
|
+
error: 'Error',
|
97
|
+
warning: 'Warning',
|
98
|
+
information: 'Information',
|
99
|
+
success: 'Success',
|
100
|
+
},
|
94
101
|
};
|
95
102
|
|
96
103
|
export default messages;
|
package/src/icons/+all.js
CHANGED
@@ -100,6 +100,7 @@ import Viewshed360Icon from './Viewshed360Icon.vue';
|
|
100
100
|
import ViewshedConeIcon from './ViewshedConeIcon.vue';
|
101
101
|
import WalkingIcon from './WalkingIcon.vue';
|
102
102
|
import WallIcon from './WallIcon.vue';
|
103
|
+
import WandIcon from './WandIcon.vue';
|
103
104
|
|
104
105
|
// * // IconMap.boundingBox
|
105
106
|
// * <v-icon size="16" v-text="'$vcsBoundingBox'" />
|
@@ -431,6 +432,9 @@ const IconMap = {
|
|
431
432
|
walking: {
|
432
433
|
component: WalkingIcon,
|
433
434
|
},
|
435
|
+
wand: {
|
436
|
+
component: WandIcon,
|
437
|
+
},
|
434
438
|
};
|
435
439
|
|
436
440
|
const nameCapitalized = (name) => { return name.charAt(0).toUpperCase() + name.slice(1); };
|
@@ -0,0 +1,63 @@
|
|
1
|
+
<!-- eslint-disable max-len -->
|
2
|
+
|
3
|
+
<template>
|
4
|
+
<svg id="icon_wizard" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
5
|
+
<g id="wand" transform="translate(1.706 1.705)">
|
6
|
+
<g id="Gruppe_1465" data-name="Gruppe 1465" transform="translate(0 10.491)">
|
7
|
+
<g id="Gruppe_1464" data-name="Gruppe 1464">
|
8
|
+
<path id="Pfad_540" data-name="Pfad 540" d="M1.574,22.1a.476.476,0,0,1-.367-.157L.157,20.892a.507.507,0,0,1,0-.734.507.507,0,0,1,.734,0l1.049,1.049a.507.507,0,0,1,0,.734A.476.476,0,0,1,1.574,22.1Z" transform="translate(0 -20)" fill="currentColor" />
|
9
|
+
</g>
|
10
|
+
</g>
|
11
|
+
<g id="Gruppe_1467" data-name="Gruppe 1467" transform="translate(1.049 1.049)">
|
12
|
+
<g id="Gruppe_1466" data-name="Gruppe 1466">
|
13
|
+
<path id="Pfad_541" data-name="Pfad 541" d="M2.525,13.54a.476.476,0,0,1-.367-.157.507.507,0,0,1,0-.734L12.648,2.157a.519.519,0,1,1,.734.734L2.892,13.382A.476.476,0,0,1,2.525,13.54Z" transform="translate(-2 -2)" fill="currentColor" />
|
14
|
+
</g>
|
15
|
+
</g>
|
16
|
+
<g id="Gruppe_1469" data-name="Gruppe 1469" transform="translate(10.491 0)">
|
17
|
+
<g id="Gruppe_1468" data-name="Gruppe 1468">
|
18
|
+
<path id="Pfad_542" data-name="Pfad 542" d="M21.574,2.1a.476.476,0,0,1-.367-.157L20.157.892a.507.507,0,0,1,0-.734.507.507,0,0,1,.734,0l1.049,1.049a.507.507,0,0,1,0,.734A.476.476,0,0,1,21.574,2.1Z" transform="translate(-20 0)" fill="currentColor" />
|
19
|
+
</g>
|
20
|
+
</g>
|
21
|
+
<g id="Gruppe_1471" data-name="Gruppe 1471" transform="translate(0 0)">
|
22
|
+
<g id="Gruppe_1470" data-name="Gruppe 1470">
|
23
|
+
<path id="Pfad_543" data-name="Pfad 543" d="M.525,11.54a.476.476,0,0,1-.367-.157.507.507,0,0,1,0-.734L10.648.157a.507.507,0,0,1,.734,0,.507.507,0,0,1,0,.734L.892,11.382A.476.476,0,0,1,.525,11.54Z" transform="translate(0 0)" fill="currentColor" />
|
24
|
+
</g>
|
25
|
+
</g>
|
26
|
+
<g id="Gruppe_1473" data-name="Gruppe 1473" transform="translate(8.393 2.098)">
|
27
|
+
<g id="Gruppe_1472" data-name="Gruppe 1472">
|
28
|
+
<path id="Pfad_544" data-name="Pfad 544" d="M17.574,6.1a.476.476,0,0,1-.367-.157L16.157,4.892a.519.519,0,0,1,.734-.734l1.049,1.049a.507.507,0,0,1,0,.734A.476.476,0,0,1,17.574,6.1Z" transform="translate(-16 -4)" fill="currentColor" />
|
29
|
+
</g>
|
30
|
+
</g>
|
31
|
+
<g id="Gruppe_1475" data-name="Gruppe 1475" transform="translate(7.344 7.344)">
|
32
|
+
<g id="Gruppe_1474" data-name="Gruppe 1474">
|
33
|
+
<path id="Pfad_545" data-name="Pfad 545" d="M14.525,16.1A.5.5,0,0,1,14,15.574V14.525a.525.525,0,1,1,1.049,0v1.049A.5.5,0,0,1,14.525,16.1Z" transform="translate(-14 -14)" fill="currentColor" />
|
34
|
+
</g>
|
35
|
+
</g>
|
36
|
+
<g id="Gruppe_1477" data-name="Gruppe 1477" transform="translate(7.344)">
|
37
|
+
<g id="Gruppe_1476" data-name="Gruppe 1476">
|
38
|
+
<path id="Pfad_546" data-name="Pfad 546" d="M14.525,2.1A.5.5,0,0,1,14,1.574V.525a.525.525,0,0,1,1.049,0V1.574A.5.5,0,0,1,14.525,2.1Z" transform="translate(-14)" fill="currentColor" />
|
39
|
+
</g>
|
40
|
+
</g>
|
41
|
+
<g id="Gruppe_1479" data-name="Gruppe 1479" transform="translate(3.147 4.196)">
|
42
|
+
<g id="Gruppe_1478" data-name="Gruppe 1478">
|
43
|
+
<path id="Pfad_547" data-name="Pfad 547" d="M7.574,9.049H6.525A.525.525,0,0,1,6.525,8H7.574a.525.525,0,0,1,0,1.049Z" transform="translate(-6 -8)" fill="currentColor" />
|
44
|
+
</g>
|
45
|
+
</g>
|
46
|
+
<g id="Gruppe_1481" data-name="Gruppe 1481" transform="translate(10.491 4.196)">
|
47
|
+
<g id="Gruppe_1480" data-name="Gruppe 1480">
|
48
|
+
<path id="Pfad_548" data-name="Pfad 548" d="M21.574,9.049H20.525a.525.525,0,0,1,0-1.049h1.049a.525.525,0,1,1,0,1.049Z" transform="translate(-20 -8)" fill="currentColor" />
|
49
|
+
</g>
|
50
|
+
</g>
|
51
|
+
<g id="Gruppe_1483" data-name="Gruppe 1483" transform="translate(3.986 0.839)">
|
52
|
+
<g id="Gruppe_1482" data-name="Gruppe 1482">
|
53
|
+
<path id="Pfad_549" data-name="Pfad 549" d="M9.279,3.8a.476.476,0,0,1-.367-.157L7.757,2.492a.519.519,0,0,1,.734-.734l1.1,1.1a.507.507,0,0,1,0,.734A.326.326,0,0,1,9.279,3.8Z" transform="translate(-7.6 -1.6)" fill="currentColor" />
|
54
|
+
</g>
|
55
|
+
</g>
|
56
|
+
<g id="Gruppe_1485" data-name="Gruppe 1485" transform="translate(9.599 6.452)">
|
57
|
+
<g id="Gruppe_1484" data-name="Gruppe 1484">
|
58
|
+
<path id="Pfad_550" data-name="Pfad 550" d="M19.926,14.451a.476.476,0,0,1-.367-.157l-1.1-1.1a.519.519,0,1,1,.734-.734l1.1,1.1a.507.507,0,0,1,0,.734A.567.567,0,0,1,19.926,14.451Z" transform="translate(-18.3 -12.3)" fill="currentColor" />
|
59
|
+
</g>
|
60
|
+
</g>
|
61
|
+
</g>
|
62
|
+
</svg>
|
63
|
+
</template>
|
@@ -19,7 +19,7 @@
|
|
19
19
|
}"
|
20
20
|
:draggable="isDynamic"
|
21
21
|
>
|
22
|
-
<slot name="headerComponent" />
|
22
|
+
<slot name="headerComponent" :props="$attrs" />
|
23
23
|
</div>
|
24
24
|
<v-divider />
|
25
25
|
<div
|
@@ -40,7 +40,7 @@
|
|
40
40
|
|
41
41
|
<script>
|
42
42
|
import {
|
43
|
-
onMounted, onUnmounted, computed, ref, nextTick,
|
43
|
+
onMounted, onUnmounted, computed, ref, nextTick, inject, provide,
|
44
44
|
} from 'vue';
|
45
45
|
import { fromEvent } from 'rxjs';
|
46
46
|
import { switchMap, take, map, tap } from 'rxjs/operators';
|
@@ -133,6 +133,13 @@
|
|
133
133
|
dropSub.unsubscribe();
|
134
134
|
}
|
135
135
|
});
|
136
|
+
|
137
|
+
const app = inject('vcsApp');
|
138
|
+
const { provides } = app.windowManager.get(windowState.id);
|
139
|
+
Object.entries(provides)
|
140
|
+
.forEach(([key, value]) => {
|
141
|
+
provide(key, value);
|
142
|
+
});
|
136
143
|
return {
|
137
144
|
isDynamic,
|
138
145
|
isDocked,
|
@@ -10,29 +10,55 @@
|
|
10
10
|
{{ $t(windowState.headerTitle) }}
|
11
11
|
</h3>
|
12
12
|
</span>
|
13
|
-
<
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
13
|
+
<div class="d-flex justify-space-between align-center">
|
14
|
+
<template v-if="windowState.headerActions?.length > 0">
|
15
|
+
<VcsActionButtonList
|
16
|
+
:actions="windowState.headerActions"
|
17
|
+
:overflow-count="windowState.headerActionsOverflowCount ?? 3"
|
18
|
+
small
|
19
|
+
/>
|
20
|
+
<v-divider
|
21
|
+
vertical
|
22
|
+
inset
|
23
|
+
class="mx-2"
|
24
|
+
/>
|
25
|
+
</template>
|
26
|
+
<VcsButton
|
27
|
+
@click.stop="close"
|
28
|
+
small
|
29
|
+
icon="mdi-close-thick"
|
30
|
+
tooltip="components.close"
|
31
|
+
/>
|
32
|
+
</div>
|
18
33
|
</span>
|
19
34
|
</template>
|
20
35
|
|
21
|
-
<style>
|
36
|
+
<style lang="scss" scoped>
|
22
37
|
.window-component-header{
|
23
38
|
max-height: 16px;
|
39
|
+
|
40
|
+
.v-divider--vertical.v-divider--inset {
|
41
|
+
margin-top: 2px;
|
42
|
+
}
|
24
43
|
}
|
25
44
|
</style>
|
26
45
|
|
27
46
|
<script>
|
28
|
-
import { VIcon } from 'vuetify/lib';
|
47
|
+
import { VIcon, VDivider } from 'vuetify/lib';
|
29
48
|
import VcsButton from '../../components/buttons/VcsButton.vue';
|
49
|
+
import VcsActionButtonList from '../../components/buttons/VcsActionButtonList.vue';
|
30
50
|
|
51
|
+
/**
|
52
|
+
* Default window component header with drag functionality close action and further optional window actions.
|
53
|
+
* @vue-prop {WindowState} windowState - state of the window component.
|
54
|
+
*/
|
31
55
|
export default {
|
32
56
|
name: 'WindowComponentHeader',
|
33
57
|
components: {
|
58
|
+
VcsActionButtonList,
|
34
59
|
VcsButton,
|
35
60
|
VIcon,
|
61
|
+
VDivider,
|
36
62
|
},
|
37
63
|
props: {
|
38
64
|
windowState: {
|
@@ -78,6 +78,7 @@ export const WindowPositions = {
|
|
78
78
|
* @property {WindowState} [state]
|
79
79
|
* @property {WindowSlot} [slot] If WindowSlot is not detached the position will be ignored
|
80
80
|
* @property {Object} [props]
|
81
|
+
* @property {Object} [provides]
|
81
82
|
*/
|
82
83
|
|
83
84
|
/**
|
@@ -87,6 +88,8 @@ export const WindowPositions = {
|
|
87
88
|
* @property {boolean} [hideHeader] be used to not show the header.
|
88
89
|
* @property {string} [headerTitle]
|
89
90
|
* @property {string} [headerIcon]
|
91
|
+
* @property {Array<VcsAction>} [headerActions]
|
92
|
+
* @property {number} [headerActionsOverflowCount]
|
90
93
|
* @property {Object<string, string>} styles[styles] Can be used to add additional styles to the root WindowComponent. Use Vue Style Bindings Object Syntax https://vuejs.org/v2/guide/class-and-style.html
|
91
94
|
* @property {Array<string>|Object<string,string>} [classes] Can be used to add additional classes to the root WindowComponent. Use Vue Class Bindings Syntax https://vuejs.org/v2/guide/class-and-style.html
|
92
95
|
*/
|
@@ -100,6 +103,7 @@ export const WindowPositions = {
|
|
100
103
|
* @property {WindowState} state
|
101
104
|
* @property {Ref<UnwrapRef<WindowSlot>>} slot
|
102
105
|
* @property {Object} props
|
106
|
+
* @property {Object} provides
|
103
107
|
*/
|
104
108
|
|
105
109
|
/**
|
@@ -417,7 +421,7 @@ class WindowManager {
|
|
417
421
|
/**
|
418
422
|
* adds a windowComponent to the WindowManager and renders the Window at the provided position/slot.
|
419
423
|
* The reactive WindowState Object can be used to watch Changes on position/WindowSlot.
|
420
|
-
* The WindowState Object can also be used to change hideHeader, headerTitle, headerIcon, styles and classes
|
424
|
+
* The WindowState Object can also be used to change hideHeader, headerTitle, headerIcon, headerActions, styles and classes
|
421
425
|
* @param {WindowComponentOptions|WindowComponent} windowComponentOptions
|
422
426
|
* @param {string|symbol} owner pluginName or vcsAppSymbol
|
423
427
|
* @throws {Error} if a windowComponent with the same ID has already been added
|
@@ -450,11 +454,14 @@ class WindowManager {
|
|
450
454
|
hideHeader: !!windowComponentOptions?.state?.hideHeader,
|
451
455
|
headerTitle: windowComponentOptions?.state?.headerTitle,
|
452
456
|
headerIcon: windowComponentOptions?.state?.headerIcon,
|
457
|
+
headerActions: windowComponentOptions?.state?.headerActions,
|
458
|
+
headerActionsOverflow: windowComponentOptions?.state?.headerActionsOverflow,
|
453
459
|
classes,
|
454
460
|
styles,
|
455
461
|
});
|
456
462
|
|
457
463
|
const props = windowComponentOptions.props || {};
|
464
|
+
const provides = windowComponentOptions.provides || {};
|
458
465
|
|
459
466
|
const position = reactive(windowPosition);
|
460
467
|
/**
|
@@ -482,6 +489,9 @@ class WindowManager {
|
|
482
489
|
get props() {
|
483
490
|
return props;
|
484
491
|
},
|
492
|
+
get provides() {
|
493
|
+
return provides;
|
494
|
+
},
|
485
495
|
};
|
486
496
|
this._removeWindowAtSlot(slot);
|
487
497
|
this._windowComponents.set(id, windowComponent);
|
@@ -205,7 +205,7 @@ class OverviewMap {
|
|
205
205
|
clone.activate();
|
206
206
|
const idx = this._map.layerCollection.indexOf(clone);
|
207
207
|
if (idx < 0) {
|
208
|
-
this._map.layerCollection.add(clone);
|
208
|
+
this._map.layerCollection.add(clone, 0);
|
209
209
|
} else {
|
210
210
|
this._map.layerCollection.remove(clone);
|
211
211
|
this._map.layerCollection.add(clone, idx);
|
@@ -298,6 +298,7 @@ class OverviewMap {
|
|
298
298
|
this._setupMapInteraction();
|
299
299
|
}
|
300
300
|
await this._map.activate();
|
301
|
+
this.map.setTarget('overview-map-container');
|
301
302
|
if (!this._active) {
|
302
303
|
this._mapActivatedListener = this._app.maps.mapActivated.addEventListener(() => {
|
303
304
|
this._clearListeners();
|
@@ -323,7 +324,6 @@ class OverviewMap {
|
|
323
324
|
this._app.windowManager.add(getWindowComponentOptions(), vcsAppSymbol);
|
324
325
|
}
|
325
326
|
await this._activate();
|
326
|
-
this.map.setTarget('overview-map-container');
|
327
327
|
}
|
328
328
|
|
329
329
|
/**
|
@@ -347,9 +347,10 @@ class OverviewMap {
|
|
347
347
|
async _initializePostRenderHandler(map) {
|
348
348
|
if (!this._cameraIconLayer) {
|
349
349
|
this._setupCameraIconLayer();
|
350
|
+
this._syncCameraViewAndFeature();
|
350
351
|
}
|
351
352
|
const navRemover = this._addNavigationListener(map);
|
352
|
-
const prRemover = map.postRender.addEventListener(this.
|
353
|
+
const prRemover = map.postRender.addEventListener(this._syncCameraViewAndFeature.bind(this));
|
353
354
|
const cleanupTasks = () => {
|
354
355
|
prRemover();
|
355
356
|
navRemover();
|
@@ -513,7 +514,7 @@ class OverviewMap {
|
|
513
514
|
* Adds and maintains the view and camera feature
|
514
515
|
* @private
|
515
516
|
*/
|
516
|
-
|
517
|
+
_syncCameraViewAndFeature() {
|
517
518
|
const viewpoint = this._app.maps.activeMap?.getViewpointSync();
|
518
519
|
if (!viewpoint || !viewpoint.isValid() || viewpoint.equals(this._cachedViewpoint)) {
|
519
520
|
return;
|
@@ -525,8 +526,6 @@ class OverviewMap {
|
|
525
526
|
let { distance } = viewpoint;
|
526
527
|
if (position[2] && !(distance && distance < position[2] * 4)) {
|
527
528
|
distance = position[2] * 4;
|
528
|
-
} else if (position[2] == null) {
|
529
|
-
position[2] = distance;
|
530
529
|
}
|
531
530
|
|
532
531
|
distance = distance > this.minimumHeight ? distance : this.minimumHeight;
|
@@ -551,9 +550,11 @@ class OverviewMap {
|
|
551
550
|
this.cameraIconStyle.image.setRotation(rotationRadians);
|
552
551
|
|
553
552
|
viewpoint.heading = 0;
|
554
|
-
viewpoint.cameraPosition
|
555
|
-
|
556
|
-
|
553
|
+
if (viewpoint.cameraPosition) {
|
554
|
+
viewpoint.cameraPosition = position;
|
555
|
+
viewpoint.groundPosition = null;
|
556
|
+
viewpoint.distance = distance * 4;
|
557
|
+
}
|
557
558
|
this._map.gotoViewpoint(viewpoint);
|
558
559
|
}
|
559
560
|
|