@vcmap/ui 5.0.0-rc.10 → 5.0.0-rc.13
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 +12 -5
- package/build/build.js +6 -3
- package/build/buildHelpers.js +12 -4
- package/build/buildPreview.js +7 -0
- package/build/getPluginProxies.js +4 -0
- package/config/aerowest.config.json +13 -3
- package/config/base.config.json +398 -219
- package/config/codes.config.json +397 -0
- package/config/dev.config.json +375 -1
- package/config/graphFeatureInfo.config.json +100 -0
- package/config/www.config.json +1232 -0
- package/dist/assets/{cesium.eb5667.js → cesium.21663e.js} +0 -0
- package/dist/assets/cesium.js +1 -1
- package/dist/assets/core.63242d.js +4 -0
- package/dist/assets/core.js +1 -1
- package/dist/assets/font/OFL.txt +93 -0
- package/dist/assets/font/TitilliumWeb-Regular.woff2 +0 -0
- package/dist/assets/{index.4ccd4433.js → index.44b91cfe.js} +1 -1
- package/dist/assets/{ol.ef03b1.js → ol.88ba9d.js} +0 -0
- package/dist/assets/ol.js +1 -1
- package/dist/assets/ui.3c2933.css +1 -0
- package/dist/assets/ui.3c2933.js +71 -0
- package/dist/assets/ui.js +1 -1
- package/dist/assets/vue.c897fc.js +9 -0
- package/dist/assets/vue.js +2 -1
- package/dist/assets/{vuetify.401a29.css → vuetify.147c3a.css} +1 -1
- package/dist/assets/{vuetify.401a29.js → vuetify.147c3a.js} +72 -72
- package/dist/assets/vuetify.js +2 -2
- package/dist/index.html +1 -5
- package/index.js +39 -5
- package/lib/vue.js +1 -0
- package/map.config.json +15 -6
- package/package.json +17 -8
- package/plugins/@vcmap/create-link/fallbackCreateLink.vue +71 -0
- package/plugins/@vcmap/create-link/index.js +83 -0
- package/plugins/@vcmap/create-link/package.json +6 -0
- package/plugins/@vcmap/pluginExample/index.js +2 -2
- package/plugins/@vcmap/pluginExample/pluginExampleComponent.vue +20 -3
- package/plugins/@vcmap/project-selector/ProjectSelectorComponent.vue +1 -1
- package/plugins/@vcmap/project-selector/index.js +1 -1
- package/plugins/@vcmap/project-selector/package.json +1 -2
- package/plugins/@vcmap/theme-changer/ThemeChangerComponent.vue +1 -1
- package/plugins/@vcmap/theme-changer/index.js +1 -1
- package/plugins/@vcmap/theme-changer/package.json +1 -2
- package/plugins/categoryTest/Categories.vue +89 -1
- package/plugins/categoryTest/Category.vue +1 -1
- package/plugins/example/index.js +10 -23
- package/plugins/simple-graph/README.md +51 -0
- package/plugins/simple-graph/SimpleGraphComponent.vue +70 -0
- package/plugins/simple-graph/index.js +17 -0
- package/plugins/simple-graph/package.json +11 -0
- package/plugins/simple-graph/simpleGraphView.js +76 -0
- package/plugins/test/editor.vue +1 -1
- package/plugins/test/index.js +76 -9
- package/plugins/test/toolbox-data.js +82 -57
- package/plugins/test/windowManagerExample.vue +1 -1
- package/src/actions/stateRefAction.js +2 -2
- package/src/actions/styleSelector.vue +1 -1
- package/src/application/Navbar.vue +13 -2
- package/src/application/VcsApp.vue +301 -116
- package/src/application/VcsMap.vue +1 -1
- package/src/application/VcsSettings.vue +1 -1
- package/src/application/vcsAppWrapper.vue +1 -0
- package/src/assets/font/OFL.txt +93 -0
- package/src/assets/font/TitilliumWeb-Regular.woff2 +0 -0
- package/src/components/form-inputs-controls/VcsCheckbox.vue +13 -0
- package/src/components/form-inputs-controls/VcsColorPicker.vue +1 -1
- package/src/components/form-inputs-controls/VcsRadio.vue +123 -0
- package/src/components/form-output/VcsFormattedNumber.vue +1 -1
- package/src/components/lists/VcsActionList.vue +22 -7
- package/src/components/lists/VcsTreeview.vue +4 -4
- package/src/components/lists/VcsTreeviewLeaf.vue +10 -3
- package/src/components/lists/VcsTreeviewSearchbar.vue +1 -2
- package/src/components/tables/VcsTable.vue +245 -0
- package/src/contentTree/LayerTree.vue +1 -1
- package/src/contentTree/contentTreeCollection.js +4 -4
- package/src/contentTree/contentTreeItem.js +9 -9
- package/src/contentTree/groupContentTreeItem.js +1 -1
- package/src/contentTree/layerContentTreeItem.js +15 -1
- package/src/contentTree/layerGroupContentTreeItem.js +21 -1
- package/src/contentTree/nodeContentTreeItem.js +1 -1
- package/src/featureInfo/AddressBalloonComponent.vue +47 -0
- package/src/featureInfo/BalloonComponent.vue +140 -0
- package/src/featureInfo/abstractFeatureInfoView.js +313 -0
- package/src/featureInfo/addressBalloonFeatureInfoView.js +118 -0
- package/src/featureInfo/balloonFeatureInfoView.js +151 -0
- package/src/featureInfo/balloonHelper.js +132 -0
- package/src/featureInfo/featureInfo.js +457 -0
- package/src/featureInfo/featureInfoInteraction.js +42 -0
- package/src/featureInfo/iframeFeatureInfoView.js +95 -0
- package/src/featureInfo/tableFeatureInfoView.js +106 -0
- package/src/i18n/de.js +26 -0
- package/src/i18n/en.js +26 -0
- package/src/i18n/i18nCollection.js +17 -0
- package/src/icons/+all.js +80 -0
- package/src/icons/ClippingHorizontalIcon.vue +7 -0
- package/src/icons/ClippingIcon.vue +7 -0
- package/src/icons/ClippingVerticalIcon.vue +7 -0
- package/src/icons/ColorPickerIcon.vue +7 -0
- package/src/icons/ComponentsIcon.vue +2 -2
- package/src/icons/DimensionsHouseIcon.vue +11 -9
- package/src/icons/EditIcon.vue +7 -0
- package/src/icons/GlobalTerrainIcon.vue +9 -0
- package/src/icons/GroundIcon.vue +18 -0
- package/src/icons/HideIcon.vue +12 -0
- package/src/icons/LogoutIcon.vue +7 -0
- package/src/icons/ObjectAttributeIcon.vue +2 -13
- package/src/icons/PedestrianIcon.vue +2 -3
- package/src/icons/PenIcon.vue +2 -9
- package/src/icons/PoiIcon.vue +5 -2
- package/src/icons/PointSelectIcon.vue +4 -2
- package/src/icons/QueryIcon.vue +6 -7
- package/src/icons/ScreenshotIcon.vue +16 -0
- package/src/icons/ShareIcon.vue +4 -16
- package/src/icons/SkipNextIcon.vue +3 -1
- package/src/icons/TerrainBoxIcon.vue +9 -0
- package/src/icons/ToolsIcon.vue +4 -30
- package/src/icons/UploadIcon.vue +2 -9
- package/src/icons/UserProfileIcon.vue +7 -0
- package/src/icons/UserShareIcon.vue +7 -0
- package/src/icons/VideoRecorderIcon.vue +5 -9
- package/src/icons/ViewpointFlightIcon.vue +11 -0
- package/src/icons/ViewpointIcon.vue +11 -0
- package/src/icons/Viewshed360Icon.vue +7 -0
- package/src/icons/ViewshedConeIcon.vue +7 -0
- package/src/icons/ViewshedIcon.vue +7 -0
- package/src/icons/WallIcon.vue +4 -9
- package/src/legend/legendHelper.js +193 -0
- package/src/legend/styleLegendItem.vue +129 -0
- package/src/legend/vcsLegend.vue +92 -0
- package/src/manager/buttonManager.js +7 -12
- package/src/manager/categoryManager/ComponentsManager.vue +30 -0
- package/src/manager/categoryManager/categoryManager.js +500 -0
- package/src/manager/contextMenu/contextMenuComponent.vue +43 -0
- package/src/manager/contextMenu/contextMenuInteraction.js +42 -0
- package/src/manager/contextMenu/contextMenuManager.js +197 -0
- package/src/manager/navbarManager.js +9 -9
- package/src/manager/toolbox/GroupToolboxComponent.vue +118 -0
- package/src/manager/toolbox/SelectToolboxComponent.vue +128 -0
- package/src/manager/toolbox/ToolboxManager.vue +116 -98
- package/src/manager/toolbox/toolboxManager.js +235 -86
- package/src/manager/window/WindowComponent.vue +1 -1
- package/src/manager/window/WindowManager.vue +5 -3
- package/src/manager/window/windowManager.js +118 -14
- package/src/navigation/mapNavigation.vue +3 -5
- package/src/navigation/overviewMap.js +28 -5
- package/src/navigation/vcsCompass.vue +1 -1
- package/src/pluginHelper.js +42 -10
- package/src/setup.js +0 -2
- package/src/state.js +256 -0
- package/src/styles/_theming.scss +0 -5
- package/src/styles/variables.scss +7 -0
- package/src/styles/vcsFont.scss +17 -0
- package/src/uiConfig.js +79 -0
- package/src/vcsUiApp.js +213 -22
- package/src/vuePlugins/vuetify.js +14 -4
- package/config/berlin.config.json +0 -510
- package/dist/assets/core.216494.js +0 -4
- package/dist/assets/ui.99a1a7.css +0 -1
- package/dist/assets/ui.99a1a7.js +0 -70
- package/dist/assets/vue-composition-api.c5aca1.js +0 -14
- package/dist/assets/vue-composition-api.js +0 -2
- package/dist/assets/vue.762edd.js +0 -9
- package/lib/vue-composition-api.js +0 -2
- package/src/manager/toolbox/ToolboxGroupComponent.vue +0 -128
package/src/styles/_theming.scss
CHANGED
@@ -7,16 +7,11 @@
|
|
7
7
|
background-image: var(--vcs-primary-logo);
|
8
8
|
height: 36px;
|
9
9
|
width: 151px;
|
10
|
-
margin: 0 auto;
|
11
10
|
}
|
12
11
|
.company-logo-mobile {
|
13
12
|
background-image: var(--vcs-mobile-logo);
|
14
13
|
height: 40px;
|
15
14
|
width: 70px;
|
16
|
-
position: absolute;
|
17
|
-
top: 1rem;
|
18
|
-
left: 1rem;
|
19
|
-
z-index: 1;
|
20
15
|
}
|
21
16
|
|
22
17
|
// Dev-Only!
|
@@ -55,6 +55,7 @@ $list-padding: 0 0; // 8px 0 !default;
|
|
55
55
|
$list-item-title-font-size: $font-size; // map-deep-get($headings, 'subtitle-1', 'size') !default;
|
56
56
|
$list-item-dense-title-font-size: $font-size; // 0.8125rem !default;
|
57
57
|
$list-item-dense-title-line-height: 24px; // 1rem !default;
|
58
|
+
$list-dense-subheader-height: 32px; // 40px !default;
|
58
59
|
$list-item-min-height: 32px; // 48px !default;
|
59
60
|
$list-dense-min-height: 24px; // 40px !default;
|
60
61
|
$list-item-content-padding: 4px 0; // 12px 0 !default;
|
@@ -68,3 +69,9 @@ $list-item-icon-margin: auto 0; // 16px 0 !default;
|
|
68
69
|
$treeview-node-level-width: 16px;
|
69
70
|
$treeview-node-margin: 4px;
|
70
71
|
$treeview-node-height: 32px; // 48px !default;
|
72
|
+
|
73
|
+
/** Expansion Panel */
|
74
|
+
$expansion-panel-header-min-height: 32px; // 48px !default;
|
75
|
+
$expansion-panel-active-header-min-height: 32px; // 64px !default;
|
76
|
+
$expansion-panel-header-padding: 6px 0; // 16px 24px !default;
|
77
|
+
$expansion-panel-content-padding: 0 0 4px; // 0 24px 16px !default;
|
package/src/styles/vcsFont.scss
CHANGED
@@ -1,3 +1,20 @@
|
|
1
|
+
/* latin-ext */
|
2
|
+
@font-face {
|
3
|
+
font-family: 'Titillium Web';
|
4
|
+
font-style: normal;
|
5
|
+
font-weight: 400;
|
6
|
+
src: url(../assets/font/TitilliumWeb-Regular.woff2) format('woff2');
|
7
|
+
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
8
|
+
}
|
9
|
+
/* latin */
|
10
|
+
@font-face {
|
11
|
+
font-family: 'Titillium Web';
|
12
|
+
font-style: normal;
|
13
|
+
font-weight: 400;
|
14
|
+
src: url(../assets/font/TitilliumWeb-Regular.woff2) format('woff2');
|
15
|
+
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
16
|
+
}
|
17
|
+
|
1
18
|
// fonts
|
2
19
|
$base-font-size: 14px; // base font-size minimum size
|
3
20
|
|
package/src/uiConfig.js
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
import { Collection, makeOverrideCollection } from '@vcmap/core';
|
2
|
+
import { ref } from 'vue';
|
3
|
+
|
4
|
+
/**
|
5
|
+
* @typedef {Object} UiConfigurationItem
|
6
|
+
* @property {string} name
|
7
|
+
* @property {*} value
|
8
|
+
*/
|
9
|
+
|
10
|
+
/**
|
11
|
+
* @typedef {Object} UiConfigObject
|
12
|
+
* @property {string} [logo] - the company logo to display. this will override any and all css overrides.
|
13
|
+
* @property {string} [mobileLogo] - an alternative logo to display in mobile view
|
14
|
+
* @property {string} [appTitle] - an optional title to display next to the company logo
|
15
|
+
* @property {string} [primaryColor] - an optional primary color to use in all themes
|
16
|
+
*/
|
17
|
+
|
18
|
+
/**
|
19
|
+
* @class
|
20
|
+
* @extends {Collection<UiConfigurationItem>}
|
21
|
+
* @implements {import("@vcmap/core").OverrideCollectionInterface<UiConfigurationItem>}
|
22
|
+
*/
|
23
|
+
class UiConfig extends Collection {
|
24
|
+
/**
|
25
|
+
* @param {function():string} getDynamicContextId
|
26
|
+
*/
|
27
|
+
constructor(getDynamicContextId) {
|
28
|
+
super();
|
29
|
+
|
30
|
+
makeOverrideCollection(this, getDynamicContextId);
|
31
|
+
/**
|
32
|
+
* This object just acts as a go between for reactivity until we have vue3
|
33
|
+
* @todo vue3 cleanup
|
34
|
+
* @type {Object<string, *>}
|
35
|
+
*/
|
36
|
+
const configObject = {};
|
37
|
+
/**
|
38
|
+
* @type {import("vue").Ref<Object<string, *>>}
|
39
|
+
* @private
|
40
|
+
*/
|
41
|
+
this._config = ref({});
|
42
|
+
/**
|
43
|
+
* @type {Array<function():void>}
|
44
|
+
* @private
|
45
|
+
*/
|
46
|
+
this._listeners = [
|
47
|
+
this.added.addEventListener((item) => {
|
48
|
+
if (typeof item?.name === 'string') {
|
49
|
+
configObject[item.name] = item.value;
|
50
|
+
this._config.value = { ...configObject }; // shallow clone to trip reactivity
|
51
|
+
}
|
52
|
+
}),
|
53
|
+
this.removed.addEventListener((item) => {
|
54
|
+
if (typeof item?.name === 'string') {
|
55
|
+
delete configObject[item.name];
|
56
|
+
this._config.value = { ...configObject }; // shallow clone to trip reactivity
|
57
|
+
}
|
58
|
+
}),
|
59
|
+
];
|
60
|
+
}
|
61
|
+
|
62
|
+
/**
|
63
|
+
* @returns {import("vue").Ref<Object<string, *>|UiConfigObject>}
|
64
|
+
*/
|
65
|
+
get config() {
|
66
|
+
return this._config;
|
67
|
+
}
|
68
|
+
|
69
|
+
/**
|
70
|
+
* @inheritDoc
|
71
|
+
*/
|
72
|
+
destroy() {
|
73
|
+
this._listeners.forEach((cb) => { cb(); });
|
74
|
+
this._listeners = [];
|
75
|
+
super.destroy();
|
76
|
+
}
|
77
|
+
}
|
78
|
+
|
79
|
+
export default UiConfig;
|
package/src/vcsUiApp.js
CHANGED
@@ -5,6 +5,10 @@ import {
|
|
5
5
|
makeOverrideCollection,
|
6
6
|
destroyCollection,
|
7
7
|
OverrideClassRegistry,
|
8
|
+
defaultDynamicContextId,
|
9
|
+
ObliqueMap,
|
10
|
+
ViewPoint,
|
11
|
+
volatileContextId,
|
8
12
|
} from '@vcmap/core';
|
9
13
|
import { getLogger as getLoggerByName } from '@vcsuite/logger';
|
10
14
|
import {
|
@@ -13,13 +17,18 @@ import {
|
|
13
17
|
serializePlugin,
|
14
18
|
deserializePlugin,
|
15
19
|
} from './pluginHelper.js';
|
16
|
-
import { setupDefaultGroups
|
20
|
+
import ToolboxManager, { setupDefaultGroups } from './manager/toolbox/toolboxManager.js';
|
17
21
|
import { WindowManager } from './manager/window/windowManager.js';
|
18
22
|
import { NavbarManager } from './manager/navbarManager.js';
|
19
23
|
import { createContentTreeCollection } from './contentTree/contentTreeCollection.js';
|
20
24
|
import { contentTreeClassRegistry } from './contentTree/contentTreeItem.js';
|
21
25
|
import OverviewMap from './navigation/overviewMap.js';
|
22
26
|
import I18nCollection from './i18n/i18nCollection.js';
|
27
|
+
import CategoryManager from './manager/categoryManager/categoryManager.js';
|
28
|
+
import ContextMenuManager from './manager/contextMenu/contextMenuManager.js';
|
29
|
+
import FeatureInfo from './featureInfo/featureInfo.js';
|
30
|
+
import UiConfig from './uiConfig.js';
|
31
|
+
import { createEmptyState, getStateFromURL } from './state.js';
|
23
32
|
|
24
33
|
/**
|
25
34
|
* @typedef {import("@vcmap/core").VcsAppConfig} VcsUiAppConfig
|
@@ -38,27 +47,32 @@ import I18nCollection from './i18n/i18nCollection.js';
|
|
38
47
|
* @callback createPlugin
|
39
48
|
* @template {Object} P
|
40
49
|
* @param {P} config
|
50
|
+
* @param {string} pluginBaseUrl
|
41
51
|
* @returns {VcsPlugin<P>}
|
42
52
|
*/
|
43
53
|
|
44
54
|
/**
|
45
55
|
* @interface VcsPlugin
|
46
56
|
* @template {Object} P
|
57
|
+
* @template {Object} S
|
47
58
|
* @property {string} version
|
48
59
|
* @property {string} name
|
49
|
-
* @property {
|
60
|
+
* @property {Object<string, *>} [i18n] - the i18n messages of this plugin
|
61
|
+
* @property {function(VcsUiApp, S=)} initialize - called on plugin added. Is passed the VcsUiApp and optionally, the state for the plugin
|
50
62
|
* @property {function(VcsUiApp)} onVcsAppMounted - called on mounted of VcsApp.vue
|
51
63
|
* @property {function():P} [toJSON] - serialization
|
52
64
|
* @property {function():Promise<void>} destroy
|
65
|
+
* @property {function(boolean=):S|Promise<S>} [getState] - should return the plugins state or a promise for said state. is passed a "for url" flag. If true, only the state relevant for sharing a URL should be passed and short keys shall be used
|
53
66
|
* @api
|
54
67
|
*/
|
55
68
|
|
69
|
+
|
56
70
|
/**
|
57
71
|
* @interface VcsComponentManager
|
58
72
|
* @template {Object} T - the component type
|
59
73
|
* @template {Object} O - component options
|
60
|
-
* @property {VcsEvent<T>} added
|
61
|
-
* @property {VcsEvent<T>} removed
|
74
|
+
* @property {import("@vcmap/core").VcsEvent<T>} added
|
75
|
+
* @property {import("@vcmap/core").VcsEvent<T>} removed
|
62
76
|
* @property {string[]} componentIds - all registered component ids as reactive array
|
63
77
|
* @property {function(string):T} get - get component by id
|
64
78
|
* @property {function(string):boolean} has - has component with id
|
@@ -84,7 +98,7 @@ class VcsUiApp extends VcsApp {
|
|
84
98
|
constructor() {
|
85
99
|
super();
|
86
100
|
/**
|
87
|
-
* @type {OverrideCollection<VcsPlugin>}
|
101
|
+
* @type {import("@vcmap/core").OverrideCollection<VcsPlugin>}
|
88
102
|
* @private
|
89
103
|
*/
|
90
104
|
this._plugins = makeOverrideCollection(
|
@@ -93,11 +107,37 @@ class VcsUiApp extends VcsApp {
|
|
93
107
|
serializePlugin,
|
94
108
|
deserializePlugin,
|
95
109
|
);
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
110
|
+
/**
|
111
|
+
* @type {Array<function():void>}
|
112
|
+
* @private
|
113
|
+
*/
|
114
|
+
this._pluginListeners = [
|
115
|
+
this._plugins.added.addEventListener((plugin) => {
|
116
|
+
this._windowManager.removeOwner(plugin.name);
|
117
|
+
this._navbarManager.removeOwner(plugin.name);
|
118
|
+
this._toolboxManager.removeOwner(plugin.name);
|
119
|
+
this._categoryManager.removeOwner(plugin.name);
|
120
|
+
this._contextMenuManager.removeOwner(plugin.name);
|
121
|
+
if (plugin.i18n) {
|
122
|
+
this.i18n.addPluginMessages(plugin.name, plugin[contextIdSymbol], plugin.i18n);
|
123
|
+
}
|
124
|
+
if (plugin.initialize) {
|
125
|
+
let state;
|
126
|
+
if (this._cachedAppState.contextIds.includes(plugin[contextIdSymbol])) {
|
127
|
+
state = this._cachedAppState.plugins.find(s => s.name === plugin.name);
|
128
|
+
}
|
129
|
+
plugin.initialize(this, state?.state);
|
130
|
+
}
|
131
|
+
}),
|
132
|
+
this._plugins.removed.addEventListener(async (plugin) => {
|
133
|
+
this._windowManager.removeOwner(plugin.name);
|
134
|
+
this._navbarManager.removeOwner(plugin.name);
|
135
|
+
this._toolboxManager.removeOwner(plugin.name);
|
136
|
+
this._categoryManager.removeOwner(plugin.name);
|
137
|
+
this._contextMenuManager.removeOwner(plugin.name);
|
138
|
+
this.i18n.removePluginMessages(plugin.name, plugin[contextIdSymbol]);
|
139
|
+
}),
|
140
|
+
];
|
101
141
|
|
102
142
|
/**
|
103
143
|
* @type {OverrideClassRegistry<ContentTreeItem>}
|
@@ -124,10 +164,20 @@ class VcsUiApp extends VcsApp {
|
|
124
164
|
*/
|
125
165
|
this._windowManager = new WindowManager();
|
126
166
|
/**
|
127
|
-
* @type {
|
167
|
+
* @type {NavbarManager}
|
128
168
|
* @private
|
129
169
|
*/
|
130
170
|
this._navbarManager = new NavbarManager();
|
171
|
+
/**
|
172
|
+
* @type {UiConfig}
|
173
|
+
* @private
|
174
|
+
*/
|
175
|
+
this._uiConfig = new UiConfig(() => this.dynamicContextId);
|
176
|
+
/**
|
177
|
+
* @type {FeatureInfo}
|
178
|
+
* @private
|
179
|
+
*/
|
180
|
+
this._featureInfo = new FeatureInfo(this);
|
131
181
|
|
132
182
|
/**
|
133
183
|
* @type {OverviewMap}
|
@@ -140,16 +190,34 @@ class VcsUiApp extends VcsApp {
|
|
140
190
|
* @private
|
141
191
|
*/
|
142
192
|
this._i18n = new I18nCollection(() => this.dynamicContextId);
|
193
|
+
|
194
|
+
/**
|
195
|
+
* @type {CategoryManager}
|
196
|
+
* @private
|
197
|
+
*/
|
198
|
+
this._categoryManager = new CategoryManager(this);
|
199
|
+
|
200
|
+
/**
|
201
|
+
* @type {ContextMenuManager}
|
202
|
+
* @private
|
203
|
+
*/
|
204
|
+
this._contextMenuManager = new ContextMenuManager(this);
|
205
|
+
|
206
|
+
/**
|
207
|
+
* @type {AppState}
|
208
|
+
* @private
|
209
|
+
*/
|
210
|
+
this._cachedAppState = getStateFromURL(new URL(window.location.href));
|
143
211
|
}
|
144
212
|
|
145
213
|
/**
|
146
|
-
* @type {OverrideCollection<VcsPlugin>}
|
214
|
+
* @type {import("@vcmap/core").OverrideCollection<VcsPlugin>}
|
147
215
|
* @readonly
|
148
216
|
*/
|
149
217
|
get plugins() { return this._plugins; }
|
150
218
|
|
151
219
|
/**
|
152
|
-
* @type {
|
220
|
+
* @type {OverrideContentTreeCollection}
|
153
221
|
* @readonly
|
154
222
|
*/
|
155
223
|
get contentTree() { return this._contentTree; }
|
@@ -173,11 +241,17 @@ class VcsUiApp extends VcsApp {
|
|
173
241
|
get windowManager() { return this._windowManager; }
|
174
242
|
|
175
243
|
/**
|
176
|
-
* @returns {
|
244
|
+
* @returns {NavbarManager}
|
177
245
|
* @readonly
|
178
246
|
*/
|
179
247
|
get navbarManager() { return this._navbarManager; }
|
180
248
|
|
249
|
+
/**
|
250
|
+
* @returns {FeatureInfo}
|
251
|
+
* @readonly
|
252
|
+
*/
|
253
|
+
get featureInfo() { return this._featureInfo; }
|
254
|
+
|
181
255
|
/**
|
182
256
|
* @type {OverviewMap}
|
183
257
|
* @readonly
|
@@ -190,6 +264,77 @@ class VcsUiApp extends VcsApp {
|
|
190
264
|
*/
|
191
265
|
get i18n() { return this._i18n; }
|
192
266
|
|
267
|
+
/**
|
268
|
+
* @returns {CategoryManager}
|
269
|
+
* @readonly
|
270
|
+
*/
|
271
|
+
get categoryManager() { return this._categoryManager; }
|
272
|
+
|
273
|
+
/**
|
274
|
+
* @type {ContextMenuManager}
|
275
|
+
* @readonly
|
276
|
+
*/
|
277
|
+
get contextMenuManager() { return this._contextMenuManager; }
|
278
|
+
|
279
|
+
/**
|
280
|
+
* @type {UiConfig}
|
281
|
+
* @readonly
|
282
|
+
*/
|
283
|
+
get uiConfig() { return this._uiConfig; }
|
284
|
+
|
285
|
+
/**
|
286
|
+
* Get the state of the application. When passed the forUrl flag, only a minimal set of states shall be provided for a sharable link to the current state (to ensure
|
287
|
+
* the maximum URL length is not exceeded). This includes: layer active state & styling, active map, active viewpoint,
|
288
|
+
* currently selected feature info & any state deemed required for a sharable URL by the currently loaded plugins.
|
289
|
+
* @param {boolean=} forUrl
|
290
|
+
* @returns {Promise<AppState>}
|
291
|
+
*/
|
292
|
+
async getState(forUrl) {
|
293
|
+
const state = createEmptyState();
|
294
|
+
state.contextIds = this.contexts
|
295
|
+
.filter(({ id }) => id !== defaultDynamicContextId)
|
296
|
+
.map(({ id }) => id);
|
297
|
+
|
298
|
+
state.activeMap = this.maps.activeMap.name;
|
299
|
+
const viewPoint = await this.maps.activeMap.getViewPoint();
|
300
|
+
state.activeViewpoint = viewPoint?.isValid?.() ? viewPoint.toJSON() : undefined;
|
301
|
+
state.layers = [...this.layers]
|
302
|
+
.filter(l => l.isSupported(this.maps.activeMap) &&
|
303
|
+
l[contextIdSymbol] !== defaultDynamicContextId &&
|
304
|
+
l[contextIdSymbol] !== volatileContextId &&
|
305
|
+
(
|
306
|
+
((l.active || l.loading) && !l.activeOnStartup) ||
|
307
|
+
(!l.active && l.activeOnStartup) ||
|
308
|
+
((l.active || l.loading) && l.style !== l.defaultStyle && this.styles.has(l.style))
|
309
|
+
))
|
310
|
+
.map((l) => {
|
311
|
+
const layerState = {
|
312
|
+
name: l.name,
|
313
|
+
active: l.active || l.loading,
|
314
|
+
};
|
315
|
+
if (
|
316
|
+
l.style.name !== l.defaultStyle.name &&
|
317
|
+
this.styles.has(l.style) &&
|
318
|
+
l.style[contextIdSymbol] !== defaultDynamicContextId &&
|
319
|
+
l.style[contextIdSymbol] !== volatileContextId
|
320
|
+
) {
|
321
|
+
layerState.styleName = l.style.name;
|
322
|
+
}
|
323
|
+
return layerState;
|
324
|
+
});
|
325
|
+
|
326
|
+
state.plugins = await Promise.all([...this.plugins]
|
327
|
+
.filter(p => p[contextIdSymbol] !== defaultDynamicContextId &&
|
328
|
+
p[contextIdSymbol] !== volatileContextId &&
|
329
|
+
typeof p.getState === 'function')
|
330
|
+
.map(async p => ({ name: p.name, state: await p.getState(forUrl) })));
|
331
|
+
|
332
|
+
if (this.maps.activeMap instanceof ObliqueMap) {
|
333
|
+
state.activeObliqueCollection = this.maps.activeMap.collection.name;
|
334
|
+
}
|
335
|
+
return state;
|
336
|
+
}
|
337
|
+
|
193
338
|
/**
|
194
339
|
* @param {import("@vcmap/core").Context} context
|
195
340
|
* @returns {Promise<void>}
|
@@ -199,7 +344,7 @@ class VcsUiApp extends VcsApp {
|
|
199
344
|
const { config } = context;
|
200
345
|
if (Array.isArray(config.plugins)) {
|
201
346
|
const plugins = await Promise.all(config.plugins.map(async (pluginConfig) => {
|
202
|
-
const plugin = await loadPlugin(
|
347
|
+
const plugin = await loadPlugin(pluginConfig.name, pluginConfig);
|
203
348
|
if (!plugin) {
|
204
349
|
return null;
|
205
350
|
}
|
@@ -212,17 +357,56 @@ class VcsUiApp extends VcsApp {
|
|
212
357
|
|
213
358
|
plugins
|
214
359
|
.filter(p => p)
|
215
|
-
.map(p => this._plugins.override(p))
|
216
|
-
.filter(p => p.i18n)
|
217
|
-
.forEach((p) => {
|
218
|
-
this.i18n.addPluginMessages(p.name, context.id, p.i18n);
|
219
|
-
});
|
360
|
+
.map(p => this._plugins.override(p));
|
220
361
|
}
|
221
362
|
if (Array.isArray(config.i18n)) {
|
222
363
|
await this.i18n.parseItems(config.i18n, context.id);
|
223
364
|
}
|
224
365
|
await super._parseContext(context);
|
225
366
|
await this._contentTree.parseItems(config.contentTree, context.id);
|
367
|
+
await this._uiConfig.parseItems(config.uiConfig, context.id);
|
368
|
+
await this._featureInfo.collection.parseItems(config.featureInfo, context.id);
|
369
|
+
}
|
370
|
+
|
371
|
+
/**
|
372
|
+
* @param {import("@vcmap/core").Context} context
|
373
|
+
* @returns {Promise<void>}
|
374
|
+
* @protected
|
375
|
+
*/
|
376
|
+
async _setContextState(context) {
|
377
|
+
await super._setContextState(context);
|
378
|
+
if (this._cachedAppState.contextIds.includes(context.id)) {
|
379
|
+
this._cachedAppState.layers.forEach((layerState) => {
|
380
|
+
const layer = this.layers.getByKey(layerState.name);
|
381
|
+
if (layer) {
|
382
|
+
if (layerState.active) {
|
383
|
+
layer.activate();
|
384
|
+
} else {
|
385
|
+
layer.deactivate();
|
386
|
+
}
|
387
|
+
|
388
|
+
if (layerState.styleName && this.styles.hasKey(layerState.styleName) && layer.setStyle) {
|
389
|
+
layer.setStyle(this.styles.getByKey(layerState.styleName));
|
390
|
+
}
|
391
|
+
}
|
392
|
+
});
|
393
|
+
if (this._cachedAppState.activeMap && this.maps.hasKey(this._cachedAppState.activeMap)) {
|
394
|
+
await this.maps.setActiveMap(this._cachedAppState.activeMap);
|
395
|
+
}
|
396
|
+
if (
|
397
|
+
this._cachedAppState.activeObliqueCollection &&
|
398
|
+
this.maps.activeMap instanceof ObliqueMap &&
|
399
|
+
this.obliqueCollections.hasKey(this._cachedAppState.activeObliqueCollection)
|
400
|
+
) {
|
401
|
+
await this.maps.activeMap.setCollection(
|
402
|
+
this.obliqueCollections.getByKey(this._cachedAppState.activeObliqueCollection),
|
403
|
+
this._cachedAppState.activeViewpoint,
|
404
|
+
);
|
405
|
+
} else if (this._cachedAppState.activeViewpoint && this.maps.activeMap) {
|
406
|
+
await this.maps.activeMap.gotoViewPoint(new ViewPoint(this._cachedAppState.activeViewpoint));
|
407
|
+
}
|
408
|
+
this._cachedAppState.contextIds.splice(this._cachedAppState.contextIds.indexOf(context.id), 1);
|
409
|
+
}
|
226
410
|
}
|
227
411
|
|
228
412
|
/**
|
@@ -236,6 +420,8 @@ class VcsUiApp extends VcsApp {
|
|
236
420
|
this._plugins.removeContext(contextId),
|
237
421
|
this._i18n.removeContext(contextId),
|
238
422
|
this._contentTree.removeContext(contextId),
|
423
|
+
this._featureInfo.collection.removeContext(contextId),
|
424
|
+
this._uiConfig.removeContext(contextId),
|
239
425
|
]);
|
240
426
|
}
|
241
427
|
|
@@ -245,13 +431,18 @@ class VcsUiApp extends VcsApp {
|
|
245
431
|
destroy() {
|
246
432
|
this.windowManager.destroy();
|
247
433
|
this.navbarManager.destroy();
|
434
|
+
this.toolboxManager.destroy();
|
435
|
+
this.categoryManager.destroy();
|
436
|
+
this.contextMenuManager.destroy();
|
248
437
|
this._overviewMap.destroy();
|
249
|
-
|
250
|
-
this.
|
438
|
+
this._pluginListeners.forEach((cb) => { cb(); });
|
439
|
+
this._pluginListeners = [];
|
251
440
|
destroyCollection(this._plugins);
|
252
441
|
destroyCollection(this._contentTree);
|
253
442
|
destroyCollection(this._i18n);
|
254
443
|
this._contentTreeClassRegistry.destroy();
|
444
|
+
this._featureInfo.destroy();
|
445
|
+
this._uiConfig.destroy();
|
255
446
|
super.destroy();
|
256
447
|
}
|
257
448
|
}
|
@@ -5,8 +5,16 @@ import Icons from '../icons/+all.js';
|
|
5
5
|
|
6
6
|
Vue.use(Vuetify);
|
7
7
|
|
8
|
+
/**
|
9
|
+
* @type {string}
|
10
|
+
*/
|
11
|
+
export const defaultPrimaryColor = '#409D76';
|
12
|
+
|
13
|
+
/**
|
14
|
+
* @returns {import("vuetify").default}
|
15
|
+
*/
|
8
16
|
export function createVuetify() {
|
9
|
-
|
17
|
+
return new Vuetify({
|
10
18
|
treeShake: false,
|
11
19
|
defaultAssets: {
|
12
20
|
font: {
|
@@ -20,7 +28,7 @@ export function createVuetify() {
|
|
20
28
|
themes: {
|
21
29
|
light: {
|
22
30
|
basic: '#FFFFFF',
|
23
|
-
primary:
|
31
|
+
primary: defaultPrimaryColor,
|
24
32
|
accent: '#EDEDED',
|
25
33
|
warning: '#FFCE00',
|
26
34
|
'gray-200': '#DEDEDE',
|
@@ -33,7 +41,7 @@ export function createVuetify() {
|
|
33
41
|
},
|
34
42
|
dark: {
|
35
43
|
basic: '#000000',
|
36
|
-
primary:
|
44
|
+
primary: defaultPrimaryColor,
|
37
45
|
secondary: '#FFFFFF',
|
38
46
|
accent: '#757575',
|
39
47
|
warning: '#FFCE00',
|
@@ -48,7 +56,9 @@ export function createVuetify() {
|
|
48
56
|
},
|
49
57
|
},
|
50
58
|
});
|
51
|
-
return vuetify;
|
52
59
|
}
|
53
60
|
|
61
|
+
/**
|
62
|
+
* @type {import("vuetify").default}
|
63
|
+
*/
|
54
64
|
export const vuetify = createVuetify();
|