@vcmap/ui 5.0.0-rc.15 → 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 +7 -45
- package/config/dev.config.json +5 -1
- package/config/www.config.json +14 -13
- package/dist/assets/{cesium.2e288a.js → cesium.41de56.js} +0 -0
- package/dist/assets/cesium.js +1 -1
- package/dist/assets/{core.8014d3.js → core.af84e3.js} +6077 -4544
- package/dist/assets/core.js +1 -1
- package/dist/assets/{index.3f74fa92.js → index.5b773cad.js} +1 -1
- package/dist/assets/{ol.31c3a5.js → ol.5c7490.js} +0 -0
- package/dist/assets/ol.js +1 -1
- package/dist/assets/ui.dffe32.css +1 -0
- package/dist/assets/{ui.36f84f.js → ui.dffe32.js} +7243 -6234
- package/dist/assets/ui.js +1 -1
- package/dist/assets/{vue.a39c10.js → vue.25da17.js} +0 -0
- package/dist/assets/vue.js +2 -2
- package/dist/assets/{vuetify.378637.css → vuetify.e4ece7.css} +1 -1
- package/dist/assets/{vuetify.378637.js → vuetify.e4ece7.js} +5 -2
- package/dist/assets/vuetify.js +2 -2
- package/dist/index.html +1 -1
- package/index.html +77 -0
- package/index.js +18 -3
- 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 +26 -2
- package/plugins/@vcmap/pluginExample/pluginExampleComponent.vue +77 -42
- package/plugins/@vcmap/search-nominatim/nominatim.js +1 -1
- package/plugins/@vcmap/theme-changer/ThemeChangerComponent.vue +4 -2
- package/plugins/categoryTest/Categories.vue +27 -13
- package/plugins/categoryTest/Category.vue +7 -1
- package/plugins/categoryTest/index.js +1 -1
- 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 +5 -5
- package/plugins/test/emptyComponent.vue +1 -1
- package/plugins/test/index.js +27 -3
- package/plugins/test/myCustomHeader.vue +9 -1
- package/plugins/test/testList.vue +290 -0
- package/plugins/test/vcsContent.vue +1 -1
- package/plugins/test/windowManagerExample.vue +12 -7
- package/plugins/wizardExample/index.js +41 -0
- package/plugins/wizardExample/wizardExample.vue +77 -0
- package/src/actions/actionHelper.js +10 -9
- package/src/application/VcsApp.vue +43 -34
- package/src/components/form-inputs-controls/VcsCheckbox.vue +1 -0
- package/src/components/form-inputs-controls/VcsFormSection.vue +23 -15
- 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 +468 -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/contentTreeCollection.js +9 -0
- package/src/contentTree/contentTreeItem.js +13 -13
- package/src/contentTree/layerContentTreeItem.js +1 -1
- package/src/contentTree/subContentTreeItem.js +1 -1
- package/src/contentTree/vcsObjectContentTreeItem.js +1 -1
- package/src/featureInfo/BalloonComponent.vue +13 -8
- package/src/featureInfo/balloonFeatureInfoView.js +16 -22
- package/src/featureInfo/balloonHelper.js +26 -5
- package/src/featureInfo/featureInfo.js +14 -2
- package/src/featureInfo/featureInfoInteraction.js +1 -1
- package/src/i18n/de.js +13 -1
- package/src/i18n/en.js +13 -1
- package/src/icons/+all.js +4 -0
- package/src/icons/WandIcon.vue +63 -0
- 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 +51 -70
- package/src/manager/window/WindowComponentHeader.vue +81 -13
- package/src/manager/window/WindowManager.vue +54 -30
- package/src/manager/window/windowHelper.js +341 -0
- package/src/manager/window/windowManager.js +173 -151
- package/src/navigation/overviewMap.js +10 -9
- package/src/notifier/notifier.js +120 -0
- package/src/notifier/notifierComponent.vue +84 -0
- package/src/styles/variables.scss +19 -3
- package/src/vcsUiApp.js +26 -2
- package/src/vuePlugins/vuetify.js +2 -0
- package/dist/assets/ui.36f84f.css +0 -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,15 +13,13 @@
|
|
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
|
-
<slot name="headerComponent" />
|
22
|
+
<slot name="headerComponent" :props="$attrs" />
|
23
23
|
</div>
|
24
24
|
<v-divider />
|
25
25
|
<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,77 +76,50 @@
|
|
68
76
|
required: true,
|
69
77
|
},
|
70
78
|
},
|
71
|
-
setup(
|
72
|
-
const
|
73
|
-
const
|
74
|
-
|
75
|
-
|
79
|
+
setup(props, { emit }) {
|
80
|
+
const app = inject('vcsApp');
|
81
|
+
const { provides } = app.windowManager.get(props.windowState.id);
|
82
|
+
Object.entries(provides)
|
83
|
+
.forEach(([key, value]) => {
|
84
|
+
provide(key, value);
|
85
|
+
});
|
86
|
+
|
87
|
+
const isDynamic = computed(() => props.slotWindow !== WindowSlot.STATIC);
|
88
|
+
const isDocked = computed(() => props.slotWindow !== WindowSlot.DETACHED);
|
89
|
+
/**
|
90
|
+
* @param {PointerEvent} e
|
91
|
+
*/
|
76
92
|
const clicked = (e) => {
|
77
93
|
emit('click', e);
|
78
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
|
+
};
|
79
116
|
|
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
117
|
return {
|
137
118
|
isDynamic,
|
138
119
|
isDocked,
|
139
|
-
draggableHeaderRef,
|
140
|
-
windowComponentRef,
|
141
120
|
clicked,
|
121
|
+
dragStart,
|
122
|
+
dragEnd,
|
142
123
|
};
|
143
124
|
},
|
144
125
|
};
|
@@ -3,54 +3,122 @@
|
|
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>
|
13
|
-
<
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
17
|
+
<div class="d-flex justify-space-between align-center">
|
18
|
+
<template v-if="windowState.headerActions?.length > 0">
|
19
|
+
<VcsActionButtonList
|
20
|
+
:actions="windowState.headerActions"
|
21
|
+
:overflow-count="windowState.headerActionsOverflowCount ?? 3"
|
22
|
+
small
|
23
|
+
/>
|
24
|
+
<v-divider
|
25
|
+
vertical
|
26
|
+
inset
|
27
|
+
class="mx-1"
|
28
|
+
/>
|
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
|
+
/>
|
46
|
+
<VcsButton
|
47
|
+
@click.stop="close"
|
48
|
+
small
|
49
|
+
icon="mdi-close-thick"
|
50
|
+
tooltip="components.close"
|
51
|
+
/>
|
52
|
+
</div>
|
18
53
|
</span>
|
19
54
|
</template>
|
20
55
|
|
21
|
-
<style>
|
56
|
+
<style lang="scss" scoped>
|
22
57
|
.window-component-header{
|
23
58
|
max-height: 16px;
|
59
|
+
|
60
|
+
.v-divider--vertical.v-divider--inset {
|
61
|
+
margin-top: 2px;
|
62
|
+
}
|
24
63
|
}
|
25
64
|
</style>
|
26
65
|
|
27
66
|
<script>
|
28
|
-
import { VIcon } from 'vuetify/lib';
|
67
|
+
import { VIcon, VDivider } from 'vuetify/lib';
|
68
|
+
import { computed } from 'vue';
|
29
69
|
import VcsButton from '../../components/buttons/VcsButton.vue';
|
70
|
+
import VcsActionButtonList from '../../components/buttons/VcsActionButtonList.vue';
|
71
|
+
import { createLinkAction } from '../../actions/actionHelper.js';
|
30
72
|
|
73
|
+
/**
|
74
|
+
* Default window component header with drag functionality close action and further optional window actions.
|
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
|
78
|
+
*/
|
31
79
|
export default {
|
32
80
|
name: 'WindowComponentHeader',
|
33
81
|
components: {
|
82
|
+
VcsActionButtonList,
|
34
83
|
VcsButton,
|
35
84
|
VIcon,
|
85
|
+
VDivider,
|
36
86
|
},
|
37
87
|
props: {
|
38
88
|
windowState: {
|
39
89
|
type: Object,
|
40
90
|
required: true,
|
41
91
|
},
|
92
|
+
isOnTop: {
|
93
|
+
type: Boolean,
|
94
|
+
required: true,
|
95
|
+
default: false,
|
96
|
+
},
|
97
|
+
slotWindow: {
|
98
|
+
type: Object,
|
99
|
+
required: true,
|
100
|
+
},
|
42
101
|
},
|
43
102
|
setup(props, { emit }) {
|
103
|
+
const pin = () => {
|
104
|
+
emit('pin');
|
105
|
+
};
|
44
106
|
const close = () => {
|
45
107
|
emit('close');
|
46
108
|
};
|
47
|
-
const
|
48
|
-
|
49
|
-
|
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) : {};
|
50
116
|
|
51
117
|
return {
|
118
|
+
pin,
|
52
119
|
close,
|
53
|
-
|
120
|
+
isDockable,
|
121
|
+
infoAction,
|
54
122
|
};
|
55
123
|
},
|
56
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,7 +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)"
|
28
|
+
v-bind="getProps(id)"
|
26
29
|
@close="close(id)"
|
30
|
+
@pin="pin(id)"
|
27
31
|
/>
|
28
32
|
</template>
|
29
33
|
</WindowComponent>
|
@@ -47,11 +51,15 @@
|
|
47
51
|
</style>
|
48
52
|
|
49
53
|
<script>
|
50
|
-
import { inject, ref } from 'vue';
|
54
|
+
import { computed, inject, onUnmounted, ref } from 'vue';
|
51
55
|
|
52
56
|
import WindowComponent from './WindowComponent.vue';
|
53
57
|
import WindowComponentHeader from './WindowComponentHeader.vue';
|
58
|
+
import { applyPositionOnTarget, getTargetSize, moveWindow } from './windowHelper.js';
|
54
59
|
|
60
|
+
/**
|
61
|
+
* WindowManager rendering all registered WindowComponents
|
62
|
+
*/
|
55
63
|
export default {
|
56
64
|
name: 'VcsWindowManager',
|
57
65
|
components: { WindowComponent },
|
@@ -59,55 +67,70 @@
|
|
59
67
|
const app = inject('vcsApp');
|
60
68
|
/** @type {WindowManager} */
|
61
69
|
const { windowManager } = app;
|
62
|
-
|
63
70
|
const { componentIds } = windowManager;
|
64
|
-
|
71
|
+
const targetSize = ref(null);
|
72
|
+
/**
|
73
|
+
* @param {string} id
|
74
|
+
* @returns {WindowState}
|
75
|
+
*/
|
65
76
|
const getState = (id) => {
|
66
77
|
return windowManager.get(id)?.state;
|
67
78
|
};
|
68
|
-
|
79
|
+
/**
|
80
|
+
* @param {string} id
|
81
|
+
* @returns {Object}
|
82
|
+
*/
|
69
83
|
const getProps = (id) => {
|
70
84
|
return windowManager.get(id)?.props ?? {};
|
71
85
|
};
|
72
|
-
|
86
|
+
/**
|
87
|
+
* @param {number} zIndex
|
88
|
+
* @returns {boolean}
|
89
|
+
*/
|
73
90
|
const isOnTop = (zIndex) => {
|
74
91
|
return zIndex === componentIds.length - 1;
|
75
92
|
};
|
76
|
-
|
77
|
-
|
93
|
+
/**
|
94
|
+
* @param {string} id
|
95
|
+
* @param {number} zIndex
|
96
|
+
* @returns {import("vue").ComputedRef<Object>}
|
97
|
+
*/
|
98
|
+
const getStyles = (id, zIndex) => computed(() => {
|
78
99
|
const windowComponent = windowManager.get(id);
|
79
100
|
const state = windowComponent?.state;
|
80
|
-
const position = windowComponent?.position;
|
101
|
+
const position = applyPositionOnTarget(windowComponent?.position, targetSize.value);
|
81
102
|
return {
|
82
103
|
zIndex,
|
83
|
-
|
84
|
-
top: position.top,
|
85
|
-
right: position.right,
|
86
|
-
bottom: position.bottom,
|
87
|
-
width: position.width,
|
88
|
-
height: position.height,
|
104
|
+
...position,
|
89
105
|
...(state.styles || {}),
|
90
106
|
};
|
91
|
-
};
|
92
|
-
|
107
|
+
});
|
108
|
+
/**
|
109
|
+
* @param {string} id
|
110
|
+
*/
|
93
111
|
const clicked = (id) => {
|
94
112
|
if (windowManager.has(id)) {
|
95
113
|
windowManager.bringWindowToTop(id);
|
96
114
|
}
|
97
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
|
+
};
|
98
123
|
|
99
|
-
const
|
100
|
-
|
101
|
-
// clip position
|
102
|
-
const top = Math.min(Math.max(0, pos.top - pos.dy), innerHeight - pos.height);
|
103
|
-
const left = Math.min(Math.max(0, pos.left - pos.dx), innerWidth - pos.width);
|
104
|
-
windowManager.setWindowPositionOptions(id, {
|
105
|
-
top,
|
106
|
-
left,
|
107
|
-
width: pos.width,
|
108
|
-
height: pos.height,
|
109
|
-
});
|
124
|
+
const setTargetSize = () => {
|
125
|
+
targetSize.value = getTargetSize(app.maps.target);
|
110
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
|
+
});
|
111
134
|
|
112
135
|
return {
|
113
136
|
componentIds: ref(componentIds),
|
@@ -119,8 +142,9 @@
|
|
119
142
|
isOnTop,
|
120
143
|
getSlot: id => windowManager.get(id).slot,
|
121
144
|
close: (id) => { windowManager.remove(id); },
|
122
|
-
|
145
|
+
pin: (id) => { windowManager.pinWindow(id); },
|
123
146
|
clicked,
|
147
|
+
move,
|
124
148
|
};
|
125
149
|
},
|
126
150
|
};
|