@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
@@ -1,5 +1,5 @@
|
|
1
1
|
// eslint-disable-next-line max-classes-per-file
|
2
|
-
import {
|
2
|
+
import { moduleIdSymbol, IndexedCollection } from '@vcmap/core';
|
3
3
|
import { getLogger } from '@vcsuite/logger';
|
4
4
|
|
5
5
|
/**
|
@@ -51,59 +51,59 @@ export function mergeDeep(...sources) {
|
|
51
51
|
*/
|
52
52
|
class I18nCollection extends IndexedCollection {
|
53
53
|
/**
|
54
|
-
* @param {function():string}
|
54
|
+
* @param {function():string} getDynamicModuleId - function to get the current dynamic module id
|
55
55
|
*/
|
56
|
-
constructor(
|
56
|
+
constructor(getDynamicModuleId) {
|
57
57
|
super(false);
|
58
58
|
/**
|
59
59
|
* @type {function(): string}
|
60
60
|
* @private
|
61
61
|
*/
|
62
|
-
this.
|
62
|
+
this._getDynamicModuleId = getDynamicModuleId;
|
63
63
|
}
|
64
64
|
|
65
65
|
/**
|
66
66
|
* @inheritDoc
|
67
67
|
*/
|
68
68
|
add(item) {
|
69
|
-
if (!item[
|
70
|
-
item[
|
69
|
+
if (!item[moduleIdSymbol]) {
|
70
|
+
item[moduleIdSymbol] = this._getDynamicModuleId();
|
71
71
|
}
|
72
72
|
super.add(item);
|
73
73
|
}
|
74
74
|
|
75
75
|
/**
|
76
76
|
* @param {Array<Object>} configArray
|
77
|
-
* @param {string}
|
77
|
+
* @param {string} moduleId
|
78
78
|
* @returns {Promise<void>}
|
79
79
|
*/
|
80
|
-
async parseItems(configArray,
|
80
|
+
async parseItems(configArray, moduleId) {
|
81
81
|
if (Array.isArray(configArray)) {
|
82
82
|
configArray.forEach((item) => {
|
83
|
-
item[
|
83
|
+
item[moduleIdSymbol] = moduleId;
|
84
84
|
this.add(item);
|
85
85
|
});
|
86
86
|
}
|
87
87
|
}
|
88
88
|
|
89
89
|
/**
|
90
|
-
* @param {string}
|
90
|
+
* @param {string} moduleId
|
91
91
|
*/
|
92
|
-
async
|
92
|
+
async removeModule(moduleId) {
|
93
93
|
[...this]
|
94
|
-
.filter(item => item[
|
94
|
+
.filter(item => item[moduleIdSymbol] === moduleId)
|
95
95
|
.forEach((item) => {
|
96
96
|
this.remove(item);
|
97
97
|
});
|
98
98
|
}
|
99
99
|
|
100
100
|
/**
|
101
|
-
* @param {string}
|
101
|
+
* @param {string} moduleId
|
102
102
|
* @returns {Array<Object>}
|
103
103
|
*/
|
104
|
-
|
104
|
+
serializeModule(moduleId) {
|
105
105
|
return [...this]
|
106
|
-
.filter(item => item[
|
106
|
+
.filter(item => item[moduleIdSymbol] === moduleId)
|
107
107
|
.filter(item => !item[i18nPluginSymbol])
|
108
108
|
.map(item => JSON.parse(JSON.stringify(item)));
|
109
109
|
}
|
@@ -112,12 +112,12 @@ class I18nCollection extends IndexedCollection {
|
|
112
112
|
* This method adds plugin messages to the collection. It is no necessary to call this function
|
113
113
|
* from within a plugin. Use the i18n property on your plugin.
|
114
114
|
* @param {string} plugin Name of the plugin
|
115
|
-
* @param {string}
|
115
|
+
* @param {string} moduleId
|
116
116
|
* @param {Object} messages
|
117
117
|
*/
|
118
|
-
addPluginMessages(plugin,
|
118
|
+
addPluginMessages(plugin, moduleId, messages) {
|
119
119
|
messages[i18nPluginSymbol] = plugin;
|
120
|
-
messages[
|
120
|
+
messages[moduleIdSymbol] = moduleId;
|
121
121
|
this.add(messages);
|
122
122
|
}
|
123
123
|
|
@@ -125,11 +125,11 @@ class I18nCollection extends IndexedCollection {
|
|
125
125
|
* This method removes plugin messages from the collection. It is no necessary to call this function
|
126
126
|
* from within a plugin. Once your plugin is removed, the VcsUiApp will call this for you.
|
127
127
|
* @param {string} pluginName
|
128
|
-
* @param {string}
|
128
|
+
* @param {string} moduleId
|
129
129
|
*/
|
130
|
-
removePluginMessages(pluginName,
|
130
|
+
removePluginMessages(pluginName, moduleId) {
|
131
131
|
[...this]
|
132
|
-
.filter(item => item[i18nPluginSymbol] === pluginName && item[
|
132
|
+
.filter(item => item[i18nPluginSymbol] === pluginName && item[moduleIdSymbol] === moduleId)
|
133
133
|
.forEach((item) => {
|
134
134
|
this.remove(item);
|
135
135
|
});
|
@@ -147,7 +147,7 @@ class I18nCollection extends IndexedCollection {
|
|
147
147
|
* @inheritDoc
|
148
148
|
*/
|
149
149
|
destroy() {
|
150
|
-
this.
|
150
|
+
this._getDynamicModuleId = null;
|
151
151
|
super.destroy();
|
152
152
|
}
|
153
153
|
}
|
package/src/init.js
CHANGED
@@ -1,20 +1,49 @@
|
|
1
1
|
import Vue from 'vue';
|
2
|
-
import { check, checkMaybe } from '@vcsuite/check';
|
3
|
-
import {
|
2
|
+
import { check, checkMaybe, is } from '@vcsuite/check';
|
3
|
+
import { VcsModule } from '@vcmap/core';
|
4
4
|
import VcsAppComponentWrapper from './application/vcsAppWrapper.vue';
|
5
5
|
import { vuetify } from './vuePlugins/vuetify.js';
|
6
6
|
import { createVueI18n, setupI18n } from './vuePlugins/i18n.js';
|
7
7
|
import VcsUiApp from './vcsUiApp.js';
|
8
8
|
|
9
|
+
/**
|
10
|
+
* Base pattern to check VcsObjects
|
11
|
+
* @type {import("vcsuite/check").PatternFor<import("@vcmap/core").VcsObject>}
|
12
|
+
*/
|
13
|
+
const VcsObjectPattern = {
|
14
|
+
type: String,
|
15
|
+
name: String,
|
16
|
+
};
|
17
|
+
|
18
|
+
/**
|
19
|
+
* Base pattern to check VcsUiAppConfig
|
20
|
+
* @type {import("vcsuite/check").PatternFor<VcsUiAppConfig>}
|
21
|
+
*/
|
22
|
+
export const VcsUiAppConfigPattern = {
|
23
|
+
id: [undefined, String],
|
24
|
+
layers: [undefined, [VcsObjectPattern]],
|
25
|
+
maps: [undefined, [VcsObjectPattern]],
|
26
|
+
styles: [undefined, [VcsObjectPattern]],
|
27
|
+
viewpoints: [undefined, [VcsObjectPattern]],
|
28
|
+
startingViewpointName: [undefined, String],
|
29
|
+
startingMapName: [undefined, String],
|
30
|
+
projection: [undefined, Object],
|
31
|
+
categories: [undefined, [{ name: String, items: [Object] }]],
|
32
|
+
obliqueCollections: [undefined, [VcsObjectPattern]],
|
33
|
+
plugins: [undefined, [Object]],
|
34
|
+
contentTree: [undefined, [Object]],
|
35
|
+
uiConfig: [undefined, [Object]],
|
36
|
+
featureInfo: [undefined, [VcsObjectPattern]],
|
37
|
+
i18n: [undefined, [Object]],
|
38
|
+
};
|
39
|
+
|
9
40
|
/**
|
10
41
|
* creates and mounts a vcsApp
|
11
42
|
* @param {string} mountTarget
|
12
|
-
* @param {string=} configUrl optional config
|
13
43
|
* @returns {Promise<VcsUiApp>}
|
14
44
|
*/
|
15
|
-
export default async function initApp(mountTarget
|
45
|
+
export default async function initApp(mountTarget) {
|
16
46
|
check(mountTarget, String);
|
17
|
-
checkMaybe(configUrl, String);
|
18
47
|
const app = new VcsUiApp();
|
19
48
|
const i18n = createVueI18n();
|
20
49
|
new Vue({
|
@@ -28,11 +57,65 @@ export default async function initApp(mountTarget, configUrl) {
|
|
28
57
|
}).$mount(mountTarget);
|
29
58
|
|
30
59
|
setupI18n(app, i18n);
|
60
|
+
return app;
|
61
|
+
}
|
62
|
+
|
63
|
+
/**
|
64
|
+
* Initializes app with an optional single config
|
65
|
+
* @param {string} mountTarget
|
66
|
+
* @param {string=} configUrl optional config
|
67
|
+
* @returns {Promise<VcsUiApp>}
|
68
|
+
*/
|
69
|
+
export async function initAppFromModule(mountTarget, configUrl) {
|
70
|
+
check(mountTarget, String);
|
71
|
+
checkMaybe(configUrl, String);
|
72
|
+
|
73
|
+
const app = await initApp(mountTarget);
|
31
74
|
if (configUrl) {
|
32
75
|
const config = await fetch(configUrl)
|
33
76
|
.then(response => response.json());
|
34
|
-
const
|
35
|
-
await app.
|
77
|
+
const module = new VcsModule(config);
|
78
|
+
await app.addModule(module);
|
36
79
|
}
|
80
|
+
|
37
81
|
return app;
|
38
82
|
}
|
83
|
+
|
84
|
+
/**
|
85
|
+
* Initializes app with a map config containing a set of config urls
|
86
|
+
* @param {string} mountTarget
|
87
|
+
* @param {string} appUrl app config containing further modules to be loaded
|
88
|
+
* @returns {Promise<VcsUiApp>}
|
89
|
+
*/
|
90
|
+
export async function initAppFromAppConfig(mountTarget, appUrl) {
|
91
|
+
check(mountTarget, String);
|
92
|
+
check(appUrl, String);
|
93
|
+
|
94
|
+
const app = await initApp(mountTarget);
|
95
|
+
/**
|
96
|
+
* @type {{modules: Array<string|VcsUiAppConfig>}}
|
97
|
+
*/
|
98
|
+
const appConfig = await fetch(appUrl)
|
99
|
+
.then(response => response.json());
|
100
|
+
|
101
|
+
check(appConfig.modules, [String, Object]);
|
102
|
+
|
103
|
+
const modules = await Promise.all(appConfig.modules.map(async (c) => {
|
104
|
+
if (is(c, VcsUiAppConfigPattern)) {
|
105
|
+
return new VcsModule(/** @type{import("@vcmap/core").VcsAppConfig} */ c);
|
106
|
+
} else if (is(c, String)) {
|
107
|
+
const response = await fetch(c);
|
108
|
+
if (response.ok) {
|
109
|
+
const config = await response.json();
|
110
|
+
return new VcsModule(config);
|
111
|
+
}
|
112
|
+
}
|
113
|
+
return null;
|
114
|
+
}));
|
115
|
+
// eslint-disable-next-line no-restricted-syntax
|
116
|
+
for await (const module of modules) {
|
117
|
+
if (module) {
|
118
|
+
await app.addModule(module);
|
119
|
+
}
|
120
|
+
}
|
121
|
+
}
|
@@ -1,48 +1,54 @@
|
|
1
1
|
<template>
|
2
|
-
<v-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
:selectable="category.selectable"
|
21
|
-
:single-select="category.singleSelect"
|
22
|
-
v-model="selection"
|
23
|
-
:show-title="false"
|
2
|
+
<v-expansion-panel
|
3
|
+
class="px-2"
|
4
|
+
@change="active = !active"
|
5
|
+
>
|
6
|
+
<v-expansion-panel-header hide-actions>
|
7
|
+
<template #default="{ open }">
|
8
|
+
<div class="d-flex justify-space-between">
|
9
|
+
<div class="d-flex align-center">
|
10
|
+
<v-icon class="mr-1" :class="{ 'rotate': !open }">
|
11
|
+
mdi-chevron-down
|
12
|
+
</v-icon>
|
13
|
+
{{ $t(category.title) }}
|
14
|
+
</div>
|
15
|
+
<VcsActionButtonList
|
16
|
+
v-if="category.actions?.length > 0"
|
17
|
+
:actions="category.actions"
|
18
|
+
small
|
19
|
+
class="float-end"
|
24
20
|
/>
|
25
|
-
</
|
26
|
-
</
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
21
|
+
</div>
|
22
|
+
</template>
|
23
|
+
</v-expansion-panel-header>
|
24
|
+
<v-expansion-panel-content class="pb-1">
|
25
|
+
<vcs-list
|
26
|
+
:items="category.items.slice(0, 10)"
|
27
|
+
:selectable="category.selectable"
|
28
|
+
:single-select="category.singleSelect"
|
29
|
+
v-model="selection"
|
30
|
+
:show-title="false"
|
31
|
+
/>
|
32
|
+
<v-sheet v-if="category.items.length > 10" class="ma-2 pl-2">
|
33
|
+
<VcsButton @click="openCategoryItemWindow" small>
|
34
|
+
{{ $t('categoryManager.more') }}
|
35
|
+
</VcsButton>
|
36
|
+
</v-sheet>
|
37
|
+
<v-sheet v-else-if="category.items.length === 0" class="ma-2 pl-2">
|
38
|
+
{{ $t('categoryManager.empty') }}
|
39
|
+
</v-sheet>
|
40
|
+
</v-expansion-panel-content>
|
41
|
+
</v-expansion-panel>
|
41
42
|
</template>
|
42
43
|
|
43
44
|
<script>
|
44
45
|
import { computed, inject, ref } from 'vue';
|
45
|
-
import {
|
46
|
+
import {
|
47
|
+
VIcon, VExpansionPanel,
|
48
|
+
VExpansionPanelHeader,
|
49
|
+
VExpansionPanelContent,
|
50
|
+
VSheet,
|
51
|
+
} from 'vuetify/lib';
|
46
52
|
import VcsList from '../../components/lists/VcsList.vue';
|
47
53
|
import VcsActionButtonList from '../../components/buttons/VcsActionButtonList.vue';
|
48
54
|
import VcsButton from '../../components/buttons/VcsButton.vue';
|
@@ -54,11 +60,12 @@
|
|
54
60
|
name: 'CategoryComponent',
|
55
61
|
components: {
|
56
62
|
VcsActionButtonList,
|
57
|
-
VcsList,
|
58
|
-
VContainer,
|
59
|
-
VRow,
|
60
63
|
VcsButton,
|
61
|
-
|
64
|
+
VcsList,
|
65
|
+
VExpansionPanel,
|
66
|
+
VExpansionPanelHeader,
|
67
|
+
VExpansionPanelContent,
|
68
|
+
VSheet,
|
62
69
|
VIcon,
|
63
70
|
},
|
64
71
|
props: {
|
@@ -72,7 +79,7 @@
|
|
72
79
|
/** @type {VcsUiApp} */
|
73
80
|
const app = inject('vcsApp');
|
74
81
|
const windowId = `${category.id}-category-list`;
|
75
|
-
const
|
82
|
+
const active = ref(false);
|
76
83
|
|
77
84
|
const selection = computed({
|
78
85
|
get() { return category.selection; },
|
@@ -84,7 +91,7 @@
|
|
84
91
|
|
85
92
|
return {
|
86
93
|
selection,
|
87
|
-
|
94
|
+
active,
|
88
95
|
openCategoryItemWindow() {
|
89
96
|
if (app.windowManager.has(windowId)) {
|
90
97
|
setTimeout(() => {
|
@@ -110,6 +117,8 @@
|
|
110
117
|
};
|
111
118
|
</script>
|
112
119
|
|
113
|
-
<style scoped>
|
114
|
-
|
120
|
+
<style lang="scss" scoped>
|
121
|
+
.rotate {
|
122
|
+
transform: rotate(-90deg);
|
123
|
+
}
|
115
124
|
</style>
|
@@ -1,17 +1,26 @@
|
|
1
1
|
<template>
|
2
|
-
<
|
3
|
-
v-
|
4
|
-
|
5
|
-
|
6
|
-
v-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
2
|
+
<v-sheet>
|
3
|
+
<v-expansion-panels
|
4
|
+
accordion
|
5
|
+
multiple
|
6
|
+
v-if="categories.length > 0"
|
7
|
+
class="rounded-0"
|
8
|
+
>
|
9
|
+
<category-component
|
10
|
+
v-for="category in categories"
|
11
|
+
:category="category"
|
12
|
+
:key="category.categoryName"
|
13
|
+
/>
|
14
|
+
</v-expansion-panels>
|
15
|
+
</v-sheet>
|
11
16
|
</template>
|
12
17
|
|
13
18
|
<script>
|
14
19
|
import { inject, ref, computed } from 'vue';
|
20
|
+
import {
|
21
|
+
VExpansionPanels,
|
22
|
+
VSheet,
|
23
|
+
} from 'vuetify/lib';
|
15
24
|
import CategoryComponent from './CategoryComponent.vue';
|
16
25
|
|
17
26
|
/**
|
@@ -21,7 +30,11 @@
|
|
21
30
|
*/
|
22
31
|
export default {
|
23
32
|
name: 'CategoryManager',
|
24
|
-
components: {
|
33
|
+
components: {
|
34
|
+
VExpansionPanels,
|
35
|
+
VSheet,
|
36
|
+
CategoryComponent,
|
37
|
+
},
|
25
38
|
setup() {
|
26
39
|
const app = inject('vcsApp');
|
27
40
|
const categoryIds = ref(app.categoryManager.componentIds);
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import { reactive } from 'vue';
|
2
|
-
import {
|
2
|
+
import { moduleIdSymbol, IndexedCollection, VcsEvent } from '@vcmap/core';
|
3
3
|
import { check } from '@vcsuite/check';
|
4
4
|
import { sortByOwner } from '../navbarManager.js';
|
5
5
|
import { validateAction, validateActions } from '../../components/lists/VcsActionList.vue';
|
@@ -145,8 +145,8 @@ class CategoryManager {
|
|
145
145
|
* @type {function():void}
|
146
146
|
* @private
|
147
147
|
*/
|
148
|
-
this.
|
149
|
-
this.
|
148
|
+
this._dynamicModuleIdListener = this._app.dynamicModuleIdChanged.addEventListener((id) => {
|
149
|
+
this._dynamicModuleId = id;
|
150
150
|
this._resetManagedCategories();
|
151
151
|
});
|
152
152
|
|
@@ -162,7 +162,7 @@ class CategoryManager {
|
|
162
162
|
* @type {string}
|
163
163
|
* @private
|
164
164
|
*/
|
165
|
-
this.
|
165
|
+
this._dynamicModuleId = this._app.dynamicModuleId;
|
166
166
|
|
167
167
|
/**
|
168
168
|
* @type {Array<ItemMapping<*>>}
|
@@ -250,7 +250,7 @@ class CategoryManager {
|
|
250
250
|
}
|
251
251
|
|
252
252
|
/**
|
253
|
-
* removes all items from all categories and rebuilds the item tree depending on the
|
253
|
+
* removes all items from all categories and rebuilds the item tree depending on the ModuleId
|
254
254
|
* @private
|
255
255
|
*/
|
256
256
|
_resetManagedCategories() {
|
@@ -281,7 +281,7 @@ class CategoryManager {
|
|
281
281
|
});
|
282
282
|
managedCategory.items = [...category.collection]
|
283
283
|
.filter((item) => {
|
284
|
-
return item[
|
284
|
+
return item[moduleIdSymbol] === this._dynamicModuleId;
|
285
285
|
})
|
286
286
|
.map((item) => {
|
287
287
|
return transformItem(item, category, itemMappings);
|
@@ -306,17 +306,17 @@ class CategoryManager {
|
|
306
306
|
|
307
307
|
const listeners = [
|
308
308
|
category.collection.added.addEventListener((item) => {
|
309
|
-
if (item[
|
309
|
+
if (item[moduleIdSymbol] === this._dynamicModuleId) {
|
310
310
|
this._handleItemAdded(item, category);
|
311
311
|
}
|
312
312
|
}),
|
313
313
|
category.collection.removed.addEventListener((item) => {
|
314
|
-
if (item[
|
314
|
+
if (item[moduleIdSymbol] === this._dynamicModuleId) {
|
315
315
|
this._handleItemRemoved(item, category);
|
316
316
|
}
|
317
317
|
}),
|
318
318
|
category.collection.replaced.addEventListener((replacedEvent) => {
|
319
|
-
if (replacedEvent.old[
|
319
|
+
if (replacedEvent.old[moduleIdSymbol] === this._dynamicModuleId) {
|
320
320
|
this._handleItemRemoved(replacedEvent.old, category);
|
321
321
|
}
|
322
322
|
}),
|
@@ -324,7 +324,7 @@ class CategoryManager {
|
|
324
324
|
|
325
325
|
if (category.collection instanceof IndexedCollection) {
|
326
326
|
listeners.push(category.collection.moved.addEventListener((item) => {
|
327
|
-
if (item[
|
327
|
+
if (item[moduleIdSymbol] === this._dynamicModuleId) {
|
328
328
|
this._handleItemMoved(item, category);
|
329
329
|
}
|
330
330
|
}));
|
@@ -572,7 +572,7 @@ class CategoryManager {
|
|
572
572
|
* destroys the categoryManager, removes all Listeners and clears all Managed Categories
|
573
573
|
*/
|
574
574
|
destroy() {
|
575
|
-
this.
|
575
|
+
this._dynamicModuleIdListener();
|
576
576
|
this._appCategoriesRemovedListener();
|
577
577
|
this.componentIds = [];
|
578
578
|
this._managedCategories.forEach((item) => {
|
@@ -84,6 +84,24 @@ class NavbarManager extends ButtonManager {
|
|
84
84
|
buttonComponent[locationSymbol] = location;
|
85
85
|
return buttonComponent;
|
86
86
|
}
|
87
|
+
|
88
|
+
/**
|
89
|
+
* Toggles a button of provided id by executing its callback.
|
90
|
+
* Use active flag to force a state to be applied.
|
91
|
+
* @param {string} id
|
92
|
+
* @param {boolean} [active]
|
93
|
+
*/
|
94
|
+
toggle(id, active = undefined) {
|
95
|
+
check(id, String);
|
96
|
+
const { action } = this.get(id);
|
97
|
+
if (active !== undefined) {
|
98
|
+
if (action?.active !== active) {
|
99
|
+
action.callback();
|
100
|
+
}
|
101
|
+
} else if (action) {
|
102
|
+
action.callback();
|
103
|
+
}
|
104
|
+
}
|
87
105
|
}
|
88
106
|
|
89
107
|
export default NavbarManager;
|
@@ -2,7 +2,7 @@
|
|
2
2
|
<v-sheet
|
3
3
|
:id="`window-component--${windowState.id}`"
|
4
4
|
class="elevation-3 position-absolute d-flex flex-column"
|
5
|
-
|
5
|
+
v-on="{ ...$listeners }"
|
6
6
|
@dragstart="dragStart"
|
7
7
|
@dragend="dragEnd"
|
8
8
|
:draggable="isDraggable"
|
@@ -24,9 +24,14 @@
|
|
24
24
|
>
|
25
25
|
<slot name="headerComponent" :props="$attrs" />
|
26
26
|
</div>
|
27
|
-
<v-divider
|
27
|
+
<v-divider
|
28
|
+
v-if="!windowState.hideHeader"
|
29
|
+
/>
|
28
30
|
<div
|
29
31
|
class="overflow-x-hidden mb-1"
|
32
|
+
:class="{
|
33
|
+
'rounded': !isDocked,
|
34
|
+
}"
|
30
35
|
>
|
31
36
|
<slot />
|
32
37
|
</div>
|
@@ -53,7 +58,8 @@
|
|
53
58
|
* @vue-prop {WindowState} windowState
|
54
59
|
* @vue-prop {boolean} isOnTop - Whether the component is focused
|
55
60
|
* @vue-prop {Object} slotWindow - slot ref of the window
|
56
|
-
* @vue-event {PointerEvent}
|
61
|
+
* @vue-event {PointerEvent} click - raised when the component is clicked
|
62
|
+
* @vue-event {MouseEvent} mousedown - raised when the component is mousedown
|
57
63
|
* @vue-event {{dx: number, dy: number}} move - raised when the component is moved (dragged)
|
58
64
|
* @vue-data {slot} [#default] - slot with the window content
|
59
65
|
* @vue-data {slot} [#headerComponent] - slot to override the default header
|
@@ -94,21 +100,14 @@
|
|
94
100
|
});
|
95
101
|
const isDockedRight = computed(() => props.slotWindow === WindowSlot.DYNAMIC_RIGHT);
|
96
102
|
const isDraggable = ref(false);
|
97
|
-
/**
|
98
|
-
* @param {PointerEvent} e
|
99
|
-
*/
|
100
|
-
const clicked = (e) => {
|
101
|
-
emit('click', e);
|
102
|
-
};
|
103
103
|
/**
|
104
104
|
* Sets window as draggable on mousedown on header.
|
105
105
|
* Stops bubbling of header action buttons.
|
106
106
|
* @param {MouseEvent} e
|
107
107
|
*/
|
108
108
|
const mousedown = (e) => {
|
109
|
+
emit('mousedown', e);
|
109
110
|
if (e.target.closest('button')) {
|
110
|
-
e.preventDefault();
|
111
|
-
e.stopPropagation();
|
112
111
|
return;
|
113
112
|
}
|
114
113
|
isDraggable.value = isDynamic.value;
|
@@ -128,9 +127,6 @@
|
|
128
127
|
startEvent = e;
|
129
128
|
// set mouse cursor to move
|
130
129
|
e.dataTransfer.effectAllowed = 'move';
|
131
|
-
const preventDefaultDragover = dragOverEvent => dragOverEvent.preventDefault();
|
132
|
-
e.target.parentElement.ondragover = preventDefaultDragover;
|
133
|
-
app.maps.target.ondragover = preventDefaultDragover;
|
134
130
|
};
|
135
131
|
/**
|
136
132
|
* @param {DragEvent} endEvent
|
@@ -153,7 +149,6 @@
|
|
153
149
|
isDynamicLeft: isDockedLeft,
|
154
150
|
isDynamicRight: isDockedRight,
|
155
151
|
isDraggable,
|
156
|
-
clicked,
|
157
152
|
dragStart,
|
158
153
|
dragEnd,
|
159
154
|
mousedown,
|
@@ -6,6 +6,7 @@
|
|
6
6
|
class="mr-2"
|
7
7
|
:class="{ 'primary--text': isOnTop }"
|
8
8
|
v-text="windowState.headerIcon"
|
9
|
+
size="16"
|
9
10
|
/>
|
10
11
|
<h3
|
11
12
|
class="d-inline-block user-select-none font-weight-bold"
|
@@ -33,7 +34,7 @@
|
|
33
34
|
small
|
34
35
|
:icon="infoAction.icon"
|
35
36
|
:tooltip="infoAction.title"
|
36
|
-
class="px-1"
|
37
|
+
class="px-1 d-flex"
|
37
38
|
/>
|
38
39
|
<VcsButton
|
39
40
|
v-if="isDockable"
|
@@ -41,13 +42,14 @@
|
|
41
42
|
small
|
42
43
|
icon="mdi-pin"
|
43
44
|
tooltip="components.pin"
|
44
|
-
class="px-1"
|
45
|
+
class="px-1 d-flex"
|
45
46
|
/>
|
46
47
|
<VcsButton
|
47
48
|
@click.stop="close"
|
48
49
|
small
|
49
50
|
icon="mdi-close-thick"
|
50
51
|
tooltip="components.close"
|
52
|
+
class="d-flex"
|
51
53
|
/>
|
52
54
|
</div>
|
53
55
|
</span>
|