qwc2 2025.10.16 → 2025.10.24

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 (62) hide show
  1. package/actions/locate.js +3 -2
  2. package/components/AttributeTableWidget.js +24 -15
  3. package/components/FeatureAttributesWindow.js +177 -0
  4. package/components/IdentifyViewer.js +80 -39
  5. package/components/LocationRecorder.js +138 -0
  6. package/components/PickFeature.js +87 -26
  7. package/components/PluginsContainer.js +16 -3
  8. package/components/map/OlLayer.js +2 -1
  9. package/components/map3d/HeightProfile3D.js +2 -0
  10. package/components/style/App.css +14 -0
  11. package/components/style/AttributeTableWidget.css +1 -1
  12. package/components/style/FeatureAttributesWindow.css +16 -0
  13. package/components/style/IdentifyViewer.css +5 -0
  14. package/components/style/LocationRecorder.css +10 -0
  15. package/components/style/NumericInputWindow.css +7 -0
  16. package/components/style/PluginsContainer.css +16 -0
  17. package/components/widgets/LayerCatalogWidget.js +40 -16
  18. package/components/widgets/NavBar.js +10 -3
  19. package/icons/circle_full.svg +75 -0
  20. package/package.json +1 -1
  21. package/plugins/AttributeTable.js +4 -0
  22. package/plugins/GeometryDigitizer.js +3 -0
  23. package/plugins/HeightProfile.js +2 -0
  24. package/plugins/Identify.js +7 -3
  25. package/plugins/ObjectList.js +116 -0
  26. package/plugins/Redlining.js +14 -55
  27. package/plugins/map/EditingSupport.js +22 -1
  28. package/plugins/map/LocateSupport.js +8 -1
  29. package/plugins/map/RedliningSupport.js +108 -18
  30. package/plugins/map/SnappingSupport.js +11 -6
  31. package/plugins/map/style/SnappingSupport.css +2 -13
  32. package/reducers/locate.js +4 -2
  33. package/reducers/redlining.js +2 -1
  34. package/static/translations/bg-BG.json +13 -0
  35. package/static/translations/ca-ES.json +13 -0
  36. package/static/translations/cs-CZ.json +13 -0
  37. package/static/translations/de-CH.json +13 -0
  38. package/static/translations/de-DE.json +14 -1
  39. package/static/translations/en-US.json +13 -0
  40. package/static/translations/es-ES.json +13 -0
  41. package/static/translations/fi-FI.json +13 -0
  42. package/static/translations/fr-FR.json +13 -0
  43. package/static/translations/hu-HU.json +13 -0
  44. package/static/translations/it-IT.json +13 -0
  45. package/static/translations/ja-JP.json +13 -0
  46. package/static/translations/nl-NL.json +13 -0
  47. package/static/translations/no-NO.json +13 -0
  48. package/static/translations/pl-PL.json +13 -0
  49. package/static/translations/pt-BR.json +13 -0
  50. package/static/translations/pt-PT.json +13 -0
  51. package/static/translations/ro-RO.json +13 -0
  52. package/static/translations/ru-RU.json +13 -0
  53. package/static/translations/sv-SE.json +13 -0
  54. package/static/translations/tr-TR.json +13 -0
  55. package/static/translations/tsconfig.json +10 -0
  56. package/static/translations/uk-UA.json +13 -0
  57. package/utils/EditingInterface.js +4 -1
  58. package/utils/EditingUtils.js +3 -1
  59. package/utils/MiscUtils.js +65 -0
  60. package/utils/expr_grammar/grammar.js +104 -22
  61. package/utils/expr_grammar/grammar.ne +2 -0
  62. package/utils/expr_grammar/test.js +21 -4
@@ -0,0 +1,138 @@
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 2015 Sourcepole AG
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 ReactDOM from 'react-dom';
25
+ import { connect } from 'react-redux';
26
+ import classNames from 'classnames';
27
+ import PropTypes from 'prop-types';
28
+ import LocaleUtils from '../utils/LocaleUtils';
29
+ import Icon from './Icon';
30
+ import { BottomToolPortalContext } from './PluginsContainer';
31
+ import NumberInput from './widgets/NumberInput';
32
+ import './style/LocationRecorder.css';
33
+ var LocationRecorder = /*#__PURE__*/function (_React$Component) {
34
+ function LocationRecorder(props) {
35
+ var _this;
36
+ _classCallCheck(this, LocationRecorder);
37
+ _this = _callSuper(this, LocationRecorder, [props]);
38
+ _defineProperty(_this, "state", {
39
+ recording: false,
40
+ interval: 1
41
+ });
42
+ _defineProperty(_this, "toggleRecording", function () {
43
+ if (_this.state.recording) {
44
+ _this.stopRecording();
45
+ } else {
46
+ _this.props.drawInteraction.abortDrawing();
47
+ _this.props.drawInteraction.setActive(false);
48
+ // Re-add overlay to map, removed by setActive(false), to ensure traced feature is visibile
49
+ _this.props.drawInteraction.getOverlay().setMap(_this.props.map);
50
+ _this.setState({
51
+ recording: true
52
+ });
53
+ if (!navigator.geolocation) {
54
+ _this.stopRecording();
55
+ /* eslint-disable-next-line */
56
+ console.error("Geolocation not supported");
57
+ } else {
58
+ _this.props.drawInteraction.appendCoordinates([_this.props.locatePosition]);
59
+ if (_this.props.geomType === "Point") {
60
+ _this.stopRecording();
61
+ } else {
62
+ _this.pollInterval = setInterval(function () {
63
+ _this.props.drawInteraction.appendCoordinates([_this.props.locatePosition]);
64
+ }, _this.state.interval * 1000);
65
+ }
66
+ }
67
+ }
68
+ });
69
+ _defineProperty(_this, "stopRecording", function () {
70
+ _this.setState({
71
+ recording: false
72
+ }, _this.finishDrawing);
73
+ clearInterval(_this.pollInterval);
74
+ });
75
+ _defineProperty(_this, "finishDrawing", function () {
76
+ _this.props.drawInteraction.finishDrawing();
77
+ _this.props.drawInteraction.setActive(true);
78
+ });
79
+ _this.pollInterval = null;
80
+ return _this;
81
+ }
82
+ _inherits(LocationRecorder, _React$Component);
83
+ return _createClass(LocationRecorder, [{
84
+ key: "componentWillUnmount",
85
+ value: function componentWillUnmount() {
86
+ this.stopRecording();
87
+ }
88
+ }, {
89
+ key: "render",
90
+ value: function render() {
91
+ var _this2 = this;
92
+ if (!this.props.locateEnabled || !this.props.locatePosition) {
93
+ return null;
94
+ }
95
+ var buttonClasses = classNames({
96
+ button: true,
97
+ pressed: this.state.recording
98
+ });
99
+ return /*#__PURE__*/ReactDOM.createPortal(/*#__PURE__*/React.createElement("div", {
100
+ className: "LocationRecorder"
101
+ }, /*#__PURE__*/React.createElement(Icon, {
102
+ icon: "screenshot"
103
+ }), /*#__PURE__*/React.createElement("button", {
104
+ className: buttonClasses,
105
+ onClick: this.toggleRecording
106
+ }, /*#__PURE__*/React.createElement(Icon, {
107
+ icon: this.state.recording ? "square" : "circle_full"
108
+ }), /*#__PURE__*/React.createElement("span", null, this.state.recording ? LocaleUtils.tr("locationrecorder.stop") : LocaleUtils.tr("locationrecorder.record"))), /*#__PURE__*/React.createElement(NumberInput, {
109
+ decimals: 1,
110
+ max: 30,
111
+ min: 0.5,
112
+ mobile: true,
113
+ onChange: function onChange(value) {
114
+ return _this2.setState({
115
+ interval: value
116
+ });
117
+ },
118
+ step: 0.5,
119
+ suffix: "s",
120
+ value: this.state.interval
121
+ })), this.context);
122
+ }
123
+ }]);
124
+ }(React.Component);
125
+ _defineProperty(LocationRecorder, "contextType", BottomToolPortalContext);
126
+ _defineProperty(LocationRecorder, "propTypes", {
127
+ drawInteraction: PropTypes.object,
128
+ geomType: PropTypes.string,
129
+ locateEnabled: PropTypes.bool,
130
+ locatePosition: PropTypes.array,
131
+ map: PropTypes.object
132
+ });
133
+ export default connect(function (state) {
134
+ return {
135
+ locateEnabled: ["ENABLED", "FOLLOWING"].includes(state.locate.state),
136
+ locatePosition: state.locate.mapPos
137
+ };
138
+ })(LocationRecorder);
@@ -31,6 +31,9 @@ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e
31
31
  import React from 'react';
32
32
  import { connect } from 'react-redux';
33
33
  import isEmpty from 'lodash.isempty';
34
+ import ol from 'openlayers';
35
+ import pointInPolygon from 'point-in-polygon';
36
+ import polygonIntersectTest from 'polygon-intersect-test';
34
37
  import PropTypes from 'prop-types';
35
38
  import { v4 as uuidv4 } from 'uuid';
36
39
  import { LayerRole, addLayerFeatures, clearLayer } from '../actions/layers';
@@ -121,29 +124,40 @@ var PickFeature = /*#__PURE__*/function (_React$Component) {
121
124
  value: function componentDidUpdate(prevProps, prevState) {
122
125
  var _this2 = this;
123
126
  if (this.state.pickGeom && this.state.pickGeom !== prevState.pickGeom) {
124
- var queryLayers = [];
127
+ var queryWmsLayers = [];
128
+ var queryVectorLayers = [];
125
129
  if (this.props.layerFilter) {
126
- queryLayers = [this.props.layers.find(function (l) {
130
+ queryWmsLayers = [this.props.layers.find(function (l) {
127
131
  return l.url === _this2.props.layerFilter.url;
128
132
  })].filter(Boolean);
129
133
  } else {
130
- queryLayers = IdentifyUtils.getQueryLayers(this.props.layers, this.props.map);
134
+ queryWmsLayers = IdentifyUtils.getQueryLayers(this.props.layers, this.props.map);
135
+ queryVectorLayers = this.props.layers.filter(function (layer) {
136
+ return layer.visibility && LayerRole.USERLAYER && (layer.type === 'vector' || layer.type === 'wfs');
137
+ });
131
138
  }
132
- if (!isEmpty(queryLayers)) {
133
- this.setState(function (state) {
134
- var getPixelFromCoordinate = MapUtils.getHook(MapUtils.GET_PIXEL_FROM_COORDINATES_HOOK);
135
- var coordinates = _this2.props.pickGeomType === "Point" ? [[state.pickGeom.coordinates]] : state.pickGeom.coordinates;
136
- var maxX = coordinates[0][0][0];
137
- var maxY = coordinates[0][0][1];
138
- for (var i = 1; i < coordinates[0].length; ++i) {
139
- if (coordinates[0][i][0] > maxX) {
140
- maxX = coordinates[0][i][0];
141
- maxY = coordinates[0][i][1];
142
- }
139
+ if (this.props.layerFilterFunc) {
140
+ queryWmsLayers = queryWmsLayers.filter(this.props.layerFilterFunc);
141
+ queryVectorLayers = queryVectorLayers.filter(this.props.layerFilterFunc);
142
+ }
143
+ if (isEmpty(queryWmsLayers) && isEmpty(queryVectorLayers)) {
144
+ return;
145
+ }
146
+ this.setState(function (state) {
147
+ var coordinates = _this2.props.pickGeomType === "Point" ? [[state.pickGeom.coordinates]] : state.pickGeom.coordinates;
148
+ var maxX = coordinates[0][0][0];
149
+ var maxY = coordinates[0][0][1];
150
+ for (var i = 1; i < coordinates[0].length; ++i) {
151
+ if (coordinates[0][i][0] > maxX) {
152
+ maxX = coordinates[0][i][0];
153
+ maxY = coordinates[0][i][1];
143
154
  }
144
- var clickPos = getPixelFromCoordinate([maxX, maxY], false);
145
- var reqId = uuidv4();
146
- queryLayers.forEach(function (layer) {
155
+ }
156
+ var reqId = uuidv4();
157
+ var getPixelFromCoordinate = MapUtils.getHook(MapUtils.GET_PIXEL_FROM_COORDINATES_HOOK);
158
+ var clickPos = getPixelFromCoordinate([maxX, maxY], false);
159
+ if (!isEmpty(queryWmsLayers)) {
160
+ queryWmsLayers.forEach(function (layer) {
147
161
  var request = null;
148
162
  if (_this2.props.pickGeomType === 'Point') {
149
163
  var _this2$props$layerFil;
@@ -159,14 +173,58 @@ var PickFeature = /*#__PURE__*/function (_React$Component) {
159
173
  return _this2.handleIdentifyResponse(response, reqId, layer, request.params.info_format);
160
174
  });
161
175
  });
162
- return {
163
- pickResults: {},
164
- clickPos: clickPos,
165
- pendingQueries: queryLayers.length,
166
- reqId: reqId
167
- };
168
- });
169
- }
176
+ }
177
+ var pickResults = {};
178
+ if (!isEmpty(queryVectorLayers)) {
179
+ var olMap = MapUtils.getHook(MapUtils.GET_MAP);
180
+ var layerMap = queryVectorLayers.reduce(function (res, layer) {
181
+ return _objectSpread(_objectSpread({}, res), {}, _defineProperty({}, layer.id, layer));
182
+ }, {});
183
+ var format = new ol.format.GeoJSON();
184
+ if (_this2.props.pickGeomType === 'Point') {
185
+ olMap.forEachFeatureAtPixel(clickPos, function (feature, layer) {
186
+ var _layer$get;
187
+ var layerid = layer === null || layer === void 0 || (_layer$get = layer.get) === null || _layer$get === void 0 ? void 0 : _layer$get.call(layer, 'id');
188
+ if (layerid in layerMap) {
189
+ var featureObj = format.writeFeatureObject(feature);
190
+ var layername = layerMap[layerid].name;
191
+ pickResults[layername] = pickResults[layername] || [];
192
+ pickResults[layername].push(featureObj);
193
+ }
194
+ });
195
+ } else if (_this2.props.pickGeomType === 'Polygon') {
196
+ var extent = ol.extent.boundingExtent(coordinates[0]);
197
+ olMap.getLayers().forEach(function (layer) {
198
+ if (!(layer.get('id') in layerMap)) {
199
+ return;
200
+ }
201
+ layer.getSource().forEachFeatureIntersectingExtent(extent, function (feature) {
202
+ var intersects = false;
203
+ if (feature.getGeometry().getType() === "Point") {
204
+ intersects = pointInPolygon(feature.getGeometry().getCoordinates(), coordinates[0]);
205
+ } else if (feature.getGeometry().getType() === "LineString") {
206
+ intersects = true; // TODO
207
+ } else if (feature.getGeometry().getType() === "Polygon") {
208
+ intersects = polygonIntersectTest(feature.getGeometry().getCoordinates()[0], coordinates[0]);
209
+ }
210
+ if (!intersects) {
211
+ return;
212
+ }
213
+ var featureObj = format.writeFeatureObject(feature);
214
+ var layername = layerMap[layer.get('id')].name;
215
+ pickResults[layername] = pickResults[layername] || [];
216
+ pickResults[layername].push(featureObj);
217
+ });
218
+ });
219
+ }
220
+ }
221
+ return {
222
+ pickResults: pickResults,
223
+ clickPos: clickPos,
224
+ pendingQueries: queryWmsLayers.length,
225
+ reqId: reqId
226
+ };
227
+ });
170
228
  }
171
229
  }
172
230
  }, {
@@ -186,6 +244,7 @@ var PickFeature = /*#__PURE__*/function (_React$Component) {
186
244
  layername = _ref6[0],
187
245
  features = _ref6[1];
188
246
  return features.map(function (feature) {
247
+ var _feature$displayname;
189
248
  return /*#__PURE__*/React.createElement("div", {
190
249
  key: layername + ":" + feature.id,
191
250
  onClickCapture: function onClickCapture() {
@@ -197,7 +256,7 @@ var PickFeature = /*#__PURE__*/function (_React$Component) {
197
256
  onMouseOver: function onMouseOver() {
198
257
  return _this3.highlightFeature(layername, feature);
199
258
  }
200
- }, layername + ": " + feature.displayname);
259
+ }, layername + ": " + ((_feature$displayname = feature.displayname) !== null && _feature$displayname !== void 0 ? _feature$displayname : feature.id));
201
260
  });
202
261
  }) : /*#__PURE__*/React.createElement("div", {
203
262
  className: "pick-feature-menu-querying"
@@ -240,6 +299,8 @@ _defineProperty(PickFeature, "propTypes", {
240
299
  url: PropTypes.string,
241
300
  name: PropTypes.string
242
301
  }),
302
+ /** Optional: Filter function to restrict pick layers */
303
+ layerFilterFunc: PropTypes.func,
243
304
  layers: PropTypes.array,
244
305
  map: PropTypes.object,
245
306
  /** Pick geometry type: Point, Polygon, ... (default: Point) */
@@ -40,6 +40,7 @@ import './style/PluginsContainer.css';
40
40
  export var MapButtonPortalContext = /*#__PURE__*/React.createContext(null);
41
41
  export var MapContainerPortalContext = /*#__PURE__*/React.createContext(null);
42
42
  export var AppInfosPortalContext = /*#__PURE__*/React.createContext(null);
43
+ export var BottomToolPortalContext = /*#__PURE__*/React.createContext(null);
43
44
  var PluginsContainer = /*#__PURE__*/function (_React$Component) {
44
45
  function PluginsContainer() {
45
46
  var _this;
@@ -51,7 +52,8 @@ var PluginsContainer = /*#__PURE__*/function (_React$Component) {
51
52
  _defineProperty(_this, "state", {
52
53
  mapButtonsContainerRef: null,
53
54
  mapContainerRef: null,
54
- appInfosContainerRef: null
55
+ appInfosContainerRef: null,
56
+ bottomToolContainerRef: null
55
57
  });
56
58
  _defineProperty(_this, "renderPlugins", function () {
57
59
  var device = ConfigUtils.isMobile() ? 'mobile' : 'desktop';
@@ -134,6 +136,11 @@ var PluginsContainer = /*#__PURE__*/function (_React$Component) {
134
136
  appInfosContainerRef: el
135
137
  });
136
138
  });
139
+ _defineProperty(_this, "setBottomToolContanerRef", function (el) {
140
+ _this.setState({
141
+ bottomToolContainerRef: el
142
+ });
143
+ });
137
144
  _defineProperty(_this, "setButtonContainerRef", function (el) {
138
145
  _this.setState({
139
146
  mapButtonsContainerRef: el
@@ -190,7 +197,7 @@ var PluginsContainer = /*#__PURE__*/function (_React$Component) {
190
197
  right: 'calc(' + right + 'px)',
191
198
  bottom: 'calc(var(--bottombar-height) + ' + bottom + 'px)'
192
199
  };
193
- var haveRefs = this.state.mapButtonsContainerRef && this.state.mapContainerRef && this.state.appInfosContainerRef;
200
+ var haveRefs = this.state.mapButtonsContainerRef && this.state.mapContainerRef && this.state.appInfosContainerRef && this.state.bottomToolContainerRef;
194
201
  return /*#__PURE__*/React.createElement("div", {
195
202
  className: "plugins-container " + ((_this$props$className = this.props.className) !== null && _this$props$className !== void 0 ? _this$props$className : ""),
196
203
  ref: this.setupTouchEvents
@@ -200,7 +207,9 @@ var PluginsContainer = /*#__PURE__*/function (_React$Component) {
200
207
  value: this.state.mapButtonsContainerRef
201
208
  }, /*#__PURE__*/React.createElement(MapContainerPortalContext.Provider, {
202
209
  value: this.state.mapContainerRef
203
- }, haveRefs ? this.renderPlugins() : null, haveRefs ? this.props.children : null))), /*#__PURE__*/React.createElement(WindowManager, null), /*#__PURE__*/React.createElement("div", {
210
+ }, /*#__PURE__*/React.createElement(BottomToolPortalContext.Provider, {
211
+ value: this.state.bottomToolContainerRef
212
+ }, haveRefs ? this.renderPlugins() : null, haveRefs ? this.props.children : null)))), /*#__PURE__*/React.createElement(WindowManager, null), /*#__PURE__*/React.createElement("div", {
204
213
  className: "map-container",
205
214
  ref: this.setMapContainerRef,
206
215
  style: mapContainerStyle
@@ -212,6 +221,10 @@ var PluginsContainer = /*#__PURE__*/function (_React$Component) {
212
221
  className: "app-infos-container",
213
222
  ref: this.setAppInfosContainerRef,
214
223
  style: mapContainerStyle
224
+ }), /*#__PURE__*/React.createElement("div", {
225
+ className: "map-bottom-tool-container",
226
+ ref: this.setBottomToolContanerRef,
227
+ style: mapContainerStyle
215
228
  }));
216
229
  }
217
230
  }]);
@@ -252,7 +252,8 @@ _defineProperty(OlLayer, "propTypes", {
252
252
  refreshLayer: PropTypes.func,
253
253
  setLayerLoading: PropTypes.func,
254
254
  swipe: PropTypes.number,
255
- zIndex: PropTypes.number
255
+ zIndex: PropTypes.number,
256
+ zoomToExtent: PropTypes.func
256
257
  });
257
258
  export default connect(function () {
258
259
  return {};
@@ -102,6 +102,8 @@ var HeightProfilePrintDialog = /*#__PURE__*/function (_React$PureComponent) {
102
102
  value: function componentDidMount() {
103
103
  var templatePath = MiscUtils.resolveAssetsPath(this.props.templatePath);
104
104
  this.externalWindow = window.open(templatePath, LocaleUtils.tr("heightprofile.title"), "toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=yes, resizable=yes");
105
+ // Inherit API
106
+ this.externalWindow.qwc2 = window.qwc2;
105
107
  this.externalWindow.addEventListener('load', this.setWindowContent, false);
106
108
  this.externalWindow.addEventListener('resize', this.windowResized, false);
107
109
  window.addEventListener('beforeunload', this.closePrintWindow);
@@ -169,6 +169,20 @@ button.button > div.spinner {
169
169
  height: 1.5em;
170
170
  }
171
171
 
172
+ button.selected {
173
+ position: relative;
174
+ }
175
+ button.selected:after {
176
+ position: absolute;
177
+ left: 0;
178
+ right: 0;
179
+ bottom: 0;
180
+ height: 3px;
181
+ background-color: var(--color-active);
182
+ border-top: 1px solid var(--border-color);
183
+ content: "";
184
+ }
185
+
172
186
  div.controlgroup {
173
187
  display: flex;
174
188
  align-items: center;
@@ -182,7 +182,7 @@ table.attribtable-table td > div.TextInput > pre {
182
182
  min-height: 2em;
183
183
  }
184
184
 
185
- table.attribtable-table td > *:disabled,
185
+ table.attribtable-table tr.row-disabled td > *:disabled,
186
186
  table.attribtable-table tr.row-disabled,
187
187
  table.attribtable-table tr.row-disabled * {
188
188
  color: var(--text-color-disabled);
@@ -0,0 +1,16 @@
1
+ div.feature-attributes-body table {
2
+ width: 100%;
3
+ }
4
+
5
+ div.feature-attributes-body table td:first-child {
6
+ width: 25%
7
+ }
8
+
9
+ div.feature-attributes-body table td:last-child {
10
+ width: 1%;
11
+ }
12
+
13
+ div.feature-attributes-body table td > input {
14
+ min-width: 0;
15
+ width: 100%;
16
+ }
@@ -76,6 +76,7 @@ div.identify-body div.identify-result-frame:hover {
76
76
 
77
77
  div.identify-body .identify-result-title {
78
78
  background-color: var(--list-section-bg-color);
79
+ color: var(--list-section-text-color);
79
80
  padding: 0.25em;
80
81
  font-weight: bold;
81
82
  flex: 0 0 auto;
@@ -94,6 +95,10 @@ div.identify-body .identify-result-title > span.icon {
94
95
  flex: 0 0 auto;
95
96
  }
96
97
 
98
+ span.identify-result-checkbox {
99
+ background-color: white;
100
+ }
101
+
97
102
  div.identify-body .identify-result-title > span:not(:first-child) {
98
103
  margin-left: 0.5em;
99
104
  }
@@ -0,0 +1,10 @@
1
+ div.LocationRecorder {
2
+ display: inline-flex;
3
+ align-items: center;
4
+ padding: 0.25em 0.5em;
5
+ background-color: var(--container-bg-color);
6
+ box-shadow: 0px -2px 4px rgba(136, 136, 136, 0.5);
7
+ border-bottom: 1px solid rgba(136, 136, 136, 0.5);
8
+ column-gap: 0.25em;
9
+ order: 1;
10
+ }
@@ -8,4 +8,11 @@ div.numeric-input-widget-body > table input {
8
8
 
9
9
  div.numeric-input-widget-body > table tr:hover {
10
10
  background-color: var(--list-item-bg-color-hover);
11
+ }
12
+
13
+ div.numeric-input-widget-body > table td:nth-child(1),
14
+ div.numeric-input-widget-body > table td:nth-child(2),
15
+ div.numeric-input-widget-body > table td:nth-child(4),
16
+ div.numeric-input-widget-body > table td:nth-child(6) {
17
+ width: 1%;
11
18
  }
@@ -25,6 +25,22 @@ div.app-infos-container {
25
25
  row-gap: 0.25em;
26
26
  }
27
27
 
28
+ div.map-bottom-tool-container {
29
+ z-index: 3;
30
+ position: absolute;
31
+ pointer-events: none;
32
+ display: flex;
33
+ flex-direction: column-reverse;
34
+ align-items: center;
35
+ align-content: flex-start;
36
+ justify-content: flex-start;
37
+ margin-bottom: -1px;
38
+ }
39
+
40
+ div.map-bottom-tool-container > * {
41
+ pointer-events: initial;
42
+ }
43
+
28
44
  div.app-info {
29
45
  z-index: 1;
30
46
  color: var(--panel-text-color);
@@ -38,6 +38,7 @@ var LayerCatalogWidget = /*#__PURE__*/function (_React$PureComponent) {
38
38
  _this = _callSuper(this, LayerCatalogWidget, [props]);
39
39
  _defineProperty(_this, "state", {
40
40
  catalog: [],
41
+ filteredCatalog: null,
41
42
  filter: ""
42
43
  });
43
44
  _defineProperty(_this, "toggleLayerListEntry", function (path) {
@@ -64,6 +65,35 @@ var LayerCatalogWidget = /*#__PURE__*/function (_React$PureComponent) {
64
65
  };
65
66
  });
66
67
  });
68
+ _defineProperty(_this, "setFilter", function (text) {
69
+ _this.setState(function (state) {
70
+ if (!text) {
71
+ return {
72
+ filter: text,
73
+ filteredCatalog: null
74
+ };
75
+ }
76
+ var filter = new RegExp(removeDiacritics(text).replace(/[-[\]/{}()*+?.\\^$|]/g, "\\$&"), "i");
77
+ var _filterCatalogEntry = function filterCatalogEntry(res, entry) {
78
+ if (entry.sublayers) {
79
+ var newEntry = _objectSpread(_objectSpread({}, entry), {}, {
80
+ sublayers: entry.sublayers.reduce(_filterCatalogEntry, []),
81
+ expanded: true
82
+ });
83
+ return newEntry.sublayers.length > 0 ? [].concat(_toConsumableArray(res), [newEntry]) : res;
84
+ } else if (removeDiacritics(entry.title).match(filter)) {
85
+ return [].concat(_toConsumableArray(res), [entry]);
86
+ } else {
87
+ return res;
88
+ }
89
+ };
90
+ var filteredCatalog = state.catalog.reduce(_filterCatalogEntry, []);
91
+ return {
92
+ filter: text,
93
+ filteredCatalog: filteredCatalog
94
+ };
95
+ });
96
+ });
67
97
  _defineProperty(_this, "addServiceLayer", function (entry) {
68
98
  var asGroup = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
69
99
  if (entry.resource) {
@@ -116,19 +146,14 @@ var LayerCatalogWidget = /*#__PURE__*/function (_React$PureComponent) {
116
146
  }
117
147
  }, {
118
148
  key: "renderCatalogEntry",
119
- value: function renderCatalogEntry(entry, filter, path) {
149
+ value: function renderCatalogEntry(entry, path) {
120
150
  var _this2 = this;
121
- var level = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
122
- var idx = arguments.length > 4 ? arguments[4] : undefined;
151
+ var level = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
152
+ var idx = arguments.length > 3 ? arguments[3] : undefined;
123
153
  var hasSublayers = !isEmpty(entry.sublayers);
124
154
  var sublayers = hasSublayers ? entry.sublayers.map(function (sublayer, i) {
125
- return _this2.renderCatalogEntry(sublayer, filter, [].concat(_toConsumableArray(path), [i]), level + 1, i);
155
+ return _this2.renderCatalogEntry(sublayer, [].concat(_toConsumableArray(path), [i]), level + 1, i);
126
156
  }) : [];
127
- if (sublayers.filter(function (item) {
128
- return item;
129
- }).length === 0 && filter && !removeDiacritics(entry.title).match(filter)) {
130
- return null;
131
- }
132
157
  var type = entry.resource ? entry.resource.slice(0, entry.resource.indexOf(":")) : entry.type;
133
158
  var key = (entry.resource || entry.type + ":" + entry.name) + ":" + idx;
134
159
  var indentSize = !this.props.levelBasedIndentSize && level > 0 ? 1.5 : level;
@@ -164,8 +189,8 @@ var LayerCatalogWidget = /*#__PURE__*/function (_React$PureComponent) {
164
189
  }, {
165
190
  key: "render",
166
191
  value: function render() {
167
- var _this3 = this;
168
- var filter = new RegExp(removeDiacritics(this.state.filter).replace(/[-[\]/{}()*+?.\\^$|]/g, "\\$&"), "i");
192
+ var _this$state$filteredC,
193
+ _this3 = this;
169
194
  var emptyEntry = null;
170
195
  if (isEmpty(this.state.catalog) && this.props.pendingRequests === 0) {
171
196
  emptyEntry = /*#__PURE__*/React.createElement("div", {
@@ -177,15 +202,14 @@ var LayerCatalogWidget = /*#__PURE__*/function (_React$PureComponent) {
177
202
  }, LocaleUtils.tr("importlayer.loading"));
178
203
  }
179
204
  var filterplaceholder = LocaleUtils.tr("importlayer.filter");
205
+ var catalog = (_this$state$filteredC = this.state.filteredCatalog) !== null && _this$state$filteredC !== void 0 ? _this$state$filteredC : this.state.catalog;
180
206
  return /*#__PURE__*/React.createElement("div", {
181
207
  className: "layer-catalog-widget"
182
208
  }, /*#__PURE__*/React.createElement(InputContainer, {
183
209
  className: "layer-catalog-widget-filter"
184
210
  }, /*#__PURE__*/React.createElement("input", {
185
211
  onChange: function onChange(ev) {
186
- return _this3.setState({
187
- filter: ev.target.value
188
- });
212
+ return _this3.setFilter(ev.target.value);
189
213
  },
190
214
  placeholder: filterplaceholder,
191
215
  role: "input",
@@ -201,8 +225,8 @@ var LayerCatalogWidget = /*#__PURE__*/function (_React$PureComponent) {
201
225
  role: "suffix"
202
226
  })), /*#__PURE__*/React.createElement("div", {
203
227
  className: "layer-catalog-widget-body"
204
- }, this.state.catalog.map(function (entry, idx) {
205
- return _this3.renderCatalogEntry(entry, filter, [idx], 0, idx);
228
+ }, catalog.map(function (entry, idx) {
229
+ return _this3.renderCatalogEntry(entry, [idx], 0, idx);
206
230
  }), emptyEntry));
207
231
  }
208
232
  }]);
@@ -21,6 +21,7 @@ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e
21
21
  */
22
22
 
23
23
  import React from 'react';
24
+ import classNames from 'classnames';
24
25
  import PropTypes from 'prop-types';
25
26
  import LocaleUtils from '../../utils/LocaleUtils';
26
27
  import Icon from '../Icon';
@@ -40,7 +41,11 @@ var NavBar = /*#__PURE__*/function (_React$Component) {
40
41
  key: idx
41
42
  }, "...");
42
43
  }
43
- var className = "button" + (page === _this.props.currentPage ? " pressed" : "");
44
+ var className = classNames({
45
+ button: true,
46
+ pressed: page === _this.props.currentPage,
47
+ selected: _this.props.selectedPages.includes(page)
48
+ });
44
49
  return /*#__PURE__*/React.createElement("button", {
45
50
  className: className,
46
51
  disabled: _this.props.disabled,
@@ -116,9 +121,11 @@ _defineProperty(NavBar, "propTypes", {
116
121
  pageChanged: PropTypes.func,
117
122
  pageSize: PropTypes.number,
118
123
  pageSizeChanged: PropTypes.func,
119
- pageSizes: PropTypes.array
124
+ pageSizes: PropTypes.array,
125
+ selectedPages: PropTypes.array
120
126
  });
121
127
  _defineProperty(NavBar, "defaultProps", {
122
- pageSizes: [10, 25, 50, 100]
128
+ pageSizes: [10, 25, 50, 100],
129
+ selectedPages: []
123
130
  });
124
131
  export { NavBar as default };