qwc2 2026.6.10 → 2026.6.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/actions/bookmark.js +40 -0
- package/actions/theme.js +92 -89
- package/components/AttributeForm.js +3 -0
- package/components/BookmarkPanel.js +312 -0
- package/components/EditUploadField.js +17 -12
- package/components/MapButton.js +4 -0
- package/components/ResizeableWindow.js +22 -0
- package/components/StandardApp.js +11 -2
- package/components/map/OlMap.js +3 -2
- package/components/map3d/Map3D.js +15 -2
- package/components/widgets/GroupSelect.js +94 -0
- package/components/widgets/PopupMenu.js +12 -10
- package/icons/drag.svg +73 -0
- package/package.json +1 -1
- package/plugins/API.js +17 -2
- package/plugins/BackgroundSwitcher.js +6 -0
- package/plugins/Bookmark.js +52 -266
- package/plugins/BottomBar.js +59 -5
- package/plugins/Identify.js +8 -1
- package/plugins/MapExport.js +6 -3
- package/plugins/Portal.js +2 -2
- package/plugins/Print.js +1 -1
- package/plugins/Settings.js +28 -49
- package/plugins/ThemeBrowser.css +132 -0
- package/plugins/ThemeBrowser.js +513 -0
- package/plugins/View3D.js +14 -0
- package/plugins/VisibilityPreset.js +137 -0
- package/reducers/bookmark.js +39 -0
- package/reducers/layers.js +6 -1
- package/scripts/updateTranslations.js +7 -3
- package/static/translations/bg-BG.json +15 -1
- package/static/translations/ca-ES.json +15 -1
- package/static/translations/cs-CZ.json +15 -1
- package/static/translations/de-CH.json +16 -2
- package/static/translations/de-DE.json +16 -2
- package/static/translations/en-US.json +16 -2
- package/static/translations/es-ES.json +15 -1
- package/static/translations/fi-FI.json +15 -1
- package/static/translations/fr-FR.json +15 -1
- package/static/translations/hu-HU.json +15 -1
- package/static/translations/it-IT.json +16 -2
- package/static/translations/ja-JP.json +15 -1
- package/static/translations/nl-NL.json +15 -1
- package/static/translations/no-NO.json +15 -1
- package/static/translations/pl-PL.json +15 -1
- package/static/translations/pt-BR.json +15 -1
- package/static/translations/pt-PT.json +15 -1
- package/static/translations/ro-RO.json +15 -1
- package/static/translations/ru-RU.json +15 -1
- package/static/translations/sv-SE.json +15 -1
- package/static/translations/tr-TR.json +15 -1
- package/static/translations/tsconfig.json +14 -1
- package/static/translations/uk-UA.json +15 -1
- package/utils/LocaleUtils.js +12 -2
- package/utils/PermaLinkUtils.js +92 -38
- package/utils/ServiceLayerUtils.js +1 -1
- package/utils/VectorLayerUtils.js +2 -1
- /package/{plugins/style/Bookmark.css → components/style/BookmarkPanel.css} +0 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2025 Stadtwerke München GmbH
|
|
3
|
+
* All rights reserved.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the BSD-style license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import bookmarkReducer from '../reducers/bookmark';
|
|
10
|
+
import ReducerIndex from '../reducers/index';
|
|
11
|
+
import { getBookmarks, getVisibilityPresets } from '../utils/PermaLinkUtils';
|
|
12
|
+
ReducerIndex.register("bookmark", bookmarkReducer);
|
|
13
|
+
export var SET_BOOKMARKS = 'SET_BOOKMARKS';
|
|
14
|
+
export var SET_VISIBILITY_PRESETS = 'SET_VISIBILITY_PRESETS';
|
|
15
|
+
export function setBookmarks(bookmarks) {
|
|
16
|
+
return {
|
|
17
|
+
type: SET_BOOKMARKS,
|
|
18
|
+
bookmarks: bookmarks
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export function setVisibilityPresets(visibilityPresets) {
|
|
22
|
+
return {
|
|
23
|
+
type: SET_VISIBILITY_PRESETS,
|
|
24
|
+
visibilityPresets: visibilityPresets
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
export function refreshBookmarks() {
|
|
28
|
+
return function (dispatch) {
|
|
29
|
+
getBookmarks(function (bookmarks) {
|
|
30
|
+
return dispatch(setBookmarks(bookmarks));
|
|
31
|
+
});
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
export function refreshVisibilityPresets() {
|
|
35
|
+
return function (dispatch) {
|
|
36
|
+
getVisibilityPresets(function (presets) {
|
|
37
|
+
return dispatch(setVisibilityPresets(presets));
|
|
38
|
+
});
|
|
39
|
+
};
|
|
40
|
+
}
|
package/actions/theme.js
CHANGED
|
@@ -33,7 +33,7 @@ import MapUtils from '../utils/MapUtils';
|
|
|
33
33
|
import { UrlParams } from '../utils/PermaLinkUtils';
|
|
34
34
|
import ServiceLayerUtils from '../utils/ServiceLayerUtils';
|
|
35
35
|
import ThemeUtils from '../utils/ThemeUtils';
|
|
36
|
-
import { LayerRole, addLayer, removeLayer, removeAllLayers, replacePlaceholderLayer, setSwipe } from './layers';
|
|
36
|
+
import { LayerRole, addLayer, removeLayer, removeAllLayers, replacePlaceholderLayer, setSwipe, setThemeLayersVisibilityPreset } from './layers';
|
|
37
37
|
import { configureMap } from './map';
|
|
38
38
|
import { showNotification, NotificationType } from './windows';
|
|
39
39
|
export var THEMES_LOADED = 'THEMES_LOADED';
|
|
@@ -51,57 +51,81 @@ export function setThemeLayersList(theme) {
|
|
|
51
51
|
themelist: theme
|
|
52
52
|
};
|
|
53
53
|
}
|
|
54
|
-
export function finishThemeSetup(dispatch, theme, themes, layerConfigs,
|
|
55
|
-
var _theme$config$section, _theme$config, _theme$config2;
|
|
56
|
-
|
|
57
|
-
var themeLayer = ThemeUtils.createThemeLayer(theme, themes);
|
|
58
|
-
var layers = [themeLayer];
|
|
59
|
-
|
|
60
|
-
// Restore theme layer configuration, create placeholders for missing layers
|
|
54
|
+
export function finishThemeSetup(dispatch, theme, themes, layerConfigs, preserve, prevLayers, prevTheme, permalinkLayers, externalLayerRestorer, visibleBgLayer, initialTask, initialVisibilityPreset) {
|
|
55
|
+
var _bgLayers$find, _theme$config$section, _theme$config, _theme$config2;
|
|
56
|
+
var layers = [];
|
|
61
57
|
var externalLayers = {};
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
58
|
+
|
|
59
|
+
// Get current background layer if it needs to be preserved
|
|
60
|
+
if (preserve && visibleBgLayer === null && ConfigUtils.getConfigProp("preserveBackgroundOnThemeSwitch", theme) === true) {
|
|
61
|
+
var _prevLayers$find$name, _prevLayers$find;
|
|
62
|
+
visibleBgLayer = (_prevLayers$find$name = (_prevLayers$find = prevLayers.find(function (layer) {
|
|
63
|
+
return layer.role === LayerRole.BACKGROUND && layer.visibility === true;
|
|
64
|
+
})) === null || _prevLayers$find === void 0 ? void 0 : _prevLayers$find.name) !== null && _prevLayers$find$name !== void 0 ? _prevLayers$find$name : null;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Remove old layers
|
|
68
|
+
var preserveUserLayers = preserve && ConfigUtils.getConfigProp("preserveNonThemeLayersOnThemeSwitch", theme) === true;
|
|
69
|
+
var insPos = 0;
|
|
70
|
+
var bgLayerKept = false;
|
|
71
|
+
prevLayers.forEach(function (layer) {
|
|
72
|
+
if (layer.role === LayerRole.USERLAYER && preserveUserLayers) {
|
|
73
|
+
++insPos;
|
|
74
|
+
} else if (layer.role === LayerRole.BACKGROUND && layer.name === visibleBgLayer) {
|
|
75
|
+
bgLayerKept = true;
|
|
76
|
+
} else {
|
|
77
|
+
dispatch(removeLayer(layer.id));
|
|
71
78
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
79
|
+
});
|
|
80
|
+
if (theme.url) {
|
|
81
|
+
// Create layer
|
|
82
|
+
var themeLayer = ThemeUtils.createThemeLayer(theme, themes);
|
|
83
|
+
layers.push(themeLayer);
|
|
84
|
+
// Restore theme layer configuration, create placeholders for missing layers
|
|
85
|
+
if (!isEmpty(permalinkLayers) && ConfigUtils.getConfigProp("storeAllLayersInPermalink")) {
|
|
86
|
+
layers = permalinkLayers;
|
|
87
|
+
} else {
|
|
88
|
+
if (layerConfigs) {
|
|
89
|
+
if (ConfigUtils.getConfigProp("allowReorderingLayers", theme) !== true) {
|
|
90
|
+
layers = LayerUtils.restoreLayerParams(themeLayer, layerConfigs, permalinkLayers, externalLayers);
|
|
91
|
+
} else {
|
|
92
|
+
layers = LayerUtils.restoreOrderedLayerParams(themeLayer, layerConfigs, permalinkLayers, externalLayers);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
if (isEmpty(layers)) {
|
|
96
|
+
layers = [_objectSpread(_objectSpread({}, themeLayer), {}, {
|
|
97
|
+
sublayers: []
|
|
98
|
+
})];
|
|
99
|
+
}
|
|
76
100
|
}
|
|
77
101
|
}
|
|
78
102
|
|
|
79
103
|
// Add background layers for theme
|
|
80
|
-
var haveVisibleBg = false;
|
|
81
104
|
var bgLayers = ThemeUtils.createThemeBackgroundLayers(theme.backgroundLayers || [], themes, visibleBgLayer, externalLayers);
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
if (visibleLayer !== visibleBgLayer) {
|
|
88
|
-
dispatch(showNotification("missingbglayer", LocaleUtils.tr("app.missingbg", visibleBgLayer), NotificationType.WARN, true));
|
|
89
|
-
}
|
|
105
|
+
var actuallyVisibleBgLayer = (_bgLayers$find = bgLayers.find(function (entry) {
|
|
106
|
+
return entry.visibility;
|
|
107
|
+
})) === null || _bgLayers$find === void 0 ? void 0 : _bgLayers$find.name;
|
|
108
|
+
if (!prevTheme && visibleBgLayer && actuallyVisibleBgLayer !== visibleBgLayer) {
|
|
109
|
+
dispatch(showNotification("missingbglayer", LocaleUtils.tr("app.missingbg", visibleBgLayer), NotificationType.WARN, true));
|
|
90
110
|
}
|
|
91
111
|
var _iterator = _createForOfIteratorHelper(bgLayers.reverse()),
|
|
92
112
|
_step;
|
|
93
113
|
try {
|
|
94
114
|
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
95
115
|
var bgLayer = _step.value;
|
|
96
|
-
|
|
97
|
-
|
|
116
|
+
// If previous visible BG layer kept, insert other BG layers around that layer
|
|
117
|
+
if (bgLayer.name === visibleBgLayer && bgLayerKept) {
|
|
118
|
+
bgLayerKept = false;
|
|
119
|
+
} else {
|
|
120
|
+
dispatch(addLayer(bgLayer, bgLayerKept ? 1 : 0));
|
|
121
|
+
}
|
|
98
122
|
}
|
|
99
123
|
} catch (err) {
|
|
100
124
|
_iterator.e(err);
|
|
101
125
|
} finally {
|
|
102
126
|
_iterator.f();
|
|
103
127
|
}
|
|
104
|
-
if (!
|
|
128
|
+
if (!actuallyVisibleBgLayer) {
|
|
105
129
|
UrlParams.updateParams({
|
|
106
130
|
bl: ""
|
|
107
131
|
});
|
|
@@ -111,7 +135,7 @@ export function finishThemeSetup(dispatch, theme, themes, layerConfigs, insertPo
|
|
|
111
135
|
try {
|
|
112
136
|
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
113
137
|
var layer = _step2.value;
|
|
114
|
-
dispatch(addLayer(layer,
|
|
138
|
+
dispatch(addLayer(layer, insPos));
|
|
115
139
|
}
|
|
116
140
|
|
|
117
141
|
// Restore external layers
|
|
@@ -134,8 +158,10 @@ export function finishThemeSetup(dispatch, theme, themes, layerConfigs, insertPo
|
|
|
134
158
|
// Don't expose sublayers
|
|
135
159
|
if (layer) {
|
|
136
160
|
layer.sublayers = null;
|
|
161
|
+
dispatch(replacePlaceholderLayer(id, layer));
|
|
162
|
+
} else {
|
|
163
|
+
dispatch(removeLayer(id));
|
|
137
164
|
}
|
|
138
|
-
dispatch(replacePlaceholderLayer(id, layer));
|
|
139
165
|
});
|
|
140
166
|
}
|
|
141
167
|
}
|
|
@@ -143,8 +169,11 @@ export function finishThemeSetup(dispatch, theme, themes, layerConfigs, insertPo
|
|
|
143
169
|
type: SET_CURRENT_THEME,
|
|
144
170
|
theme: theme
|
|
145
171
|
});
|
|
172
|
+
if (initialVisibilityPreset) {
|
|
173
|
+
dispatch(setThemeLayersVisibilityPreset(initialVisibilityPreset));
|
|
174
|
+
}
|
|
146
175
|
var section = ConfigUtils.isMobile() ? "mobile" : "desktop";
|
|
147
|
-
var task = initialTask || ((_theme$config$section = theme === null || theme === void 0 || (_theme$config = theme.config) === null || _theme$config === void 0 || (_theme$config = _theme$config[section]) === null || _theme$config === void 0 ? void 0 : _theme$config.startupTask) !== null && _theme$config$section !== void 0 ? _theme$config$section : theme === null || theme === void 0 || (_theme$config2 = theme.config) === null || _theme$config2 === void 0 ? void 0 : _theme$config2.startupTask) || (
|
|
176
|
+
var task = initialTask || ((_theme$config$section = theme === null || theme === void 0 || (_theme$config = theme.config) === null || _theme$config === void 0 || (_theme$config = _theme$config[section]) === null || _theme$config === void 0 ? void 0 : _theme$config.startupTask) !== null && _theme$config$section !== void 0 ? _theme$config$section : theme === null || theme === void 0 || (_theme$config2 = theme.config) === null || _theme$config2 === void 0 ? void 0 : _theme$config2.startupTask) || (!prevTheme ? ConfigUtils.getConfigProp("startupTask") : null);
|
|
148
177
|
if (task) {
|
|
149
178
|
var mapClickAction = ConfigUtils.getPluginConfig(task.key).mapClickAction;
|
|
150
179
|
dispatch(setCurrentTask(task.key, task.mode, mapClickAction, task.data));
|
|
@@ -159,68 +188,37 @@ export function setCurrentTheme(theme, themes) {
|
|
|
159
188
|
var themeLayerRestorer = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : null;
|
|
160
189
|
var externalLayerRestorer = arguments.length > 8 && arguments[8] !== undefined ? arguments[8] : null;
|
|
161
190
|
var initialTask = arguments.length > 9 && arguments[9] !== undefined ? arguments[9] : null;
|
|
191
|
+
var initialVisibilityPreset = arguments.length > 10 && arguments[10] !== undefined ? arguments[10] : null;
|
|
162
192
|
return function (dispatch, getState) {
|
|
163
|
-
var _getState$layers, _ref, _theme$mapTips;
|
|
164
|
-
|
|
193
|
+
var _getState$layers, _themes$defaultMapCrs, _themes$defaultMapExt, _themes$defaultMapCrs2, _theme$bbox, _theme$initialBbox, _ref, _theme$version, _ref2, _theme$scales, _theme$printScales, _theme$printResolutio, _theme$printGrid, _theme$searchProvider, _ref3, _theme$backgroundLaye, _theme$mapTips;
|
|
194
|
+
dispatch(setSwipe(null));
|
|
165
195
|
var mapCrs = theme.mapCrs || themes.defaultMapCrs || "EPSG:3857";
|
|
166
196
|
if (!(mapCrs in CoordinatesUtils.getAvailableCRS())) {
|
|
167
197
|
dispatch(showNotification("missingprojection", LocaleUtils.tr("app.missingprojection", theme.title, mapCrs), NotificationType.WARN, true));
|
|
168
|
-
return;
|
|
169
|
-
}
|
|
170
|
-
var initialTheme = !getState().theme.current;
|
|
171
|
-
|
|
172
|
-
// Get current background layer if it needs to be preserved
|
|
173
|
-
if (preserve && visibleBgLayer === null && ConfigUtils.getConfigProp("preserveBackgroundOnThemeSwitch", theme) === true) {
|
|
174
|
-
var curBgLayer = curLayers.find(function (layer) {
|
|
175
|
-
return layer.role === LayerRole.BACKGROUND && layer.visibility === true;
|
|
176
|
-
});
|
|
177
|
-
visibleBgLayer = curBgLayer ? curBgLayer.name : null;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
// Remove old layers
|
|
181
|
-
var insertPos = 0;
|
|
182
|
-
if (preserve && ConfigUtils.getConfigProp("preserveNonThemeLayersOnThemeSwitch", theme) === true) {
|
|
183
|
-
// Compute insertion position of new theme layers by counting how many non-theme layers remain
|
|
184
|
-
insertPos = curLayers.filter(function (layer) {
|
|
185
|
-
return layer.role === LayerRole.USERLAYER;
|
|
186
|
-
}).length;
|
|
187
|
-
var removeLayers = curLayers.filter(function (layer) {
|
|
188
|
-
return layer.role !== LayerRole.USERLAYER;
|
|
189
|
-
}).map(function (layer) {
|
|
190
|
-
return layer.id;
|
|
191
|
-
});
|
|
192
|
-
var _iterator3 = _createForOfIteratorHelper(removeLayers),
|
|
193
|
-
_step3;
|
|
194
|
-
try {
|
|
195
|
-
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
196
|
-
var layerId = _step3.value;
|
|
197
|
-
dispatch(removeLayer(layerId));
|
|
198
|
-
}
|
|
199
|
-
} catch (err) {
|
|
200
|
-
_iterator3.e(err);
|
|
201
|
-
} finally {
|
|
202
|
-
_iterator3.f();
|
|
203
|
-
}
|
|
204
|
-
} else {
|
|
205
198
|
dispatch(removeAllLayers());
|
|
206
|
-
}
|
|
207
|
-
dispatch(setSwipe(null));
|
|
208
|
-
if (!theme) {
|
|
209
199
|
return;
|
|
210
200
|
}
|
|
201
|
+
var prevLayers = ((_getState$layers = getState().layers) === null || _getState$layers === void 0 ? void 0 : _getState$layers.flat) || [];
|
|
202
|
+
var prevTheme = getState().theme.current;
|
|
203
|
+
var defaultExtent = {
|
|
204
|
+
crs: (_themes$defaultMapCrs = themes.defaultMapCrs) !== null && _themes$defaultMapCrs !== void 0 ? _themes$defaultMapCrs : "EPSG:3857",
|
|
205
|
+
bounds: (_themes$defaultMapExt = themes.defaultMapExtent) !== null && _themes$defaultMapExt !== void 0 ? _themes$defaultMapExt : CoordinatesUtils.reproject([-20037508.34, -20048966.10, 20037508.34, 20048966.10], "EPSG:3857", (_themes$defaultMapCrs2 = themes.defaultMapCrs) !== null && _themes$defaultMapCrs2 !== void 0 ? _themes$defaultMapCrs2 : "EPSG:3857")
|
|
206
|
+
};
|
|
211
207
|
|
|
212
208
|
// Inherit defaults if necessary
|
|
213
209
|
theme = _objectSpread(_objectSpread({}, theme), {}, {
|
|
214
210
|
mapCrs: mapCrs,
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
211
|
+
bbox: (_theme$bbox = theme.bbox) !== null && _theme$bbox !== void 0 ? _theme$bbox : defaultExtent,
|
|
212
|
+
initialBbox: (_theme$initialBbox = theme.initialBbox) !== null && _theme$initialBbox !== void 0 ? _theme$initialBbox : defaultExtent,
|
|
213
|
+
version: (_ref = (_theme$version = theme.version) !== null && _theme$version !== void 0 ? _theme$version : themes.defaultWMSVersion) !== null && _ref !== void 0 ? _ref : "1.3.0",
|
|
214
|
+
scales: (_ref2 = (_theme$scales = theme.scales) !== null && _theme$scales !== void 0 ? _theme$scales : themes.defaultScales) !== null && _ref2 !== void 0 ? _ref2 : MapUtils.getGoogleMercatorScales(0, 21),
|
|
215
|
+
printScales: (_theme$printScales = theme.printScales) !== null && _theme$printScales !== void 0 ? _theme$printScales : themes.defaultPrintScales,
|
|
216
|
+
printResolutions: (_theme$printResolutio = theme.printResolutions) !== null && _theme$printResolutio !== void 0 ? _theme$printResolutio : themes.defaultPrintResolutions,
|
|
217
|
+
printGrid: (_theme$printGrid = theme.printGrid) !== null && _theme$printGrid !== void 0 ? _theme$printGrid : themes.defaultPrintGrid,
|
|
218
|
+
searchProviders: (_theme$searchProvider = theme.searchProviders) !== null && _theme$searchProvider !== void 0 ? _theme$searchProvider : themes.defaultSearchProviders,
|
|
219
|
+
backgroundLayers: (_ref3 = (_theme$backgroundLaye = theme.backgroundLayers) !== null && _theme$backgroundLaye !== void 0 ? _theme$backgroundLaye : themes.defaultBackgroundLayers) !== null && _ref3 !== void 0 ? _ref3 : [],
|
|
220
|
+
mapTips: (_theme$mapTips = theme.mapTips) !== null && _theme$mapTips !== void 0 ? _theme$mapTips : themes.defaultMapTips,
|
|
221
|
+
defaultDisplayCrs: theme.defaultDisplayCrs || themes.defaultDisplayCrs
|
|
224
222
|
});
|
|
225
223
|
|
|
226
224
|
// Preserve extent if desired and possible
|
|
@@ -307,13 +305,18 @@ export function setCurrentTheme(theme, themes) {
|
|
|
307
305
|
dispatch(showNotification("missinglayers", LocaleUtils.tr("app.missinglayers", diff.join(", ")), NotificationType.WARN, true));
|
|
308
306
|
}
|
|
309
307
|
}
|
|
310
|
-
finishThemeSetup(dispatch, newTheme, themes, layerConfigs,
|
|
308
|
+
finishThemeSetup(dispatch, newTheme, themes, layerConfigs, preserve, prevLayers, prevTheme, permalinkLayers, externalLayerRestorer, visibleBgLayer, initialTask, initialVisibilityPreset);
|
|
311
309
|
});
|
|
312
310
|
} else {
|
|
313
311
|
if (!isEmpty(missingThemeLayers)) {
|
|
314
312
|
dispatch(showNotification("missinglayers", LocaleUtils.tr("app.missinglayers", Object.keys(missingThemeLayers).join(", ")), NotificationType.WARN, true));
|
|
315
313
|
}
|
|
316
|
-
finishThemeSetup(dispatch, theme, themes, layerConfigs,
|
|
314
|
+
finishThemeSetup(dispatch, theme, themes, layerConfigs, preserve, prevLayers, prevTheme, permalinkLayers, externalLayerRestorer, visibleBgLayer, initialTask, initialVisibilityPreset);
|
|
317
315
|
}
|
|
318
316
|
};
|
|
317
|
+
}
|
|
318
|
+
export function setBlankTheme(themes) {
|
|
319
|
+
return setCurrentTheme({
|
|
320
|
+
id: ""
|
|
321
|
+
}, themes);
|
|
319
322
|
}
|
|
@@ -441,6 +441,9 @@ var AttributeForm = /*#__PURE__*/function (_React$Component) {
|
|
|
441
441
|
_defineProperty(_this, "validateForm", function (feature) {
|
|
442
442
|
var validCallback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
|
|
443
443
|
var invalidCallback = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
|
|
444
|
+
if (!_this.form) {
|
|
445
|
+
return;
|
|
446
|
+
}
|
|
444
447
|
var constraintExpressions = _this.props.editContext.editConfig.fields.reduce(function (res, cur) {
|
|
445
448
|
var _cur$constraints;
|
|
446
449
|
if ((_cur$constraints = cur.constraints) !== null && _cur$constraints !== void 0 && _cur$constraints.expression) {
|
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
2
|
+
function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
|
|
3
|
+
function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
|
|
4
|
+
function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
|
|
5
|
+
function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
|
|
6
|
+
function _possibleConstructorReturn(t, e) { if (e && ("object" == _typeof(e) || "function" == typeof e)) return e; if (void 0 !== e) throw new TypeError("Derived constructors may only return object or undefined"); return _assertThisInitialized(t); }
|
|
7
|
+
function _assertThisInitialized(e) { if (void 0 === e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); return e; }
|
|
8
|
+
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
|
|
9
|
+
function _getPrototypeOf(t) { return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function (t) { return t.__proto__ || Object.getPrototypeOf(t); }, _getPrototypeOf(t); }
|
|
10
|
+
function _inherits(t, e) { if ("function" != typeof e && null !== e) throw new TypeError("Super expression must either be null or a function"); t.prototype = Object.create(e && e.prototype, { constructor: { value: t, writable: !0, configurable: !0 } }), Object.defineProperty(t, "prototype", { writable: !1 }), e && _setPrototypeOf(t, e); }
|
|
11
|
+
function _setPrototypeOf(t, e) { return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) { return t.__proto__ = e, t; }, _setPrototypeOf(t, e); }
|
|
12
|
+
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
13
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
|
|
14
|
+
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
15
|
+
/**
|
|
16
|
+
* Copyright 2021 Oslandia SAS <infos+qwc2@oslandia.com>
|
|
17
|
+
* All rights reserved.
|
|
18
|
+
*
|
|
19
|
+
* This source code is licensed under the BSD-style license found in the
|
|
20
|
+
* LICENSE file in the root directory of this source tree.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
import React from 'react';
|
|
24
|
+
import classnames from 'classnames';
|
|
25
|
+
import isEmpty from 'lodash.isempty';
|
|
26
|
+
import PropTypes from 'prop-types';
|
|
27
|
+
import Icon from '../components/Icon';
|
|
28
|
+
import InputContainer from '../components/widgets/InputContainer';
|
|
29
|
+
import TextInput from '../components/widgets/TextInput';
|
|
30
|
+
import ConfigUtils from '../utils/ConfigUtils';
|
|
31
|
+
import LocaleUtils from '../utils/LocaleUtils';
|
|
32
|
+
import MiscUtils from '../utils/MiscUtils';
|
|
33
|
+
import './style/BookmarkPanel.css';
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Allows managing user bookmarks.
|
|
37
|
+
* or user visibility presets if `visibilityPresetsMode` is true.
|
|
38
|
+
*
|
|
39
|
+
* Bookmarks are only allowed for authenticated users.
|
|
40
|
+
*
|
|
41
|
+
* Requires `permalinkServiceUrl` to point to a `qwc-permalink-service`.
|
|
42
|
+
*/
|
|
43
|
+
var BookmarkPanel = /*#__PURE__*/function (_React$Component) {
|
|
44
|
+
function BookmarkPanel() {
|
|
45
|
+
var _this;
|
|
46
|
+
_classCallCheck(this, BookmarkPanel);
|
|
47
|
+
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
48
|
+
args[_key] = arguments[_key];
|
|
49
|
+
}
|
|
50
|
+
_this = _callSuper(this, BookmarkPanel, [].concat(args));
|
|
51
|
+
_defineProperty(_this, "state", {
|
|
52
|
+
renameBookmark: null,
|
|
53
|
+
currentBookmark: null,
|
|
54
|
+
busy: false
|
|
55
|
+
});
|
|
56
|
+
_defineProperty(_this, "bookmarkClicked", function (ev, bookmark) {
|
|
57
|
+
if (_this.state.renameBookmark) {
|
|
58
|
+
// pass
|
|
59
|
+
} else if (_this.props.openOnClick) {
|
|
60
|
+
_this.props.onOpen(bookmark.key, ev.button === 1);
|
|
61
|
+
} else if (_this.state.currentBookmark === bookmark.key) {
|
|
62
|
+
_this.setState({
|
|
63
|
+
currentBookmark: null,
|
|
64
|
+
description: ""
|
|
65
|
+
});
|
|
66
|
+
} else {
|
|
67
|
+
_this.setState({
|
|
68
|
+
currentBookmark: bookmark.key,
|
|
69
|
+
description: bookmark.description
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
_defineProperty(_this, "bookmarkDoubleClicked", function (ev, bookmark) {
|
|
74
|
+
if (!_this.state.renameBookmark) {
|
|
75
|
+
_this.props.onOpen(bookmark.key, false);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
_defineProperty(_this, "updateBookmarkName", function (text) {
|
|
79
|
+
_this.setState({
|
|
80
|
+
busy: true
|
|
81
|
+
});
|
|
82
|
+
_this.props.onRename(_this.state.renameBookmark, text, function (success) {
|
|
83
|
+
if (!success) {
|
|
84
|
+
var _this$props$translati;
|
|
85
|
+
/* eslint-disable-next-line */
|
|
86
|
+
alert((_this$props$translati = _this.props.translations) === null || _this$props$translati === void 0 ? void 0 : _this$props$translati.savefailed);
|
|
87
|
+
}
|
|
88
|
+
_this.props.onRefresh();
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
_defineProperty(_this, "addBookmark", function () {
|
|
92
|
+
var _this$props$translati2;
|
|
93
|
+
_this.setState({
|
|
94
|
+
busy: true
|
|
95
|
+
});
|
|
96
|
+
_this.props.onAdd((_this$props$translati2 = _this.props.translations) === null || _this$props$translati2 === void 0 ? void 0 : _this$props$translati2.newbookmark, function (success, key) {
|
|
97
|
+
if (!success) {
|
|
98
|
+
var _this$props$translati3;
|
|
99
|
+
/* eslint-disable-next-line */
|
|
100
|
+
alert((_this$props$translati3 = _this.props.translations) === null || _this$props$translati3 === void 0 ? void 0 : _this$props$translati3.addfailed);
|
|
101
|
+
}
|
|
102
|
+
_this.props.onRefresh();
|
|
103
|
+
});
|
|
104
|
+
_this.setState({
|
|
105
|
+
description: "",
|
|
106
|
+
currentBookmark: null
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
_defineProperty(_this, "updateBookmark", function (key) {
|
|
110
|
+
_this.setState({
|
|
111
|
+
busy: true
|
|
112
|
+
});
|
|
113
|
+
var description = _this.props.bookmarks.find(function (bk) {
|
|
114
|
+
return bk.key === key;
|
|
115
|
+
}).description;
|
|
116
|
+
_this.props.onUpdate(key, description, function (success) {
|
|
117
|
+
if (!success) {
|
|
118
|
+
var _this$props$translati4;
|
|
119
|
+
/* eslint-disable-next-line */
|
|
120
|
+
alert((_this$props$translati4 = _this.props.translations) === null || _this$props$translati4 === void 0 ? void 0 : _this$props$translati4.savefailed);
|
|
121
|
+
}
|
|
122
|
+
_this.props.onRefresh();
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
_defineProperty(_this, "removeBookmark", function (key) {
|
|
126
|
+
_this.setState({
|
|
127
|
+
busy: true
|
|
128
|
+
});
|
|
129
|
+
_this.props.onRemove(key, function (success) {
|
|
130
|
+
if (!success) {
|
|
131
|
+
var _this$props$translati5;
|
|
132
|
+
/* eslint-disable-next-line */
|
|
133
|
+
alert((_this$props$translati5 = _this.props.translations) === null || _this$props$translati5 === void 0 ? void 0 : _this$props$translati5.removefailed);
|
|
134
|
+
}
|
|
135
|
+
_this.props.onRefresh();
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
return _this;
|
|
139
|
+
}
|
|
140
|
+
_inherits(BookmarkPanel, _React$Component);
|
|
141
|
+
return _createClass(BookmarkPanel, [{
|
|
142
|
+
key: "componentDidUpdate",
|
|
143
|
+
value: function componentDidUpdate(prevProps) {
|
|
144
|
+
// Check exact identity of bookmarks array to reset busy state in all cases
|
|
145
|
+
if (prevProps.bookmarks !== this.props.bookmarks) {
|
|
146
|
+
this.setState({
|
|
147
|
+
renameBookmark: null,
|
|
148
|
+
busy: false
|
|
149
|
+
});
|
|
150
|
+
// Select a recently added bookmark
|
|
151
|
+
var addedBookmark = this.props.bookmarks.find(function (bookmark) {
|
|
152
|
+
return !prevProps.bookmarks.some(function (prevBookmark) {
|
|
153
|
+
return prevBookmark.key === bookmark.key;
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
if (addedBookmark) {
|
|
157
|
+
this.setState({
|
|
158
|
+
renameBookmark: addedBookmark.key,
|
|
159
|
+
currentBookmark: null
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}, {
|
|
165
|
+
key: "render",
|
|
166
|
+
value: function render() {
|
|
167
|
+
var _this$props$translati6,
|
|
168
|
+
_this$props$translati7,
|
|
169
|
+
_this$props$translati8,
|
|
170
|
+
_this2 = this,
|
|
171
|
+
_this$props$translati9,
|
|
172
|
+
_this$props$translati0,
|
|
173
|
+
_this$props$translati1,
|
|
174
|
+
_this$props$translati10,
|
|
175
|
+
_this$props$translati11;
|
|
176
|
+
var username = ConfigUtils.getConfigProp("username");
|
|
177
|
+
var currentBookmark = this.state.currentBookmark;
|
|
178
|
+
var buttonsDisabled = !currentBookmark || this.state.busy;
|
|
179
|
+
return !username ? /*#__PURE__*/React.createElement("div", {
|
|
180
|
+
className: "bookmark-body",
|
|
181
|
+
role: "body"
|
|
182
|
+
}, " ", (_this$props$translati6 = this.props.translations) === null || _this$props$translati6 === void 0 ? void 0 : _this$props$translati6.notloggedin) : /*#__PURE__*/React.createElement("div", {
|
|
183
|
+
className: "bookmark-body",
|
|
184
|
+
role: "body"
|
|
185
|
+
}, /*#__PURE__*/React.createElement("h4", {
|
|
186
|
+
className: "bookmark-header"
|
|
187
|
+
}, /*#__PURE__*/React.createElement("span", null, (_this$props$translati7 = this.props.translations) === null || _this$props$translati7 === void 0 ? void 0 : _this$props$translati7.manage), /*#__PURE__*/React.createElement("button", {
|
|
188
|
+
className: "button",
|
|
189
|
+
onClick: this.addBookmark,
|
|
190
|
+
title: (_this$props$translati8 = this.props.translations) === null || _this$props$translati8 === void 0 ? void 0 : _this$props$translati8.add
|
|
191
|
+
}, /*#__PURE__*/React.createElement(Icon, {
|
|
192
|
+
icon: "plus"
|
|
193
|
+
}))), !this.props.openOnClick ? /*#__PURE__*/React.createElement("div", {
|
|
194
|
+
className: "bookmark-actions controlgroup"
|
|
195
|
+
}, /*#__PURE__*/React.createElement("button", {
|
|
196
|
+
className: "button",
|
|
197
|
+
disabled: buttonsDisabled,
|
|
198
|
+
onClick: function onClick() {
|
|
199
|
+
return _this2.props.onOpen(currentBookmark, false);
|
|
200
|
+
},
|
|
201
|
+
title: (_this$props$translati9 = this.props.translations) === null || _this$props$translati9 === void 0 ? void 0 : _this$props$translati9.open
|
|
202
|
+
}, /*#__PURE__*/React.createElement(Icon, {
|
|
203
|
+
icon: "folder-open"
|
|
204
|
+
})), this.props.showOpenTab ? /*#__PURE__*/React.createElement("button", {
|
|
205
|
+
className: "button",
|
|
206
|
+
disabled: buttonsDisabled,
|
|
207
|
+
onClick: function onClick() {
|
|
208
|
+
return _this2.props.onOpen(currentBookmark, true);
|
|
209
|
+
},
|
|
210
|
+
title: (_this$props$translati0 = this.props.translations) === null || _this$props$translati0 === void 0 ? void 0 : _this$props$translati0.openTab
|
|
211
|
+
}, /*#__PURE__*/React.createElement(Icon, {
|
|
212
|
+
icon: "open_link"
|
|
213
|
+
})) : null, this.props.showZoomToExtent ? /*#__PURE__*/React.createElement("button", {
|
|
214
|
+
className: "button",
|
|
215
|
+
disabled: buttonsDisabled,
|
|
216
|
+
onClick: function onClick() {
|
|
217
|
+
return _this2.props.onZoomToExtent(currentBookmark);
|
|
218
|
+
},
|
|
219
|
+
title: (_this$props$translati1 = this.props.translations) === null || _this$props$translati1 === void 0 ? void 0 : _this$props$translati1.zoomToExtent
|
|
220
|
+
}, /*#__PURE__*/React.createElement(Icon, {
|
|
221
|
+
icon: "zoom"
|
|
222
|
+
})) : null, /*#__PURE__*/React.createElement("button", {
|
|
223
|
+
className: "button",
|
|
224
|
+
disabled: buttonsDisabled,
|
|
225
|
+
onClick: function onClick() {
|
|
226
|
+
return _this2.updateBookmark(currentBookmark);
|
|
227
|
+
},
|
|
228
|
+
title: (_this$props$translati10 = this.props.translations) === null || _this$props$translati10 === void 0 ? void 0 : _this$props$translati10.update
|
|
229
|
+
}, /*#__PURE__*/React.createElement(Icon, {
|
|
230
|
+
icon: "save"
|
|
231
|
+
}))) : null, /*#__PURE__*/React.createElement("div", {
|
|
232
|
+
className: "bookmark-list"
|
|
233
|
+
}, this.props.bookmarks.map(function (bookmark) {
|
|
234
|
+
var _this2$props$translat;
|
|
235
|
+
var itemclasses = classnames({
|
|
236
|
+
"bookmark-list-item": true,
|
|
237
|
+
"bookmark-list-item-active": currentBookmark === bookmark.key
|
|
238
|
+
});
|
|
239
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
240
|
+
className: itemclasses,
|
|
241
|
+
key: bookmark.key,
|
|
242
|
+
onAuxClick: function onAuxClick(ev) {
|
|
243
|
+
return _this2.bookmarkClicked(ev, bookmark);
|
|
244
|
+
},
|
|
245
|
+
onClick: function onClick(ev) {
|
|
246
|
+
return _this2.bookmarkClicked(ev, bookmark);
|
|
247
|
+
},
|
|
248
|
+
onDoubleClick: function onDoubleClick(ev) {
|
|
249
|
+
return _this2.bookmarkDoubleClicked(ev, bookmark);
|
|
250
|
+
},
|
|
251
|
+
title: ((_this2$props$translat = _this2.props.translations) === null || _this2$props$translat === void 0 ? void 0 : _this2$props$translat.lastUpdate) + ": " + bookmark.date
|
|
252
|
+
}, _this2.state.renameBookmark === bookmark.key ? /*#__PURE__*/React.createElement(InputContainer, null, /*#__PURE__*/React.createElement(TextInput, {
|
|
253
|
+
focusOnRef: true,
|
|
254
|
+
onChange: _this2.updateBookmarkName,
|
|
255
|
+
onNoChange: function onNoChange() {
|
|
256
|
+
return _this2.setState({
|
|
257
|
+
renameBookmark: null
|
|
258
|
+
});
|
|
259
|
+
},
|
|
260
|
+
role: "input",
|
|
261
|
+
showClear: false,
|
|
262
|
+
value: bookmark.description
|
|
263
|
+
}), /*#__PURE__*/React.createElement(Icon, {
|
|
264
|
+
icon: "ok",
|
|
265
|
+
onClick: MiscUtils.killEvent,
|
|
266
|
+
role: "suffix"
|
|
267
|
+
})) : /*#__PURE__*/React.createElement("span", null, bookmark.description), _this2.state.renameBookmark !== bookmark.key ? /*#__PURE__*/React.createElement(Icon, {
|
|
268
|
+
icon: "draw",
|
|
269
|
+
onClick: function onClick(ev) {
|
|
270
|
+
_this2.setState({
|
|
271
|
+
renameBookmark: bookmark.key,
|
|
272
|
+
currentBookmark: null
|
|
273
|
+
});
|
|
274
|
+
MiscUtils.killEvent(ev);
|
|
275
|
+
},
|
|
276
|
+
title: LocaleUtils.tr("common.rename")
|
|
277
|
+
}) : null, _this2.state.renameBookmark !== bookmark.key ? /*#__PURE__*/React.createElement(Icon, {
|
|
278
|
+
disabled: _this2.state.busy,
|
|
279
|
+
icon: "trash",
|
|
280
|
+
onClick: function onClick(ev) {
|
|
281
|
+
_this2.removeBookmark(bookmark.key);
|
|
282
|
+
MiscUtils.killEvent(ev);
|
|
283
|
+
},
|
|
284
|
+
title: LocaleUtils.tr("common.delete")
|
|
285
|
+
}) : null);
|
|
286
|
+
}), isEmpty(this.props.bookmarks) ? /*#__PURE__*/React.createElement("div", {
|
|
287
|
+
className: "bookmark-list-item-empty"
|
|
288
|
+
}, (_this$props$translati11 = this.props.translations) === null || _this$props$translati11 === void 0 ? void 0 : _this$props$translati11.nobookmarks) : null));
|
|
289
|
+
}
|
|
290
|
+
}]);
|
|
291
|
+
}(React.Component);
|
|
292
|
+
_defineProperty(BookmarkPanel, "availableIn3D", true);
|
|
293
|
+
_defineProperty(BookmarkPanel, "propTypes", {
|
|
294
|
+
bookmarks: PropTypes.array,
|
|
295
|
+
onAdd: PropTypes.func,
|
|
296
|
+
onOpen: PropTypes.func,
|
|
297
|
+
onRefresh: PropTypes.func,
|
|
298
|
+
onRemove: PropTypes.func,
|
|
299
|
+
onRename: PropTypes.func,
|
|
300
|
+
onUpdate: PropTypes.func,
|
|
301
|
+
onZoomToExtent: PropTypes.func,
|
|
302
|
+
/** Whether to directly open the bookmark on click / middle click, instead of showing dedicated open buttons. */
|
|
303
|
+
openOnClick: PropTypes.bool,
|
|
304
|
+
showOpenTab: PropTypes.bool,
|
|
305
|
+
showZoomToExtent: PropTypes.bool,
|
|
306
|
+
translations: PropTypes.objectOf(PropTypes.string)
|
|
307
|
+
});
|
|
308
|
+
_defineProperty(BookmarkPanel, "defaultProps", {
|
|
309
|
+
showOpenTab: true,
|
|
310
|
+
showZoomToExtent: false
|
|
311
|
+
});
|
|
312
|
+
export default BookmarkPanel;
|