@vcmap/ui 5.0.0-rc.16 → 5.0.0-rc.17
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/buildHelpers.js +7 -1
- package/config/base.config.json +3 -45
- package/config/www.config.json +9 -10
- package/dist/assets/{cesium.430460.js → cesium.41de56.js} +0 -0
- package/dist/assets/cesium.js +1 -1
- package/dist/assets/{core.5089ba.js → core.af84e3.js} +1700 -1718
- package/dist/assets/core.js +1 -1
- package/dist/assets/{index.854f8e2b.js → index.5b773cad.js} +1 -1
- package/dist/assets/{ol.9be53a.js → ol.5c7490.js} +0 -0
- package/dist/assets/ol.js +1 -1
- package/dist/assets/{ui.49010a.css → ui.dffe32.css} +1 -1
- package/dist/assets/{ui.49010a.js → ui.dffe32.js} +6345 -6011
- package/dist/assets/ui.js +1 -1
- package/dist/assets/{vue.247c1c.js → vue.25da17.js} +0 -0
- package/dist/assets/vue.js +2 -2
- package/dist/assets/{vuetify.735e58.css → vuetify.e4ece7.css} +0 -0
- package/dist/assets/{vuetify.735e58.js → vuetify.e4ece7.js} +5 -2
- package/dist/assets/vuetify.js +2 -2
- package/dist/index.html +1 -1
- package/index.js +14 -3
- package/package.json +2 -2
- package/plugins/@vcmap/pluginExample/index.js +2 -1
- package/plugins/@vcmap/pluginExample/pluginExampleComponent.vue +7 -0
- package/plugins/categoryTest/Categories.vue +27 -13
- package/plugins/categoryTest/Category.vue +7 -1
- package/plugins/categoryTest/index.js +1 -1
- package/plugins/test/allIconsComponent.vue +3 -3
- package/plugins/test/index.js +6 -4
- package/plugins/test/testList.vue +4 -1
- package/plugins/test/vcsContent.vue +1 -1
- package/plugins/test/windowManagerExample.vue +9 -7
- package/src/actions/actionHelper.js +10 -9
- package/src/application/VcsApp.vue +25 -26
- package/src/components/form-inputs-controls/VcsCheckbox.vue +1 -0
- package/src/components/form-inputs-controls/VcsFormSection.vue +14 -6
- package/src/components/lists/VcsList.vue +4 -2
- package/src/contentTree/contentTreeCollection.js +9 -0
- package/src/contentTree/layerContentTreeItem.js +1 -1
- package/src/featureInfo/BalloonComponent.vue +3 -0
- package/src/featureInfo/balloonFeatureInfoView.js +2 -8
- package/src/featureInfo/balloonHelper.js +22 -5
- package/src/featureInfo/featureInfo.js +1 -2
- package/src/i18n/de.js +6 -1
- package/src/i18n/en.js +6 -1
- package/src/manager/categoryManager/CategoryComponent.vue +115 -0
- package/src/manager/categoryManager/CategoryComponentList.vue +57 -0
- package/src/manager/categoryManager/CategoryManager.vue +35 -0
- package/src/manager/categoryManager/categoryManager.js +251 -165
- package/src/manager/contextMenu/contextMenuManager.js +8 -2
- package/src/manager/window/WindowComponent.vue +49 -75
- package/src/manager/window/WindowComponentHeader.vue +49 -7
- package/src/manager/window/WindowManager.vue +53 -30
- package/src/manager/window/windowHelper.js +341 -0
- package/src/manager/window/windowManager.js +162 -150
- package/src/notifier/notifier.js +4 -5
- package/src/vcsUiApp.js +7 -1
- package/src/manager/categoryManager/ComponentsManager.vue +0 -30
@@ -2,8 +2,10 @@
|
|
2
2
|
<v-sheet
|
3
3
|
:id="`window-component--${windowState.id}`"
|
4
4
|
class="elevation-3 position-absolute d-flex flex-column"
|
5
|
-
ref="windowComponentRef"
|
6
5
|
@click="clicked"
|
6
|
+
@dragstart="dragStart"
|
7
|
+
@dragend="dragEnd"
|
8
|
+
:draggable="isDynamic"
|
7
9
|
:class="{
|
8
10
|
'rounded': !isDocked,
|
9
11
|
'marginToTop': isDocked
|
@@ -11,13 +13,11 @@
|
|
11
13
|
>
|
12
14
|
<div
|
13
15
|
v-if="!windowState.hideHeader"
|
14
|
-
ref="draggableHeaderRef"
|
15
16
|
class="pa-2"
|
16
17
|
:class="{
|
17
18
|
'cursor-grab': isDynamic,
|
18
19
|
'grey--text': !isOnTop,
|
19
20
|
}"
|
20
|
-
:draggable="isDynamic"
|
21
21
|
>
|
22
22
|
<slot name="headerComponent" :props="$attrs" />
|
23
23
|
</div>
|
@@ -40,13 +40,21 @@
|
|
40
40
|
|
41
41
|
<script>
|
42
42
|
import {
|
43
|
-
|
43
|
+
computed, inject, provide,
|
44
44
|
} from 'vue';
|
45
|
-
import { fromEvent } from 'rxjs';
|
46
|
-
import { switchMap, take, map, tap } from 'rxjs/operators';
|
47
45
|
import { VDivider, VSheet } from 'vuetify/lib';
|
48
46
|
import { WindowSlot } from './windowManager.js';
|
49
47
|
|
48
|
+
/**
|
49
|
+
* WindowComponent defining the structure and style of VC Map windows
|
50
|
+
* @vue-prop {WindowState} windowState
|
51
|
+
* @vue-prop {boolean} isOnTop - Whether the component is focused
|
52
|
+
* @vue-prop {Object} slotWindow - slot ref of the window
|
53
|
+
* @vue-event {PointerEvent} clicked - raised when the component is clicked
|
54
|
+
* @vue-event {{dx: number, dy: number}} move - raised when the component is moved (dragged)
|
55
|
+
* @vue-data {slot} [#default] - slot with the window content
|
56
|
+
* @vue-data {slot} [#headerComponent] - slot to override the default header
|
57
|
+
*/
|
50
58
|
export default {
|
51
59
|
name: 'WindowComponent',
|
52
60
|
components: {
|
@@ -68,84 +76,50 @@
|
|
68
76
|
required: true,
|
69
77
|
},
|
70
78
|
},
|
71
|
-
setup(
|
72
|
-
const draggableHeaderRef = ref(null);
|
73
|
-
const windowComponentRef = ref(null);
|
74
|
-
const isDynamic = computed(() => slotWindow.value !== WindowSlot.STATIC);
|
75
|
-
const isDocked = computed(() => slotWindow.value !== WindowSlot.DETACHED);
|
76
|
-
const clicked = (e) => {
|
77
|
-
emit('click', e);
|
78
|
-
};
|
79
|
-
|
80
|
-
let dragOverSub;
|
81
|
-
let dropSub;
|
82
|
-
onMounted(() => {
|
83
|
-
if (!windowState.hideHeader && slotWindow.value !== WindowSlot.STATIC) {
|
84
|
-
nextTick(() => {
|
85
|
-
const dragStart = fromEvent(draggableHeaderRef.value, 'dragstart');
|
86
|
-
const dragOver = fromEvent(document.body, 'dragover');
|
87
|
-
const drop = fromEvent(document.body, 'drop');
|
88
|
-
const dragThenDrop = dragStart.pipe(
|
89
|
-
tap(() => {
|
90
|
-
dragOverSub = dragOver.subscribe((e) => {
|
91
|
-
// make it accepting drop events
|
92
|
-
// TODO check if setting the position here works.
|
93
|
-
e.preventDefault();
|
94
|
-
});
|
95
|
-
}),
|
96
|
-
switchMap((startEvent) => {
|
97
|
-
// To get to the Root Element of a Custom Component .$el is used here.
|
98
|
-
const style = window.getComputedStyle(windowComponentRef.value.$el, null);
|
99
|
-
const windowPosition = {
|
100
|
-
top: parseInt(style.getPropertyValue('top'), 10),
|
101
|
-
left: parseInt(style.getPropertyValue('left'), 10),
|
102
|
-
width: parseInt(style.getPropertyValue('width'), 10),
|
103
|
-
height: parseInt(style.getPropertyValue('height'), 10),
|
104
|
-
};
|
105
|
-
// set dataTransfer for Firefox
|
106
|
-
startEvent.dataTransfer.setData('text/html', null);
|
107
|
-
|
108
|
-
return drop.pipe(
|
109
|
-
take(1),
|
110
|
-
map((dropEvent) => {
|
111
|
-
windowPosition.dx = startEvent.clientX - dropEvent.clientX;
|
112
|
-
windowPosition.dy = startEvent.clientY - dropEvent.clientY;
|
113
|
-
return windowPosition;
|
114
|
-
}),
|
115
|
-
tap(() => {
|
116
|
-
dragOverSub.unsubscribe();
|
117
|
-
}),
|
118
|
-
);
|
119
|
-
}),
|
120
|
-
);
|
121
|
-
dropSub = dragThenDrop.subscribe((pos) => {
|
122
|
-
emit('dropped', pos);
|
123
|
-
});
|
124
|
-
});
|
125
|
-
}
|
126
|
-
});
|
127
|
-
|
128
|
-
onUnmounted(() => {
|
129
|
-
if (dragOverSub) {
|
130
|
-
dragOverSub.unsubscribe();
|
131
|
-
}
|
132
|
-
if (dropSub) {
|
133
|
-
dropSub.unsubscribe();
|
134
|
-
}
|
135
|
-
});
|
136
|
-
|
79
|
+
setup(props, { emit }) {
|
137
80
|
const app = inject('vcsApp');
|
138
|
-
const { provides } = app.windowManager.get(windowState.id);
|
81
|
+
const { provides } = app.windowManager.get(props.windowState.id);
|
139
82
|
Object.entries(provides)
|
140
83
|
.forEach(([key, value]) => {
|
141
84
|
provide(key, value);
|
142
85
|
});
|
86
|
+
|
87
|
+
const isDynamic = computed(() => props.slotWindow !== WindowSlot.STATIC);
|
88
|
+
const isDocked = computed(() => props.slotWindow !== WindowSlot.DETACHED);
|
89
|
+
/**
|
90
|
+
* @param {PointerEvent} e
|
91
|
+
*/
|
92
|
+
const clicked = (e) => {
|
93
|
+
emit('click', e);
|
94
|
+
};
|
95
|
+
/**
|
96
|
+
* @type {DragEvent}
|
97
|
+
*/
|
98
|
+
let startEvent;
|
99
|
+
/**
|
100
|
+
* @param {DragEvent} e
|
101
|
+
*/
|
102
|
+
const dragStart = (e) => {
|
103
|
+
startEvent = e;
|
104
|
+
};
|
105
|
+
/**
|
106
|
+
* @param {DragEvent} endEvent
|
107
|
+
*/
|
108
|
+
const dragEnd = (endEvent) => {
|
109
|
+
const movement = {
|
110
|
+
dx: endEvent.clientX - startEvent.clientX,
|
111
|
+
dy: endEvent.clientY - startEvent.clientY,
|
112
|
+
};
|
113
|
+
emit('moved', movement);
|
114
|
+
startEvent = null;
|
115
|
+
};
|
116
|
+
|
143
117
|
return {
|
144
118
|
isDynamic,
|
145
119
|
isDocked,
|
146
|
-
draggableHeaderRef,
|
147
|
-
windowComponentRef,
|
148
120
|
clicked,
|
121
|
+
dragStart,
|
122
|
+
dragEnd,
|
149
123
|
};
|
150
124
|
},
|
151
125
|
};
|
@@ -3,10 +3,14 @@
|
|
3
3
|
<span>
|
4
4
|
<v-icon
|
5
5
|
v-if="windowState.headerIcon"
|
6
|
-
class="mr-2
|
6
|
+
class="mr-2"
|
7
|
+
:class="{ 'text--primary': isOnTop }"
|
7
8
|
v-text="windowState.headerIcon"
|
8
9
|
/>
|
9
|
-
<h3
|
10
|
+
<h3
|
11
|
+
class="font-size-14 d-inline-block user-select-none font-weight-bold"
|
12
|
+
:class="{ 'text--primary': isOnTop }"
|
13
|
+
>
|
10
14
|
{{ $t(windowState.headerTitle) }}
|
11
15
|
</h3>
|
12
16
|
</span>
|
@@ -20,9 +24,25 @@
|
|
20
24
|
<v-divider
|
21
25
|
vertical
|
22
26
|
inset
|
23
|
-
class="mx-
|
27
|
+
class="mx-1"
|
24
28
|
/>
|
25
29
|
</template>
|
30
|
+
<VcsButton
|
31
|
+
v-if="windowState.infoUrl"
|
32
|
+
@click.stop="infoAction.callback()"
|
33
|
+
small
|
34
|
+
:icon="infoAction.icon"
|
35
|
+
:tooltip="infoAction.title"
|
36
|
+
class="px-1"
|
37
|
+
/>
|
38
|
+
<VcsButton
|
39
|
+
v-if="isDockable"
|
40
|
+
@click.stop="pin"
|
41
|
+
small
|
42
|
+
icon="mdi-pin"
|
43
|
+
tooltip="components.pin"
|
44
|
+
class="px-1"
|
45
|
+
/>
|
26
46
|
<VcsButton
|
27
47
|
@click.stop="close"
|
28
48
|
small
|
@@ -45,12 +65,16 @@
|
|
45
65
|
|
46
66
|
<script>
|
47
67
|
import { VIcon, VDivider } from 'vuetify/lib';
|
68
|
+
import { computed } from 'vue';
|
48
69
|
import VcsButton from '../../components/buttons/VcsButton.vue';
|
49
70
|
import VcsActionButtonList from '../../components/buttons/VcsActionButtonList.vue';
|
71
|
+
import { createLinkAction } from '../../actions/actionHelper.js';
|
50
72
|
|
51
73
|
/**
|
52
74
|
* Default window component header with drag functionality close action and further optional window actions.
|
53
75
|
* @vue-prop {WindowState} windowState - state of the window component.
|
76
|
+
* @vue-event {void} pin - raised when pin button is clicked
|
77
|
+
* @vue-event {void} close - raised when close button is clicked
|
54
78
|
*/
|
55
79
|
export default {
|
56
80
|
name: 'WindowComponentHeader',
|
@@ -65,18 +89,36 @@
|
|
65
89
|
type: Object,
|
66
90
|
required: true,
|
67
91
|
},
|
92
|
+
isOnTop: {
|
93
|
+
type: Boolean,
|
94
|
+
required: true,
|
95
|
+
default: false,
|
96
|
+
},
|
97
|
+
slotWindow: {
|
98
|
+
type: Object,
|
99
|
+
required: true,
|
100
|
+
},
|
68
101
|
},
|
69
102
|
setup(props, { emit }) {
|
103
|
+
const pin = () => {
|
104
|
+
emit('pin');
|
105
|
+
};
|
70
106
|
const close = () => {
|
71
107
|
emit('close');
|
72
108
|
};
|
73
|
-
const
|
74
|
-
|
75
|
-
|
109
|
+
const isDockable = computed(() => !props.windowState.hidePin && props.windowState.dockable);
|
110
|
+
|
111
|
+
const infoAction = props.windowState.infoUrl ? createLinkAction({
|
112
|
+
name: 'info',
|
113
|
+
title: 'content.infoAction.title',
|
114
|
+
icon: '$vcsInfo',
|
115
|
+
}, props.windowState.infoUrl) : {};
|
76
116
|
|
77
117
|
return {
|
118
|
+
pin,
|
78
119
|
close,
|
79
|
-
|
120
|
+
isDockable,
|
121
|
+
infoAction,
|
80
122
|
};
|
81
123
|
},
|
82
124
|
};
|
@@ -8,9 +8,9 @@
|
|
8
8
|
:window-state="getState(id)"
|
9
9
|
:slot-window="getSlot(id)"
|
10
10
|
:z-index="zIndex"
|
11
|
-
@
|
11
|
+
@moved="move(id, $event)"
|
12
12
|
@click="clicked(id)"
|
13
|
-
:style="getStyles(id, zIndex)"
|
13
|
+
:style="getStyles(id, zIndex).value"
|
14
14
|
:class="getState(id).classes"
|
15
15
|
:is-on-top="isOnTop(zIndex)"
|
16
16
|
>
|
@@ -23,8 +23,11 @@
|
|
23
23
|
<component
|
24
24
|
:is="getHeaderComponent(id)"
|
25
25
|
:window-state="getState(id)"
|
26
|
+
:is-on-top="isOnTop(zIndex)"
|
27
|
+
:slot-window="getSlot(id)"
|
26
28
|
v-bind="getProps(id)"
|
27
29
|
@close="close(id)"
|
30
|
+
@pin="pin(id)"
|
28
31
|
/>
|
29
32
|
</template>
|
30
33
|
</WindowComponent>
|
@@ -48,11 +51,15 @@
|
|
48
51
|
</style>
|
49
52
|
|
50
53
|
<script>
|
51
|
-
import { inject, ref } from 'vue';
|
54
|
+
import { computed, inject, onUnmounted, ref } from 'vue';
|
52
55
|
|
53
56
|
import WindowComponent from './WindowComponent.vue';
|
54
57
|
import WindowComponentHeader from './WindowComponentHeader.vue';
|
58
|
+
import { applyPositionOnTarget, getTargetSize, moveWindow } from './windowHelper.js';
|
55
59
|
|
60
|
+
/**
|
61
|
+
* WindowManager rendering all registered WindowComponents
|
62
|
+
*/
|
56
63
|
export default {
|
57
64
|
name: 'VcsWindowManager',
|
58
65
|
components: { WindowComponent },
|
@@ -60,55 +67,70 @@
|
|
60
67
|
const app = inject('vcsApp');
|
61
68
|
/** @type {WindowManager} */
|
62
69
|
const { windowManager } = app;
|
63
|
-
|
64
70
|
const { componentIds } = windowManager;
|
65
|
-
|
71
|
+
const targetSize = ref(null);
|
72
|
+
/**
|
73
|
+
* @param {string} id
|
74
|
+
* @returns {WindowState}
|
75
|
+
*/
|
66
76
|
const getState = (id) => {
|
67
77
|
return windowManager.get(id)?.state;
|
68
78
|
};
|
69
|
-
|
79
|
+
/**
|
80
|
+
* @param {string} id
|
81
|
+
* @returns {Object}
|
82
|
+
*/
|
70
83
|
const getProps = (id) => {
|
71
84
|
return windowManager.get(id)?.props ?? {};
|
72
85
|
};
|
73
|
-
|
86
|
+
/**
|
87
|
+
* @param {number} zIndex
|
88
|
+
* @returns {boolean}
|
89
|
+
*/
|
74
90
|
const isOnTop = (zIndex) => {
|
75
91
|
return zIndex === componentIds.length - 1;
|
76
92
|
};
|
77
|
-
|
78
|
-
|
93
|
+
/**
|
94
|
+
* @param {string} id
|
95
|
+
* @param {number} zIndex
|
96
|
+
* @returns {import("vue").ComputedRef<Object>}
|
97
|
+
*/
|
98
|
+
const getStyles = (id, zIndex) => computed(() => {
|
79
99
|
const windowComponent = windowManager.get(id);
|
80
100
|
const state = windowComponent?.state;
|
81
|
-
const position = windowComponent?.position;
|
101
|
+
const position = applyPositionOnTarget(windowComponent?.position, targetSize.value);
|
82
102
|
return {
|
83
103
|
zIndex,
|
84
|
-
|
85
|
-
top: position.top,
|
86
|
-
right: position.right,
|
87
|
-
bottom: position.bottom,
|
88
|
-
width: position.width,
|
89
|
-
height: position.height,
|
104
|
+
...position,
|
90
105
|
...(state.styles || {}),
|
91
106
|
};
|
92
|
-
};
|
93
|
-
|
107
|
+
});
|
108
|
+
/**
|
109
|
+
* @param {string} id
|
110
|
+
*/
|
94
111
|
const clicked = (id) => {
|
95
112
|
if (windowManager.has(id)) {
|
96
113
|
windowManager.bringWindowToTop(id);
|
97
114
|
}
|
98
115
|
};
|
116
|
+
/**
|
117
|
+
* @param {string} id
|
118
|
+
* @param {{dx: number, dy: number}} translation
|
119
|
+
*/
|
120
|
+
const move = (id, translation) => {
|
121
|
+
moveWindow(id, translation, windowManager, targetSize.value);
|
122
|
+
};
|
99
123
|
|
100
|
-
const
|
101
|
-
|
102
|
-
// clip position
|
103
|
-
const top = Math.min(Math.max(0, pos.top - pos.dy), innerHeight - pos.height);
|
104
|
-
const left = Math.min(Math.max(0, pos.left - pos.dx), innerWidth - pos.width);
|
105
|
-
windowManager.setWindowPositionOptions(id, {
|
106
|
-
top,
|
107
|
-
left,
|
108
|
-
width: pos.width,
|
109
|
-
height: pos.height,
|
110
|
-
});
|
124
|
+
const setTargetSize = () => {
|
125
|
+
targetSize.value = getTargetSize(app.maps.target);
|
111
126
|
};
|
127
|
+
window.addEventListener('resize', setTargetSize);
|
128
|
+
const setTargetDestroy = app.maps.mapActivated.addEventListener(setTargetSize);
|
129
|
+
|
130
|
+
onUnmounted(() => {
|
131
|
+
window.removeEventListener('resize', setTargetSize);
|
132
|
+
setTargetDestroy();
|
133
|
+
});
|
112
134
|
|
113
135
|
return {
|
114
136
|
componentIds: ref(componentIds),
|
@@ -120,8 +142,9 @@
|
|
120
142
|
isOnTop,
|
121
143
|
getSlot: id => windowManager.get(id).slot,
|
122
144
|
close: (id) => { windowManager.remove(id); },
|
123
|
-
|
145
|
+
pin: (id) => { windowManager.pinWindow(id); },
|
124
146
|
clicked,
|
147
|
+
move,
|
125
148
|
};
|
126
149
|
},
|
127
150
|
};
|