qwc2 2026.5.27 → 2026.5.28

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.
Files changed (38) hide show
  1. package/actions/theme.js +4 -8
  2. package/components/ImportLayer.js +2 -3
  3. package/components/StandardApp.js +1 -8
  4. package/package.json +1 -1
  5. package/plugins/Bookmark.js +266 -57
  6. package/plugins/BottomBar.js +5 -49
  7. package/plugins/Portal.js +2 -2
  8. package/plugins/Settings.js +48 -27
  9. package/static/translations/bg-BG.json +1 -15
  10. package/static/translations/ca-ES.json +1 -15
  11. package/static/translations/cs-CZ.json +1 -15
  12. package/static/translations/de-CH.json +1 -15
  13. package/static/translations/de-DE.json +1 -15
  14. package/static/translations/en-US.json +1 -15
  15. package/static/translations/es-ES.json +1 -15
  16. package/static/translations/fi-FI.json +1 -15
  17. package/static/translations/fr-FR.json +1 -15
  18. package/static/translations/hu-HU.json +1 -15
  19. package/static/translations/it-IT.json +1 -15
  20. package/static/translations/ja-JP.json +1 -15
  21. package/static/translations/nl-NL.json +1 -15
  22. package/static/translations/no-NO.json +1 -15
  23. package/static/translations/pl-PL.json +1 -15
  24. package/static/translations/pt-BR.json +1 -15
  25. package/static/translations/pt-PT.json +1 -15
  26. package/static/translations/ro-RO.json +1 -15
  27. package/static/translations/ru-RU.json +1 -15
  28. package/static/translations/sv-SE.json +1 -15
  29. package/static/translations/tr-TR.json +1 -15
  30. package/static/translations/tsconfig.json +1 -13
  31. package/static/translations/uk-UA.json +1 -15
  32. package/utils/PermaLinkUtils.js +22 -31
  33. package/actions/bookmark.js +0 -40
  34. package/components/BookmarkPanel.js +0 -307
  35. package/components/widgets/GroupSelect.js +0 -94
  36. package/plugins/VisibilityPreset.js +0 -127
  37. package/reducers/bookmark.js +0 -39
  38. /package/{components/style/BookmarkPanel.css → plugins/style/Bookmark.css} +0 -0
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, setThemeLayersVisibilityPreset } from './layers';
36
+ import { LayerRole, addLayer, removeLayer, removeAllLayers, replacePlaceholderLayer, setSwipe } from './layers';
37
37
  import { configureMap } from './map';
38
38
  import { showNotification, NotificationType } from './windows';
39
39
  export var THEMES_LOADED = 'THEMES_LOADED';
@@ -51,7 +51,7 @@ export function setThemeLayersList(theme) {
51
51
  themelist: theme
52
52
  };
53
53
  }
54
- export function finishThemeSetup(dispatch, theme, themes, layerConfigs, insertPos, permalinkLayers, externalLayerRestorer, visibleBgLayer, initialTheme, initialTask, initialVisibilityPreset) {
54
+ export function finishThemeSetup(dispatch, theme, themes, layerConfigs, insertPos, permalinkLayers, externalLayerRestorer, visibleBgLayer, initialTheme, initialTask) {
55
55
  var _theme$config$section, _theme$config, _theme$config2;
56
56
  // Create layer
57
57
  var themeLayer = ThemeUtils.createThemeLayer(theme, themes);
@@ -143,9 +143,6 @@ export function finishThemeSetup(dispatch, theme, themes, layerConfigs, insertPo
143
143
  type: SET_CURRENT_THEME,
144
144
  theme: theme
145
145
  });
146
- if (initialVisibilityPreset) {
147
- dispatch(setThemeLayersVisibilityPreset(initialVisibilityPreset));
148
- }
149
146
  var section = ConfigUtils.isMobile() ? "mobile" : "desktop";
150
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) || (initialTheme ? ConfigUtils.getConfigProp("startupTask") : null);
151
148
  if (task) {
@@ -162,7 +159,6 @@ export function setCurrentTheme(theme, themes) {
162
159
  var themeLayerRestorer = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : null;
163
160
  var externalLayerRestorer = arguments.length > 8 && arguments[8] !== undefined ? arguments[8] : null;
164
161
  var initialTask = arguments.length > 9 && arguments[9] !== undefined ? arguments[9] : null;
165
- var initialVisibilityPreset = arguments.length > 10 && arguments[10] !== undefined ? arguments[10] : null;
166
162
  return function (dispatch, getState) {
167
163
  var _getState$layers, _ref, _theme$mapTips;
168
164
  var curLayers = ((_getState$layers = getState().layers) === null || _getState$layers === void 0 ? void 0 : _getState$layers.flat) || [];
@@ -311,13 +307,13 @@ export function setCurrentTheme(theme, themes) {
311
307
  dispatch(showNotification("missinglayers", LocaleUtils.tr("app.missinglayers", diff.join(", ")), NotificationType.WARN, true));
312
308
  }
313
309
  }
314
- finishThemeSetup(dispatch, newTheme, themes, layerConfigs, insertPos, permalinkLayers, externalLayerRestorer, visibleBgLayer, initialTheme, initialTask, initialVisibilityPreset);
310
+ finishThemeSetup(dispatch, newTheme, themes, layerConfigs, insertPos, permalinkLayers, externalLayerRestorer, visibleBgLayer, initialTheme, initialTask);
315
311
  });
316
312
  } else {
317
313
  if (!isEmpty(missingThemeLayers)) {
318
314
  dispatch(showNotification("missinglayers", LocaleUtils.tr("app.missinglayers", Object.keys(missingThemeLayers).join(", ")), NotificationType.WARN, true));
319
315
  }
320
- finishThemeSetup(dispatch, theme, themes, layerConfigs, insertPos, permalinkLayers, externalLayerRestorer, visibleBgLayer, initialTheme, initialTask, initialVisibilityPreset);
316
+ finishThemeSetup(dispatch, theme, themes, layerConfigs, insertPos, permalinkLayers, externalLayerRestorer, visibleBgLayer, initialTheme, initialTask);
321
317
  }
322
318
  };
323
319
  }
@@ -38,7 +38,6 @@ import React from 'react';
38
38
  import { connect } from 'react-redux';
39
39
  import axios from 'axios';
40
40
  import isEmpty from 'lodash.isempty';
41
- import { WorkerMessageHandler } from "pdfjs-dist/build/pdf.worker";
42
41
  import Proj4js from 'proj4';
43
42
  import PropTypes from 'prop-types';
44
43
  import { addLayer, addLayerFeatures } from '../actions/layers';
@@ -439,8 +438,8 @@ var ImportLayer = /*#__PURE__*/function (_React$Component) {
439
438
  var tr = computeCorner(idxTR);
440
439
  var geoextent = [bl.coo[0], bl.coo[1], tr.coo[0], tr.coo[1]];
441
440
  var imgextent = [bl.pixel[0], bl.pixel[1], tr.pixel[0], tr.pixel[1]];
442
- import('pdfjs-dist/build/pdf').then(function (pdfjsLib) {
443
- pdfjsLib.GlobalWorkerOptions.workerSrc = WorkerMessageHandler;
441
+ import('pdfjs-dist').then(function (pdfjsLib) {
442
+ pdfjsLib.GlobalWorkerOptions.workerSrc = new URL('pdfjs-dist/build/pdf.worker.min.mjs', import.meta.url).toString();
444
443
  pdfjsLib.getDocument(ev.target.result).promise.then(function (pdf) {
445
444
  pdf.getPage(1).then(function (page) {
446
445
  var pageViewport = page.getViewport({
@@ -40,7 +40,6 @@ import deepmerge from 'deepmerge';
40
40
  import { register as olProj4Register } from 'ol/proj/proj4';
41
41
  import Proj4js from 'proj4';
42
42
  import PropTypes from 'prop-types';
43
- import { refreshBookmarks, refreshVisibilityPresets } from '../actions/bookmark';
44
43
  import { localConfigLoaded, setStartupParameters, setColorScheme } from '../actions/localConfig';
45
44
  import { changeLocale } from '../actions/locale';
46
45
  import { setCurrentTask } from '../actions/task';
@@ -164,7 +163,7 @@ var AppContainerComponent = /*#__PURE__*/function (_React$Component) {
164
163
  layerParams.reverse();
165
164
  }
166
165
  var initialTaskParam = params.task ? JSON.parse(decodeURIComponent(params.task)) : null;
167
- _this.props.setCurrentTheme(theme, themes, false, initialExtent, layerParams, (_params$bl = params.bl) !== null && _params$bl !== void 0 ? _params$bl : null, state.layers, _this.props.appConfig.themeLayerRestorer, _this.props.appConfig.externalLayerRestorer, initialTaskParam, state.visibilityPreset);
166
+ _this.props.setCurrentTheme(theme, themes, false, initialExtent, layerParams, (_params$bl = params.bl) !== null && _params$bl !== void 0 ? _params$bl : null, state.layers, _this.props.appConfig.themeLayerRestorer, _this.props.appConfig.externalLayerRestorer, initialTaskParam);
168
167
  } else if (!ConfigUtils.havePlugin("Portal")) {
169
168
  _this.props.showNotification("missingdefaulttheme", LocaleUtils.tr("app.missingdefaulttheme", params.t), NotificationType.WARN, true);
170
169
  }
@@ -205,7 +204,6 @@ var AppContainerComponent = /*#__PURE__*/function (_React$Component) {
205
204
  }(React.Component);
206
205
  _defineProperty(AppContainerComponent, "propTypes", {
207
206
  appConfig: PropTypes.object,
208
- currentTheme: PropTypes.object,
209
207
  defaultUrlParams: PropTypes.string,
210
208
  haveMapSize: PropTypes.bool,
211
209
  localConfig: PropTypes.object,
@@ -213,7 +211,6 @@ _defineProperty(AppContainerComponent, "propTypes", {
213
211
  setBottombarHeight: PropTypes.func,
214
212
  setCurrentTask: PropTypes.func,
215
213
  setCurrentTheme: PropTypes.func,
216
- setThemeLayersVisibilityPreset: PropTypes.func,
217
214
  setTopbarHeight: PropTypes.func,
218
215
  showNotification: PropTypes.func,
219
216
  startupConfig: PropTypes.object,
@@ -334,10 +331,6 @@ var StandardApp = /*#__PURE__*/function (_React$Component2) {
334
331
  var colorScheme = initialParams.style || storedColorScheme || ConfigUtils.getConfigProp("defaultColorScheme");
335
332
  StandardApp.store.dispatch(setColorScheme(colorScheme));
336
333
 
337
- // Load all bookmarks & visiblity presets
338
- StandardApp.store.dispatch(refreshBookmarks());
339
- StandardApp.store.dispatch(refreshVisibilityPresets());
340
-
341
334
  // Resolve permalink and restore settings
342
335
  resolvePermaLink(initialParams, function (params, state, success) {
343
336
  StandardApp.store.dispatch(setStartupParameters(params, state));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qwc2",
3
- "version": "2026.05.27",
3
+ "version": "2026.05.28",
4
4
  "description": "QGIS Web Client",
5
5
  "author": "Sourcepole AG",
6
6
  "license": "BSD-2-Clause",
@@ -12,23 +12,37 @@ function _setPrototypeOf(t, e) { return _setPrototypeOf = Object.setPrototypeOf
12
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
13
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
14
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
+
15
23
  import React from 'react';
16
24
  import { connect } from 'react-redux';
25
+ import classnames from 'classnames';
26
+ import isEmpty from 'lodash.isempty';
17
27
  import PropTypes from 'prop-types';
18
- import { refreshBookmarks } from '../actions/bookmark';
19
- import { zoomToExtent, zoomToPoint } from "../actions/map";
20
- import BookmarkPanel from '../components/BookmarkPanel';
28
+ import { zoomToExtent, zoomToPoint } from '../actions/map';
29
+ import Icon from '../components/Icon';
21
30
  import SideBar from '../components/SideBar';
22
- import LocaleUtils from "../utils/LocaleUtils";
23
- import MapUtils from "../utils/MapUtils";
24
- import { createBookmark, removeBookmark, renameBookmark, resolveBookmark, updateBookmark } from '../utils/PermaLinkUtils';
31
+ import InputContainer from '../components/widgets/InputContainer';
32
+ import TextInput from '../components/widgets/TextInput';
33
+ import ConfigUtils from '../utils/ConfigUtils';
34
+ import LocaleUtils from '../utils/LocaleUtils';
35
+ import MapUtils from '../utils/MapUtils';
36
+ import MiscUtils from '../utils/MiscUtils';
37
+ import { createBookmark, getBookmarks, removeBookmark, renameBookmark, resolveBookmark, updateBookmark } from '../utils/PermaLinkUtils';
38
+ import './style/Bookmark.css';
25
39
 
26
- /**
27
- * Allows managing user bookmarks which are storing the current view, including the location and zoom level.
28
- *
29
- * Bookmarks are only allowed for authenticated users.
30
- *
31
- * Requires `permalinkServiceUrl` to point to a `qwc-permalink-service`.
40
+ /**
41
+ * Allows managing user bookmarks.
42
+ *
43
+ * Bookmarks are only allowed for authenticated users.
44
+ *
45
+ * Requires `permalinkServiceUrl` to point to a `qwc-permalink-service`.
32
46
  */
33
47
  var Bookmark = /*#__PURE__*/function (_React$Component) {
34
48
  function Bookmark() {
@@ -38,46 +52,57 @@ var Bookmark = /*#__PURE__*/function (_React$Component) {
38
52
  args[_key] = arguments[_key];
39
53
  }
40
54
  _this = _callSuper(this, Bookmark, [].concat(args));
41
- _defineProperty(_this, "translations", {
42
- add: LocaleUtils.tr("bookmark.add"),
43
- addfailed: LocaleUtils.tr("bookmark.addfailed"),
44
- lastUpdate: LocaleUtils.tr("bookmark.lastUpdate"),
45
- manage: LocaleUtils.tr("bookmark.manage"),
46
- newbookmark: LocaleUtils.tr("bookmark.newbookmark"),
47
- nobookmarks: LocaleUtils.tr("bookmark.nobookmarks"),
48
- notloggedin: LocaleUtils.tr("bookmark.notloggedin"),
49
- open: LocaleUtils.tr("bookmark.open"),
50
- openTab: LocaleUtils.tr("bookmark.openTab"),
51
- update: LocaleUtils.tr("bookmark.update"),
52
- zoomToExtent: LocaleUtils.tr("bookmark.zoomToExtent"),
53
- removefailed: LocaleUtils.tr("bookmark.removefailed"),
54
- savefailed: LocaleUtils.tr("bookmark.savefailed")
55
+ _defineProperty(_this, "state", {
56
+ bookmarks: [],
57
+ renameBookmark: null,
58
+ currentBookmark: null,
59
+ description: "",
60
+ busy: false
61
+ });
62
+ _defineProperty(_this, "bookmarkClicked", function (ev, bookmark) {
63
+ if (_this.state.renameBookmark) {
64
+ // pass
65
+ } else if (_this.props.openOnClick) {
66
+ _this.open(bookmark.key, ev.button === 1);
67
+ } else if (_this.state.currentBookmark === bookmark.key) {
68
+ _this.setState({
69
+ currentBookmark: null,
70
+ description: ""
71
+ });
72
+ } else {
73
+ _this.setState({
74
+ currentBookmark: bookmark.key,
75
+ description: bookmark.description
76
+ });
77
+ }
55
78
  });
56
- _defineProperty(_this, "renderBody", function () {
57
- return /*#__PURE__*/React.createElement(BookmarkPanel, {
58
- bookmarks: _this.props.bookmarks,
59
- onAdd: createBookmark,
60
- onOpen: _this.onOpen,
61
- onRefresh: _this.props.refreshBookmarks,
62
- onRemove: removeBookmark,
63
- onRename: renameBookmark,
64
- onUpdate: updateBookmark,
65
- onZoomToExtent: _this.zoomToBookmarkExtent,
66
- openOnClick: _this.props.openOnClick,
67
- showZoomToExtent: _this.props.mapCrs && _this.props.mapScales,
68
- translations: _this.translations
79
+ _defineProperty(_this, "updateBookmarkName", function (text) {
80
+ _this.setState({
81
+ busy: true
82
+ });
83
+ renameBookmark(_this.state.renameBookmark, text, function (success) {
84
+ if (!success) {
85
+ /* eslint-disable-next-line */
86
+ alert(LocaleUtils.tr("bookmark.savefailed"));
87
+ }
88
+ _this.refresh(function () {
89
+ return _this.setState({
90
+ renameBookmark: null,
91
+ busy: false
92
+ });
93
+ });
69
94
  });
70
95
  });
71
- _defineProperty(_this, "onOpen", function (key, newtab) {
72
- var url = location.href.split("?")[0] + '?bk=' + key;
96
+ _defineProperty(_this, "open", function (bookmarkkey, newtab) {
97
+ var url = location.href.split("?")[0] + '?bk=' + bookmarkkey;
73
98
  if (newtab) {
74
99
  window.open(url, '_blank');
75
100
  } else {
76
101
  location.href = url;
77
102
  }
78
103
  });
79
- _defineProperty(_this, "zoomToBookmarkExtent", function (key) {
80
- resolveBookmark(key, function (params) {
104
+ _defineProperty(_this, "zoomToBookmarkExtent", function (bookmarkkey) {
105
+ resolveBookmark(bookmarkkey, function (params) {
81
106
  if ('c' in params && 's' in params) {
82
107
  var _params$crs;
83
108
  var scale = parseFloat(params.s);
@@ -95,53 +120,237 @@ var Bookmark = /*#__PURE__*/function (_React$Component) {
95
120
  }
96
121
  });
97
122
  });
123
+ _defineProperty(_this, "addBookmark", function () {
124
+ _this.setState({
125
+ busy: true
126
+ });
127
+ createBookmark(LocaleUtils.tr("bookmark.newbookmark"), function (success, key) {
128
+ if (!success) {
129
+ /* eslint-disable-next-line */
130
+ alert(LocaleUtils.tr("bookmark.addfailed"));
131
+ } else {
132
+ _this.refresh(function () {
133
+ return _this.setState({
134
+ renameBookmark: key,
135
+ busy: false
136
+ });
137
+ });
138
+ }
139
+ });
140
+ _this.setState({
141
+ description: "",
142
+ currentBookmark: null
143
+ });
144
+ });
145
+ _defineProperty(_this, "updateBookmark", function (key) {
146
+ _this.setState({
147
+ busy: true
148
+ });
149
+ var description = _this.state.bookmarks.find(function (bk) {
150
+ return bk.key === key;
151
+ }).description;
152
+ updateBookmark(key, description, function (success) {
153
+ if (!success) {
154
+ /* eslint-disable-next-line */
155
+ alert(LocaleUtils.tr("bookmark.savefailed"));
156
+ }
157
+ _this.refresh(function () {
158
+ return _this.setState({
159
+ busy: false,
160
+ currentBookmark: null
161
+ });
162
+ });
163
+ });
164
+ });
165
+ _defineProperty(_this, "removeBookmark", function (key) {
166
+ _this.setState({
167
+ busy: true
168
+ });
169
+ removeBookmark(key, function (success) {
170
+ if (!success) {
171
+ /* eslint-disable-next-line */
172
+ alert(LocaleUtils.tr("bookmark.removefailed"));
173
+ }
174
+ _this.refresh(function () {
175
+ return _this.setState({
176
+ busy: false
177
+ });
178
+ });
179
+ });
180
+ });
181
+ _defineProperty(_this, "refresh", function () {
182
+ var callback = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
183
+ if (ConfigUtils.getConfigProp("username")) {
184
+ getBookmarks(function (bookmarks) {
185
+ _this.setState({
186
+ bookmarks: bookmarks
187
+ });
188
+ callback === null || callback === void 0 || callback(bookmarks);
189
+ });
190
+ }
191
+ });
98
192
  return _this;
99
193
  }
100
194
  _inherits(Bookmark, _React$Component);
101
195
  return _createClass(Bookmark, [{
196
+ key: "componentDidMount",
197
+ value: function componentDidMount() {
198
+ this.refresh();
199
+ }
200
+ }, {
102
201
  key: "render",
103
202
  value: function render() {
104
203
  var _this2 = this;
204
+ var openTitle = LocaleUtils.tr("bookmark.open");
205
+ var openTabTitle = LocaleUtils.tr("bookmark.openTab");
206
+ var zoomTitle = LocaleUtils.tr("bookmark.zoomToExtent");
207
+ var username = ConfigUtils.getConfigProp("username");
208
+ var updateTitle = LocaleUtils.tr("bookmark.update");
209
+ var lastUpdateTitle = LocaleUtils.tr("bookmark.lastUpdate");
210
+ var currentBookmark = this.state.currentBookmark;
211
+ var buttonsDisabled = !currentBookmark || this.state.busy;
105
212
  return /*#__PURE__*/React.createElement(SideBar, {
106
213
  icon: "bookmark",
107
214
  id: "Bookmark",
215
+ onShow: this.refresh,
108
216
  side: this.props.side,
109
217
  title: LocaleUtils.tr("appmenu.items.Bookmark"),
110
218
  width: "20em"
111
- }, function () {
112
- return {
113
- body: _this2.renderBody()
114
- };
115
- });
219
+ }, !username ? /*#__PURE__*/React.createElement("div", {
220
+ className: "bookmark-body",
221
+ role: "body"
222
+ }, LocaleUtils.tr("bookmark.notloggedin")) : /*#__PURE__*/React.createElement("div", {
223
+ className: "bookmark-body",
224
+ role: "body"
225
+ }, /*#__PURE__*/React.createElement("h4", {
226
+ className: "bookmark-header"
227
+ }, /*#__PURE__*/React.createElement("span", null, LocaleUtils.tr("bookmark.manage")), /*#__PURE__*/React.createElement("button", {
228
+ className: "button",
229
+ onClick: this.addBookmark,
230
+ title: LocaleUtils.tr("bookmark.add")
231
+ }, /*#__PURE__*/React.createElement(Icon, {
232
+ icon: "plus"
233
+ }))), !this.props.openOnClick ? /*#__PURE__*/React.createElement("div", {
234
+ className: "bookmark-actions controlgroup"
235
+ }, /*#__PURE__*/React.createElement("button", {
236
+ className: "button",
237
+ disabled: buttonsDisabled,
238
+ onClick: function onClick() {
239
+ return _this2.open(currentBookmark, false);
240
+ },
241
+ title: openTitle
242
+ }, /*#__PURE__*/React.createElement(Icon, {
243
+ icon: "folder-open"
244
+ })), /*#__PURE__*/React.createElement("button", {
245
+ className: "button",
246
+ disabled: buttonsDisabled,
247
+ onClick: function onClick() {
248
+ return _this2.open(currentBookmark, true);
249
+ },
250
+ title: openTabTitle
251
+ }, /*#__PURE__*/React.createElement(Icon, {
252
+ icon: "open_link"
253
+ })), this.props.mapCrs && this.props.mapScales ? /*#__PURE__*/React.createElement("button", {
254
+ className: "button",
255
+ disabled: buttonsDisabled,
256
+ onClick: function onClick() {
257
+ return _this2.zoomToBookmarkExtent(currentBookmark);
258
+ },
259
+ title: zoomTitle
260
+ }, /*#__PURE__*/React.createElement(Icon, {
261
+ icon: "zoom"
262
+ })) : null, /*#__PURE__*/React.createElement("button", {
263
+ className: "button",
264
+ disabled: buttonsDisabled,
265
+ onClick: function onClick() {
266
+ return _this2.updateBookmark(currentBookmark);
267
+ },
268
+ title: updateTitle
269
+ }, /*#__PURE__*/React.createElement(Icon, {
270
+ icon: "save"
271
+ }))) : null, /*#__PURE__*/React.createElement("div", {
272
+ className: "bookmark-list"
273
+ }, this.state.bookmarks.map(function (bookmark) {
274
+ var itemclasses = classnames({
275
+ "bookmark-list-item": true,
276
+ "bookmark-list-item-active": currentBookmark === bookmark.key
277
+ });
278
+ return /*#__PURE__*/React.createElement("div", {
279
+ className: itemclasses,
280
+ key: bookmark.key,
281
+ onAuxClick: function onAuxClick(ev) {
282
+ return _this2.bookmarkClicked(ev, bookmark);
283
+ },
284
+ onClick: function onClick(ev) {
285
+ return _this2.bookmarkClicked(ev, bookmark);
286
+ },
287
+ onDoubleClick: function onDoubleClick() {
288
+ return _this2.open(bookmark.key, false);
289
+ },
290
+ title: lastUpdateTitle + ": " + bookmark.date
291
+ }, _this2.state.renameBookmark === bookmark.key ? /*#__PURE__*/React.createElement(InputContainer, null, /*#__PURE__*/React.createElement(TextInput, {
292
+ focusOnRef: true,
293
+ onChange: _this2.updateBookmarkName,
294
+ onNoChange: function onNoChange() {
295
+ return _this2.setState({
296
+ renameBookmark: null
297
+ });
298
+ },
299
+ role: "input",
300
+ showClear: false,
301
+ value: bookmark.description
302
+ }), /*#__PURE__*/React.createElement(Icon, {
303
+ icon: "ok",
304
+ onClick: MiscUtils.killEvent,
305
+ role: "suffix"
306
+ })) : /*#__PURE__*/React.createElement("span", null, bookmark.description), _this2.state.renameBookmark !== bookmark.key ? /*#__PURE__*/React.createElement(Icon, {
307
+ icon: "draw",
308
+ onClick: function onClick(ev) {
309
+ _this2.setState({
310
+ renameBookmark: bookmark.key,
311
+ currentBookmark: null
312
+ });
313
+ MiscUtils.killEvent(ev);
314
+ },
315
+ title: LocaleUtils.tr("common.rename")
316
+ }) : null, _this2.state.renameBookmark !== bookmark.key ? /*#__PURE__*/React.createElement(Icon, {
317
+ disabled: _this2.state.busy,
318
+ icon: "trash",
319
+ onClick: function onClick(ev) {
320
+ _this2.removeBookmark(bookmark.key);
321
+ MiscUtils.killEvent(ev);
322
+ },
323
+ title: LocaleUtils.tr("common.delete")
324
+ }) : null);
325
+ }), isEmpty(this.state.bookmarks) ? /*#__PURE__*/React.createElement("div", {
326
+ className: "bookmark-list-item-empty"
327
+ }, LocaleUtils.tr("bookmark.nobookmarks")) : null)));
116
328
  }
117
329
  }]);
118
330
  }(React.Component);
119
331
  _defineProperty(Bookmark, "availableIn3D", true);
120
332
  _defineProperty(Bookmark, "propTypes", {
121
- bookmarks: PropTypes.array,
122
333
  mapCrs: PropTypes.string,
123
334
  mapScales: PropTypes.array,
124
335
  /** Whether to directly open the bookmark on click / middle click, instead of showing dedicated open buttons. */
125
336
  openOnClick: PropTypes.bool,
126
- refreshBookmarks: PropTypes.func,
127
337
  /** The side of the application on which to display the sidebar. */
128
338
  side: PropTypes.string,
339
+ theme: PropTypes.object,
129
340
  zoomToExtent: PropTypes.func,
130
341
  zoomToPoint: PropTypes.func
131
342
  });
132
343
  _defineProperty(Bookmark, "defaultProps", {
133
344
  side: 'right'
134
345
  });
135
- var selector = function selector(state) {
136
- var _state$bookmark, _state$map, _state$map2;
346
+ export default connect(function (state) {
347
+ var _state$map, _state$map2;
137
348
  return {
138
- bookmarks: (_state$bookmark = state.bookmark) === null || _state$bookmark === void 0 ? void 0 : _state$bookmark.bookmarks,
139
349
  mapCrs: (_state$map = state.map) === null || _state$map === void 0 ? void 0 : _state$map.projection,
140
- mapScales: (_state$map2 = state.map) === null || _state$map2 === void 0 ? void 0 : _state$map2.scales
350
+ mapScales: (_state$map2 = state.map) === null || _state$map2 === void 0 ? void 0 : _state$map2.scales,
351
+ theme: state.theme.current
141
352
  };
142
- };
143
- export default connect(selector, {
144
- refreshBookmarks: refreshBookmarks,
353
+ }, {
145
354
  zoomToExtent: zoomToExtent,
146
355
  zoomToPoint: zoomToPoint
147
356
  })(Bookmark);
@@ -36,17 +36,14 @@ import React from 'react';
36
36
  import { connect } from 'react-redux';
37
37
  import ol from 'openlayers';
38
38
  import PropTypes from 'prop-types';
39
- import { setThemeLayersVisibilityPreset } from '../actions/layers';
40
39
  import { changeZoomLevel, setDisplayCrs } from '../actions/map';
41
40
  import { openExternalUrl, setBottombarHeight } from '../actions/windows';
42
41
  import CoordinateDisplayer from '../components/CoordinateDisplayer';
43
- import GroupSelect from '../components/widgets/GroupSelect';
44
42
  import InputContainer from '../components/widgets/InputContainer';
45
43
  import NumberInput from '../components/widgets/NumberInput';
46
44
  import CoordinatesUtils from '../utils/CoordinatesUtils';
47
45
  import LocaleUtils from '../utils/LocaleUtils';
48
46
  import MapUtils from '../utils/MapUtils';
49
- import { resolveVisibilityPreset } from "../utils/PermaLinkUtils";
50
47
  import './style/BottomBar.css';
51
48
 
52
49
  /**
@@ -94,22 +91,6 @@ var BottomBar = /*#__PURE__*/function (_React$Component) {
94
91
  });
95
92
  ev.preventDefault();
96
93
  });
97
- _defineProperty(_this, "openBookmarkOrPreset", function (prefixedKey) {
98
- if (prefixedKey.startsWith("vp:")) {
99
- var key = prefixedKey.slice("vp:".length);
100
- resolveVisibilityPreset(key, function (preset) {
101
- if (preset) {
102
- _this.props.setThemeLayersVisibilityPreset(preset);
103
- }
104
- });
105
- } else if (prefixedKey.startsWith("bk:")) {
106
- var _key2 = prefixedKey.slice("bk:".length);
107
- location.href = location.href.split("?")[0] + '?bk=' + _key2;
108
- } else {
109
- /* eslint-disable-next-line */
110
- console.warn("openBookmarkOrPreset: unexpected key format:", prefixedKey);
111
- }
112
- });
113
94
  _defineProperty(_this, "setScale", function (value) {
114
95
  var scale = parseInt(value, 10);
115
96
  if (!isNaN(scale)) {
@@ -176,6 +157,7 @@ var BottomBar = /*#__PURE__*/function (_React$Component) {
176
157
  rightBottomLinks.push(this.renderLink(_entry));
177
158
  }
178
159
  var enabledMouseCrs = [].concat(_toConsumableArray(this.props.additionalMouseCrs || []), [this.props.map.projection, "EPSG:4326"]);
160
+ // eslint-disable-next-line no-unused-vars
179
161
  var availableCRS = Object.fromEntries(Object.entries(CoordinatesUtils.getAvailableCRS()).filter(function (_ref) {
180
162
  var _ref2 = _slicedToArray(_ref, 2),
181
163
  key = _ref2[0],
@@ -240,23 +222,6 @@ var BottomBar = /*#__PURE__*/function (_React$Component) {
240
222
  value: this.state.scale
241
223
  })));
242
224
  }
243
- var quickSelectDropdown = null;
244
- if (this.props.displayQuickSelectDropdown && (this.props.bookmarks && this.props.bookmarks.length > 0 || this.props.visibilityPresets && this.props.visibilityPresets.length > 0)) {
245
- var bookmarks = this.props.bookmarks || [];
246
- var visibilityPresets = this.props.visibilityPresets || [];
247
- var options = _defineProperty(_defineProperty({}, LocaleUtils.tr("appmenu.items.Bookmark"), bookmarks.map(function (bm) {
248
- return ["bk:" + bm.key, bm.description];
249
- })), LocaleUtils.tr("appmenu.items.VisibilityPresets"), visibilityPresets.map(function (bm) {
250
- return ["vp:" + bm.key, bm.description];
251
- }));
252
- quickSelectDropdown = /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("span", {
253
- className: "bottombar-quick-select-label"
254
- }, LocaleUtils.tr("bottombar.quick_select_label"), ":\xA0"), /*#__PURE__*/React.createElement(GroupSelect, {
255
- onChange: this.openBookmarkOrPreset,
256
- options: options,
257
- placeholder: LocaleUtils.tr("bottombar.select")
258
- }));
259
- }
260
225
  var style = {
261
226
  marginLeft: this.props.mapMargins.outerLeft + 'px',
262
227
  marginRight: this.props.mapMargins.outerRight + 'px'
@@ -269,7 +234,7 @@ var BottomBar = /*#__PURE__*/function (_React$Component) {
269
234
  className: "bottombar-links"
270
235
  }, leftBottomLinks), /*#__PURE__*/React.createElement("span", {
271
236
  className: "bottombar-spacer"
272
- }), coordinates, scales, quickSelectDropdown, /*#__PURE__*/React.createElement("span", {
237
+ }), coordinates, scales, /*#__PURE__*/React.createElement("span", {
273
238
  className: "bottombar-spacer"
274
239
  }), /*#__PURE__*/React.createElement("span", {
275
240
  className: "bottombar-links"
@@ -288,14 +253,11 @@ _defineProperty(BottomBar, "propTypes", {
288
253
  icon: PropTypes.string
289
254
  })),
290
255
  additionalMouseCrs: PropTypes.array,
291
- bookmarks: PropTypes.array,
292
256
  changeZoomLevel: PropTypes.func,
293
257
  /** Custom coordinate formatter, as `(coordinate, crs) => string`. */
294
258
  coordinateFormatter: PropTypes.func,
295
259
  /** Whether to display the coordinates in the bottom bar. */
296
260
  displayCoordinates: PropTypes.bool,
297
- /** Whether to display a dropdown menu for the selection of user bookmarks and visibility presets in the bottom bar. */
298
- displayQuickSelectDropdown: PropTypes.bool,
299
261
  /** Whether to display the scalebar in the bottom bar. */
300
262
  displayScalebar: PropTypes.bool,
301
263
  /** Whether to display the scale in the bottom bar. */
@@ -308,7 +270,6 @@ _defineProperty(BottomBar, "propTypes", {
308
270
  scalebarOptions: PropTypes.object,
309
271
  setBottombarHeight: PropTypes.func,
310
272
  setDisplayCrs: PropTypes.func,
311
- setThemeLayersVisibilityPreset: PropTypes.func,
312
273
  /** The URL of the terms label anchor. */
313
274
  termsUrl: PropTypes.string,
314
275
  /** Icon of the terms inline window. Relevant only when `termsUrlTarget` is `iframe`. */
@@ -320,21 +281,17 @@ _defineProperty(BottomBar, "propTypes", {
320
281
  /** Icon of the viewer title inline window. Relevant only when `viewertitleUrl` is `iframe`. */
321
282
  viewertitleUrlIcon: PropTypes.string,
322
283
  /** The target where to open the viewer title URL. If `iframe`, it will be displayed in an inline window, otherwise in a new tab. You can also use the `:iframedialog:<dialogname>:<options>` syntax to set up the inline window. */
323
- viewertitleUrlTarget: PropTypes.string,
324
- visibilityPresets: PropTypes.array
284
+ viewertitleUrlTarget: PropTypes.string
325
285
  });
326
286
  _defineProperty(BottomBar, "defaultProps", {
327
287
  displayCoordinates: true,
328
- displayQuickSelectDropdown: false,
329
288
  displayScalebar: true,
330
289
  displayScales: true
331
290
  });
332
291
  export default connect(function (state) {
333
- var _state$bookmark, _state$bookmark2, _state$display, _state$theme$current$, _state$theme$current;
292
+ var _state$display, _state$theme$current$, _state$theme$current;
334
293
  return {
335
294
  map: state.map,
336
- bookmarks: (_state$bookmark = state.bookmark) === null || _state$bookmark === void 0 ? void 0 : _state$bookmark.bookmarks,
337
- visibilityPresets: (_state$bookmark2 = state.bookmark) === null || _state$bookmark2 === void 0 ? void 0 : _state$bookmark2.visibilityPresets,
338
295
  fullscreen: (_state$display = state.display) === null || _state$display === void 0 ? void 0 : _state$display.fullscreen,
339
296
  mapMargins: state.windows.mapMargins,
340
297
  additionalMouseCrs: (_state$theme$current$ = (_state$theme$current = state.theme.current) === null || _state$theme$current === void 0 ? void 0 : _state$theme$current.additionalMouseCrs) !== null && _state$theme$current$ !== void 0 ? _state$theme$current$ : []
@@ -343,6 +300,5 @@ export default connect(function (state) {
343
300
  changeZoomLevel: changeZoomLevel,
344
301
  openExternalUrl: openExternalUrl,
345
302
  setBottombarHeight: setBottombarHeight,
346
- setDisplayCrs: setDisplayCrs,
347
- setThemeLayersVisibilityPreset: setThemeLayersVisibilityPreset
303
+ setDisplayCrs: setDisplayCrs
348
304
  })(BottomBar);