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.
Files changed (55) hide show
  1. package/actions/layers.js +6 -29
  2. package/components/AttributeForm.js +106 -77
  3. package/components/AttributeTableWidget.js +89 -88
  4. package/components/IdentifyViewer.js +4 -2
  5. package/components/LinkFeatureForm.js +17 -9
  6. package/components/LocationRecorder.js +1 -1
  7. package/components/PickFeature.js +45 -33
  8. package/components/QtDesignerForm.js +20 -18
  9. package/components/StandardApp.js +4 -0
  10. package/components/ThemeList.js +9 -10
  11. package/components/map3d/Map3D.js +6 -3
  12. package/package.json +2 -1
  13. package/plugins/Cyclomedia.js +5 -4
  14. package/plugins/Editing.js +307 -72
  15. package/plugins/FeatureForm.js +103 -111
  16. package/plugins/LayerTree.js +4 -1
  17. package/plugins/NewsPopup.js +2 -2
  18. package/plugins/Portal.js +3 -1
  19. package/plugins/Print.js +4 -4
  20. package/plugins/Redlining.js +9 -0
  21. package/plugins/ThemeSwitcher.js +3 -0
  22. package/plugins/map/EditingSupport.js +2 -2
  23. package/plugins/map/RedliningSupport.js +63 -13
  24. package/plugins/style/Editing.css +34 -0
  25. package/reducers/editing.js +12 -7
  26. package/reducers/layers.js +27 -5
  27. package/static/translations/bg-BG.json +10 -0
  28. package/static/translations/ca-ES.json +10 -0
  29. package/static/translations/cs-CZ.json +10 -0
  30. package/static/translations/de-CH.json +10 -0
  31. package/static/translations/de-DE.json +10 -0
  32. package/static/translations/en-US.json +11 -1
  33. package/static/translations/es-ES.json +10 -0
  34. package/static/translations/fi-FI.json +10 -0
  35. package/static/translations/fr-FR.json +10 -0
  36. package/static/translations/hu-HU.json +10 -0
  37. package/static/translations/it-IT.json +10 -0
  38. package/static/translations/ja-JP.json +10 -0
  39. package/static/translations/nl-NL.json +10 -0
  40. package/static/translations/no-NO.json +10 -0
  41. package/static/translations/pl-PL.json +10 -0
  42. package/static/translations/pt-BR.json +10 -0
  43. package/static/translations/pt-PT.json +10 -0
  44. package/static/translations/ro-RO.json +10 -0
  45. package/static/translations/ru-RU.json +10 -0
  46. package/static/translations/sv-SE.json +10 -0
  47. package/static/translations/tr-TR.json +10 -0
  48. package/static/translations/tsconfig.json +10 -0
  49. package/static/translations/uk-UA.json +10 -0
  50. package/utils/EditingUtils.js +15 -13
  51. package/utils/ElevationInterface.js +1 -2
  52. package/utils/LayerUtils.js +5 -3
  53. package/utils/MapUtils.js +2 -11
  54. package/utils/ServiceLayerUtils.js +53 -2
  55. package/utils/ThemeUtils.js +3 -1
@@ -1,6 +1,16 @@
1
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 _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
3
+ function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
4
+ function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
5
+ function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
2
6
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
3
7
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
8
+ function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
9
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
10
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
11
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
12
+ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
13
+ function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
4
14
  function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
5
15
  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); } }
6
16
  function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
@@ -24,12 +34,14 @@ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e
24
34
 
25
35
  import React from 'react';
26
36
  import { connect } from 'react-redux';
37
+ import { parseNumber } from '@norbulcz/num-parse';
38
+ import dateParser from 'any-date-parser';
27
39
  import isEmpty from 'lodash.isempty';
28
40
  import isEqual from 'lodash.isequal';
29
41
  import PropTypes from 'prop-types';
30
42
  import { v4 as uuidv4 } from 'uuid';
31
43
  import { setEditContext, clearEditContext } from '../actions/editing';
32
- import { LayerRole, addLayerFeatures, removeLayer, refreshLayer, changeLayerProperty } from '../actions/layers';
44
+ import { addLayerFeatures, removeLayer, changeLayerProperty } from '../actions/layers';
33
45
  import { setSnappingConfig } from '../actions/map';
34
46
  import { setCurrentTask, setCurrentTaskBlocked } from '../actions/task';
35
47
  import AttributeForm from '../components/AttributeForm';
@@ -67,7 +79,8 @@ var Editing = /*#__PURE__*/function (_React$Component) {
67
79
  pickedFeatures: null,
68
80
  busy: false,
69
81
  minimized: false,
70
- drawPick: false
82
+ drawPick: false,
83
+ pendingClone: null
71
84
  });
72
85
  _defineProperty(_this, "onShow", function () {
73
86
  if (_this.props.taskData) {
@@ -85,18 +98,68 @@ var Editing = /*#__PURE__*/function (_React$Component) {
85
98
  drawPick: false
86
99
  });
87
100
  });
101
+ _defineProperty(_this, "renderCloneAttributeDialog", function () {
102
+ var quickButtons = [{
103
+ key: 'All',
104
+ label: LocaleUtils.tr("editing.clone_all")
105
+ }, {
106
+ key: 'None',
107
+ label: LocaleUtils.tr("editing.clone_none")
108
+ }, {
109
+ key: 'Visible',
110
+ label: LocaleUtils.tr("editing.clone_visible")
111
+ }];
112
+ var actionButtons = [{
113
+ key: 'Copy',
114
+ label: LocaleUtils.tr("editing.clone_copy"),
115
+ icon: "ok",
116
+ extraClasses: "button-accept"
117
+ }, {
118
+ key: 'DontCopy',
119
+ label: LocaleUtils.tr("editing.clone_dontcopy"),
120
+ icon: "remove",
121
+ extraClasses: "button-reject"
122
+ }];
123
+ return /*#__PURE__*/React.createElement("div", {
124
+ className: "editing-body"
125
+ }, /*#__PURE__*/React.createElement("div", {
126
+ className: "editing-clone-dialog"
127
+ }, /*#__PURE__*/React.createElement("div", {
128
+ className: "editing-clone-header"
129
+ }, LocaleUtils.tr("editing.clone_select_attrs")), /*#__PURE__*/React.createElement(ButtonBar, {
130
+ buttons: quickButtons,
131
+ onClick: _this.onCloneAttrQuickSelect
132
+ }), /*#__PURE__*/React.createElement("table", {
133
+ className: "editing-clone-table"
134
+ }, /*#__PURE__*/React.createElement("tbody", null, _this.state.pendingClone.matchingAttributes.map(function (attr) {
135
+ return /*#__PURE__*/React.createElement("tr", {
136
+ key: attr.fieldId
137
+ }, /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement("label", {
138
+ className: "editing-clone-attribute",
139
+ key: attr.fieldId
140
+ }, /*#__PURE__*/React.createElement("input", {
141
+ checked: _this.state.pendingClone.selectedAttributes.includes(attr.fieldId),
142
+ onChange: function onChange() {
143
+ return _this.toggleAttribute(attr.fieldId);
144
+ },
145
+ type: "checkbox"
146
+ }), /*#__PURE__*/React.createElement("span", {
147
+ className: "editing-clone-attribute-name"
148
+ }, attr.fieldName, !attr.visible ? /*#__PURE__*/React.createElement("i", null, " " + LocaleUtils.tr("editing.clone_hidden")) : "", attr.autoCalculated ? /*#__PURE__*/React.createElement("i", null, " " + LocaleUtils.tr("editing.clone_defaulted")) : ""))), /*#__PURE__*/React.createElement("td", {
149
+ title: attr.value
150
+ }, attr.value));
151
+ }))), /*#__PURE__*/React.createElement(ButtonBar, {
152
+ buttons: actionButtons,
153
+ onClick: _this.onCloneAction
154
+ })));
155
+ });
88
156
  _defineProperty(_this, "renderBody", function () {
89
- if (!_this.props.theme || isEmpty(_this.props.theme.editConfig)) {
90
- return /*#__PURE__*/React.createElement("div", {
91
- role: "body",
92
- style: {
93
- padding: "1em"
94
- }
95
- }, LocaleUtils.tr("editing.noeditablelayers"));
157
+ var _this$props$editConte, _editConfig$permissio;
158
+ // Show clone attribute selection dialog if pending
159
+ if (_this.state.pendingClone) {
160
+ return _this.renderCloneAttributeDialog();
96
161
  }
97
- var editConfig = _this.props.theme.editConfig;
98
- var curConfig = editConfig[_this.state.selectedLayer];
99
- if (!curConfig) {
162
+ if (!_this.props.theme || isEmpty(_this.props.editConfigs)) {
100
163
  return /*#__PURE__*/React.createElement("div", {
101
164
  role: "body",
102
165
  style: {
@@ -104,7 +167,8 @@ var Editing = /*#__PURE__*/function (_React$Component) {
104
167
  }
105
168
  }, LocaleUtils.tr("editing.noeditablelayers"));
106
169
  }
107
- var editPermissions = curConfig.permissions || {};
170
+ var editConfig = (_this$props$editConte = _this.props.editContext) === null || _this$props$editConte === void 0 ? void 0 : _this$props$editConte.editConfig;
171
+ var editPermissions = (_editConfig$permissio = editConfig === null || editConfig === void 0 ? void 0 : editConfig.permissions) !== null && _editConfig$permissio !== void 0 ? _editConfig$permissio : {};
108
172
  var actionButtons = [];
109
173
  actionButtons.push({
110
174
  key: 'Pick',
@@ -136,7 +200,7 @@ var Editing = /*#__PURE__*/function (_React$Component) {
136
200
  });
137
201
  }
138
202
  var featureSelection = null;
139
- if (_this.state.pickedFeatures && _this.state.pickedFeatures.length > 1) {
203
+ if (editConfig && _this.state.pickedFeatures && _this.state.pickedFeatures.length > 1) {
140
204
  var featureText = LocaleUtils.tr("editing.feature");
141
205
  featureSelection = /*#__PURE__*/React.createElement("div", {
142
206
  className: "editing-feature-selection"
@@ -151,7 +215,7 @@ var Editing = /*#__PURE__*/function (_React$Component) {
151
215
  return /*#__PURE__*/React.createElement("option", {
152
216
  key: feature.id,
153
217
  value: feature.id
154
- }, curConfig.displayField ? feature.properties[curConfig.displayField] : featureText + " " + feature.id);
218
+ }, editConfig.displayField ? feature.properties[editConfig.displayField] : featureText + " " + feature.id);
155
219
  })));
156
220
  }
157
221
  var pickBar = null;
@@ -168,17 +232,18 @@ var Editing = /*#__PURE__*/function (_React$Component) {
168
232
  });
169
233
  }
170
234
  var attributeForm = null;
171
- if (_this.props.editContext.feature && (_this.props.editContext.action === "Pick" || _this.props.editContext.feature.geometry)) {
235
+ if (editConfig && _this.props.editContext.feature && (_this.props.editContext.action === "Pick" || _this.props.editContext.feature.geometry)) {
236
+ var _this$props$layers$fi;
237
+ var translations = (_this$props$layers$fi = _this.props.layers.find(function (layer) {
238
+ return layer.wms_name === _this.props.editContext.mapPrefix;
239
+ })) === null || _this$props$layers$fi === void 0 ? void 0 : _this$props$layers$fi.translations;
172
240
  attributeForm = /*#__PURE__*/React.createElement(AttributeForm, {
173
- editConfig: curConfig,
174
241
  editContext: _this.props.editContext,
175
242
  iface: _this.props.iface,
176
- onCommit: _this.updatePickedFeatures
243
+ onCommit: _this.updatePickedFeatures,
244
+ translations: translations
177
245
  });
178
246
  }
179
- var themeSublayers = _this.props.layers.reduce(function (accum, layer) {
180
- return layer.role === LayerRole.THEME ? accum.concat(LayerUtils.getSublayerNames(layer)) : accum;
181
- }, []);
182
247
  return /*#__PURE__*/React.createElement("div", {
183
248
  className: "editing-body"
184
249
  }, /*#__PURE__*/React.createElement("div", {
@@ -190,20 +255,33 @@ var Editing = /*#__PURE__*/function (_React$Component) {
190
255
  return _this.changeSelectedLayer(ev.target.value);
191
256
  },
192
257
  value: _this.state.selectedLayer || ""
193
- }, Object.keys(editConfig).filter(function (layerId) {
194
- return themeSublayers.includes(layerId);
195
- }).map(function (layerId) {
196
- var _this$props$theme$tra, _this$props$theme$tra2, _LayerUtils$searchLay, _LayerUtils$searchLay2;
197
- var layerName = editConfig[layerId].layerName;
198
- var layerTitle = editConfig[layerId].layerTitle ? (_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.layertree) === null || _this$props$theme$tra2 === void 0 ? void 0 : _this$props$theme$tra2[layerName]) !== null && _this$props$theme$tra !== void 0 ? _this$props$theme$tra : editConfig[layerId].layerTitle : (_LayerUtils$searchLay = (_LayerUtils$searchLay2 = LayerUtils.searchLayer(_this.props.layers, _this.props.theme.url, layerName)) === null || _LayerUtils$searchLay2 === void 0 || (_LayerUtils$searchLay2 = _LayerUtils$searchLay2.sublayer) === null || _LayerUtils$searchLay2 === void 0 ? void 0 : _LayerUtils$searchLay2.title) !== null && _LayerUtils$searchLay !== void 0 ? _LayerUtils$searchLay : layerName;
199
- return /*#__PURE__*/React.createElement("option", {
200
- key: layerId,
201
- value: layerId
202
- }, layerTitle);
258
+ }, /*#__PURE__*/React.createElement("option", {
259
+ disabled: true,
260
+ value: ""
261
+ }, LocaleUtils.tr("editing.selectlayer")), Object.entries(_this.props.editConfigs).map(function (_ref) {
262
+ var _ref2 = _slicedToArray(_ref, 2),
263
+ mapName = _ref2[0],
264
+ serviceConfigs = _ref2[1];
265
+ return Object.entries(serviceConfigs).map(function (_ref3) {
266
+ var _ref5, _ref6, _match$layer$translat, _match$layer$translat2, _match$sublayer;
267
+ var _ref4 = _slicedToArray(_ref3, 2),
268
+ layerName = _ref4[0],
269
+ edConfig = _ref4[1];
270
+ var match = LayerUtils.searchLayer(_this.props.layers, 'wms_name', mapName, 'name', layerName);
271
+ if (!match) {
272
+ return null;
273
+ }
274
+ var layerTitle = (_ref5 = (_ref6 = (_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 : edConfig.layerTitle) !== null && _ref6 !== void 0 ? _ref6 : match === null || match === void 0 || (_match$sublayer = match.sublayer) === null || _match$sublayer === void 0 ? void 0 : _match$sublayer.title) !== null && _ref5 !== void 0 ? _ref5 : layerName;
275
+ var value = mapName + "#" + layerName;
276
+ return /*#__PURE__*/React.createElement("option", {
277
+ key: value,
278
+ value: value
279
+ }, layerTitle);
280
+ });
203
281
  }))), /*#__PURE__*/React.createElement(ButtonBar, {
204
282
  active: _this.state.drawPick ? "Draw" : _this.props.editContext.action,
205
283
  buttons: actionButtons,
206
- disabled: _this.props.editContext.changed || _this.props.editContext.id !== _this.props.currentEditContext,
284
+ disabled: !editConfig || _this.props.editContext.changed || _this.props.editContext.id !== _this.props.currentEditContext,
207
285
  onClick: _this.actionClicked
208
286
  }), featureSelection, pickBar, attributeForm);
209
287
  });
@@ -217,17 +295,13 @@ var Editing = /*#__PURE__*/function (_React$Component) {
217
295
  layer: _this.state.selectedLayer
218
296
  });
219
297
  } else if (action === "Draw") {
220
- var editConfig = _this.props.theme.editConfig;
221
- var curConfig = editConfig[_this.state.selectedLayer];
222
298
  var featureSkel = {
223
299
  type: "Feature",
224
300
  properties: {}
225
301
  };
226
- var mapPrefix = (curConfig.editDataset.match(/^[^.]+\./) || [""])[0];
227
- getFeatureTemplate(curConfig, featureSkel, _this.props.iface, mapPrefix, _this.props.map.projection, function (feature) {
302
+ getFeatureTemplate(_this.props.editContext.editConfig, featureSkel, _this.props.iface, _this.props.editContext.mapPrefix, _this.props.map.projection, function (feature) {
228
303
  _this.props.setEditContext('Editing', _objectSpread(_objectSpread({}, data), {}, {
229
- feature: feature,
230
- geomReadOnly: false
304
+ feature: feature
231
305
  }));
232
306
  });
233
307
  } else {
@@ -235,13 +309,13 @@ var Editing = /*#__PURE__*/function (_React$Component) {
235
309
  }
236
310
  });
237
311
  _defineProperty(_this, "pickFilter", function (feature) {
238
- var _this$props$theme$edi;
239
- var geomType = (_this$props$theme$edi = _this.props.theme.editConfig[_this.state.selectedLayer]) === null || _this$props$theme$edi === void 0 ? void 0 : _this$props$theme$edi.geomType;
312
+ var geomType = _this.props.editContext.geomType;
240
313
  return feature.geometry && (feature.geometry.type === geomType || "Multi" + feature.geometry.type === geomType || feature.geometry.type.replace(/^Multi/, "") === geomType && feature.geometry.coordinates.length === 1);
241
314
  });
242
- _defineProperty(_this, "geomPicked", function (layer, feature) {
243
- var _this$props$theme$edi2;
244
- var geomType = (_this$props$theme$edi2 = _this.props.theme.editConfig[_this.state.selectedLayer]) === null || _this$props$theme$edi2 === void 0 ? void 0 : _this$props$theme$edi2.geomType;
315
+ _defineProperty(_this, "geomPicked", function (layer, feature, mapName) {
316
+ var _this$props$editConte2;
317
+ console.log(mapName);
318
+ var geomType = _this.props.editContext.geomType;
245
319
  var geometry = feature.geometry;
246
320
  if (geometry.type !== geomType) {
247
321
  if ("Multi" + feature.geometry.type === geomType) {
@@ -266,27 +340,183 @@ var Editing = /*#__PURE__*/function (_React$Component) {
266
340
  geometry: geometry,
267
341
  id: uuidv4()
268
342
  };
343
+ var targetFields = (_this$props$editConte2 = _this.props.editContext.editConfig) === null || _this$props$editConte2 === void 0 ? void 0 : _this$props$editConte2.fields;
344
+ var matchingAttributes = [];
345
+ if (!isEmpty(targetFields)) {
346
+ var _this$props$editConfi;
347
+ var sourceProperties = feature.properties || {};
348
+
349
+ // Get source layer's field configuration and build name-to-id mapping
350
+ var sourceFields = (_this$props$editConfi = _this.props.editConfigs[mapName]) === null || _this$props$editConfi === void 0 || (_this$props$editConfi = _this$props$editConfi[layer]) === null || _this$props$editConfi === void 0 ? void 0 : _this$props$editConfi.fields;
351
+ var sourceNameToIdMap = (sourceFields || []).reduce(function (res, field) {
352
+ return _objectSpread(_objectSpread({}, res), {}, _defineProperty(_defineProperty({}, sourceFields.name, sourceFields.id), sourceFields.id, sourceFields.id));
353
+ }, {});
354
+ var sourcePropertiesById = Object.entries(sourceProperties).reduce(function (res, _ref7) {
355
+ var _ref8 = _slicedToArray(_ref7, 2),
356
+ key = _ref8[0],
357
+ value = _ref8[1];
358
+ return _objectSpread(_objectSpread({}, res), {}, _defineProperty({}, sourceNameToIdMap[key] || key, value));
359
+ }, {});
360
+
361
+ // Build list of matching attributes with metadata
362
+ targetFields.forEach(function (field) {
363
+ if (!field.expression) {
364
+ var value = sourcePropertiesById[field.id];
365
+ if (value !== null && value !== undefined && value !== '') {
366
+ var _field$constraints;
367
+ // Parse number values
368
+ if (field.type === 'number') {
369
+ if (typeof value === 'string') {
370
+ var numValue = parseNumber(value.replace(',', '.'));
371
+ if (!isNaN(numValue)) {
372
+ value = numValue;
373
+ }
374
+ }
375
+ } else if (field.type === 'boolean') {
376
+ value = !['0', 'false'].includes(String(value).toLowerCase());
377
+ } else if (field.type === 'date') {
378
+ if (typeof value === 'string') {
379
+ value = dateParser.fromString(value).toISOString();
380
+ }
381
+ } else if (field.type === 'list') {
382
+ // Not supported
383
+ return;
384
+ }
385
+ matchingAttributes.push({
386
+ fieldId: field.id,
387
+ fieldName: field.name,
388
+ value: value,
389
+ visible: ((_field$constraints = field.constraints) === null || _field$constraints === void 0 ? void 0 : _field$constraints.hidden) !== true,
390
+ autoCalculated: !!field.defaultValue
391
+ });
392
+ }
393
+ }
394
+ });
395
+ }
396
+ if (matchingAttributes.length > 0) {
397
+ // Default selection: only visible, non-auto-calculated fields
398
+ var defaultSelection = matchingAttributes.filter(function (attr) {
399
+ return attr.visible && !attr.autoCalculated;
400
+ }).map(function (attr) {
401
+ return attr.fieldId;
402
+ });
403
+ _this.setState({
404
+ drawPick: false,
405
+ pendingClone: {
406
+ editFeature: editFeature,
407
+ matchingAttributes: matchingAttributes,
408
+ selectedAttributes: defaultSelection
409
+ }
410
+ });
411
+ } else {
412
+ _this.props.setEditContext('Editing', {
413
+ action: "Draw",
414
+ feature: editFeature,
415
+ changed: true
416
+ });
417
+ _this.setState({
418
+ drawPick: false
419
+ });
420
+ }
421
+ });
422
+ _defineProperty(_this, "confirmCopyAttributes", function () {
423
+ var _this$state$pendingCl = _this.state.pendingClone,
424
+ editFeature = _this$state$pendingCl.editFeature,
425
+ matchingAttributes = _this$state$pendingCl.matchingAttributes,
426
+ selectedAttributes = _this$state$pendingCl.selectedAttributes;
427
+ var copiedProperties = {};
428
+ matchingAttributes.forEach(function (attr) {
429
+ if (selectedAttributes.includes(attr.fieldId)) {
430
+ copiedProperties[attr.fieldId] = attr.value;
431
+ }
432
+ });
433
+ editFeature.properties = copiedProperties;
269
434
  _this.props.setEditContext('Editing', {
270
435
  action: "Draw",
271
436
  feature: editFeature,
272
437
  changed: true
273
438
  });
274
439
  _this.setState({
275
- drawPick: false
440
+ pendingClone: null
441
+ });
442
+ });
443
+ _defineProperty(_this, "cancelCopyAttributes", function () {
444
+ var editFeature = _this.state.pendingClone.editFeature;
445
+ _this.props.setEditContext('Editing', {
446
+ action: "Draw",
447
+ feature: editFeature,
448
+ changed: true
449
+ });
450
+ _this.setState({
451
+ pendingClone: null
452
+ });
453
+ });
454
+ _defineProperty(_this, "toggleAttribute", function (fieldId) {
455
+ _this.setState(function (state) {
456
+ var selectedAttributes = state.pendingClone.selectedAttributes.includes(fieldId) ? state.pendingClone.selectedAttributes.filter(function (id) {
457
+ return id !== fieldId;
458
+ }) : [].concat(_toConsumableArray(state.pendingClone.selectedAttributes), [fieldId]);
459
+ return {
460
+ pendingClone: _objectSpread(_objectSpread({}, state.pendingClone), {}, {
461
+ selectedAttributes: selectedAttributes
462
+ })
463
+ };
276
464
  });
277
465
  });
466
+ _defineProperty(_this, "onCloneAttrQuickSelect", function (action) {
467
+ if (action === 'All') {
468
+ var allFieldIds = _this.state.pendingClone.matchingAttributes.map(function (attr) {
469
+ return attr.fieldId;
470
+ });
471
+ _this.setState(function (state) {
472
+ return {
473
+ pendingClone: _objectSpread(_objectSpread({}, state.pendingClone), {}, {
474
+ selectedAttributes: allFieldIds
475
+ })
476
+ };
477
+ });
478
+ } else if (action === 'None') {
479
+ _this.setState(function (state) {
480
+ return {
481
+ pendingClone: _objectSpread(_objectSpread({}, state.pendingClone), {}, {
482
+ selectedAttributes: []
483
+ })
484
+ };
485
+ });
486
+ } else if (action === 'Visible') {
487
+ var visibleFieldIds = _this.state.pendingClone.matchingAttributes.filter(function (attr) {
488
+ return attr.visible && !attr.autoCalculated;
489
+ }).map(function (attr) {
490
+ return attr.fieldId;
491
+ });
492
+ _this.setState(function (state) {
493
+ return {
494
+ pendingClone: _objectSpread(_objectSpread({}, state.pendingClone), {}, {
495
+ selectedAttributes: visibleFieldIds
496
+ })
497
+ };
498
+ });
499
+ }
500
+ });
501
+ _defineProperty(_this, "onCloneAction", function (action) {
502
+ if (action === 'Copy') {
503
+ _this.confirmCopyAttributes();
504
+ } else if (action === 'DontCopy') {
505
+ _this.cancelCopyAttributes();
506
+ }
507
+ });
278
508
  _defineProperty(_this, "setLayerVisibility", function (selectedLayer, visibility) {
279
509
  if (selectedLayer !== null) {
280
- var path = [];
281
- var sublayer = null;
282
- var layer = _this.props.layers.find(function (l) {
283
- return l.role === LayerRole.THEME && (sublayer = LayerUtils.searchSubLayer(l, 'name', selectedLayer, path));
284
- });
285
- if (layer && sublayer) {
286
- var oldvisibility = sublayer.visibility;
510
+ var _selectedLayer$split = selectedLayer.split("#"),
511
+ _selectedLayer$split2 = _slicedToArray(_selectedLayer$split, 2),
512
+ wmsName = _selectedLayer$split2[0],
513
+ layerName = _selectedLayer$split2[1];
514
+ var match = LayerUtils.searchLayer(_this.props.layers, 'wms_name', wmsName, 'name', layerName);
515
+ if (match) {
516
+ var oldvisibility = match.sublayer.visibility;
287
517
  if (oldvisibility !== visibility && visibility !== null) {
288
518
  var recurseDirection = !oldvisibility ? "both" : "children";
289
- _this.props.changeLayerProperty(layer.id, "visibility", visibility, path, recurseDirection);
519
+ _this.props.changeLayerProperty(match.layer.id, "visibility", visibility, match.path, recurseDirection);
290
520
  }
291
521
  return oldvisibility;
292
522
  }
@@ -295,12 +525,17 @@ var Editing = /*#__PURE__*/function (_React$Component) {
295
525
  });
296
526
  _defineProperty(_this, "changeSelectedLayer", function (selectedLayer) {
297
527
  var feature = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
298
- var curConfig = _this.props.theme && _this.props.theme.editConfig && selectedLayer ? _this.props.theme.editConfig[selectedLayer] : null;
528
+ var _split = (selectedLayer !== null && selectedLayer !== void 0 ? selectedLayer : '#').split("#"),
529
+ _split2 = _slicedToArray(_split, 2),
530
+ mapName = _split2[0],
531
+ layerName = _split2[1];
532
+ var editConfig = selectedLayer ? _this.props.editConfigs[mapName][layerName] : null;
299
533
  _this.props.setEditContext('Editing', {
300
534
  action: "Pick",
301
535
  feature: feature,
302
- geomType: (curConfig === null || curConfig === void 0 ? void 0 : curConfig.geomType) || null,
303
- permissions: (curConfig === null || curConfig === void 0 ? void 0 : curConfig.permissions) || {}
536
+ changed: false,
537
+ mapPrefix: mapName,
538
+ editConfig: editConfig
304
539
  });
305
540
  var prevLayerVisibility = null;
306
541
  if (_this.state.selectedLayer !== null) {
@@ -351,20 +586,16 @@ var Editing = /*#__PURE__*/function (_React$Component) {
351
586
  key: "componentDidUpdate",
352
587
  value: function componentDidUpdate(prevProps, prevState) {
353
588
  var _this2 = this;
354
- var themeSublayers = this.props.layers.reduce(function (accum, layer) {
355
- return layer.role === LayerRole.THEME ? accum.concat(LayerUtils.getSublayerNames(layer)) : accum;
356
- }, []);
357
- // Update selected layer on layers change
358
- if (this.props.enabled && (this.props.layers !== prevProps.layers || !prevProps.enabled)) {
359
- var layerIds = Object.keys(this.props.theme && this.props.theme.editConfig || {}).filter(function (layerId) {
360
- return themeSublayers.includes(layerId);
361
- });
362
- if (!isEmpty(layerIds)) {
363
- if (!layerIds.includes(this.state.selectedLayer)) {
364
- this.changeSelectedLayer(layerIds[0]);
365
- }
366
- } else if (this.state.selectedLayer) {
367
- this.changeSelectedLayer(null);
589
+ // Clear selected layer on layers change
590
+ if (this.props.layers !== prevProps.layers && this.state.selectedLayer) {
591
+ var _this$state$selectedL = this.state.selectedLayer.split("#"),
592
+ _this$state$selectedL2 = _slicedToArray(_this$state$selectedL, 2),
593
+ wmsName = _this$state$selectedL2[0],
594
+ layerName = _this$state$selectedL2[1];
595
+ if (!LayerUtils.searchLayer(this.props.layers, 'wms_name', wmsName, 'name', layerName)) {
596
+ this.setState({
597
+ selectedLayer: null
598
+ });
368
599
  }
369
600
  }
370
601
  // If click point changed and in pick mode with a selected layer, trigger a pick
@@ -375,7 +606,11 @@ var Editing = /*#__PURE__*/function (_React$Component) {
375
606
  if (newPoint.coordinate && !isEqual(newPoint.coordinate, oldPoint.coordinate)) {
376
607
  var _this$props$filter$fi;
377
608
  var scale = Math.round(MapUtils.computeForZoom(this.props.map.scales, this.props.map.zoom));
378
- var editConfig = this.props.theme.editConfig[this.state.selectedLayer];
609
+ var _this$state$selectedL3 = this.state.selectedLayer.split("#"),
610
+ _this$state$selectedL4 = _slicedToArray(_this$state$selectedL3, 2),
611
+ _wmsName = _this$state$selectedL4[0],
612
+ _layerName = _this$state$selectedL4[1];
613
+ var editConfig = this.props.editConfigs[_wmsName][_layerName];
379
614
  this.props.iface.getFeature(editConfig, newPoint.coordinate, this.props.map.projection, scale, 96, function (featureCollection) {
380
615
  var features = featureCollection ? featureCollection.features : null;
381
616
  _this2.setState({
@@ -446,13 +681,13 @@ _defineProperty(Editing, "propTypes", {
446
681
  changeLayerProperty: PropTypes.func,
447
682
  clearEditContext: PropTypes.func,
448
683
  currentEditContext: PropTypes.string,
684
+ editConfigs: PropTypes.object,
449
685
  editContext: PropTypes.object,
450
686
  enabled: PropTypes.bool,
451
687
  filter: PropTypes.object,
452
688
  iface: PropTypes.object,
453
689
  layers: PropTypes.array,
454
690
  map: PropTypes.object,
455
- refreshLayer: PropTypes.func,
456
691
  removeLayer: PropTypes.func,
457
692
  setCurrentTask: PropTypes.func,
458
693
  setCurrentTaskBlocked: PropTypes.func,
@@ -488,6 +723,7 @@ export default (function () {
488
723
  theme: state.theme.current,
489
724
  layers: state.layers.flat,
490
725
  filter: state.layers.filter,
726
+ editConfigs: state.layers.editConfigs,
491
727
  map: state.map,
492
728
  iface: iface,
493
729
  editContext: state.editing.contexts.Editing || {},
@@ -502,7 +738,6 @@ export default (function () {
502
738
  setSnappingConfig: setSnappingConfig,
503
739
  setCurrentTask: setCurrentTask,
504
740
  setCurrentTaskBlocked: setCurrentTaskBlocked,
505
- refreshLayer: refreshLayer,
506
741
  changeLayerProperty: changeLayerProperty
507
742
  })(Editing);
508
743
  });