qwc2 2025.10.30 → 2025.11.12
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/layers.js +6 -29
- package/components/AttributeForm.js +106 -77
- package/components/AttributeTableWidget.js +89 -88
- package/components/IdentifyViewer.js +4 -2
- package/components/LinkFeatureForm.js +17 -9
- package/components/LocationRecorder.js +1 -1
- package/components/PickFeature.js +45 -33
- package/components/QtDesignerForm.js +20 -18
- package/components/StandardApp.js +4 -0
- package/components/ThemeList.js +9 -10
- package/components/map3d/Map3D.js +6 -3
- package/package.json +2 -1
- package/plugins/Cyclomedia.js +5 -4
- package/plugins/Editing.js +307 -72
- package/plugins/FeatureForm.js +103 -111
- package/plugins/LayerTree.js +4 -1
- package/plugins/NewsPopup.js +2 -2
- package/plugins/Portal.js +3 -1
- package/plugins/Print.js +4 -4
- package/plugins/Redlining.js +9 -0
- package/plugins/ThemeSwitcher.js +3 -0
- package/plugins/map/EditingSupport.js +2 -2
- package/plugins/map/RedliningSupport.js +63 -13
- package/plugins/style/Editing.css +34 -0
- package/reducers/editing.js +12 -7
- package/reducers/layers.js +27 -5
- package/static/translations/bg-BG.json +10 -0
- package/static/translations/ca-ES.json +10 -0
- package/static/translations/cs-CZ.json +10 -0
- package/static/translations/de-CH.json +10 -0
- package/static/translations/de-DE.json +10 -0
- package/static/translations/en-US.json +11 -1
- package/static/translations/es-ES.json +10 -0
- package/static/translations/fi-FI.json +10 -0
- package/static/translations/fr-FR.json +10 -0
- package/static/translations/hu-HU.json +10 -0
- package/static/translations/it-IT.json +10 -0
- package/static/translations/ja-JP.json +10 -0
- package/static/translations/nl-NL.json +10 -0
- package/static/translations/no-NO.json +10 -0
- package/static/translations/pl-PL.json +10 -0
- package/static/translations/pt-BR.json +10 -0
- package/static/translations/pt-PT.json +10 -0
- package/static/translations/ro-RO.json +10 -0
- package/static/translations/ru-RU.json +10 -0
- package/static/translations/sv-SE.json +10 -0
- package/static/translations/tr-TR.json +10 -0
- package/static/translations/tsconfig.json +10 -0
- package/static/translations/uk-UA.json +10 -0
- package/utils/EditingUtils.js +15 -13
- package/utils/ElevationInterface.js +1 -2
- package/utils/LayerUtils.js +5 -3
- package/utils/MapUtils.js +2 -11
- package/utils/ServiceLayerUtils.js +53 -2
- package/utils/ThemeUtils.js +3 -1
package/plugins/FeatureForm.js
CHANGED
|
@@ -33,7 +33,6 @@ import { connect } from 'react-redux';
|
|
|
33
33
|
import isEmpty from 'lodash.isempty';
|
|
34
34
|
import PropTypes from 'prop-types';
|
|
35
35
|
import { setEditContext, clearEditContext } from '../actions/editing';
|
|
36
|
-
import { LayerRole } from '../actions/layers';
|
|
37
36
|
import { setCurrentTask } from '../actions/task';
|
|
38
37
|
import AttributeForm from '../components/AttributeForm';
|
|
39
38
|
import ResizeableWindow from '../components/ResizeableWindow';
|
|
@@ -81,56 +80,47 @@ var FeatureForm = /*#__PURE__*/function (_React$Component) {
|
|
|
81
80
|
});
|
|
82
81
|
_defineProperty(_this, "queryFeatures", function (pos) {
|
|
83
82
|
var pendingRequests = 0;
|
|
84
|
-
Object.entries(_this.props.
|
|
85
|
-
var _this$props$filter$fi;
|
|
83
|
+
Object.entries(_this.props.editConfigs).forEach(function (_ref) {
|
|
86
84
|
var _ref2 = _slicedToArray(_ref, 2),
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
_this.setState(function (state) {
|
|
108
|
-
var newPickedFeatures = Object.fromEntries(Object.entries(_objectSpread(_objectSpread({}, state.pickedFeatures), featureCollection.features.reduce(function (res, feature) {
|
|
109
|
-
return _objectSpread(_objectSpread({}, res), {}, _defineProperty({}, layerId + "::" + feature.id, feature));
|
|
110
|
-
}, {}))).sort(function (a, b) {
|
|
111
|
-
var partsA = a[0].split("::");
|
|
112
|
-
var partsB = b[0].split("::");
|
|
113
|
-
var diff = layerOrder.indexOf(partsB[0]) - layerOrder.indexOf(partsA[0]);
|
|
114
|
-
return diff === 0 ? partsA[1].localeCompare(partsB[1]) : diff;
|
|
115
|
-
}));
|
|
116
|
-
var selectedFeature = state.pendingRequests <= 1 && !state.selectedFeature ? Object.keys(newPickedFeatures)[0] : "";
|
|
117
|
-
return {
|
|
118
|
-
pickedFeatures: newPickedFeatures,
|
|
119
|
-
pendingRequests: state.pendingRequests - 1,
|
|
120
|
-
selectedFeature: selectedFeature
|
|
121
|
-
};
|
|
122
|
-
});
|
|
123
|
-
} else {
|
|
85
|
+
mapName = _ref2[0],
|
|
86
|
+
editConfigs = _ref2[1];
|
|
87
|
+
Object.entries(editConfigs).forEach(function (_ref3) {
|
|
88
|
+
var _this$props$filter$fi;
|
|
89
|
+
var _ref4 = _slicedToArray(_ref3, 2),
|
|
90
|
+
layerName = _ref4[0],
|
|
91
|
+
editConfig = _ref4[1];
|
|
92
|
+
if (!editConfig.geomType) {
|
|
93
|
+
// Skip geometryless datasets
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
var match = LayerUtils.searchLayer(_this.props.layers, 'wms_name', mapName, 'name', layerName);
|
|
97
|
+
var mapScale = MapUtils.computeForZoom(_this.props.map.scales, _this.props.map.zoom);
|
|
98
|
+
if (!match || !LayerUtils.sublayerVisible(match.layer, match.path) || !LayerUtils.layerScaleInRange(match.sublayer, mapScale)) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
var layerOrder = match.layer.params.LAYERS.split(",");
|
|
102
|
+
++pendingRequests;
|
|
103
|
+
var scale = Math.round(MapUtils.computeForZoom(_this.props.map.scales, _this.props.map.zoom));
|
|
104
|
+
_this.props.iface.getFeature(editConfig, pos, _this.props.map.projection, scale, 96, function (featureCollection) {
|
|
124
105
|
_this.setState(function (state) {
|
|
125
|
-
var
|
|
126
|
-
|
|
106
|
+
var pickedFeatures = state.pickedFeatures;
|
|
107
|
+
if (!isEmpty(featureCollection === null || featureCollection === void 0 ? void 0 : featureCollection.features)) {
|
|
108
|
+
pickedFeatures = Object.fromEntries(Object.entries(_objectSpread(_objectSpread({}, state.pickedFeatures), featureCollection.features.reduce(function (res, feature) {
|
|
109
|
+
return _objectSpread(_objectSpread({}, res), {}, _defineProperty({}, mapName + "#" + layerName + "#" + feature.id, feature));
|
|
110
|
+
}, {}))).sort(function (a, b) {
|
|
111
|
+
var partsA = a[0].split("#");
|
|
112
|
+
var partsB = b[0].split("#");
|
|
113
|
+
var diff = layerOrder.indexOf(partsB[1]) - layerOrder.indexOf(partsA[1]);
|
|
114
|
+
return diff === 0 ? partsA[1].localeCompare(partsB[1]) : diff;
|
|
115
|
+
}));
|
|
116
|
+
}
|
|
127
117
|
return {
|
|
128
|
-
|
|
129
|
-
|
|
118
|
+
pickedFeatures: pickedFeatures,
|
|
119
|
+
pendingRequests: state.pendingRequests - 1
|
|
130
120
|
};
|
|
131
121
|
});
|
|
132
|
-
}
|
|
133
|
-
}
|
|
122
|
+
}, (_this$props$filter$fi = _this.props.filter.filterParams) === null || _this$props$filter$fi === void 0 ? void 0 : _this$props$filter$fi[match.sublayer.name], _this.props.filter.filterGeom);
|
|
123
|
+
});
|
|
134
124
|
});
|
|
135
125
|
_this.setState({
|
|
136
126
|
pendingRequests: pendingRequests,
|
|
@@ -138,29 +128,46 @@ var FeatureForm = /*#__PURE__*/function (_React$Component) {
|
|
|
138
128
|
selectedFeature: ""
|
|
139
129
|
});
|
|
140
130
|
});
|
|
141
|
-
_defineProperty(_this, "setSelectedFeature", function (
|
|
131
|
+
_defineProperty(_this, "setSelectedFeature", function (selectedFeature) {
|
|
132
|
+
if (selectedFeature) {
|
|
133
|
+
var _selectedFeature$spli = selectedFeature.split("#", 2),
|
|
134
|
+
_selectedFeature$spli2 = _slicedToArray(_selectedFeature$spli, 2),
|
|
135
|
+
mapName = _selectedFeature$spli2[0],
|
|
136
|
+
layerName = _selectedFeature$spli2[1];
|
|
137
|
+
var editConfig = _this.props.editConfigs[mapName][layerName];
|
|
138
|
+
_this.props.setEditContext('FeatureForm', {
|
|
139
|
+
action: 'Pick',
|
|
140
|
+
feature: _this.state.pickedFeatures[selectedFeature],
|
|
141
|
+
changed: false,
|
|
142
|
+
mapPrefix: mapName,
|
|
143
|
+
editConfig: editConfig
|
|
144
|
+
});
|
|
145
|
+
} else {
|
|
146
|
+
_this.props.clearEditContext('FeatureForm');
|
|
147
|
+
}
|
|
142
148
|
_this.setState({
|
|
143
|
-
selectedFeature:
|
|
149
|
+
selectedFeature: selectedFeature
|
|
144
150
|
});
|
|
145
151
|
});
|
|
146
152
|
_defineProperty(_this, "onWindowClose", function () {
|
|
147
|
-
_this.
|
|
148
|
-
|
|
149
|
-
_this.props.
|
|
153
|
+
if (!_this.props.editContext.changed) {
|
|
154
|
+
_this.clearResults();
|
|
155
|
+
if (_this.props.exitTaskOnResultsClose) {
|
|
156
|
+
_this.props.setCurrentTask(null);
|
|
157
|
+
}
|
|
150
158
|
}
|
|
151
159
|
});
|
|
152
160
|
_defineProperty(_this, "clearResults", function () {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
}
|
|
161
|
+
_this.props.clearEditContext('FeatureForm');
|
|
162
|
+
_this.setState(FeatureForm.defaultState);
|
|
156
163
|
});
|
|
157
164
|
_defineProperty(_this, "updatePickedFeatures", function (newfeature) {
|
|
158
165
|
_this.setState(function (state) {
|
|
159
166
|
return {
|
|
160
|
-
pickedFeatures: Object.entries(state.pickedFeatures).reduce(function (res,
|
|
161
|
-
var
|
|
162
|
-
key =
|
|
163
|
-
feature =
|
|
167
|
+
pickedFeatures: Object.entries(state.pickedFeatures).reduce(function (res, _ref5) {
|
|
168
|
+
var _ref6 = _slicedToArray(_ref5, 2),
|
|
169
|
+
key = _ref6[0],
|
|
170
|
+
feature = _ref6[1];
|
|
164
171
|
res[key] = feature.id === newfeature.id ? newfeature : feature;
|
|
165
172
|
return res;
|
|
166
173
|
}, {})
|
|
@@ -193,43 +200,19 @@ var FeatureForm = /*#__PURE__*/function (_React$Component) {
|
|
|
193
200
|
var mapCrs = this.props.theme.mapCrs;
|
|
194
201
|
this.queryFeatures(CoordinatesUtils.reproject(c, startupParams.crs || mapCrs, mapCrs));
|
|
195
202
|
}
|
|
196
|
-
} else if (this.props.theme !== prevProps.theme) {
|
|
203
|
+
} else if (this.props.theme !== prevProps.theme || !this.props.enabled && prevProps.enabled) {
|
|
197
204
|
this.clearResults();
|
|
198
|
-
} else if (!this.props.enabled && prevProps.enabled) {
|
|
199
|
-
if (this.props.clearResultsOnClose) {
|
|
200
|
-
this.clearResults();
|
|
201
|
-
}
|
|
202
205
|
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
action: 'Pick'
|
|
206
|
-
});
|
|
207
|
-
}
|
|
208
|
-
var isCurrentContext = this.props.editContext.id === this.props.currentEditContext;
|
|
209
|
-
if (this.props.enabled && isCurrentContext && !this.props.editContext.changed && this.state.pendingRequests === 0) {
|
|
206
|
+
var isAllowedContext = [null, "FeatureForm"].includes(this.props.currentEditContext);
|
|
207
|
+
if (this.props.enabled && this.state.pendingRequests === 0 && isAllowedContext && !this.props.editContext.changed) {
|
|
210
208
|
var clickPoint = this.queryPoint(prevProps);
|
|
211
209
|
if (clickPoint) {
|
|
212
210
|
this.queryFeatures(clickPoint);
|
|
213
211
|
}
|
|
214
212
|
}
|
|
215
|
-
if (this.
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
var curConfig = this.props.theme.editConfig[curLayerId] || {};
|
|
219
|
-
var canEditGeometry = ['Point', 'LineString', 'Polygon'].includes((curConfig.geomType || "").replace(/^Multi/, '').replace(/Z$/, ''));
|
|
220
|
-
var editPermissions = curConfig.permissions || {};
|
|
221
|
-
this.props.setEditContext('FeatureForm', {
|
|
222
|
-
action: 'Pick',
|
|
223
|
-
feature: feature,
|
|
224
|
-
changed: false,
|
|
225
|
-
geomType: curConfig.geomType || null,
|
|
226
|
-
geomReadOnly: editPermissions.updatable === false || !canEditGeometry,
|
|
227
|
-
permissions: (curConfig === null || curConfig === void 0 ? void 0 : curConfig.permissions) || {}
|
|
228
|
-
});
|
|
229
|
-
}
|
|
230
|
-
if (!this.props.enabled && prevProps.enabled) {
|
|
231
|
-
this.props.clearEditContext('FeatureForm');
|
|
232
|
-
this.setState(FeatureForm.defaultState);
|
|
213
|
+
if (this.state.pendingRequests === 0 && prevState.pendingRequests > 0) {
|
|
214
|
+
// Select first result
|
|
215
|
+
this.setSelectedFeature(Object.keys(this.state.pickedFeatures)[0]);
|
|
233
216
|
}
|
|
234
217
|
}
|
|
235
218
|
}, {
|
|
@@ -255,39 +238,48 @@ var FeatureForm = /*#__PURE__*/function (_React$Component) {
|
|
|
255
238
|
}, LocaleUtils.tr("featureform.noresults")));
|
|
256
239
|
} else {
|
|
257
240
|
var featureText = LocaleUtils.tr("featureform.feature");
|
|
258
|
-
var
|
|
259
|
-
|
|
241
|
+
var attributeForm = null;
|
|
242
|
+
if (this.props.editContext.feature) {
|
|
243
|
+
var _this$props$layers$fi;
|
|
244
|
+
var translations = (_this$props$layers$fi = this.props.layers.find(function (layer) {
|
|
245
|
+
return layer.wms_name === _this2.props.editContext.mapPrefix;
|
|
246
|
+
})) === null || _this$props$layers$fi === void 0 ? void 0 : _this$props$layers$fi.translations;
|
|
247
|
+
attributeForm = /*#__PURE__*/React.createElement(AttributeForm, {
|
|
248
|
+
editContext: this.props.editContext,
|
|
249
|
+
iface: this.props.iface,
|
|
250
|
+
onCommit: this.updatePickedFeatures,
|
|
251
|
+
translations: translations
|
|
252
|
+
});
|
|
253
|
+
}
|
|
260
254
|
body = /*#__PURE__*/React.createElement("div", {
|
|
261
255
|
className: "feature-query-body",
|
|
262
256
|
role: "body"
|
|
263
257
|
}, Object.keys(this.state.pickedFeatures).length > 1 ? /*#__PURE__*/React.createElement("div", {
|
|
264
258
|
className: "feature-query-selection"
|
|
265
259
|
}, /*#__PURE__*/React.createElement("select", {
|
|
266
|
-
onChange:
|
|
260
|
+
onChange: function onChange(ev) {
|
|
261
|
+
return _this2.setSelectedFeature(ev.target.value);
|
|
262
|
+
},
|
|
267
263
|
value: this.state.selectedFeature
|
|
268
|
-
}, Object.entries(this.state.pickedFeatures).map(function (
|
|
269
|
-
var
|
|
270
|
-
var
|
|
271
|
-
id =
|
|
272
|
-
feature =
|
|
273
|
-
var _id$split = id.split("
|
|
274
|
-
_id$split2 = _slicedToArray(_id$split,
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
var
|
|
279
|
-
var
|
|
264
|
+
}, Object.entries(this.state.pickedFeatures).map(function (_ref7) {
|
|
265
|
+
var _ref9, _ref10, _match$layer$translat, _match$layer$translat2, _match$sublayer;
|
|
266
|
+
var _ref8 = _slicedToArray(_ref7, 2),
|
|
267
|
+
id = _ref8[0],
|
|
268
|
+
feature = _ref8[1];
|
|
269
|
+
var _id$split = id.split("#"),
|
|
270
|
+
_id$split2 = _slicedToArray(_id$split, 3),
|
|
271
|
+
mapName = _id$split2[0],
|
|
272
|
+
layerName = _id$split2[1],
|
|
273
|
+
featureId = _id$split2[2];
|
|
274
|
+
var editConfig = _this2.props.editConfigs[mapName][layerName];
|
|
275
|
+
var match = LayerUtils.searchLayer(_this2.props.layers, 'wms_name', mapName, 'name', layerName);
|
|
276
|
+
var layerTitle = (_ref9 = (_ref10 = (_match$layer$translat = (_match$layer$translat2 = match.layer.translations) === null || _match$layer$translat2 === void 0 || (_match$layer$translat2 = _match$layer$translat2.layertree) === null || _match$layer$translat2 === void 0 ? void 0 : _match$layer$translat2[layerName]) !== null && _match$layer$translat !== void 0 ? _match$layer$translat : editConfig.layerTitle) !== null && _ref10 !== void 0 ? _ref10 : match === null || match === void 0 || (_match$sublayer = match.sublayer) === null || _match$sublayer === void 0 ? void 0 : _match$sublayer.title) !== null && _ref9 !== void 0 ? _ref9 : layerName;
|
|
280
277
|
var featureName = editConfig.displayField ? feature.properties[editConfig.displayField] : featureText + " " + featureId;
|
|
281
278
|
return /*#__PURE__*/React.createElement("option", {
|
|
282
279
|
key: id,
|
|
283
280
|
value: id
|
|
284
281
|
}, layerTitle + ": " + featureName);
|
|
285
|
-
}))) : null,
|
|
286
|
-
editConfig: curConfig,
|
|
287
|
-
editContext: this.props.editContext,
|
|
288
|
-
iface: this.props.iface,
|
|
289
|
-
onCommit: this.updatePickedFeatures
|
|
290
|
-
}) : null);
|
|
282
|
+
}))) : null, attributeForm);
|
|
291
283
|
}
|
|
292
284
|
resultWindow = /*#__PURE__*/React.createElement(ResizeableWindow, {
|
|
293
285
|
dockable: this.props.geometry.side,
|
|
@@ -315,10 +307,9 @@ var FeatureForm = /*#__PURE__*/function (_React$Component) {
|
|
|
315
307
|
}(React.Component);
|
|
316
308
|
_defineProperty(FeatureForm, "propTypes", {
|
|
317
309
|
clearEditContext: PropTypes.func,
|
|
318
|
-
/** Whether to clear the identify results when exiting the identify tool. */
|
|
319
|
-
clearResultsOnClose: PropTypes.bool,
|
|
320
310
|
click: PropTypes.object,
|
|
321
311
|
currentEditContext: PropTypes.string,
|
|
312
|
+
editConfigs: PropTypes.object,
|
|
322
313
|
editContext: PropTypes.object,
|
|
323
314
|
enabled: PropTypes.bool,
|
|
324
315
|
/** Whether to clear the task when the results window is closed. */
|
|
@@ -372,6 +363,7 @@ export default (function () {
|
|
|
372
363
|
layers: state.layers.flat,
|
|
373
364
|
filter: state.layers.filter,
|
|
374
365
|
map: state.map,
|
|
366
|
+
editConfigs: state.layers.editConfigs,
|
|
375
367
|
theme: state.theme.current,
|
|
376
368
|
startupParams: state.localConfig.startupParams
|
|
377
369
|
};
|
package/plugins/LayerTree.js
CHANGED
|
@@ -401,6 +401,7 @@ var LayerTree = /*#__PURE__*/function (_React$Component) {
|
|
|
401
401
|
}) : null);
|
|
402
402
|
});
|
|
403
403
|
_defineProperty(_this, "renderOptionsMenu", function (layer, sublayer, path, marginRight) {
|
|
404
|
+
var _this$props$editConfi;
|
|
404
405
|
var subtreevisibility = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 0;
|
|
405
406
|
var allowReordering = ConfigUtils.getConfigProp("allowReorderingLayers", _this.props.theme) === true;
|
|
406
407
|
var zoomToLayerButton = null;
|
|
@@ -453,7 +454,7 @@ var LayerTree = /*#__PURE__*/function (_React$Component) {
|
|
|
453
454
|
});
|
|
454
455
|
}
|
|
455
456
|
var attrTableButton = null;
|
|
456
|
-
if (_this.props.showAttributeTableLink && ConfigUtils.havePlugin("AttributeTable") && layer.role === LayerRole.THEME && _this.props.
|
|
457
|
+
if (_this.props.showAttributeTableLink && ConfigUtils.havePlugin("AttributeTable") && layer.role === LayerRole.THEME && (_this$props$editConfi = _this.props.editConfigs[layer.wms_name]) !== null && _this$props$editConfi !== void 0 && _this$props$editConfi[sublayer.name]) {
|
|
457
458
|
attrTableButton = /*#__PURE__*/React.createElement(Icon, {
|
|
458
459
|
icon: "editing",
|
|
459
460
|
onClick: function onClick() {
|
|
@@ -1079,6 +1080,7 @@ _defineProperty(LayerTree, "propTypes", {
|
|
|
1079
1080
|
/** Whether to display a BBOX dependent legend. Can be `true|false|"theme"`, latter means only for theme layers. */
|
|
1080
1081
|
bboxDependentLegend: PropTypes.oneOfType([PropTypes.bool, PropTypes.string]),
|
|
1081
1082
|
changeLayerProperty: PropTypes.func,
|
|
1083
|
+
editConfigs: PropTypes.object,
|
|
1082
1084
|
/** Whether to enable the legend print functionality. */
|
|
1083
1085
|
enableLegendPrint: PropTypes.bool,
|
|
1084
1086
|
/** Whether to display a service info button to display the WMS service metadata. */
|
|
@@ -1178,6 +1180,7 @@ _defineProperty(LayerTree, "defaultProps", {
|
|
|
1178
1180
|
});
|
|
1179
1181
|
var selector = function selector(state) {
|
|
1180
1182
|
return {
|
|
1183
|
+
editConfigs: state.layers.editConfigs,
|
|
1181
1184
|
layers: state.layers.flat,
|
|
1182
1185
|
filter: state.layers.filter,
|
|
1183
1186
|
loadingLayers: state.layers.loading,
|
package/plugins/NewsPopup.js
CHANGED
|
@@ -52,7 +52,7 @@ var NewsPopup = /*#__PURE__*/function (_React$Component) {
|
|
|
52
52
|
className: "newspopup-dialog-popup-body",
|
|
53
53
|
role: "body"
|
|
54
54
|
}, /*#__PURE__*/React.createElement("iframe", {
|
|
55
|
-
src: _this.props.newsDocument
|
|
55
|
+
src: _this.props.newsDocument.replace('{lang}', LocaleUtils.lang())
|
|
56
56
|
}), /*#__PURE__*/React.createElement("div", {
|
|
57
57
|
className: "newspopup-dialog-popup-buttonbar"
|
|
58
58
|
}, /*#__PURE__*/React.createElement("button", {
|
|
@@ -127,7 +127,7 @@ var NewsPopup = /*#__PURE__*/function (_React$Component) {
|
|
|
127
127
|
}(React.Component);
|
|
128
128
|
_defineProperty(NewsPopup, "availableIn3D", true);
|
|
129
129
|
_defineProperty(NewsPopup, "propTypes", {
|
|
130
|
-
/** URL to the news HTML document to display in the popup.
|
|
130
|
+
/** URL to the news HTML document to display in the popup. Can contain `{lang}` as a placeholder which will be replaced with the current viewer language.*/
|
|
131
131
|
newsDocument: PropTypes.string,
|
|
132
132
|
/** Revision of the document. */
|
|
133
133
|
newsRev: PropTypes.string,
|
package/plugins/Portal.js
CHANGED
|
@@ -133,6 +133,7 @@ var Portal = /*#__PURE__*/function (_React$Component) {
|
|
|
133
133
|
}, /*#__PURE__*/React.createElement(ThemeList, {
|
|
134
134
|
collapsibleGroups: this.props.collapsibleGroups,
|
|
135
135
|
dontPreserveSettingsOnSwitch: !preserveSettings,
|
|
136
|
+
expandGroups: this.props.expandGroups,
|
|
136
137
|
filter: this.state.filter
|
|
137
138
|
})), /*#__PURE__*/React.createElement("div", {
|
|
138
139
|
className: "portal-bottombar"
|
|
@@ -169,6 +170,8 @@ _defineProperty(Portal, "propTypes", {
|
|
|
169
170
|
collapsibleGroups: PropTypes.bool,
|
|
170
171
|
currentTask: PropTypes.string,
|
|
171
172
|
currentTheme: PropTypes.object,
|
|
173
|
+
/** Whether to expand theme groups by default. */
|
|
174
|
+
expandGroups: PropTypes.bool,
|
|
172
175
|
keepMenuOpen: PropTypes.bool,
|
|
173
176
|
/** Name of a logo image below assets/img. */
|
|
174
177
|
logo: PropTypes.string,
|
|
@@ -186,7 +189,6 @@ _defineProperty(Portal, "propTypes", {
|
|
|
186
189
|
userName: PropTypes.string
|
|
187
190
|
});
|
|
188
191
|
_defineProperty(Portal, "defaultProps", {
|
|
189
|
-
collapsibleGroups: true,
|
|
190
192
|
menuItems: []
|
|
191
193
|
});
|
|
192
194
|
var selector = function selector(state) {
|
package/plugins/Print.js
CHANGED
|
@@ -254,7 +254,7 @@ var Print = /*#__PURE__*/function (_React$Component) {
|
|
|
254
254
|
return /*#__PURE__*/React.createElement("option", {
|
|
255
255
|
key: item.name,
|
|
256
256
|
value: item.name
|
|
257
|
-
}, _this.translateLayoutName(item
|
|
257
|
+
}, _this.translateLayoutName(item));
|
|
258
258
|
})))), _this.props.formats.length > 1 ? /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("td", null, LocaleUtils.tr("print.format")), /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement("select", {
|
|
259
259
|
disabled: _this.state.printSeriesEnabled,
|
|
260
260
|
name: "FORMAT",
|
|
@@ -782,9 +782,9 @@ var Print = /*#__PURE__*/function (_React$Component) {
|
|
|
782
782
|
});
|
|
783
783
|
});
|
|
784
784
|
});
|
|
785
|
-
_defineProperty(_this, "translateLayoutName", function (
|
|
786
|
-
var _this$props$theme$tra, _this$props$theme$tra2;
|
|
787
|
-
return (_this$props$theme$tra = (_this$props$theme$tra2 = _this.props.theme.translations) === null || _this$props$theme$tra2 === void 0 || (_this$props$theme$tra2 = _this$props$theme$tra2.layouts) === null || _this$props$theme$tra2 === void 0 ? void 0 : _this$props$theme$tra2[
|
|
785
|
+
_defineProperty(_this, "translateLayoutName", function (item) {
|
|
786
|
+
var _ref9, _ref10, _this$props$theme$tra, _this$props$theme$tra2, _this$props$theme$tra3;
|
|
787
|
+
return (_ref9 = (_ref10 = (_this$props$theme$tra = (_this$props$theme$tra2 = _this.props.theme.translations) === null || _this$props$theme$tra2 === void 0 || (_this$props$theme$tra2 = _this$props$theme$tra2.layouts) === null || _this$props$theme$tra2 === void 0 ? void 0 : _this$props$theme$tra2[item.title]) !== null && _this$props$theme$tra !== void 0 ? _this$props$theme$tra : (_this$props$theme$tra3 = _this.props.theme.translations) === null || _this$props$theme$tra3 === void 0 || (_this$props$theme$tra3 = _this$props$theme$tra3.layouts) === null || _this$props$theme$tra3 === void 0 ? void 0 : _this$props$theme$tra3[item.name]) !== null && _ref10 !== void 0 ? _ref10 : item.title) !== null && _ref9 !== void 0 ? _ref9 : item.name;
|
|
788
788
|
});
|
|
789
789
|
_this.printForm = null;
|
|
790
790
|
_this.state.grid = props.gridInitiallyEnabled;
|
package/plugins/Redlining.js
CHANGED
|
@@ -220,6 +220,15 @@ var Redlining = /*#__PURE__*/function (_React$Component) {
|
|
|
220
220
|
geomType: null,
|
|
221
221
|
text: ""
|
|
222
222
|
}
|
|
223
|
+
} : null, toolEnabled("Clone") ? {
|
|
224
|
+
key: "Clone",
|
|
225
|
+
tooltip: LocaleUtils.tr("redlining.clone"),
|
|
226
|
+
icon: "clone",
|
|
227
|
+
data: {
|
|
228
|
+
action: "Clone",
|
|
229
|
+
geomType: null
|
|
230
|
+
},
|
|
231
|
+
disabled: !_this.props.redlining.selectedFeature
|
|
223
232
|
} : null, {
|
|
224
233
|
key: "Delete",
|
|
225
234
|
tooltip: LocaleUtils.tr("redlining.delete"),
|
package/plugins/ThemeSwitcher.js
CHANGED
|
@@ -106,6 +106,7 @@ var ThemeSwitcher = /*#__PURE__*/function (_React$Component) {
|
|
|
106
106
|
allowAddingOtherThemeLayers: showAddThemeLayersButton,
|
|
107
107
|
allowAddingOtherThemes: showAddThemeButton,
|
|
108
108
|
collapsibleGroups: _this2.props.collapsibleGroups,
|
|
109
|
+
expandGroups: _this2.props.expandGroups,
|
|
109
110
|
filter: _this2.state.filter,
|
|
110
111
|
showDefaultThemeSelector: _this2.props.showDefaultThemeSelector,
|
|
111
112
|
showLayerAfterChangeTheme: _this2.props.showLayerAfterChangeTheme
|
|
@@ -128,6 +129,8 @@ _defineProperty(ThemeSwitcher, "propTypes", {
|
|
|
128
129
|
/** Whether to allow collapsing theme groups. */
|
|
129
130
|
collapsibleGroups: PropTypes.bool,
|
|
130
131
|
currentTask: PropTypes.object,
|
|
132
|
+
/** Whether to expand theme groups by default. */
|
|
133
|
+
expandGroups: PropTypes.bool,
|
|
131
134
|
/** Whether to hide the add theme button. Note: the button will also be hidden if the global option `allowAddingOtherThemes` is `false`. */
|
|
132
135
|
hideAddThemeButton: PropTypes.bool,
|
|
133
136
|
/** Whether to hide the add theme layers button. Note: the button will also be hidden if the global option `allowAddingOtherThemes` is `false`. */
|
|
@@ -104,7 +104,7 @@ var EditingSupport = /*#__PURE__*/function (_React$Component) {
|
|
|
104
104
|
_this.props.map.addInteraction(drawInteraction);
|
|
105
105
|
_this.interaction = drawInteraction;
|
|
106
106
|
_this.setState({
|
|
107
|
-
showRecordLocation: ["Point", "LineString"].includes(geomType)
|
|
107
|
+
showRecordLocation: ["Point", "LineString", "MultiPoint", "MultiLineString"].includes(geomType)
|
|
108
108
|
});
|
|
109
109
|
});
|
|
110
110
|
_defineProperty(_this, "addEditInteraction", function () {
|
|
@@ -199,7 +199,7 @@ var EditingSupport = /*#__PURE__*/function (_React$Component) {
|
|
|
199
199
|
}, {
|
|
200
200
|
key: "render",
|
|
201
201
|
value: function render() {
|
|
202
|
-
if (this.state.showRecordLocation) {
|
|
202
|
+
if (this.state.showRecordLocation && this.props.editContext.geomType) {
|
|
203
203
|
var geomType = this.props.editContext.geomType.replace(/Z$/, '');
|
|
204
204
|
return /*#__PURE__*/React.createElement(LocationRecorder, {
|
|
205
205
|
drawInteraction: this.interaction,
|
|
@@ -376,7 +376,7 @@ var RedliningSupport = /*#__PURE__*/function (_React$Component) {
|
|
|
376
376
|
_defineProperty(_this, "addTransformInteraction", function () {
|
|
377
377
|
var redliningLayer = _this.searchRedliningLayer(_this.props.redlining.layer);
|
|
378
378
|
if (!redliningLayer) {
|
|
379
|
-
return;
|
|
379
|
+
return null;
|
|
380
380
|
}
|
|
381
381
|
var transformInteraction = _this.setupTransformInteraction(redliningLayer, [], true);
|
|
382
382
|
transformInteraction.on('select', function (evt) {
|
|
@@ -390,6 +390,7 @@ var RedliningSupport = /*#__PURE__*/function (_React$Component) {
|
|
|
390
390
|
_this.commitFeatures(removed, _this.props.redlining);
|
|
391
391
|
});
|
|
392
392
|
_this.picking = true;
|
|
393
|
+
return transformInteraction;
|
|
393
394
|
});
|
|
394
395
|
_defineProperty(_this, "maybeEnterTemporaryDrawMode", function (ev) {
|
|
395
396
|
var redliningLayer = _this.searchRedliningLayer(_this.props.redlining.layer);
|
|
@@ -537,6 +538,45 @@ var RedliningSupport = /*#__PURE__*/function (_React$Component) {
|
|
|
537
538
|
_this.selectedFeatures = [];
|
|
538
539
|
}
|
|
539
540
|
});
|
|
541
|
+
_defineProperty(_this, "cloneCurrentFeatures", function () {
|
|
542
|
+
if (isEmpty(_this.selectedFeatures)) {
|
|
543
|
+
return;
|
|
544
|
+
}
|
|
545
|
+
var _shiftCoordinates = function shiftCoordinates(coords) {
|
|
546
|
+
if (typeof coords[0] === 'number') {
|
|
547
|
+
coords[0] += 10;
|
|
548
|
+
coords[1] += 10;
|
|
549
|
+
} else {
|
|
550
|
+
coords.map(_shiftCoordinates);
|
|
551
|
+
}
|
|
552
|
+
};
|
|
553
|
+
var cloneIds = [];
|
|
554
|
+
var newFeatureObjs = _this.selectedFeatures.map(function (feature) {
|
|
555
|
+
_this.deselectFeature(feature, false);
|
|
556
|
+
var featureObj = _this.serializeFeature(feature);
|
|
557
|
+
featureObj.id = uuidv4();
|
|
558
|
+
_shiftCoordinates(featureObj.geometry.coordinates);
|
|
559
|
+
cloneIds.push(featureObj.id);
|
|
560
|
+
return featureObj;
|
|
561
|
+
});
|
|
562
|
+
_this.updateRedliningState(true);
|
|
563
|
+
var layer = {
|
|
564
|
+
id: _this.props.redlining.layer,
|
|
565
|
+
title: _this.props.redlining.layerTitle,
|
|
566
|
+
role: LayerRole.USERLAYER
|
|
567
|
+
};
|
|
568
|
+
_this.props.addLayerFeatures(layer, newFeatureObjs);
|
|
569
|
+
_this.waitForFeatureAndLayer(_this.props.redlining.layer, cloneIds[0], function (l) {
|
|
570
|
+
var features = cloneIds.map(function (id) {
|
|
571
|
+
return l.getSource().getFeatureById(id);
|
|
572
|
+
});
|
|
573
|
+
_this.selectFeatures(features);
|
|
574
|
+
while (_this.interactions.length > 0) {
|
|
575
|
+
_this.props.map.removeInteraction(_this.interactions.shift());
|
|
576
|
+
}
|
|
577
|
+
_this.addTransformInteraction().setSelection(new ol.Collection(features));
|
|
578
|
+
});
|
|
579
|
+
});
|
|
540
580
|
_defineProperty(_this, "updateRedliningState", function (firstSelection) {
|
|
541
581
|
if (_this.selectedFeatures.length > 0) {
|
|
542
582
|
var features = _this.selectedFeatures;
|
|
@@ -574,17 +614,23 @@ var RedliningSupport = /*#__PURE__*/function (_React$Component) {
|
|
|
574
614
|
});
|
|
575
615
|
_this.updateRedliningState(firstSelection);
|
|
576
616
|
});
|
|
617
|
+
_defineProperty(_this, "deselectFeature", function (feature, updateState) {
|
|
618
|
+
var styleName = feature.get("shape") === "Text" ? "text" : "default";
|
|
619
|
+
var style = FeatureStyles[styleName](feature, feature.get('styleOptions'));
|
|
620
|
+
feature.setStyle(style);
|
|
621
|
+
feature.un('change', _this.updateMeasurements);
|
|
622
|
+
_this.selectedFeatures = _this.selectedFeatures.filter(function (f) {
|
|
623
|
+
return f !== feature;
|
|
624
|
+
});
|
|
625
|
+
if (updateState) {
|
|
626
|
+
_this.updateRedliningState(false);
|
|
627
|
+
}
|
|
628
|
+
});
|
|
577
629
|
_defineProperty(_this, "commitFeatures", function (features, redliningProps) {
|
|
578
630
|
var newFeature = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
579
631
|
var featureObjects = features.map(function (feature) {
|
|
580
632
|
var _featureObj$geometry;
|
|
581
|
-
|
|
582
|
-
var style = FeatureStyles[styleName](feature, feature.get('styleOptions'));
|
|
583
|
-
feature.setStyle(style);
|
|
584
|
-
feature.un('change', _this.updateMeasurements);
|
|
585
|
-
_this.selectedFeatures = _this.selectedFeatures.filter(function (f) {
|
|
586
|
-
return f !== feature;
|
|
587
|
-
});
|
|
633
|
+
_this.deselectFeature(feature, false);
|
|
588
634
|
var featureObj = _this.serializeFeature(feature);
|
|
589
635
|
// Don't commit empty/invalid features
|
|
590
636
|
if (featureObj.shape === "Text" && !featureObj.properties.label || featureObj.shape === "Circle" && featureObj.circleParams.radius === 0 || ((_featureObj$geometry = featureObj.geometry) === null || _featureObj$geometry === void 0 ? void 0 : _featureObj$geometry.type) === "Polygon" && feature.getGeometry().getArea() === 0) {
|
|
@@ -631,12 +677,9 @@ var RedliningSupport = /*#__PURE__*/function (_React$Component) {
|
|
|
631
677
|
_this.commitFeatures(_this.selectedFeatures, redliningProps, false);
|
|
632
678
|
} else {
|
|
633
679
|
_this.selectedFeatures.forEach(function (feature) {
|
|
634
|
-
|
|
635
|
-
var style = FeatureStyles[styleName](feature, feature.get('styleOptions'));
|
|
636
|
-
feature.setStyle(style);
|
|
637
|
-
feature.un('change', _this.updateMeasurements);
|
|
680
|
+
_this.deselectFeature(feature, false);
|
|
638
681
|
});
|
|
639
|
-
_this.
|
|
682
|
+
_this.updateRedliningState(false);
|
|
640
683
|
}
|
|
641
684
|
_this.props.map.un('click', _this.maybeEnterTemporaryDrawMode);
|
|
642
685
|
_this.picking = false;
|
|
@@ -773,6 +816,13 @@ var RedliningSupport = /*#__PURE__*/function (_React$Component) {
|
|
|
773
816
|
}));
|
|
774
817
|
return;
|
|
775
818
|
}
|
|
819
|
+
if (this.props.redlining.action === 'Clone') {
|
|
820
|
+
this.cloneCurrentFeatures();
|
|
821
|
+
this.props.changeRedliningState(_objectSpread(_objectSpread({}, prevProps.redlining), {}, {
|
|
822
|
+
selectedFeature: null
|
|
823
|
+
}));
|
|
824
|
+
return;
|
|
825
|
+
}
|
|
776
826
|
if (this.props.redlining.action === 'Export') {
|
|
777
827
|
this["export"]();
|
|
778
828
|
this.props.changeRedliningState(_objectSpread(_objectSpread({}, prevProps.redlining), {}, {
|
|
@@ -40,3 +40,37 @@
|
|
|
40
40
|
#Editing select.editing-feature-select:disabled {
|
|
41
41
|
cursor: not-allowed;
|
|
42
42
|
}
|
|
43
|
+
|
|
44
|
+
.editing-clone-dialog {
|
|
45
|
+
display: flex;
|
|
46
|
+
flex-direction: column;
|
|
47
|
+
gap: 0.25em;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.editing-clone-header {
|
|
51
|
+
font-weight: bold;
|
|
52
|
+
margin-bottom: 0.25em;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.editing-clone-table {
|
|
56
|
+
margin-top: calc(-0.25em - 1px);
|
|
57
|
+
background: var(--list-bg-color);
|
|
58
|
+
border: 1px solid var(--border-color);
|
|
59
|
+
width: 100%;
|
|
60
|
+
table-layout: fixed;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.editing-clone-table td {
|
|
64
|
+
padding: 0.125em 0.25em;
|
|
65
|
+
white-space: nowrap;
|
|
66
|
+
overflow: hidden;
|
|
67
|
+
text-overflow: ellipsis;
|
|
68
|
+
width: 50%;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.editing-clone-attribute {
|
|
72
|
+
display: flex;
|
|
73
|
+
align-items: center;
|
|
74
|
+
gap: 0.5em;
|
|
75
|
+
cursor: pointer;
|
|
76
|
+
}
|