qwc2 2025.11.5 → 2025.11.13

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 (54) hide show
  1. package/actions/layers.js +6 -29
  2. package/components/AttributeForm.js +104 -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/package.json +2 -1
  12. package/plugins/Cyclomedia.js +1 -1
  13. package/plugins/Editing.js +306 -72
  14. package/plugins/FeatureForm.js +103 -111
  15. package/plugins/LayerTree.js +4 -1
  16. package/plugins/NewsPopup.js +2 -2
  17. package/plugins/Portal.js +3 -1
  18. package/plugins/Print.js +4 -4
  19. package/plugins/ThemeSwitcher.js +3 -0
  20. package/plugins/map/EditingSupport.js +2 -2
  21. package/plugins/map/RedliningSupport.js +1 -1
  22. package/plugins/style/Editing.css +34 -0
  23. package/reducers/editing.js +12 -7
  24. package/reducers/layers.js +27 -5
  25. package/reducers/locale.js +3 -0
  26. package/static/translations/bg-BG.json +9 -0
  27. package/static/translations/ca-ES.json +9 -0
  28. package/static/translations/cs-CZ.json +9 -0
  29. package/static/translations/de-CH.json +9 -0
  30. package/static/translations/de-DE.json +9 -0
  31. package/static/translations/en-US.json +9 -0
  32. package/static/translations/es-ES.json +9 -0
  33. package/static/translations/fi-FI.json +9 -0
  34. package/static/translations/fr-FR.json +9 -0
  35. package/static/translations/hu-HU.json +9 -0
  36. package/static/translations/it-IT.json +9 -0
  37. package/static/translations/ja-JP.json +9 -0
  38. package/static/translations/nl-NL.json +9 -0
  39. package/static/translations/no-NO.json +9 -0
  40. package/static/translations/pl-PL.json +9 -0
  41. package/static/translations/pt-BR.json +9 -0
  42. package/static/translations/pt-PT.json +9 -0
  43. package/static/translations/ro-RO.json +9 -0
  44. package/static/translations/ru-RU.json +9 -0
  45. package/static/translations/sv-SE.json +9 -0
  46. package/static/translations/tr-TR.json +9 -0
  47. package/static/translations/tsconfig.json +9 -0
  48. package/static/translations/uk-UA.json +9 -0
  49. package/utils/EditingUtils.js +11 -9
  50. package/utils/ElevationInterface.js +1 -2
  51. package/utils/LayerUtils.js +11 -7
  52. package/utils/LocaleUtils.js +0 -15
  53. package/utils/ServiceLayerUtils.js +55 -2
  54. package/utils/ThemeUtils.js +7 -2
@@ -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,12 @@ 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
+ var geomType = _this.props.editContext.geomType;
245
318
  var geometry = feature.geometry;
246
319
  if (geometry.type !== geomType) {
247
320
  if ("Multi" + feature.geometry.type === geomType) {
@@ -266,27 +339,183 @@ var Editing = /*#__PURE__*/function (_React$Component) {
266
339
  geometry: geometry,
267
340
  id: uuidv4()
268
341
  };
342
+ var targetFields = (_this$props$editConte2 = _this.props.editContext.editConfig) === null || _this$props$editConte2 === void 0 ? void 0 : _this$props$editConte2.fields;
343
+ var matchingAttributes = [];
344
+ if (!isEmpty(targetFields)) {
345
+ var _this$props$editConfi;
346
+ var sourceProperties = feature.properties || {};
347
+
348
+ // Get source layer's field configuration and build name-to-id mapping
349
+ 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;
350
+ var sourceNameToIdMap = (sourceFields || []).reduce(function (res, field) {
351
+ return _objectSpread(_objectSpread({}, res), {}, _defineProperty(_defineProperty({}, sourceFields.name, sourceFields.id), sourceFields.id, sourceFields.id));
352
+ }, {});
353
+ var sourcePropertiesById = Object.entries(sourceProperties).reduce(function (res, _ref7) {
354
+ var _ref8 = _slicedToArray(_ref7, 2),
355
+ key = _ref8[0],
356
+ value = _ref8[1];
357
+ return _objectSpread(_objectSpread({}, res), {}, _defineProperty({}, sourceNameToIdMap[key] || key, value));
358
+ }, {});
359
+
360
+ // Build list of matching attributes with metadata
361
+ targetFields.forEach(function (field) {
362
+ if (!field.expression) {
363
+ var value = sourcePropertiesById[field.id];
364
+ if (value !== null && value !== undefined && value !== '') {
365
+ var _field$constraints;
366
+ // Parse number values
367
+ if (field.type === 'number') {
368
+ if (typeof value === 'string') {
369
+ var numValue = parseNumber(value.replace(',', '.'));
370
+ if (!isNaN(numValue)) {
371
+ value = numValue;
372
+ }
373
+ }
374
+ } else if (field.type === 'boolean') {
375
+ value = !['0', 'false'].includes(String(value).toLowerCase());
376
+ } else if (field.type === 'date') {
377
+ if (typeof value === 'string') {
378
+ value = dateParser.fromString(value).toISOString();
379
+ }
380
+ } else if (field.type === 'list') {
381
+ // Not supported
382
+ return;
383
+ }
384
+ matchingAttributes.push({
385
+ fieldId: field.id,
386
+ fieldName: field.name,
387
+ value: value,
388
+ visible: ((_field$constraints = field.constraints) === null || _field$constraints === void 0 ? void 0 : _field$constraints.hidden) !== true,
389
+ autoCalculated: !!field.defaultValue
390
+ });
391
+ }
392
+ }
393
+ });
394
+ }
395
+ if (matchingAttributes.length > 0) {
396
+ // Default selection: only visible, non-auto-calculated fields
397
+ var defaultSelection = matchingAttributes.filter(function (attr) {
398
+ return attr.visible && !attr.autoCalculated;
399
+ }).map(function (attr) {
400
+ return attr.fieldId;
401
+ });
402
+ _this.setState({
403
+ drawPick: false,
404
+ pendingClone: {
405
+ editFeature: editFeature,
406
+ matchingAttributes: matchingAttributes,
407
+ selectedAttributes: defaultSelection
408
+ }
409
+ });
410
+ } else {
411
+ _this.props.setEditContext('Editing', {
412
+ action: "Draw",
413
+ feature: editFeature,
414
+ changed: true
415
+ });
416
+ _this.setState({
417
+ drawPick: false
418
+ });
419
+ }
420
+ });
421
+ _defineProperty(_this, "confirmCopyAttributes", function () {
422
+ var _this$state$pendingCl = _this.state.pendingClone,
423
+ editFeature = _this$state$pendingCl.editFeature,
424
+ matchingAttributes = _this$state$pendingCl.matchingAttributes,
425
+ selectedAttributes = _this$state$pendingCl.selectedAttributes;
426
+ var copiedProperties = {};
427
+ matchingAttributes.forEach(function (attr) {
428
+ if (selectedAttributes.includes(attr.fieldId)) {
429
+ copiedProperties[attr.fieldId] = attr.value;
430
+ }
431
+ });
432
+ editFeature.properties = copiedProperties;
269
433
  _this.props.setEditContext('Editing', {
270
434
  action: "Draw",
271
435
  feature: editFeature,
272
436
  changed: true
273
437
  });
274
438
  _this.setState({
275
- drawPick: false
439
+ pendingClone: null
440
+ });
441
+ });
442
+ _defineProperty(_this, "cancelCopyAttributes", function () {
443
+ var editFeature = _this.state.pendingClone.editFeature;
444
+ _this.props.setEditContext('Editing', {
445
+ action: "Draw",
446
+ feature: editFeature,
447
+ changed: true
448
+ });
449
+ _this.setState({
450
+ pendingClone: null
451
+ });
452
+ });
453
+ _defineProperty(_this, "toggleAttribute", function (fieldId) {
454
+ _this.setState(function (state) {
455
+ var selectedAttributes = state.pendingClone.selectedAttributes.includes(fieldId) ? state.pendingClone.selectedAttributes.filter(function (id) {
456
+ return id !== fieldId;
457
+ }) : [].concat(_toConsumableArray(state.pendingClone.selectedAttributes), [fieldId]);
458
+ return {
459
+ pendingClone: _objectSpread(_objectSpread({}, state.pendingClone), {}, {
460
+ selectedAttributes: selectedAttributes
461
+ })
462
+ };
276
463
  });
277
464
  });
465
+ _defineProperty(_this, "onCloneAttrQuickSelect", function (action) {
466
+ if (action === 'All') {
467
+ var allFieldIds = _this.state.pendingClone.matchingAttributes.map(function (attr) {
468
+ return attr.fieldId;
469
+ });
470
+ _this.setState(function (state) {
471
+ return {
472
+ pendingClone: _objectSpread(_objectSpread({}, state.pendingClone), {}, {
473
+ selectedAttributes: allFieldIds
474
+ })
475
+ };
476
+ });
477
+ } else if (action === 'None') {
478
+ _this.setState(function (state) {
479
+ return {
480
+ pendingClone: _objectSpread(_objectSpread({}, state.pendingClone), {}, {
481
+ selectedAttributes: []
482
+ })
483
+ };
484
+ });
485
+ } else if (action === 'Visible') {
486
+ var visibleFieldIds = _this.state.pendingClone.matchingAttributes.filter(function (attr) {
487
+ return attr.visible && !attr.autoCalculated;
488
+ }).map(function (attr) {
489
+ return attr.fieldId;
490
+ });
491
+ _this.setState(function (state) {
492
+ return {
493
+ pendingClone: _objectSpread(_objectSpread({}, state.pendingClone), {}, {
494
+ selectedAttributes: visibleFieldIds
495
+ })
496
+ };
497
+ });
498
+ }
499
+ });
500
+ _defineProperty(_this, "onCloneAction", function (action) {
501
+ if (action === 'Copy') {
502
+ _this.confirmCopyAttributes();
503
+ } else if (action === 'DontCopy') {
504
+ _this.cancelCopyAttributes();
505
+ }
506
+ });
278
507
  _defineProperty(_this, "setLayerVisibility", function (selectedLayer, visibility) {
279
508
  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;
509
+ var _selectedLayer$split = selectedLayer.split("#"),
510
+ _selectedLayer$split2 = _slicedToArray(_selectedLayer$split, 2),
511
+ wmsName = _selectedLayer$split2[0],
512
+ layerName = _selectedLayer$split2[1];
513
+ var match = LayerUtils.searchLayer(_this.props.layers, 'wms_name', wmsName, 'name', layerName);
514
+ if (match) {
515
+ var oldvisibility = match.sublayer.visibility;
287
516
  if (oldvisibility !== visibility && visibility !== null) {
288
517
  var recurseDirection = !oldvisibility ? "both" : "children";
289
- _this.props.changeLayerProperty(layer.id, "visibility", visibility, path, recurseDirection);
518
+ _this.props.changeLayerProperty(match.layer.id, "visibility", visibility, match.path, recurseDirection);
290
519
  }
291
520
  return oldvisibility;
292
521
  }
@@ -295,12 +524,17 @@ var Editing = /*#__PURE__*/function (_React$Component) {
295
524
  });
296
525
  _defineProperty(_this, "changeSelectedLayer", function (selectedLayer) {
297
526
  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;
527
+ var _split = (selectedLayer !== null && selectedLayer !== void 0 ? selectedLayer : '#').split("#"),
528
+ _split2 = _slicedToArray(_split, 2),
529
+ mapName = _split2[0],
530
+ layerName = _split2[1];
531
+ var editConfig = selectedLayer ? _this.props.editConfigs[mapName][layerName] : null;
299
532
  _this.props.setEditContext('Editing', {
300
533
  action: "Pick",
301
534
  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) || {}
535
+ changed: false,
536
+ mapPrefix: mapName,
537
+ editConfig: editConfig
304
538
  });
305
539
  var prevLayerVisibility = null;
306
540
  if (_this.state.selectedLayer !== null) {
@@ -351,20 +585,16 @@ var Editing = /*#__PURE__*/function (_React$Component) {
351
585
  key: "componentDidUpdate",
352
586
  value: function componentDidUpdate(prevProps, prevState) {
353
587
  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);
588
+ // Clear selected layer on layers change
589
+ if (this.props.layers !== prevProps.layers && this.state.selectedLayer) {
590
+ var _this$state$selectedL = this.state.selectedLayer.split("#"),
591
+ _this$state$selectedL2 = _slicedToArray(_this$state$selectedL, 2),
592
+ wmsName = _this$state$selectedL2[0],
593
+ layerName = _this$state$selectedL2[1];
594
+ if (!LayerUtils.searchLayer(this.props.layers, 'wms_name', wmsName, 'name', layerName)) {
595
+ this.setState({
596
+ selectedLayer: null
597
+ });
368
598
  }
369
599
  }
370
600
  // If click point changed and in pick mode with a selected layer, trigger a pick
@@ -375,7 +605,11 @@ var Editing = /*#__PURE__*/function (_React$Component) {
375
605
  if (newPoint.coordinate && !isEqual(newPoint.coordinate, oldPoint.coordinate)) {
376
606
  var _this$props$filter$fi;
377
607
  var scale = Math.round(MapUtils.computeForZoom(this.props.map.scales, this.props.map.zoom));
378
- var editConfig = this.props.theme.editConfig[this.state.selectedLayer];
608
+ var _this$state$selectedL3 = this.state.selectedLayer.split("#"),
609
+ _this$state$selectedL4 = _slicedToArray(_this$state$selectedL3, 2),
610
+ _wmsName = _this$state$selectedL4[0],
611
+ _layerName = _this$state$selectedL4[1];
612
+ var editConfig = this.props.editConfigs[_wmsName][_layerName];
379
613
  this.props.iface.getFeature(editConfig, newPoint.coordinate, this.props.map.projection, scale, 96, function (featureCollection) {
380
614
  var features = featureCollection ? featureCollection.features : null;
381
615
  _this2.setState({
@@ -446,13 +680,13 @@ _defineProperty(Editing, "propTypes", {
446
680
  changeLayerProperty: PropTypes.func,
447
681
  clearEditContext: PropTypes.func,
448
682
  currentEditContext: PropTypes.string,
683
+ editConfigs: PropTypes.object,
449
684
  editContext: PropTypes.object,
450
685
  enabled: PropTypes.bool,
451
686
  filter: PropTypes.object,
452
687
  iface: PropTypes.object,
453
688
  layers: PropTypes.array,
454
689
  map: PropTypes.object,
455
- refreshLayer: PropTypes.func,
456
690
  removeLayer: PropTypes.func,
457
691
  setCurrentTask: PropTypes.func,
458
692
  setCurrentTaskBlocked: PropTypes.func,
@@ -488,6 +722,7 @@ export default (function () {
488
722
  theme: state.theme.current,
489
723
  layers: state.layers.flat,
490
724
  filter: state.layers.filter,
725
+ editConfigs: state.layers.editConfigs,
491
726
  map: state.map,
492
727
  iface: iface,
493
728
  editContext: state.editing.contexts.Editing || {},
@@ -502,7 +737,6 @@ export default (function () {
502
737
  setSnappingConfig: setSnappingConfig,
503
738
  setCurrentTask: setCurrentTask,
504
739
  setCurrentTaskBlocked: setCurrentTaskBlocked,
505
- refreshLayer: refreshLayer,
506
740
  changeLayerProperty: changeLayerProperty
507
741
  })(Editing);
508
742
  });