qwc2 2025.10.9 → 2025.10.14

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 (241) hide show
  1. package/actions/display.js +30 -1
  2. package/actions/editing.js +22 -1
  3. package/actions/layerinfo.js +13 -1
  4. package/actions/layers.js +213 -3
  5. package/actions/localConfig.js +58 -1
  6. package/actions/locale.js +21 -1
  7. package/actions/locate.js +26 -1
  8. package/actions/logging.js +10 -1
  9. package/actions/map.js +105 -2
  10. package/actions/measurement.js +12 -1
  11. package/actions/processNotifications.js +37 -1
  12. package/actions/redlining.js +18 -1
  13. package/actions/redliningPick.js +12 -1
  14. package/actions/search.js +12 -1
  15. package/actions/serviceinfo.js +12 -1
  16. package/actions/task.js +55 -3
  17. package/actions/theme.js +339 -19
  18. package/actions/windows.js +164 -5
  19. package/components/AppMenu.js +435 -3
  20. package/components/AttributeForm.js +928 -32
  21. package/components/AttributeTableWidget.js +1105 -13
  22. package/components/AutoEditForm.js +189 -3
  23. package/components/CoordinateDisplayer.js +78 -2
  24. package/components/EditComboField.js +190 -6
  25. package/components/EditUploadField.js +315 -3
  26. package/components/ExportSelection.js +203 -2
  27. package/components/FullscreenSwitcher.js +90 -3
  28. package/components/Icon.js +81 -2
  29. package/components/IdentifyViewer.js +1161 -6
  30. package/components/ImportLayer.js +718 -20
  31. package/components/LayerInfoWindow.js +145 -2
  32. package/components/LinkFeatureForm.js +246 -5
  33. package/components/MapButton.js +88 -2
  34. package/components/MapSelection.js +287 -8
  35. package/components/MessageBar.js +68 -2
  36. package/components/NumericInputWindow.js +359 -2
  37. package/components/PickFeature.js +266 -2
  38. package/components/PluginsContainer.js +227 -8
  39. package/components/PrintSelection.js +620 -49
  40. package/components/ProcessNotifications.js +104 -2
  41. package/components/QtDesignerForm.js +1137 -18
  42. package/components/ResizeableWindow.js +591 -8
  43. package/components/SearchBox.js +1307 -20
  44. package/components/ServiceInfoWindow.js +107 -2
  45. package/components/SideBar.js +204 -4
  46. package/components/StandardApp.js +381 -20
  47. package/components/Swipeable.js +15 -1
  48. package/components/TaskBar.js +85 -2
  49. package/components/ThemeLayersListWindow.js +216 -4
  50. package/components/ThemeList.js +381 -7
  51. package/components/Toolbar.js +106 -2
  52. package/components/WindowManager.js +178 -2
  53. package/components/map/OlLayer.js +257 -6
  54. package/components/map/OlMap.js +405 -5
  55. package/components/map/layers/BingLayer.js +31 -2
  56. package/components/map/layers/GoogleLayer.js +222 -19
  57. package/components/map/layers/GraticuleLayer.js +21 -1
  58. package/components/map/layers/ImageLayer.js +15 -1
  59. package/components/map/layers/MVTLayer.js +52 -2
  60. package/components/map/layers/OSMLayer.js +24 -2
  61. package/components/map/layers/OverlayLayer.js +55 -3
  62. package/components/map/layers/VectorLayer.js +173 -8
  63. package/components/map/layers/WFSLayer.js +220 -6
  64. package/components/map/layers/WMSLayer.js +180 -6
  65. package/components/map/layers/WMTSLayer.js +67 -3
  66. package/components/map/layers/XYZLayer.js +24 -2
  67. package/components/map/layers/index.js +28 -1
  68. package/components/map3d/EditDataset3D.js +190 -3
  69. package/components/map3d/HeightProfile3D.js +402 -3
  70. package/components/map3d/ImportObjects3D.js +162 -2
  71. package/components/map3d/Map3D.js +1304 -38
  72. package/components/map3d/MapControls3D.js +392 -7
  73. package/components/map3d/SearchField3D.js +183 -11
  74. package/components/map3d/View3DSwitcher.js +98 -2
  75. package/components/map3d/drawtool/CreateTool3D.js +174 -4
  76. package/components/map3d/drawtool/EditTool3D.js +590 -6
  77. package/components/map3d/drawtool/NumericInput3D.js +336 -4
  78. package/components/map3d/layers/GeoTIFFLayer3D.js +15 -1
  79. package/components/map3d/layers/VectorLayer3D.js +53 -2
  80. package/components/map3d/layers/WFSLayer3D.js +109 -3
  81. package/components/map3d/layers/WMSLayer3D.js +70 -2
  82. package/components/map3d/layers/WMTSLayer3D.js +27 -3
  83. package/components/map3d/layers/index.js +14 -1
  84. package/components/map3d/utils/FirstPersonControls3D.js +423 -16
  85. package/components/map3d/utils/MiscUtils3D.js +221 -13
  86. package/components/map3d/utils/OrbitControls3D.js +176 -5
  87. package/components/map3d/utils/Tiles3DStyle.js +238 -9
  88. package/components/share/ShareLink.js +54 -2
  89. package/components/share/ShareQRCode.js +62 -2
  90. package/components/share/ShareSocials.js +125 -3
  91. package/components/timeline/FixedTimeline.js +236 -5
  92. package/components/timeline/InfiniteTimeline.js +347 -8
  93. package/components/timeline/TimelineFeaturesSlider.js +439 -5
  94. package/components/widgets/AccordeonWidget.js +96 -2
  95. package/components/widgets/ButtonBar.js +124 -2
  96. package/components/widgets/ColorButton.js +201 -3
  97. package/components/widgets/ComboBox.js +166 -2
  98. package/components/widgets/CopyButton.js +110 -2
  99. package/components/widgets/DateTimeInput.js +100 -3
  100. package/components/widgets/EditableSelect.js +230 -3
  101. package/components/widgets/FileSelector.js +128 -4
  102. package/components/widgets/Input.js +124 -2
  103. package/components/widgets/InputContainer.js +96 -2
  104. package/components/widgets/LayerCatalogWidget.js +219 -3
  105. package/components/widgets/MenuButton.js +157 -1
  106. package/components/widgets/ModalDialog.js +64 -2
  107. package/components/widgets/NavBar.js +119 -2
  108. package/components/widgets/NumberInput.js +226 -4
  109. package/components/widgets/PopupMenu.js +72 -1
  110. package/components/widgets/Primitives.js +6 -1
  111. package/components/widgets/ReCaptchaWidget.js +55 -1
  112. package/components/widgets/SearchWidget.js +255 -2
  113. package/components/widgets/Spinner.js +44 -2
  114. package/components/widgets/SuggestionInput.js +77 -2
  115. package/components/widgets/TextInput.js +308 -2
  116. package/components/widgets/ToggleSwitch.js +85 -2
  117. package/components/widgets/VectorLayerPicker.js +85 -3
  118. package/libs/openlayers.js +225 -5
  119. package/package.json +1 -1
  120. package/plugins/API.js +358 -15
  121. package/plugins/AttributeTable.js +109 -3
  122. package/plugins/Authentication.js +130 -5
  123. package/plugins/BackgroundSwitcher.js +218 -4
  124. package/plugins/Bookmark.js +289 -3
  125. package/plugins/BottomBar.js +298 -4
  126. package/plugins/CookiePopup.js +67 -3
  127. package/plugins/Cyclomedia.js +442 -5
  128. package/plugins/Editing.js +497 -9
  129. package/plugins/FeatureForm.js +366 -4
  130. package/plugins/FeatureSearch.js +458 -3
  131. package/plugins/GeometryDigitizer.js +664 -7
  132. package/plugins/HeightProfile.js +763 -15
  133. package/plugins/Help.js +102 -3
  134. package/plugins/HomeButton.js +80 -3
  135. package/plugins/Identify.js +543 -5
  136. package/plugins/LayerCatalog.js +215 -4
  137. package/plugins/LayerTree.js +1194 -6
  138. package/plugins/LocateButton.js +94 -3
  139. package/plugins/Map.js +320 -16
  140. package/plugins/MapCompare.js +94 -3
  141. package/plugins/MapCopyright.js +127 -5
  142. package/plugins/MapExport.js +613 -20
  143. package/plugins/MapFilter.js +868 -12
  144. package/plugins/MapInfoTooltip.js +277 -3
  145. package/plugins/MapLegend.js +253 -4
  146. package/plugins/MapTip.js +290 -4
  147. package/plugins/Measure.js +220 -4
  148. package/plugins/NewsPopup.js +137 -3
  149. package/plugins/OverviewMap.js +167 -7
  150. package/plugins/Panoramax.js +340 -2
  151. package/plugins/Portal.js +199 -4
  152. package/plugins/Print.js +1231 -15
  153. package/plugins/Redlining.js +750 -6
  154. package/plugins/Reports.js +332 -3
  155. package/plugins/Routing.js +1278 -15
  156. package/plugins/ScratchDrawing.js +173 -5
  157. package/plugins/Settings.js +241 -4
  158. package/plugins/Share.js +198 -3
  159. package/plugins/StartupMarker.js +84 -4
  160. package/plugins/TaskButton.js +88 -3
  161. package/plugins/ThemeSwitcher.js +164 -4
  162. package/plugins/TimeManager.js +971 -10
  163. package/plugins/TopBar.js +300 -7
  164. package/plugins/TourGuide.js +213 -2
  165. package/plugins/ValueTool.js +419 -4
  166. package/plugins/View3D.js +519 -14
  167. package/plugins/ZoomButtons.js +165 -3
  168. package/plugins/map/EditingSupport.js +199 -7
  169. package/plugins/map/LocateSupport.js +260 -4
  170. package/plugins/map/MeasurementSupport.js +216 -8
  171. package/plugins/map/RedliningPickSupport.js +201 -7
  172. package/plugins/map/RedliningSupport.js +726 -17
  173. package/plugins/map/SnapInteraction.js +101 -1
  174. package/plugins/map/SnapSupport.js +210 -2
  175. package/plugins/map/SnappingSupport.js +356 -17
  176. package/plugins/map3d/BackgroundSwitcher3D.js +44 -3
  177. package/plugins/map3d/BottomBar3D.js +118 -3
  178. package/plugins/map3d/Compare3D.js +422 -8
  179. package/plugins/map3d/Draw3D.js +353 -6
  180. package/plugins/map3d/ExportObjects3D.js +393 -18
  181. package/plugins/map3d/HideObjects3D.js +313 -12
  182. package/plugins/map3d/Identify3D.js +283 -12
  183. package/plugins/map3d/LayerTree3D.js +323 -3
  184. package/plugins/map3d/MapCopyright3D.js +128 -5
  185. package/plugins/map3d/MapExport3D.js +590 -10
  186. package/plugins/map3d/MapLight3D.js +553 -6
  187. package/plugins/map3d/Measure3D.js +571 -20
  188. package/plugins/map3d/OverviewMap3D.js +169 -3
  189. package/plugins/map3d/Settings3D.js +73 -3
  190. package/plugins/map3d/TopBar3D.js +207 -9
  191. package/plugins/redlining/RedliningBufferSupport.js +206 -3
  192. package/reducers/display.js +34 -2
  193. package/reducers/editing.js +68 -3
  194. package/reducers/index.js +9 -1
  195. package/reducers/layerinfo.js +26 -2
  196. package/reducers/layers.js +456 -9
  197. package/reducers/localConfig.js +122 -2
  198. package/reducers/locale.js +38 -2
  199. package/reducers/locate.js +40 -2
  200. package/reducers/map.js +176 -5
  201. package/reducers/measurement.js +42 -2
  202. package/reducers/processNotifications.js +49 -2
  203. package/reducers/redlining.js +50 -2
  204. package/reducers/redliningPick.js +27 -2
  205. package/reducers/search.js +20 -1
  206. package/reducers/serviceinfo.js +25 -2
  207. package/reducers/task.js +45 -2
  208. package/reducers/theme.js +51 -2
  209. package/reducers/windows.js +203 -2
  210. package/scripts/dist.sh +1 -1
  211. package/scripts/gen-plugin-docs.js +152 -2
  212. package/scripts/makeIconkit.js +85 -6
  213. package/scripts/themesConfig.js +742 -40
  214. package/scripts/updateTranslations.js +251 -10
  215. package/selectors/searchproviders.js +44 -2
  216. package/stores/StandardStore.js +42 -2
  217. package/utils/ConfigUtils.js +84 -3
  218. package/utils/CoordinatesUtils.js +234 -23
  219. package/utils/DxfUtils.js +237 -11
  220. package/utils/EditingInterface.js +421 -87
  221. package/utils/EditingUtils.js +357 -13
  222. package/utils/ElevationInterface.js +83 -22
  223. package/utils/FeatureStyles.js +429 -5
  224. package/utils/IdentifyUtils.js +443 -7
  225. package/utils/ImageEditor.js +79 -9
  226. package/utils/LayerUtils.js +1516 -50
  227. package/utils/LocaleUtils.js +117 -7
  228. package/utils/MapUtils.js +241 -59
  229. package/utils/MeasureUtils.js +323 -2
  230. package/utils/MiscUtils.js +189 -11
  231. package/utils/PermaLinkUtils.js +429 -6
  232. package/utils/PluginStore.js +27 -1
  233. package/utils/ResourceRegistry.js +15 -1
  234. package/utils/RoutingInterface.js +307 -7
  235. package/utils/SearchProviders.js +722 -19
  236. package/utils/ServiceLayerUtils.js +669 -14
  237. package/utils/Signal.js +32 -2
  238. package/utils/ThemeUtils.js +341 -7
  239. package/utils/VectorLayerUtils.js +589 -15
  240. package/utils/expr_grammar/grammar.js +2239 -2
  241. package/utils/expr_grammar/test.js +65 -3
@@ -1,18 +1,1110 @@
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)}function _slicedToArray(r,e){return _arrayWithHoles(r)||_iterableToArrayLimit(r,e)||_unsupportedIterableToArray(r,e)||_nonIterableRest()}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.")}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}}function _arrayWithHoles(r){if(Array.isArray(r))return r}function _toConsumableArray(r){return _arrayWithoutHoles(r)||_iterableToArray(r)||_unsupportedIterableToArray(r)||_nonIterableSpread()}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.")}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}}function _iterableToArray(r){if("undefined"!=typeof Symbol&&null!=r[Symbol.iterator]||null!=r["@@iterator"])return Array.from(r)}function _arrayWithoutHoles(r){if(Array.isArray(r))return _arrayLikeToArray(r)}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}function _extends(){return _extends=Object.assign?Object.assign.bind():function(n){for(var e=1;e<arguments.length;e++){var t=arguments[e];for(var r in t)({}).hasOwnProperty.call(t,r)&&(n[r]=t[r])}return n},_extends.apply(null,arguments)}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}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}function _classCallCheck(a,n){if(!(a instanceof n))throw new TypeError("Cannot call a class as a function")}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)}}function _createClass(e,r,t){return r&&_defineProperties(e.prototype,r),t&&_defineProperties(e,t),Object.defineProperty(e,"prototype",{writable:!1}),e}function _callSuper(t,o,e){return o=_getPrototypeOf(o),_possibleConstructorReturn(t,_isNativeReflectConstruct()?Reflect.construct(o,e||[],_getPrototypeOf(t).constructor):o.apply(t,e))}function _possibleConstructorReturn(t,e){if(e&&("object"==_typeof(e)||"function"==typeof e))return e;if(void 0!==e)throw new TypeError("Derived constructors may only return object or undefined");return _assertThisInitialized(t)}function _assertThisInitialized(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function _isNativeReflectConstruct(){try{var t=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}))}catch(t){}return(_isNativeReflectConstruct=function _isNativeReflectConstruct(){return!!t})()}function _getPrototypeOf(t){return _getPrototypeOf=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(t){return t.__proto__||Object.getPrototypeOf(t)},_getPrototypeOf(t)}function _inherits(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),Object.defineProperty(t,"prototype",{writable:!1}),e&&_setPrototypeOf(t,e)}function _setPrototypeOf(t,e){return _setPrototypeOf=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(t,e){return t.__proto__=e,t},_setPrototypeOf(t,e)}function _defineProperty(e,r,t){return(r=_toPropertyKey(r))in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function _toPropertyKey(t){var i=_toPrimitive(t,"string");return"symbol"==_typeof(i)?i:i+""}function _toPrimitive(t,r){if("object"!=_typeof(t)||!t)return t;var e=t[Symbol.toPrimitive];if(void 0!==e){var i=e.call(t,r||"default");if("object"!=_typeof(i))return i;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===r?String:Number)(t)}/**
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 _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
3
+ 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."); }
4
+ 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; } }
5
+ function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
6
+ function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
7
+ 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."); }
8
+ 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; } }
9
+ function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
10
+ function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
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 _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
13
+ 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; }
14
+ 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; }
15
+ function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
16
+ 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); } }
17
+ function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
18
+ function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
19
+ function _possibleConstructorReturn(t, e) { if (e && ("object" == _typeof(e) || "function" == typeof e)) return e; if (void 0 !== e) throw new TypeError("Derived constructors may only return object or undefined"); return _assertThisInitialized(t); }
20
+ function _assertThisInitialized(e) { if (void 0 === e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); return e; }
21
+ function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
22
+ function _getPrototypeOf(t) { return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function (t) { return t.__proto__ || Object.getPrototypeOf(t); }, _getPrototypeOf(t); }
23
+ function _inherits(t, e) { if ("function" != typeof e && null !== e) throw new TypeError("Super expression must either be null or a function"); t.prototype = Object.create(e && e.prototype, { constructor: { value: t, writable: !0, configurable: !0 } }), Object.defineProperty(t, "prototype", { writable: !1 }), e && _setPrototypeOf(t, e); }
24
+ function _setPrototypeOf(t, e) { return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) { return t.__proto__ = e, t; }, _setPrototypeOf(t, e); }
25
+ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
26
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
27
+ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
28
+ /**
2
29
  * Copyright 2024 Sourcepole AG
3
30
  * All rights reserved.
4
31
  *
5
32
  * This source code is licensed under the BSD-style license found in the
6
33
  * LICENSE file in the root directory of this source tree.
7
- */import React from"react";import{connect}from"react-redux";import FileSaver from"file-saver";import isEmpty from"lodash.isempty";import PropTypes from"prop-types";import{LayerRole,addLayerFeatures,removeLayer}from"../actions/layers";import{zoomToExtent,zoomToPoint}from"../actions/map";import{setCurrentTask,setCurrentTaskBlocked}from"../actions/task";import EditComboField from"../components/EditComboField";import EditUploadField from"../components/EditUploadField";import Icon from"../components/Icon";import NavBar from"../components/widgets/NavBar";import NumberInput from"../components/widgets/NumberInput";import ReCaptchaWidget from"../components/widgets/ReCaptchaWidget";import Spinner from"../components/widgets/Spinner";import TextInput from"../components/widgets/TextInput";import ConfigUtils from"../utils/ConfigUtils";import CoordinatesUtils from"../utils/CoordinatesUtils";import{FeatureCache,KeyValCache,parseExpression,getFeatureTemplate}from"../utils/EditingUtils";import LayerUtils from"../utils/LayerUtils";import LocaleUtils from"../utils/LocaleUtils";import MapUtils from"../utils/MapUtils";import VectorLayerUtils from"../utils/VectorLayerUtils";import"./style/AttributeTableWidget.css";var AttributeTableWidget=/*#__PURE__*/function(_React$Component){function AttributeTableWidget(props){var _this;_classCallCheck(this,AttributeTableWidget);_this=_callSuper(this,AttributeTableWidget,[props]);_defineProperty(_this,"renderSortIndicator",function(field){if(_this.state.sortField&&_this.state.sortField.field===field){return/*#__PURE__*/React.createElement(Icon,{icon:_this.state.sortField.dir>0?"chevron-down":"chevron-up"})}else{return null}});_defineProperty(_this,"renderColumnResizeHandle",function(col,pos){return/*#__PURE__*/React.createElement("span",{className:"attribtable-table-"+pos+"draghandle",onPointerDown:function onPointerDown(ev){return _this.resizeTable(ev,col,true)}})});_defineProperty(_this,"renderRowResizeHandle",function(row,pos){return/*#__PURE__*/React.createElement("span",{className:"attribtable-table-"+pos+"draghandle",onPointerDown:function onPointerDown(ev){return _this.resizeTable(ev,row,false)}})});_defineProperty(_this,"changeSelectedLayer",function(value){_this.setState({selectedLayer:value})});_defineProperty(_this,"reload",function(){var layerName=arguments.length>0&&arguments[0]!==undefined?arguments[0]:null;_this.setState(function(state){var _this$props$filter$fi;var selectedLayer=layerName||state.selectedLayer;var editConfig=_this.props.theme.editConfig||{};var currentEditConfig=editConfig[selectedLayer];KeyValCache.clear();FeatureCache.clear();var bbox=_this.state.limitToExtent?_this.props.mapBbox.bounds:null;_this.props.iface.getFeatures(currentEditConfig,_this.props.mapCrs,function(result){if(result){var features=result.features||[];_this.setState(function(state2){return{loading:false,features:features,filteredSortedFeatures:_this.filteredSortedFeatures(features,state2),loadedLayer:selectedLayer}})}else{// eslint-disable-next-line
8
- alert(LocaleUtils.tr("attribtable.loadfailed"));_this.setState({loading:false,features:[],filteredSortedFeatures:[],loadedLayer:""})}},bbox,(_this$props$filter$fi=_this.props.filter.filterParams)===null||_this$props$filter$fi===void 0?void 0:_this$props$filter$fi[selectedLayer],_this.props.filter.filterGeom);return _objectSpread(_objectSpread({},AttributeTableWidget.defaultState),{},{loading:true,selectedLayer:selectedLayer,limitToExtent:state.limitToExtent})})});_defineProperty(_this,"sortBy",function(field){var newState={};if(_this.state.sortField&&_this.state.sortField.field===field){newState={sortField:{field:field,dir:-_this.state.sortField.dir}}}else{newState={sortField:{field:field,dir:1}}}newState.filteredSortedFeatures=_this.filteredSortedFeatures(_this.state.features,_objectSpread(_objectSpread({},_this.state),newState));_this.setState(newState)});_defineProperty(_this,"renderField",function(currentEditConfig,field,featureidx,filteredIndex,fielddisabled){var feature=_this.state.features[featureidx];var value=feature.properties[field.id];if(value===undefined||value===null){value=""}var mapPrefix=(currentEditConfig.editDataset.match(/^[^.]+\./)||[""])[0];var updateField=function updateField(fieldid,val){var emptynull=arguments.length>2&&arguments[2]!==undefined?arguments[2]:false;return _this.updateField(featureidx,filteredIndex,fieldid,val,emptynull)};var constraints=field.constraints||{};var disabled=constraints.readOnly||fielddisabled;var input=null;if(field.type==="boolean"||field.type==="bool"){input=/*#__PURE__*/React.createElement("input",_extends({name:field.id},constraints,{checked:value,disabled:disabled,onChange:function onChange(ev){return updateField(field.id,ev.target.checked)},type:"checkbox"}))}else if(constraints.values||constraints.keyvalrel){var filterExpr=null;if(field.filterExpression){filterExpr=parseExpression(field.filterExpression,feature,currentEditConfig,_this.props.iface,mapPrefix,_this.props.mapCrs,function(){return _this.setState({reevaluate:+new Date})},true)}input=/*#__PURE__*/React.createElement(EditComboField,{editIface:_this.props.iface,fieldId:field.id,filterExpr:filterExpr,keyvalrel:constraints.keyvalrel,multiSelect:constraints.allowMulti===true,name:field.id,readOnly:constraints.readOnly||disabled,required:constraints.required,updateField:updateField,value:value,values:constraints.values})}else if(field.type==="number"){var _constraints$prec,_constraints$step;var precision=(_constraints$prec=constraints.prec)!==null&&_constraints$prec!==void 0?_constraints$prec:0;var step=(_constraints$step=constraints.step)!==null&&_constraints$step!==void 0?_constraints$step:1;input=/*#__PURE__*/React.createElement(NumberInput,{decimals:precision,disabled:disabled,fitParent:true,max:constraints.max,min:constraints.min,name:field.id,onChange:function onChange(v){return updateField(field.id,v,true)},readOnly:constraints.readOnly,required:constraints.required,step:step,value:value})}else if(field.type==="date"){// Truncate time portion of ISO date string
9
- value=value.substr(0,10);input=/*#__PURE__*/React.createElement("input",_extends({disabled:disabled,name:field.id,type:field.type},constraints,{onChange:function onChange(ev){return updateField(field.id,ev.target.value,true)},value:value}))}else if(field.type==="file"){return/*#__PURE__*/React.createElement(EditUploadField,{constraints:constraints,dataset:currentEditConfig.editDataset,disabled:disabled,fieldId:field.id,iface:_this.props.iface,name:field.id,showThumbnails:false,updateField:updateField,updateFile:function updateFile(fieldId,data){_this.changedFiles[fieldId]=data},value:value})}else if(field.type==="text"){var _feature$properties$f;if(((_feature$properties$f=feature.properties[field.id])!==null&&_feature$properties$f!==void 0?_feature$properties$f:null)===null){var _ConfigUtils$getConfi;value=(_ConfigUtils$getConfi=ConfigUtils.getConfigProp("editTextNullValue"))!==null&&_ConfigUtils$getConfi!==void 0?_ConfigUtils$getConfi:""}var updateTextField=function updateTextField(val){if(val!==value){var textNullValue=ConfigUtils.getConfigProp("editTextNullValue");updateField(field.id,textNullValue!==undefined&&val===textNullValue?null:val)}};var addLinkAnchors=ConfigUtils.getConfigProp("editingAddLinkAnchors")!==false;var editTextNullValue=ConfigUtils.getConfigProp("editTextNullValue");input=/*#__PURE__*/React.createElement(TextInput,{addLinkAnchors:addLinkAnchors,clearValue:editTextNullValue,disabled:disabled,multiline:constraints.multiline,name:field.id,onChange:updateTextField,required:constraints.required,value:value})}else{input=/*#__PURE__*/React.createElement("input",_extends({disabled:disabled,name:field.id,type:field.type},constraints,{onChange:function onChange(ev){return updateField(field.id,ev.target.value)},value:value}))}return input});_defineProperty(_this,"addFeature",function(){var editConfig=_this.props.theme.editConfig||{};var currentEditConfig=editConfig[_this.state.loadedLayer];if(!currentEditConfig){return}var hasGeometry=(currentEditConfig||{}).geomType!==null;if(!_this.props.allowAddForGeometryLayers&&hasGeometry){// eslint-disable-next-line
10
- alert(LocaleUtils.tr("attribtable.geomnoadd"));return}var featureSkel={type:"Feature",geometry:null,properties:currentEditConfig.fields.reduce(function(res,field){if(field.id!=="id"){res[field.id]=field.type==="text"?"":null}return res},{})};var mapPrefix=(currentEditConfig.editDataset.match(/^[^.]+\./)||[""])[0];getFeatureTemplate(currentEditConfig,featureSkel,_this.props.iface,mapPrefix,_this.props.mapCrs,function(feature){_this.setState(function(state){return{features:[].concat(_toConsumableArray(state.features),[feature]),filteredSortedFeatures:[].concat(_toConsumableArray(state.filteredSortedFeatures),[_objectSpread(_objectSpread({},feature),{},{originalIndex:state.features.length})]),filterVal:"",currentPage:Math.floor(state.features.length/state.pageSize),changedFeatureIdx:state.filteredSortedFeatures.length,newFeature:true}});_this.props.setCurrentTaskBlocked(true,LocaleUtils.tr("editing.unsavedchanged"))})});_defineProperty(_this,"deleteSelectedFeatured",function(){_this.setState(function(state){var features=state.filteredSortedFeatures.filter(function(feature){return state.selectedFeatures[feature.id]===true});var selectedLayer=state.selectedLayer;var editConfig=_this.props.theme.editConfig||{};var currentEditConfig=editConfig[selectedLayer];features.forEach(function(feature){_this.props.iface.deleteFeature(currentEditConfig,feature.id,function(success){_this.setState(function(state2){var newState={deleteTask:_objectSpread(_objectSpread({},state2.deleteTask),{},{pending:state2.deleteTask.pending.filter(function(entry){return entry!==feature.id}),failed:success?state2.deleteTask.failed:[].concat(_toConsumableArray(state2.deleteTask.failed),[feature.id]),deleted:!success?state2.deleteTask.deleted:[].concat(_toConsumableArray(state2.deleteTask.deleted),[feature.id])})};if(isEmpty(newState.deleteTask.pending)){newState.features=state.features.filter(function(f){return!newState.deleteTask.deleted.includes(f.id)});newState.filteredSortedFeatures=_this.filteredSortedFeatures(newState.features,state);if(!isEmpty(newState.deleteTask.failed)){// eslint-disable-next-line
11
- alert(LocaleUtils.tr("attribtable.deletefailed"))}newState.deleteTask=null;newState.currentPage=Math.floor((newState.features.length-1)/state.pageSize);newState.selectedFeatures={};newState.confirmDelete=false}return newState})},state.captchaResponse)});return{deleteTask:{pending:features.map(function(feature){return feature.id}),failed:[],deleted:[]}}})});_defineProperty(_this,"updateField",function(featureidx,filteredIdx,fieldid,value,emptynull){_this.props.setCurrentTaskBlocked(true,LocaleUtils.tr("editing.unsavedchanged"));_this.setState(function(state){value=value===""&&emptynull?null:value;var newFeatures=_toConsumableArray(state.features);newFeatures[featureidx]=_objectSpread({},newFeatures[featureidx]);newFeatures[featureidx].properties=_objectSpread(_objectSpread({},newFeatures[featureidx].properties),{},_defineProperty({},fieldid,value));var newfilteredSortedFeatures=_toConsumableArray(state.filteredSortedFeatures);newfilteredSortedFeatures[filteredIdx]=_objectSpread({},newfilteredSortedFeatures[filteredIdx]);newfilteredSortedFeatures[filteredIdx].properties=_objectSpread(_objectSpread({},newfilteredSortedFeatures[filteredIdx].properties),{},_defineProperty({},fieldid,value));var originalFeatureProps=state.originalFeatureProps||_objectSpread({},state.features[featureidx].properties);return{features:newFeatures,filteredSortedFeatures:newfilteredSortedFeatures,changedFeatureIdx:featureidx,originalFeatureProps:originalFeatureProps}})});_defineProperty(_this,"commit",function(){var feature=_objectSpread(_objectSpread({},_this.state.features[_this.state.changedFeatureIdx]),{},{crs:{type:"name",properties:{name:CoordinatesUtils.toOgcUrnCrs(_this.props.mapCrs)}}});var editConfig=_this.props.theme.editConfig||{};var currentEditConfig=editConfig[_this.state.loadedLayer];Object.keys(feature.properties||{}).forEach(function(name){var _currentEditConfig$fi,_currentEditConfig$fi2,_currentEditConfig$fi3;var fieldConfig=(_currentEditConfig$fi=(_currentEditConfig$fi2=currentEditConfig.fields)===null||_currentEditConfig$fi2===void 0||(_currentEditConfig$fi3=_currentEditConfig$fi2.find)===null||_currentEditConfig$fi3===void 0?void 0:_currentEditConfig$fi3.call(_currentEditConfig$fi2,function(f){return f.id===name}))!==null&&_currentEditConfig$fi!==void 0?_currentEditConfig$fi:{};if(fieldConfig.expression){// Skip virtual fields
12
- delete feature.properties[name]}});// Omit geometry if it is read-only
13
- var canEditGeometry=["Point","LineString","Polygon"].includes((currentEditConfig.geomType||"").replace(/^Multi/,"").replace(/Z$/,""));if(!canEditGeometry){delete feature.geometry}var featureData=new FormData;featureData.set("feature",JSON.stringify(feature));Object.entries(_this.changedFiles).forEach(function(_ref){var _ref2=_slicedToArray(_ref,2),key=_ref2[0],value=_ref2[1];return featureData.set("file:"+key,value)});if(_this.state.captchaResponse){featureData.set("g-recaptcha-response",_this.state.captchaResponse)}if(_this.state.newFeature){_this.props.iface.addFeatureMultipart(currentEditConfig,_this.props.mapCrs,featureData,function(success,result){return _this.featureCommited(success,result)})}else{_this.props.iface.editFeatureMultipart(currentEditConfig,_this.props.mapCrs,feature.id,featureData,function(success,result){return _this.featureCommited(success,result)})}});_defineProperty(_this,"featureCommited",function(success,result){if(!success){// eslint-disable-next-line
14
- alert(result)}else{_this.changedFiles={};_this.setState(function(state){var newFeatures=_toConsumableArray(state.features);newFeatures[state.changedFeatureIdx]=result;return{features:newFeatures,filteredSortedFeatures:_this.filteredSortedFeatures(newFeatures,state),changedFeatureIdx:null,originalFeatureProps:null,newFeature:false}})}_this.props.setCurrentTaskBlocked(false)});_defineProperty(_this,"discard",function(){var newFeatures=_toConsumableArray(_this.state.features);if(_this.state.newFeature){newFeatures.splice(_this.state.changedFeatureIdx,1)}else{var featureidx=_this.state.changedFeatureIdx;newFeatures[featureidx]=_objectSpread({},newFeatures[featureidx]);newFeatures[featureidx].properties=_this.state.originalFeatureProps}_this.changedFiles={};_this.setState(function(state){return{features:newFeatures,filteredSortedFeatures:_this.filteredSortedFeatures(newFeatures,state),changedFeatureIdx:null,originalFeatureProps:null,newFeature:false}});_this.props.setCurrentTaskBlocked(false)});_defineProperty(_this,"highlightFeatures",function(){var features=[];if(_this.state.highlightedFeature){features.push(_this.state.highlightedFeature)}else if(_this.state.filterVal){features.push.apply(features,_toConsumableArray(Object.values(_this.state.filteredSortedFeatures)))}var layer={id:"__attributetablehighlight",role:LayerRole.SELECTION};_this.props.addLayerFeatures(layer,features.map(function(f){return{id:f.id,geometry:f.geometry}}),true)});_defineProperty(_this,"zoomToSelection",function(){var collection={type:"FeatureCollection",features:_this.state.filteredSortedFeatures.filter(function(feature){return _this.state.selectedFeatures[feature.id]===true&&feature.geometry})};if(!isEmpty(collection.features)){if(collection.features.length===1&&collection.features[0].geometry.type==="Point"){var zoom=MapUtils.computeZoom(_this.props.mapScales,_this.props.zoomLevel);_this.props.zoomToPoint(collection.features[0].geometry.coordinates,zoom,_this.props.mapCrs)}else{_this.props.zoomToExtent(VectorLayerUtils.computeFeatureBBox(collection),_this.props.mapCrs)}}});_defineProperty(_this,"switchToFormEditMode",function(){var editConfig=_this.props.theme.editConfig||{};var currentEditConfig=editConfig[_this.state.loadedLayer];var hasGeometry=(currentEditConfig||{}).geomType!==null;if(!hasGeometry){// eslint-disable-next-line
15
- alert(LocaleUtils.tr("attribtable.nogeomnoform"));return}var feature=_this.state.filteredSortedFeatures.find(function(f){return _this.state.selectedFeatures[f.id]===true});_this.props.setCurrentTask("Editing",null,null,{layer:_this.state.loadedLayer,feature:feature})});_defineProperty(_this,"updateFilter",function(field,val){var resetPage=arguments.length>2&&arguments[2]!==undefined?arguments[2]:false;_this.setState(function(state){return _defineProperty(_defineProperty(_defineProperty({},field,val),"currentPage",resetPage?0:state.currentPage),"filteredSortedFeatures",_this.filteredSortedFeatures(state.features,_objectSpread(_objectSpread({},state),{},_defineProperty({},field,val))))})});_defineProperty(_this,"filteredSortedFeatures",function(features,state){var filteredFeatures=[];if(!state.filterVal){filteredFeatures=features.map(function(feature,idx){return _objectSpread(_objectSpread({},feature),{},{originalIndex:idx})})}else{var filterVal=state.filterVal.toLowerCase();var test=null;if(state.filterOp==="~"){test=function test(x){return String(x).toLowerCase().includes(filterVal)}}else if(state.filterOp==="="){test=function test(x){return String(x).toLowerCase()===filterVal}}else if(state.filterOp===">"){test=function test(x){return Number(x)>Number(filterVal)}}else if(state.filterOp===">="){test=function test(x){return Number(x)>=Number(filterVal)}}else if(state.filterOp==="<="){test=function test(x){return Number(x)<=Number(filterVal)}}else if(state.filterOp==="<"){test=function test(x){return Number(x)<Number(filterVal)}}// Build value relation lookup
16
- var editConfig=_this.props.theme.editConfig||{};var currentEditConfig=editConfig[_this.state.loadedLayer];var valueLookup=currentEditConfig.fields.reduce(function(res,field){if(field.constraints&&field.constraints.values){res[field.id]=field.constraints.values.reduce(function(res2,constraint){res2[constraint.value]=constraint.label;return res2},{})}else if(field.constraints&&field.constraints.keyvalrel){res[field.id]=KeyValCache.getSync(_this.props.iface,field.constraints.keyvalrel).reduce(function(res2,entry){res2[entry.value]=entry.label;return res2},{})}return res},{});var filterFieldValue=state.filterField==="id"?function(feature){return feature.id}:function(feature){var value=feature.properties[state.filterField];return valueLookup[state.filterField]?valueLookup[state.filterField][value]:value};filteredFeatures=features.reduce(function(res,feature,idx){if(test(filterFieldValue(feature))){res.push(_objectSpread(_objectSpread({},feature),{},{originalIndex:idx}))}return res},[])}if(state.sortField){var sortFieldValue=state.sortField.field==="id"?function(feature){return feature.id}:function(feature){return feature.properties[state.sortField.field]};return filteredFeatures.sort(function(f1,f2){var v1=String(sortFieldValue(f1));var v2=String(sortFieldValue(f2));return v1.localeCompare(v2,undefined,{numeric:true,sensitivity:"base"})*state.sortField.dir})}else{return filteredFeatures}});_defineProperty(_this,"resizeTable",function(ev,index,resizeCol){if(_this.table){var element=_this.table.getElementsByTagName(resizeCol?"th":"tr")[index];var initial=0;if(resizeCol){initial=parseFloat(element.style.minWidth.replace(/px$/,""))||element.clientWidth}else{initial=parseFloat(element.style.height.replace(/px$/,""))||element.clientHeight}var resize={anchor:resizeCol?ev.clientX:ev.clientY,element:element,initial:initial};var resizeDo=resizeCol?function(event){var delta=event.clientX-resize.anchor;resize.element.style.minWidth=Math.max(resize.initial+delta,16)+"px";resize.element.style.width=Math.max(resize.initial+delta,16)+"px"}:function(event){var delta=event.clientY-resize.anchor;resize.element.style.height=Math.max(resize.initial+delta,16)+"px"};var eventShield=ev.view.document.createElement("div");eventShield.className="__event_shield";ev.view.document.body.appendChild(eventShield);ev.view.document.body.classList.add(resizeCol?"ewresizing":"nsresizing");ev.view.addEventListener("pointermove",resizeDo);ev.view.addEventListener("pointerup",function(event){event.view.document.body.removeChild(eventShield);event.view.removeEventListener("pointermove",resizeDo);event.view.document.body.classList.remove(resizeCol?"ewresizing":"nsresizing")},{once:true})}});_defineProperty(_this,"csvExport",function(){var editConfig=_this.props.theme.editConfig||{};var currentEditConfig=editConfig[_this.state.loadedLayer];if(!currentEditConfig){return}var fields=currentEditConfig.fields.filter(function(field){return field.id!=="id"});var data="";data+="id,"+fields.map(function(field){return"\"".concat(field.name.replaceAll("\"","\"\""),"\"")}).join(",")+"\n";_this.state.features.forEach(function(feature){data+=feature.id+","+fields.map(function(field){var value=feature.properties[field.id];if(value===null||value===undefined){return"null"}else{return"\"".concat(String(feature.properties[field.id]).replaceAll("\"","\"\""),"\"")}}).join(",")+"\n"});FileSaver.saveAs(new Blob([data],{type:"text/plain;charset=utf-8"}),_this.state.loadedLayer+".csv")});_defineProperty(_this,"translateFieldName",function(fieldName,layerName){var _this$props$theme$tra,_this$props$theme$tra2;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.layers)===null||_this$props$theme$tra2===void 0||(_this$props$theme$tra2=_this$props$theme$tra2[layerName])===null||_this$props$theme$tra2===void 0||(_this$props$theme$tra2=_this$props$theme$tra2.fields)===null||_this$props$theme$tra2===void 0?void 0:_this$props$theme$tra2[fieldName])!==null&&_this$props$theme$tra!==void 0?_this$props$theme$tra:fieldName});_this.changedFiles={};_this.state=AttributeTableWidget.defaultState;_this.table=null;_this.attribTableContents=null;return _this}_inherits(AttributeTableWidget,_React$Component);return _createClass(AttributeTableWidget,[{key:"componentDidMount",value:function componentDidMount(){if(this.props.initialLayer){this.reload(this.props.initialLayer)}}},{key:"componentDidUpdate",value:function componentDidUpdate(prevProps,prevState){if(this.state.newFeature&&!prevState.newFeature){if(this.attribTableContents){this.attribTableContents.scrollTop=this.attribTableContents.scrollHeight}}// Reload conditions when limited to extent
17
- if(this.state.limitToExtent&&this.state.selectedLayer&&(!prevState.limitToExtent||this.props.mapBbox!==prevProps.mapBbox)){this.reload()}else if(!this.state.limitToExtent&&prevState.limitToExtent){this.reload()}// Highlight feature
18
- if(this.state.highlightedFeature!==prevState.highlightedFeature||this.state.filteredSortedFeatures!==prevState.filteredSortedFeatures){this.highlightFeatures()}}},{key:"componentWillUnmount",value:function componentWillUnmount(){this.props.removeLayer("__attributetablehighlight")}},{key:"render",value:function render(){var _this2=this;var captchaRequired=ConfigUtils.getConfigProp("editServiceCaptchaSiteKey")&&!ConfigUtils.getConfigProp("username");var captchaPending=captchaRequired&&!this.state.captchaResponse;var editConfig=this.props.theme.editConfig||{};var currentEditConfig=editConfig[this.state.loadedLayer];var editPermissions=(editConfig[this.state.loadedLayer]||{}).permissions||{};var readOnly=editPermissions.updatable===false;var loadOverlay=null;if(this.state.selectedLayer&&this.state.selectedLayer!==this.state.loadedLayer){if(this.state.loading){loadOverlay=/*#__PURE__*/React.createElement("div",{className:"attribtable-overlay"},/*#__PURE__*/React.createElement(Spinner,null),/*#__PURE__*/React.createElement("span",null,LocaleUtils.tr("attribtable.loading")))}else{loadOverlay=/*#__PURE__*/React.createElement("div",{className:"attribtable-overlay"},/*#__PURE__*/React.createElement("span",null,LocaleUtils.tr("attribtable.pleasereload")))}}else if(this.state.selectedLayer&&this.state.deleteTask){loadOverlay=/*#__PURE__*/React.createElement("div",{className:"attribtable-overlay"},/*#__PURE__*/React.createElement(Spinner,null),/*#__PURE__*/React.createElement("span",null,LocaleUtils.tr("attribtable.deleting")))}var table=null;var footbar=null;if(currentEditConfig&&this.state.features){var fields=currentEditConfig.fields.filter(function(field){return field.id!=="id"}).filter(function(field){var _field$constraints;return _this2.props.showHiddenFields||((_field$constraints=field.constraints)===null||_field$constraints===void 0?void 0:_field$constraints.hidden)!==true});var indexOffset=this.state.currentPage*this.state.pageSize;var features=this.state.filteredSortedFeatures.slice(indexOffset,indexOffset+this.state.pageSize);table=/*#__PURE__*/React.createElement("table",{className:"attribtable-table",ref:function ref(el){_this2.table=el}},/*#__PURE__*/React.createElement("thead",null,/*#__PURE__*/React.createElement("tr",null,/*#__PURE__*/React.createElement("th",null),/*#__PURE__*/React.createElement("th",{onClick:function onClick(){return _this2.sortBy("id")},title:this.translateFieldName("id",this.state.loadedLayer)},/*#__PURE__*/React.createElement("span",null,/*#__PURE__*/React.createElement("span",{className:"attribtable-table-headername"},this.translateFieldName("id",this.state.loadedLayer)),this.renderSortIndicator("id"),this.renderColumnResizeHandle(1,"r"))),fields.map(function(field,idx){return/*#__PURE__*/React.createElement("th",{key:field.id,onClick:function onClick(){return _this2.sortBy(field.id)},title:_this2.translateFieldName(field.name,_this2.state.loadedLayer)},/*#__PURE__*/React.createElement("span",null,_this2.renderColumnResizeHandle(idx+1,"l"),/*#__PURE__*/React.createElement("span",{className:"attribtable-table-headername"},_this2.translateFieldName(field.name,_this2.state.loadedLayer)),_this2.renderSortIndicator(field.id),idx<fields.length-1?_this2.renderColumnResizeHandle(idx+2,"r"):null))}))),/*#__PURE__*/React.createElement("tbody",null,features.map(function(feature,filteredIndex){var featureidx=feature.originalIndex;var disabled=readOnly||_this2.state.changedFeatureIdx!==null&&_this2.state.changedFeatureIdx!==featureidx;var key=_this2.state.changedFeatureIdx===featureidx&&_this2.state.newFeature?"newfeature":feature.id;return/*#__PURE__*/React.createElement("tr",{className:disabled?"row-disabled":"",key:key,onMouseEnter:function onMouseEnter(){return _this2.setState({highlightedFeature:feature})},onMouseLeave:function onMouseLeave(){return _this2.setState(function(state){return{highlightedFeature:state.highlightedFeature===feature?null:state.highlightedFeature}})}},/*#__PURE__*/React.createElement("td",null,/*#__PURE__*/React.createElement("span",null,filteredIndex>0?_this2.renderRowResizeHandle(filteredIndex,"t"):null,/*#__PURE__*/React.createElement("input",{checked:_this2.state.selectedFeatures[feature.id]===true,onChange:function onChange(ev){return _this2.setState(function(state){return{selectedFeatures:_objectSpread(_objectSpread({},state.selectedFeatures),{},_defineProperty({},feature.id,ev.target.checked))}})},type:"checkbox"}),_this2.renderRowResizeHandle(filteredIndex+1,"b"))),/*#__PURE__*/React.createElement("td",null,feature.id),fields.map(function(field){return/*#__PURE__*/React.createElement("td",{key:field.id},_this2.renderField(currentEditConfig,field,featureidx,indexOffset+filteredIndex,disabled||!!_this2.state.filterVal&&field.id===_this2.state.filterField))}))})));var npages=Math.ceil(this.state.filteredSortedFeatures.length/this.state.pageSize);var pages=[this.state.currentPage];var extraright=Math.max(0,2-this.state.currentPage);var extraleft=Math.max(0,this.state.currentPage-(npages-3));for(var i=0;i<3+extraleft;++i){if(this.state.currentPage-i>0){pages.unshift(this.state.currentPage-i)}}for(var _i=0;_i<3+extraright;++_i){if(this.state.currentPage+_i<npages-1){pages.push(this.state.currentPage-_i+1)}}footbar=/*#__PURE__*/React.createElement("div",{className:"attribtable-footbar"},/*#__PURE__*/React.createElement(NavBar,{currentPage:this.state.currentPage,disabled:this.state.changedFeatureIdx!==null,nPages:npages,pageChanged:function pageChanged(currentPage){return _this2.setState({currentPage:currentPage})},pageSize:this.state.pageSize,pageSizeChanged:function pageSizeChanged(pageSize){return _this2.setState({pageSize:pageSize})}}),/*#__PURE__*/React.createElement("div",{className:"attribtable-filter controlgroup"},/*#__PURE__*/React.createElement(Icon,{icon:"filter"}),/*#__PURE__*/React.createElement("select",{disabled:this.state.changedFeatureIdx!==null,onChange:function onChange(ev){return _this2.updateFilter("filterField",ev.target.value)},value:this.state.filterField},/*#__PURE__*/React.createElement("option",{value:"id"},this.translateFieldName("id",this.state.loadedLayer)),fields.map(function(field){return/*#__PURE__*/React.createElement("option",{key:field.id,value:field.id},_this2.translateFieldName(field.name,_this2.state.loadedLayer))})),/*#__PURE__*/React.createElement("select",{disabled:this.state.changedFeatureIdx!==null,onChange:function onChange(ev){return _this2.updateFilter("filterOp",ev.target.value)},value:this.state.filterOp},/*#__PURE__*/React.createElement("option",{value:"~"},"~"),/*#__PURE__*/React.createElement("option",{value:"="},"="),/*#__PURE__*/React.createElement("option",{value:">"},">"),/*#__PURE__*/React.createElement("option",{value:">="},">="),/*#__PURE__*/React.createElement("option",{value:"<="},"<="),/*#__PURE__*/React.createElement("option",{value:"<"},"<")),/*#__PURE__*/React.createElement(TextInput,{disabled:this.state.changedFeatureIdx!==null,onChange:function onChange(value){return _this2.updateFilter("filterVal",value,true)},value:this.state.filterVal})),this.props.showLimitToExtent?/*#__PURE__*/React.createElement("div",null,/*#__PURE__*/React.createElement("label",null,/*#__PURE__*/React.createElement("input",{checked:this.state.limitToExtent,onChange:function onChange(ev){return _this2.setState({limitToExtent:ev.target.checked})},type:"checkbox"})," ",LocaleUtils.tr("attribtable.limittoextent"))):null)}var nolayer=!this.state.selectedLayer;var loading=this.state.loading;var editing=this.state.changedFeatureIdx!==null;var layerChanged=this.state.selectedLayer!==this.state.loadedLayer;var hasGeometry=(currentEditConfig||{}).geomType!==null;var showAddButton=editPermissions.creatable!==false&&(this.props.allowAddForGeometryLayers||!hasGeometry);var showDelButton=editPermissions.deletable!==false;var showEditButton=ConfigUtils.havePlugin("Editing")&&this.props.showEditFormButton;var deleteButton=showDelButton?/*#__PURE__*/React.createElement("button",{className:"button",disabled:layerChanged||editing||!Object.values(this.state.selectedFeatures).find(function(entry){return entry===true}),onClick:function onClick(){return _this2.setState({confirmDelete:true})},title:LocaleUtils.tr("attribtable.deletefeatures")},/*#__PURE__*/React.createElement(Icon,{icon:"trash"})):null;var captchaBar=null;if(captchaRequired&&(this.state.changedFeatureIdx!==null||this.state.confirmDelete)){captchaBar=/*#__PURE__*/React.createElement("div",null,/*#__PURE__*/React.createElement(ReCaptchaWidget,{onChange:function onChange(value){return _this2.setState({captchaResponse:value})},sitekey:ConfigUtils.getConfigProp("editServiceCaptchaSiteKey")}))}return/*#__PURE__*/React.createElement("div",{className:"AttributeTable"},loadOverlay,/*#__PURE__*/React.createElement("div",{className:"attribtable-toolbar"},this.props.showLayerSelection?/*#__PURE__*/React.createElement("select",{disabled:loading||editing,onChange:function onChange(ev){return _this2.changeSelectedLayer(ev.target.value)},value:this.state.selectedLayer||""},/*#__PURE__*/React.createElement("option",{disabled:true,value:""},LocaleUtils.tr("attribtable.selectlayer")),Object.keys(editConfig).map(function(layerId){var _this2$props$theme$tr,_this2$props$theme$tr2,_LayerUtils$searchLay,_LayerUtils$searchLay2;var layerName=editConfig[layerId].layerName;var layerTitle=editConfig[layerId].layerTitle?(_this2$props$theme$tr=(_this2$props$theme$tr2=_this2.props.theme.translations)===null||_this2$props$theme$tr2===void 0||(_this2$props$theme$tr2=_this2$props$theme$tr2.layertree)===null||_this2$props$theme$tr2===void 0?void 0:_this2$props$theme$tr2[layerName])!==null&&_this2$props$theme$tr!==void 0?_this2$props$theme$tr:editConfig[layerId].layerTitle:(_LayerUtils$searchLay=(_LayerUtils$searchLay2=LayerUtils.searchLayer(_this2.props.layers,_this2.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;return/*#__PURE__*/React.createElement("option",{key:layerId,value:layerId},layerTitle)})):null,/*#__PURE__*/React.createElement("button",{className:"button",disabled:editing||nolayer||this.state.loading,onClick:function onClick(){return _this2.reload()},title:LocaleUtils.tr("attribtable.reload")},/*#__PURE__*/React.createElement(Icon,{icon:"refresh"})),showAddButton?/*#__PURE__*/React.createElement("button",{className:"button",disabled:nolayer||editing||loading||layerChanged,onClick:this.addFeature,title:LocaleUtils.tr("attribtable.addfeature")},/*#__PURE__*/React.createElement(Icon,{icon:"plus"})):null,/*#__PURE__*/React.createElement("button",{className:"button",disabled:layerChanged||!Object.values(this.state.selectedFeatures).find(function(entry){return entry===true}),onClick:this.zoomToSelection,title:LocaleUtils.tr("attribtable.zoomtoselection")},/*#__PURE__*/React.createElement(Icon,{icon:"search"})),showEditButton?/*#__PURE__*/React.createElement("button",{className:"button",disabled:layerChanged||editing||Object.values(this.state.selectedFeatures).filter(function(entry){return entry===true}).length!==1,onClick:this.switchToFormEditMode,title:LocaleUtils.tr("attribtable.formeditmode")},/*#__PURE__*/React.createElement(Icon,{icon:"editing"})):null,this.state.confirmDelete?/*#__PURE__*/React.createElement("button",{className:"button button-accept",disabled:captchaPending,onClick:this.deleteSelectedFeatured},/*#__PURE__*/React.createElement(Icon,{icon:"ok"}),/*#__PURE__*/React.createElement("span",null,LocaleUtils.tr("attribtable.delete"))):deleteButton,this.state.confirmDelete?/*#__PURE__*/React.createElement("button",{className:"button button-reject",onClick:function onClick(){return _this2.setState({confirmDelete:false,captchaResponse:null})}},/*#__PURE__*/React.createElement(Icon,{icon:"remove"}),/*#__PURE__*/React.createElement("span",null,LocaleUtils.tr("attribtable.nodelete"))):null,this.state.changedFeatureIdx!==null?/*#__PURE__*/React.createElement("button",{className:"button button-accept",disabled:captchaPending,onClick:this.commit},/*#__PURE__*/React.createElement(Icon,{icon:"ok"}),/*#__PURE__*/React.createElement("span",null,LocaleUtils.tr("attribtable.commit"))):null,this.state.changedFeatureIdx!==null?/*#__PURE__*/React.createElement("button",{className:"button button-reject",onClick:this.discard},/*#__PURE__*/React.createElement(Icon,{icon:"remove"}),/*#__PURE__*/React.createElement("span",null,LocaleUtils.tr("attribtable.discard"))):null,/*#__PURE__*/React.createElement("button",{className:"button",disabled:isEmpty(this.state.features),onClick:function onClick(){return _this2.csvExport()},title:LocaleUtils.tr("attribtable.csvexport")},/*#__PURE__*/React.createElement(Icon,{icon:"export"}))),captchaBar,/*#__PURE__*/React.createElement("div",{className:"attribtable-contents",ref:function ref(el){_this2.attribTableContents=el}},table),footbar)}}])}(React.Component);_defineProperty(AttributeTableWidget,"propTypes",{addLayerFeatures:PropTypes.func,/** Whether to allow adding records for datasets which have a geometry column. */allowAddForGeometryLayers:PropTypes.bool,filter:PropTypes.object,iface:PropTypes.object,initialLayer:PropTypes.string,layers:PropTypes.array,mapBbox:PropTypes.object,mapCrs:PropTypes.string,mapScales:PropTypes.array,removeLayer:PropTypes.func,setCurrentTask:PropTypes.func,setCurrentTaskBlocked:PropTypes.func,/** Whether to show a button to open the edit form for selected layer. Requires the Editing plugin to be enabled. */showEditFormButton:PropTypes.bool,/** Whether to show hidden Fields. */showHiddenFields:PropTypes.bool,/** Whether to show the layer selection menu. */showLayerSelection:PropTypes.bool,/** Whether to show the "Limit to extent" checkbox */showLimitToExtent:PropTypes.bool,theme:PropTypes.object,/** The zoom level for zooming to point features. */zoomLevel:PropTypes.number,zoomToExtent:PropTypes.func,zoomToPoint:PropTypes.func});_defineProperty(AttributeTableWidget,"defaultProps",{zoomLevel:1000,showEditFormButton:true,showHiddenFields:true,showLayerSelection:true});_defineProperty(AttributeTableWidget,"defaultState",{loading:false,selectedLayer:"",loadedLayer:"",features:[],filteredSortedFeatures:[],selectedFeatures:{},highlightedFeature:null,changedFeatureIdx:null,originalFeatureProps:null,pageSize:50,currentPage:0,filterField:"id",filterOp:"~",filterVal:"",sortField:null,deleteTask:null,newFeature:false,confirmDelete:false,limitToExtent:false,captchaResponse:""});export default connect(function(state){return{layers:state.layers.flat,filter:state.layers.filter,mapBbox:state.map.bbox,mapCrs:state.map.projection,mapScales:state.map.scales,theme:state.theme.current}},{addLayerFeatures:addLayerFeatures,removeLayer:removeLayer,setCurrentTask:setCurrentTask,setCurrentTaskBlocked:setCurrentTaskBlocked,zoomToExtent:zoomToExtent,zoomToPoint:zoomToPoint})(AttributeTableWidget);
34
+ */
35
+
36
+ import React from 'react';
37
+ import { connect } from 'react-redux';
38
+ import FileSaver from 'file-saver';
39
+ import isEmpty from 'lodash.isempty';
40
+ import PropTypes from 'prop-types';
41
+ import { LayerRole, addLayerFeatures, removeLayer } from '../actions/layers';
42
+ import { zoomToExtent, zoomToPoint } from '../actions/map';
43
+ import { setCurrentTask, setCurrentTaskBlocked } from '../actions/task';
44
+ import EditComboField from '../components/EditComboField';
45
+ import EditUploadField from '../components/EditUploadField';
46
+ import Icon from '../components/Icon';
47
+ import NavBar from '../components/widgets/NavBar';
48
+ import NumberInput from '../components/widgets/NumberInput';
49
+ import ReCaptchaWidget from '../components/widgets/ReCaptchaWidget';
50
+ import Spinner from '../components/widgets/Spinner';
51
+ import TextInput from '../components/widgets/TextInput';
52
+ import ConfigUtils from '../utils/ConfigUtils';
53
+ import CoordinatesUtils from '../utils/CoordinatesUtils';
54
+ import { FeatureCache, KeyValCache, parseExpression, getFeatureTemplate } from '../utils/EditingUtils';
55
+ import LayerUtils from '../utils/LayerUtils';
56
+ import LocaleUtils from '../utils/LocaleUtils';
57
+ import MapUtils from '../utils/MapUtils';
58
+ import VectorLayerUtils from '../utils/VectorLayerUtils';
59
+ import './style/AttributeTableWidget.css';
60
+ var AttributeTableWidget = /*#__PURE__*/function (_React$Component) {
61
+ function AttributeTableWidget(props) {
62
+ var _this;
63
+ _classCallCheck(this, AttributeTableWidget);
64
+ _this = _callSuper(this, AttributeTableWidget, [props]);
65
+ _defineProperty(_this, "renderSortIndicator", function (field) {
66
+ if (_this.state.sortField && _this.state.sortField.field === field) {
67
+ return /*#__PURE__*/React.createElement(Icon, {
68
+ icon: _this.state.sortField.dir > 0 ? "chevron-down" : "chevron-up"
69
+ });
70
+ } else {
71
+ return null;
72
+ }
73
+ });
74
+ _defineProperty(_this, "renderColumnResizeHandle", function (col, pos) {
75
+ return /*#__PURE__*/React.createElement("span", {
76
+ className: "attribtable-table-" + pos + "draghandle",
77
+ onPointerDown: function onPointerDown(ev) {
78
+ return _this.resizeTable(ev, col, true);
79
+ }
80
+ });
81
+ });
82
+ _defineProperty(_this, "renderRowResizeHandle", function (row, pos) {
83
+ return /*#__PURE__*/React.createElement("span", {
84
+ className: "attribtable-table-" + pos + "draghandle",
85
+ onPointerDown: function onPointerDown(ev) {
86
+ return _this.resizeTable(ev, row, false);
87
+ }
88
+ });
89
+ });
90
+ _defineProperty(_this, "changeSelectedLayer", function (value) {
91
+ _this.setState({
92
+ selectedLayer: value
93
+ });
94
+ });
95
+ _defineProperty(_this, "reload", function () {
96
+ var layerName = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
97
+ _this.setState(function (state) {
98
+ var _this$props$filter$fi;
99
+ var selectedLayer = layerName || state.selectedLayer;
100
+ var editConfig = _this.props.theme.editConfig || {};
101
+ var currentEditConfig = editConfig[selectedLayer];
102
+ KeyValCache.clear();
103
+ FeatureCache.clear();
104
+ var bbox = _this.state.limitToExtent ? _this.props.mapBbox.bounds : null;
105
+ _this.props.iface.getFeatures(currentEditConfig, _this.props.mapCrs, function (result) {
106
+ if (result) {
107
+ var features = result.features || [];
108
+ _this.setState(function (state2) {
109
+ return {
110
+ loading: false,
111
+ features: features,
112
+ filteredSortedFeatures: _this.filteredSortedFeatures(features, state2),
113
+ loadedLayer: selectedLayer
114
+ };
115
+ });
116
+ } else {
117
+ // eslint-disable-next-line
118
+ alert(LocaleUtils.tr("attribtable.loadfailed"));
119
+ _this.setState({
120
+ loading: false,
121
+ features: [],
122
+ filteredSortedFeatures: [],
123
+ loadedLayer: ""
124
+ });
125
+ }
126
+ }, bbox, (_this$props$filter$fi = _this.props.filter.filterParams) === null || _this$props$filter$fi === void 0 ? void 0 : _this$props$filter$fi[selectedLayer], _this.props.filter.filterGeom);
127
+ return _objectSpread(_objectSpread({}, AttributeTableWidget.defaultState), {}, {
128
+ loading: true,
129
+ selectedLayer: selectedLayer,
130
+ limitToExtent: state.limitToExtent
131
+ });
132
+ });
133
+ });
134
+ _defineProperty(_this, "sortBy", function (field) {
135
+ var newState = {};
136
+ if (_this.state.sortField && _this.state.sortField.field === field) {
137
+ newState = {
138
+ sortField: {
139
+ field: field,
140
+ dir: -_this.state.sortField.dir
141
+ }
142
+ };
143
+ } else {
144
+ newState = {
145
+ sortField: {
146
+ field: field,
147
+ dir: 1
148
+ }
149
+ };
150
+ }
151
+ newState.filteredSortedFeatures = _this.filteredSortedFeatures(_this.state.features, _objectSpread(_objectSpread({}, _this.state), newState));
152
+ _this.setState(newState);
153
+ });
154
+ _defineProperty(_this, "renderField", function (currentEditConfig, field, featureidx, filteredIndex, fielddisabled) {
155
+ var feature = _this.state.features[featureidx];
156
+ var value = feature.properties[field.id];
157
+ if (value === undefined || value === null) {
158
+ value = "";
159
+ }
160
+ var mapPrefix = (currentEditConfig.editDataset.match(/^[^.]+\./) || [""])[0];
161
+ var updateField = function updateField(fieldid, val) {
162
+ var emptynull = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
163
+ return _this.updateField(featureidx, filteredIndex, fieldid, val, emptynull);
164
+ };
165
+ var constraints = field.constraints || {};
166
+ var disabled = constraints.readOnly || fielddisabled;
167
+ var input = null;
168
+ if (field.type === "boolean" || field.type === "bool") {
169
+ input = /*#__PURE__*/React.createElement("input", _extends({
170
+ name: field.id
171
+ }, constraints, {
172
+ checked: value,
173
+ disabled: disabled,
174
+ onChange: function onChange(ev) {
175
+ return updateField(field.id, ev.target.checked);
176
+ },
177
+ type: "checkbox"
178
+ }));
179
+ } else if (constraints.values || constraints.keyvalrel) {
180
+ var filterExpr = null;
181
+ if (field.filterExpression) {
182
+ filterExpr = parseExpression(field.filterExpression, feature, currentEditConfig, _this.props.iface, mapPrefix, _this.props.mapCrs, function () {
183
+ return _this.setState({
184
+ reevaluate: +new Date()
185
+ });
186
+ }, true);
187
+ }
188
+ input = /*#__PURE__*/React.createElement(EditComboField, {
189
+ editIface: _this.props.iface,
190
+ fieldId: field.id,
191
+ filterExpr: filterExpr,
192
+ keyvalrel: constraints.keyvalrel,
193
+ multiSelect: constraints.allowMulti === true,
194
+ name: field.id,
195
+ readOnly: constraints.readOnly || disabled,
196
+ required: constraints.required,
197
+ updateField: updateField,
198
+ value: value,
199
+ values: constraints.values
200
+ });
201
+ } else if (field.type === "number") {
202
+ var _constraints$prec, _constraints$step;
203
+ var precision = (_constraints$prec = constraints.prec) !== null && _constraints$prec !== void 0 ? _constraints$prec : 0;
204
+ var step = (_constraints$step = constraints.step) !== null && _constraints$step !== void 0 ? _constraints$step : 1;
205
+ input = /*#__PURE__*/React.createElement(NumberInput, {
206
+ decimals: precision,
207
+ disabled: disabled,
208
+ fitParent: true,
209
+ max: constraints.max,
210
+ min: constraints.min,
211
+ name: field.id,
212
+ onChange: function onChange(v) {
213
+ return updateField(field.id, v, true);
214
+ },
215
+ readOnly: constraints.readOnly,
216
+ required: constraints.required,
217
+ step: step,
218
+ value: value
219
+ });
220
+ } else if (field.type === "date") {
221
+ // Truncate time portion of ISO date string
222
+ value = value.substr(0, 10);
223
+ input = /*#__PURE__*/React.createElement("input", _extends({
224
+ disabled: disabled,
225
+ name: field.id,
226
+ type: field.type
227
+ }, constraints, {
228
+ onChange: function onChange(ev) {
229
+ return updateField(field.id, ev.target.value, true);
230
+ },
231
+ value: value
232
+ }));
233
+ } else if (field.type === "file") {
234
+ return /*#__PURE__*/React.createElement(EditUploadField, {
235
+ constraints: constraints,
236
+ dataset: currentEditConfig.editDataset,
237
+ disabled: disabled,
238
+ fieldId: field.id,
239
+ iface: _this.props.iface,
240
+ name: field.id,
241
+ showThumbnails: false,
242
+ updateField: updateField,
243
+ updateFile: function updateFile(fieldId, data) {
244
+ _this.changedFiles[fieldId] = data;
245
+ },
246
+ value: value
247
+ });
248
+ } else if (field.type === "text") {
249
+ var _feature$properties$f;
250
+ if (((_feature$properties$f = feature.properties[field.id]) !== null && _feature$properties$f !== void 0 ? _feature$properties$f : null) === null) {
251
+ var _ConfigUtils$getConfi;
252
+ value = (_ConfigUtils$getConfi = ConfigUtils.getConfigProp("editTextNullValue")) !== null && _ConfigUtils$getConfi !== void 0 ? _ConfigUtils$getConfi : "";
253
+ }
254
+ var updateTextField = function updateTextField(val) {
255
+ if (val !== value) {
256
+ var textNullValue = ConfigUtils.getConfigProp("editTextNullValue");
257
+ updateField(field.id, textNullValue !== undefined && val === textNullValue ? null : val);
258
+ }
259
+ };
260
+ var addLinkAnchors = ConfigUtils.getConfigProp("editingAddLinkAnchors") !== false;
261
+ var editTextNullValue = ConfigUtils.getConfigProp("editTextNullValue");
262
+ input = /*#__PURE__*/React.createElement(TextInput, {
263
+ addLinkAnchors: addLinkAnchors,
264
+ clearValue: editTextNullValue,
265
+ disabled: disabled,
266
+ multiline: constraints.multiline,
267
+ name: field.id,
268
+ onChange: updateTextField,
269
+ required: constraints.required,
270
+ value: value
271
+ });
272
+ } else {
273
+ input = /*#__PURE__*/React.createElement("input", _extends({
274
+ disabled: disabled,
275
+ name: field.id,
276
+ type: field.type
277
+ }, constraints, {
278
+ onChange: function onChange(ev) {
279
+ return updateField(field.id, ev.target.value);
280
+ },
281
+ value: value
282
+ }));
283
+ }
284
+ return input;
285
+ });
286
+ _defineProperty(_this, "addFeature", function () {
287
+ var editConfig = _this.props.theme.editConfig || {};
288
+ var currentEditConfig = editConfig[_this.state.loadedLayer];
289
+ if (!currentEditConfig) {
290
+ return;
291
+ }
292
+ var hasGeometry = (currentEditConfig || {}).geomType !== null;
293
+ if (!_this.props.allowAddForGeometryLayers && hasGeometry) {
294
+ // eslint-disable-next-line
295
+ alert(LocaleUtils.tr("attribtable.geomnoadd"));
296
+ return;
297
+ }
298
+ var featureSkel = {
299
+ type: "Feature",
300
+ geometry: null,
301
+ properties: currentEditConfig.fields.reduce(function (res, field) {
302
+ if (field.id !== "id") {
303
+ res[field.id] = field.type === "text" ? "" : null;
304
+ }
305
+ return res;
306
+ }, {})
307
+ };
308
+ var mapPrefix = (currentEditConfig.editDataset.match(/^[^.]+\./) || [""])[0];
309
+ getFeatureTemplate(currentEditConfig, featureSkel, _this.props.iface, mapPrefix, _this.props.mapCrs, function (feature) {
310
+ _this.setState(function (state) {
311
+ return {
312
+ features: [].concat(_toConsumableArray(state.features), [feature]),
313
+ filteredSortedFeatures: [].concat(_toConsumableArray(state.filteredSortedFeatures), [_objectSpread(_objectSpread({}, feature), {}, {
314
+ originalIndex: state.features.length
315
+ })]),
316
+ filterVal: "",
317
+ currentPage: Math.floor(state.features.length / state.pageSize),
318
+ changedFeatureIdx: state.filteredSortedFeatures.length,
319
+ newFeature: true
320
+ };
321
+ });
322
+ _this.props.setCurrentTaskBlocked(true, LocaleUtils.tr("editing.unsavedchanged"));
323
+ });
324
+ });
325
+ _defineProperty(_this, "deleteSelectedFeatured", function () {
326
+ _this.setState(function (state) {
327
+ var features = state.filteredSortedFeatures.filter(function (feature) {
328
+ return state.selectedFeatures[feature.id] === true;
329
+ });
330
+ var selectedLayer = state.selectedLayer;
331
+ var editConfig = _this.props.theme.editConfig || {};
332
+ var currentEditConfig = editConfig[selectedLayer];
333
+ features.forEach(function (feature) {
334
+ _this.props.iface.deleteFeature(currentEditConfig, feature.id, function (success) {
335
+ _this.setState(function (state2) {
336
+ var newState = {
337
+ deleteTask: _objectSpread(_objectSpread({}, state2.deleteTask), {}, {
338
+ pending: state2.deleteTask.pending.filter(function (entry) {
339
+ return entry !== feature.id;
340
+ }),
341
+ failed: success ? state2.deleteTask.failed : [].concat(_toConsumableArray(state2.deleteTask.failed), [feature.id]),
342
+ deleted: !success ? state2.deleteTask.deleted : [].concat(_toConsumableArray(state2.deleteTask.deleted), [feature.id])
343
+ })
344
+ };
345
+ if (isEmpty(newState.deleteTask.pending)) {
346
+ newState.features = state.features.filter(function (f) {
347
+ return !newState.deleteTask.deleted.includes(f.id);
348
+ });
349
+ newState.filteredSortedFeatures = _this.filteredSortedFeatures(newState.features, state);
350
+ if (!isEmpty(newState.deleteTask.failed)) {
351
+ // eslint-disable-next-line
352
+ alert(LocaleUtils.tr("attribtable.deletefailed"));
353
+ }
354
+ newState.deleteTask = null;
355
+ newState.currentPage = Math.floor((newState.features.length - 1) / state.pageSize);
356
+ newState.selectedFeatures = {};
357
+ newState.confirmDelete = false;
358
+ }
359
+ return newState;
360
+ });
361
+ }, state.captchaResponse);
362
+ });
363
+ return {
364
+ deleteTask: {
365
+ pending: features.map(function (feature) {
366
+ return feature.id;
367
+ }),
368
+ failed: [],
369
+ deleted: []
370
+ }
371
+ };
372
+ });
373
+ });
374
+ _defineProperty(_this, "updateField", function (featureidx, filteredIdx, fieldid, value, emptynull) {
375
+ _this.props.setCurrentTaskBlocked(true, LocaleUtils.tr("editing.unsavedchanged"));
376
+ _this.setState(function (state) {
377
+ value = value === "" && emptynull ? null : value;
378
+ var newFeatures = _toConsumableArray(state.features);
379
+ newFeatures[featureidx] = _objectSpread({}, newFeatures[featureidx]);
380
+ newFeatures[featureidx].properties = _objectSpread(_objectSpread({}, newFeatures[featureidx].properties), {}, _defineProperty({}, fieldid, value));
381
+ var newfilteredSortedFeatures = _toConsumableArray(state.filteredSortedFeatures);
382
+ newfilteredSortedFeatures[filteredIdx] = _objectSpread({}, newfilteredSortedFeatures[filteredIdx]);
383
+ newfilteredSortedFeatures[filteredIdx].properties = _objectSpread(_objectSpread({}, newfilteredSortedFeatures[filteredIdx].properties), {}, _defineProperty({}, fieldid, value));
384
+ var originalFeatureProps = state.originalFeatureProps || _objectSpread({}, state.features[featureidx].properties);
385
+ return {
386
+ features: newFeatures,
387
+ filteredSortedFeatures: newfilteredSortedFeatures,
388
+ changedFeatureIdx: featureidx,
389
+ originalFeatureProps: originalFeatureProps
390
+ };
391
+ });
392
+ });
393
+ _defineProperty(_this, "commit", function () {
394
+ var feature = _objectSpread(_objectSpread({}, _this.state.features[_this.state.changedFeatureIdx]), {}, {
395
+ crs: {
396
+ type: "name",
397
+ properties: {
398
+ name: CoordinatesUtils.toOgcUrnCrs(_this.props.mapCrs)
399
+ }
400
+ }
401
+ });
402
+ var editConfig = _this.props.theme.editConfig || {};
403
+ var currentEditConfig = editConfig[_this.state.loadedLayer];
404
+ Object.keys(feature.properties || {}).forEach(function (name) {
405
+ var _currentEditConfig$fi, _currentEditConfig$fi2, _currentEditConfig$fi3;
406
+ var fieldConfig = (_currentEditConfig$fi = (_currentEditConfig$fi2 = currentEditConfig.fields) === null || _currentEditConfig$fi2 === void 0 || (_currentEditConfig$fi3 = _currentEditConfig$fi2.find) === null || _currentEditConfig$fi3 === void 0 ? void 0 : _currentEditConfig$fi3.call(_currentEditConfig$fi2, function (f) {
407
+ return f.id === name;
408
+ })) !== null && _currentEditConfig$fi !== void 0 ? _currentEditConfig$fi : {};
409
+ if (fieldConfig.expression) {
410
+ // Skip virtual fields
411
+ delete feature.properties[name];
412
+ }
413
+ });
414
+ // Omit geometry if it is read-only
415
+ var canEditGeometry = ['Point', 'LineString', 'Polygon'].includes((currentEditConfig.geomType || "").replace(/^Multi/, '').replace(/Z$/, ''));
416
+ if (!canEditGeometry) {
417
+ delete feature.geometry;
418
+ }
419
+ var featureData = new FormData();
420
+ featureData.set('feature', JSON.stringify(feature));
421
+ Object.entries(_this.changedFiles).forEach(function (_ref) {
422
+ var _ref2 = _slicedToArray(_ref, 2),
423
+ key = _ref2[0],
424
+ value = _ref2[1];
425
+ return featureData.set('file:' + key, value);
426
+ });
427
+ if (_this.state.captchaResponse) {
428
+ featureData.set('g-recaptcha-response', _this.state.captchaResponse);
429
+ }
430
+ if (_this.state.newFeature) {
431
+ _this.props.iface.addFeatureMultipart(currentEditConfig, _this.props.mapCrs, featureData, function (success, result) {
432
+ return _this.featureCommited(success, result);
433
+ });
434
+ } else {
435
+ _this.props.iface.editFeatureMultipart(currentEditConfig, _this.props.mapCrs, feature.id, featureData, function (success, result) {
436
+ return _this.featureCommited(success, result);
437
+ });
438
+ }
439
+ });
440
+ _defineProperty(_this, "featureCommited", function (success, result) {
441
+ if (!success) {
442
+ // eslint-disable-next-line
443
+ alert(result);
444
+ } else {
445
+ _this.changedFiles = {};
446
+ _this.setState(function (state) {
447
+ var newFeatures = _toConsumableArray(state.features);
448
+ newFeatures[state.changedFeatureIdx] = result;
449
+ return {
450
+ features: newFeatures,
451
+ filteredSortedFeatures: _this.filteredSortedFeatures(newFeatures, state),
452
+ changedFeatureIdx: null,
453
+ originalFeatureProps: null,
454
+ newFeature: false
455
+ };
456
+ });
457
+ }
458
+ _this.props.setCurrentTaskBlocked(false);
459
+ });
460
+ _defineProperty(_this, "discard", function () {
461
+ var newFeatures = _toConsumableArray(_this.state.features);
462
+ if (_this.state.newFeature) {
463
+ newFeatures.splice(_this.state.changedFeatureIdx, 1);
464
+ } else {
465
+ var featureidx = _this.state.changedFeatureIdx;
466
+ newFeatures[featureidx] = _objectSpread({}, newFeatures[featureidx]);
467
+ newFeatures[featureidx].properties = _this.state.originalFeatureProps;
468
+ }
469
+ _this.changedFiles = {};
470
+ _this.setState(function (state) {
471
+ return {
472
+ features: newFeatures,
473
+ filteredSortedFeatures: _this.filteredSortedFeatures(newFeatures, state),
474
+ changedFeatureIdx: null,
475
+ originalFeatureProps: null,
476
+ newFeature: false
477
+ };
478
+ });
479
+ _this.props.setCurrentTaskBlocked(false);
480
+ });
481
+ _defineProperty(_this, "highlightFeatures", function () {
482
+ var features = [];
483
+ if (_this.state.highlightedFeature) {
484
+ features.push(_this.state.highlightedFeature);
485
+ } else if (_this.state.filterVal) {
486
+ features.push.apply(features, _toConsumableArray(Object.values(_this.state.filteredSortedFeatures)));
487
+ }
488
+ var layer = {
489
+ id: "__attributetablehighlight",
490
+ role: LayerRole.SELECTION
491
+ };
492
+ _this.props.addLayerFeatures(layer, features.map(function (f) {
493
+ return {
494
+ id: f.id,
495
+ geometry: f.geometry
496
+ };
497
+ }), true);
498
+ });
499
+ _defineProperty(_this, "zoomToSelection", function () {
500
+ var collection = {
501
+ type: "FeatureCollection",
502
+ features: _this.state.filteredSortedFeatures.filter(function (feature) {
503
+ return _this.state.selectedFeatures[feature.id] === true && feature.geometry;
504
+ })
505
+ };
506
+ if (!isEmpty(collection.features)) {
507
+ if (collection.features.length === 1 && collection.features[0].geometry.type === "Point") {
508
+ var zoom = MapUtils.computeZoom(_this.props.mapScales, _this.props.zoomLevel);
509
+ _this.props.zoomToPoint(collection.features[0].geometry.coordinates, zoom, _this.props.mapCrs);
510
+ } else {
511
+ _this.props.zoomToExtent(VectorLayerUtils.computeFeatureBBox(collection), _this.props.mapCrs);
512
+ }
513
+ }
514
+ });
515
+ _defineProperty(_this, "switchToFormEditMode", function () {
516
+ var editConfig = _this.props.theme.editConfig || {};
517
+ var currentEditConfig = editConfig[_this.state.loadedLayer];
518
+ var hasGeometry = (currentEditConfig || {}).geomType !== null;
519
+ if (!hasGeometry) {
520
+ // eslint-disable-next-line
521
+ alert(LocaleUtils.tr("attribtable.nogeomnoform"));
522
+ return;
523
+ }
524
+ var feature = _this.state.filteredSortedFeatures.find(function (f) {
525
+ return _this.state.selectedFeatures[f.id] === true;
526
+ });
527
+ _this.props.setCurrentTask("Editing", null, null, {
528
+ layer: _this.state.loadedLayer,
529
+ feature: feature
530
+ });
531
+ });
532
+ _defineProperty(_this, "updateFilter", function (field, val) {
533
+ var resetPage = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
534
+ _this.setState(function (state) {
535
+ return _defineProperty(_defineProperty(_defineProperty({}, field, val), "currentPage", resetPage ? 0 : state.currentPage), "filteredSortedFeatures", _this.filteredSortedFeatures(state.features, _objectSpread(_objectSpread({}, state), {}, _defineProperty({}, field, val))));
536
+ });
537
+ });
538
+ _defineProperty(_this, "filteredSortedFeatures", function (features, state) {
539
+ var filteredFeatures = [];
540
+ if (!state.filterVal) {
541
+ filteredFeatures = features.map(function (feature, idx) {
542
+ return _objectSpread(_objectSpread({}, feature), {}, {
543
+ originalIndex: idx
544
+ });
545
+ });
546
+ } else {
547
+ var filterVal = state.filterVal.toLowerCase();
548
+ var test = null;
549
+ if (state.filterOp === "~") {
550
+ test = function test(x) {
551
+ return String(x).toLowerCase().includes(filterVal);
552
+ };
553
+ } else if (state.filterOp === "=") {
554
+ test = function test(x) {
555
+ return String(x).toLowerCase() === filterVal;
556
+ };
557
+ } else if (state.filterOp === ">") {
558
+ test = function test(x) {
559
+ return Number(x) > Number(filterVal);
560
+ };
561
+ } else if (state.filterOp === ">=") {
562
+ test = function test(x) {
563
+ return Number(x) >= Number(filterVal);
564
+ };
565
+ } else if (state.filterOp === "<=") {
566
+ test = function test(x) {
567
+ return Number(x) <= Number(filterVal);
568
+ };
569
+ } else if (state.filterOp === "<") {
570
+ test = function test(x) {
571
+ return Number(x) < Number(filterVal);
572
+ };
573
+ }
574
+ // Build value relation lookup
575
+ var editConfig = _this.props.theme.editConfig || {};
576
+ var currentEditConfig = editConfig[_this.state.loadedLayer];
577
+ var valueLookup = currentEditConfig.fields.reduce(function (res, field) {
578
+ if (field.constraints && field.constraints.values) {
579
+ res[field.id] = field.constraints.values.reduce(function (res2, constraint) {
580
+ res2[constraint.value] = constraint.label;
581
+ return res2;
582
+ }, {});
583
+ } else if (field.constraints && field.constraints.keyvalrel) {
584
+ res[field.id] = KeyValCache.getSync(_this.props.iface, field.constraints.keyvalrel).reduce(function (res2, entry) {
585
+ res2[entry.value] = entry.label;
586
+ return res2;
587
+ }, {});
588
+ }
589
+ return res;
590
+ }, {});
591
+ var filterFieldValue = state.filterField === "id" ? function (feature) {
592
+ return feature.id;
593
+ } : function (feature) {
594
+ var value = feature.properties[state.filterField];
595
+ return valueLookup[state.filterField] ? valueLookup[state.filterField][value] : value;
596
+ };
597
+ filteredFeatures = features.reduce(function (res, feature, idx) {
598
+ if (test(filterFieldValue(feature))) {
599
+ res.push(_objectSpread(_objectSpread({}, feature), {}, {
600
+ originalIndex: idx
601
+ }));
602
+ }
603
+ return res;
604
+ }, []);
605
+ }
606
+ if (state.sortField) {
607
+ var sortFieldValue = state.sortField.field === "id" ? function (feature) {
608
+ return feature.id;
609
+ } : function (feature) {
610
+ return feature.properties[state.sortField.field];
611
+ };
612
+ return filteredFeatures.sort(function (f1, f2) {
613
+ var v1 = String(sortFieldValue(f1));
614
+ var v2 = String(sortFieldValue(f2));
615
+ return v1.localeCompare(v2, undefined, {
616
+ numeric: true,
617
+ sensitivity: 'base'
618
+ }) * state.sortField.dir;
619
+ });
620
+ } else {
621
+ return filteredFeatures;
622
+ }
623
+ });
624
+ _defineProperty(_this, "resizeTable", function (ev, index, resizeCol) {
625
+ if (_this.table) {
626
+ var element = _this.table.getElementsByTagName(resizeCol ? "th" : "tr")[index];
627
+ var initial = 0;
628
+ if (resizeCol) {
629
+ initial = parseFloat(element.style.minWidth.replace(/px$/, '')) || element.clientWidth;
630
+ } else {
631
+ initial = parseFloat(element.style.height.replace(/px$/, '')) || element.clientHeight;
632
+ }
633
+ var resize = {
634
+ anchor: resizeCol ? ev.clientX : ev.clientY,
635
+ element: element,
636
+ initial: initial
637
+ };
638
+ var resizeDo = resizeCol ? function (event) {
639
+ var delta = event.clientX - resize.anchor;
640
+ resize.element.style.minWidth = Math.max(resize.initial + delta, 16) + "px";
641
+ resize.element.style.width = Math.max(resize.initial + delta, 16) + "px";
642
+ } : function (event) {
643
+ var delta = event.clientY - resize.anchor;
644
+ resize.element.style.height = Math.max(resize.initial + delta, 16) + "px";
645
+ };
646
+ var eventShield = ev.view.document.createElement("div");
647
+ eventShield.className = '__event_shield';
648
+ ev.view.document.body.appendChild(eventShield);
649
+ ev.view.document.body.classList.add(resizeCol ? 'ewresizing' : 'nsresizing');
650
+ ev.view.addEventListener("pointermove", resizeDo);
651
+ ev.view.addEventListener("pointerup", function (event) {
652
+ event.view.document.body.removeChild(eventShield);
653
+ event.view.removeEventListener("pointermove", resizeDo);
654
+ event.view.document.body.classList.remove(resizeCol ? 'ewresizing' : 'nsresizing');
655
+ }, {
656
+ once: true
657
+ });
658
+ }
659
+ });
660
+ _defineProperty(_this, "csvExport", function () {
661
+ var editConfig = _this.props.theme.editConfig || {};
662
+ var currentEditConfig = editConfig[_this.state.loadedLayer];
663
+ if (!currentEditConfig) {
664
+ return;
665
+ }
666
+ var fields = currentEditConfig.fields.filter(function (field) {
667
+ return field.id !== 'id';
668
+ });
669
+ var data = "";
670
+ data += "id," + fields.map(function (field) {
671
+ return "\"".concat(field.name.replaceAll('"', '""'), "\"");
672
+ }).join(",") + "\n";
673
+ _this.state.features.forEach(function (feature) {
674
+ data += feature.id + "," + fields.map(function (field) {
675
+ var value = feature.properties[field.id];
676
+ if (value === null || value === undefined) {
677
+ return "null";
678
+ } else {
679
+ return "\"".concat(String(feature.properties[field.id]).replaceAll('"', '""'), "\"");
680
+ }
681
+ }).join(",") + "\n";
682
+ });
683
+ FileSaver.saveAs(new Blob([data], {
684
+ type: "text/plain;charset=utf-8"
685
+ }), _this.state.loadedLayer + ".csv");
686
+ });
687
+ _defineProperty(_this, "translateFieldName", function (fieldName, layerName) {
688
+ var _this$props$theme$tra, _this$props$theme$tra2;
689
+ 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.layers) === null || _this$props$theme$tra2 === void 0 || (_this$props$theme$tra2 = _this$props$theme$tra2[layerName]) === null || _this$props$theme$tra2 === void 0 || (_this$props$theme$tra2 = _this$props$theme$tra2.fields) === null || _this$props$theme$tra2 === void 0 ? void 0 : _this$props$theme$tra2[fieldName]) !== null && _this$props$theme$tra !== void 0 ? _this$props$theme$tra : fieldName;
690
+ });
691
+ _this.changedFiles = {};
692
+ _this.state = AttributeTableWidget.defaultState;
693
+ _this.table = null;
694
+ _this.attribTableContents = null;
695
+ return _this;
696
+ }
697
+ _inherits(AttributeTableWidget, _React$Component);
698
+ return _createClass(AttributeTableWidget, [{
699
+ key: "componentDidMount",
700
+ value: function componentDidMount() {
701
+ if (this.props.initialLayer) {
702
+ this.reload(this.props.initialLayer);
703
+ }
704
+ }
705
+ }, {
706
+ key: "componentDidUpdate",
707
+ value: function componentDidUpdate(prevProps, prevState) {
708
+ if (this.state.newFeature && !prevState.newFeature) {
709
+ if (this.attribTableContents) {
710
+ this.attribTableContents.scrollTop = this.attribTableContents.scrollHeight;
711
+ }
712
+ }
713
+ // Reload conditions when limited to extent
714
+ if (this.state.limitToExtent && this.state.selectedLayer && (!prevState.limitToExtent || this.props.mapBbox !== prevProps.mapBbox)) {
715
+ this.reload();
716
+ } else if (!this.state.limitToExtent && prevState.limitToExtent) {
717
+ this.reload();
718
+ }
719
+ // Highlight feature
720
+ if (this.state.highlightedFeature !== prevState.highlightedFeature || this.state.filteredSortedFeatures !== prevState.filteredSortedFeatures) {
721
+ this.highlightFeatures();
722
+ }
723
+ }
724
+ }, {
725
+ key: "componentWillUnmount",
726
+ value: function componentWillUnmount() {
727
+ this.props.removeLayer("__attributetablehighlight");
728
+ }
729
+ }, {
730
+ key: "render",
731
+ value: function render() {
732
+ var _this2 = this;
733
+ var captchaRequired = ConfigUtils.getConfigProp("editServiceCaptchaSiteKey") && !ConfigUtils.getConfigProp("username");
734
+ var captchaPending = captchaRequired && !this.state.captchaResponse;
735
+ var editConfig = this.props.theme.editConfig || {};
736
+ var currentEditConfig = editConfig[this.state.loadedLayer];
737
+ var editPermissions = (editConfig[this.state.loadedLayer] || {}).permissions || {};
738
+ var readOnly = editPermissions.updatable === false;
739
+ var loadOverlay = null;
740
+ if (this.state.selectedLayer && this.state.selectedLayer !== this.state.loadedLayer) {
741
+ if (this.state.loading) {
742
+ loadOverlay = /*#__PURE__*/React.createElement("div", {
743
+ className: "attribtable-overlay"
744
+ }, /*#__PURE__*/React.createElement(Spinner, null), /*#__PURE__*/React.createElement("span", null, LocaleUtils.tr("attribtable.loading")));
745
+ } else {
746
+ loadOverlay = /*#__PURE__*/React.createElement("div", {
747
+ className: "attribtable-overlay"
748
+ }, /*#__PURE__*/React.createElement("span", null, LocaleUtils.tr("attribtable.pleasereload")));
749
+ }
750
+ } else if (this.state.selectedLayer && this.state.deleteTask) {
751
+ loadOverlay = /*#__PURE__*/React.createElement("div", {
752
+ className: "attribtable-overlay"
753
+ }, /*#__PURE__*/React.createElement(Spinner, null), /*#__PURE__*/React.createElement("span", null, LocaleUtils.tr("attribtable.deleting")));
754
+ }
755
+ var table = null;
756
+ var footbar = null;
757
+ if (currentEditConfig && this.state.features) {
758
+ var fields = currentEditConfig.fields.filter(function (field) {
759
+ return field.id !== "id";
760
+ }).filter(function (field) {
761
+ var _field$constraints;
762
+ return _this2.props.showHiddenFields || ((_field$constraints = field.constraints) === null || _field$constraints === void 0 ? void 0 : _field$constraints.hidden) !== true;
763
+ });
764
+ var indexOffset = this.state.currentPage * this.state.pageSize;
765
+ var features = this.state.filteredSortedFeatures.slice(indexOffset, indexOffset + this.state.pageSize);
766
+ table = /*#__PURE__*/React.createElement("table", {
767
+ className: "attribtable-table",
768
+ ref: function ref(el) {
769
+ _this2.table = el;
770
+ }
771
+ }, /*#__PURE__*/React.createElement("thead", null, /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("th", null), /*#__PURE__*/React.createElement("th", {
772
+ onClick: function onClick() {
773
+ return _this2.sortBy("id");
774
+ },
775
+ title: this.translateFieldName("id", this.state.loadedLayer)
776
+ }, /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement("span", {
777
+ className: "attribtable-table-headername"
778
+ }, this.translateFieldName("id", this.state.loadedLayer)), this.renderSortIndicator("id"), this.renderColumnResizeHandle(1, 'r'))), fields.map(function (field, idx) {
779
+ return /*#__PURE__*/React.createElement("th", {
780
+ key: field.id,
781
+ onClick: function onClick() {
782
+ return _this2.sortBy(field.id);
783
+ },
784
+ title: _this2.translateFieldName(field.name, _this2.state.loadedLayer)
785
+ }, /*#__PURE__*/React.createElement("span", null, _this2.renderColumnResizeHandle(idx + 1, 'l'), /*#__PURE__*/React.createElement("span", {
786
+ className: "attribtable-table-headername"
787
+ }, _this2.translateFieldName(field.name, _this2.state.loadedLayer)), _this2.renderSortIndicator(field.id), idx < fields.length - 1 ? _this2.renderColumnResizeHandle(idx + 2, 'r') : null));
788
+ }))), /*#__PURE__*/React.createElement("tbody", null, features.map(function (feature, filteredIndex) {
789
+ var featureidx = feature.originalIndex;
790
+ var disabled = readOnly || _this2.state.changedFeatureIdx !== null && _this2.state.changedFeatureIdx !== featureidx;
791
+ var key = _this2.state.changedFeatureIdx === featureidx && _this2.state.newFeature ? "newfeature" : feature.id;
792
+ return /*#__PURE__*/React.createElement("tr", {
793
+ className: disabled ? "row-disabled" : "",
794
+ key: key,
795
+ onMouseEnter: function onMouseEnter() {
796
+ return _this2.setState({
797
+ highlightedFeature: feature
798
+ });
799
+ },
800
+ onMouseLeave: function onMouseLeave() {
801
+ return _this2.setState(function (state) {
802
+ return {
803
+ highlightedFeature: state.highlightedFeature === feature ? null : state.highlightedFeature
804
+ };
805
+ });
806
+ }
807
+ }, /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement("span", null, filteredIndex > 0 ? _this2.renderRowResizeHandle(filteredIndex, 't') : null, /*#__PURE__*/React.createElement("input", {
808
+ checked: _this2.state.selectedFeatures[feature.id] === true,
809
+ onChange: function onChange(ev) {
810
+ return _this2.setState(function (state) {
811
+ return {
812
+ selectedFeatures: _objectSpread(_objectSpread({}, state.selectedFeatures), {}, _defineProperty({}, feature.id, ev.target.checked))
813
+ };
814
+ });
815
+ },
816
+ type: "checkbox"
817
+ }), _this2.renderRowResizeHandle(filteredIndex + 1, 'b'))), /*#__PURE__*/React.createElement("td", null, feature.id), fields.map(function (field) {
818
+ return /*#__PURE__*/React.createElement("td", {
819
+ key: field.id
820
+ }, _this2.renderField(currentEditConfig, field, featureidx, indexOffset + filteredIndex, disabled || !!_this2.state.filterVal && field.id === _this2.state.filterField));
821
+ }));
822
+ })));
823
+ var npages = Math.ceil(this.state.filteredSortedFeatures.length / this.state.pageSize);
824
+ var pages = [this.state.currentPage];
825
+ var extraright = Math.max(0, 2 - this.state.currentPage);
826
+ var extraleft = Math.max(0, this.state.currentPage - (npages - 3));
827
+ for (var i = 0; i < 3 + extraleft; ++i) {
828
+ if (this.state.currentPage - i > 0) {
829
+ pages.unshift(this.state.currentPage - i);
830
+ }
831
+ }
832
+ for (var _i = 0; _i < 3 + extraright; ++_i) {
833
+ if (this.state.currentPage + _i < npages - 1) {
834
+ pages.push(this.state.currentPage - _i + 1);
835
+ }
836
+ }
837
+ footbar = /*#__PURE__*/React.createElement("div", {
838
+ className: "attribtable-footbar"
839
+ }, /*#__PURE__*/React.createElement(NavBar, {
840
+ currentPage: this.state.currentPage,
841
+ disabled: this.state.changedFeatureIdx !== null,
842
+ nPages: npages,
843
+ pageChanged: function pageChanged(currentPage) {
844
+ return _this2.setState({
845
+ currentPage: currentPage
846
+ });
847
+ },
848
+ pageSize: this.state.pageSize,
849
+ pageSizeChanged: function pageSizeChanged(pageSize) {
850
+ return _this2.setState({
851
+ pageSize: pageSize
852
+ });
853
+ }
854
+ }), /*#__PURE__*/React.createElement("div", {
855
+ className: "attribtable-filter controlgroup"
856
+ }, /*#__PURE__*/React.createElement(Icon, {
857
+ icon: "filter"
858
+ }), /*#__PURE__*/React.createElement("select", {
859
+ disabled: this.state.changedFeatureIdx !== null,
860
+ onChange: function onChange(ev) {
861
+ return _this2.updateFilter("filterField", ev.target.value);
862
+ },
863
+ value: this.state.filterField
864
+ }, /*#__PURE__*/React.createElement("option", {
865
+ value: "id"
866
+ }, this.translateFieldName("id", this.state.loadedLayer)), fields.map(function (field) {
867
+ return /*#__PURE__*/React.createElement("option", {
868
+ key: field.id,
869
+ value: field.id
870
+ }, _this2.translateFieldName(field.name, _this2.state.loadedLayer));
871
+ })), /*#__PURE__*/React.createElement("select", {
872
+ disabled: this.state.changedFeatureIdx !== null,
873
+ onChange: function onChange(ev) {
874
+ return _this2.updateFilter("filterOp", ev.target.value);
875
+ },
876
+ value: this.state.filterOp
877
+ }, /*#__PURE__*/React.createElement("option", {
878
+ value: "~"
879
+ }, "~"), /*#__PURE__*/React.createElement("option", {
880
+ value: "="
881
+ }, "="), /*#__PURE__*/React.createElement("option", {
882
+ value: ">"
883
+ }, ">"), /*#__PURE__*/React.createElement("option", {
884
+ value: ">="
885
+ }, ">="), /*#__PURE__*/React.createElement("option", {
886
+ value: "<="
887
+ }, "<="), /*#__PURE__*/React.createElement("option", {
888
+ value: "<"
889
+ }, "<")), /*#__PURE__*/React.createElement(TextInput, {
890
+ disabled: this.state.changedFeatureIdx !== null,
891
+ onChange: function onChange(value) {
892
+ return _this2.updateFilter("filterVal", value, true);
893
+ },
894
+ value: this.state.filterVal
895
+ })), this.props.showLimitToExtent ? /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, /*#__PURE__*/React.createElement("input", {
896
+ checked: this.state.limitToExtent,
897
+ onChange: function onChange(ev) {
898
+ return _this2.setState({
899
+ limitToExtent: ev.target.checked
900
+ });
901
+ },
902
+ type: "checkbox"
903
+ }), " ", LocaleUtils.tr("attribtable.limittoextent"))) : null);
904
+ }
905
+ var nolayer = !this.state.selectedLayer;
906
+ var loading = this.state.loading;
907
+ var editing = this.state.changedFeatureIdx !== null;
908
+ var layerChanged = this.state.selectedLayer !== this.state.loadedLayer;
909
+ var hasGeometry = (currentEditConfig || {}).geomType !== null;
910
+ var showAddButton = editPermissions.creatable !== false && (this.props.allowAddForGeometryLayers || !hasGeometry);
911
+ var showDelButton = editPermissions.deletable !== false;
912
+ var showEditButton = ConfigUtils.havePlugin("Editing") && this.props.showEditFormButton;
913
+ var deleteButton = showDelButton ? /*#__PURE__*/React.createElement("button", {
914
+ className: "button",
915
+ disabled: layerChanged || editing || !Object.values(this.state.selectedFeatures).find(function (entry) {
916
+ return entry === true;
917
+ }),
918
+ onClick: function onClick() {
919
+ return _this2.setState({
920
+ confirmDelete: true
921
+ });
922
+ },
923
+ title: LocaleUtils.tr("attribtable.deletefeatures")
924
+ }, /*#__PURE__*/React.createElement(Icon, {
925
+ icon: "trash"
926
+ })) : null;
927
+ var captchaBar = null;
928
+ if (captchaRequired && (this.state.changedFeatureIdx !== null || this.state.confirmDelete)) {
929
+ captchaBar = /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(ReCaptchaWidget, {
930
+ onChange: function onChange(value) {
931
+ return _this2.setState({
932
+ captchaResponse: value
933
+ });
934
+ },
935
+ sitekey: ConfigUtils.getConfigProp("editServiceCaptchaSiteKey")
936
+ }));
937
+ }
938
+ return /*#__PURE__*/React.createElement("div", {
939
+ className: "AttributeTable"
940
+ }, loadOverlay, /*#__PURE__*/React.createElement("div", {
941
+ className: "attribtable-toolbar"
942
+ }, this.props.showLayerSelection ? /*#__PURE__*/React.createElement("select", {
943
+ disabled: loading || editing,
944
+ onChange: function onChange(ev) {
945
+ return _this2.changeSelectedLayer(ev.target.value);
946
+ },
947
+ value: this.state.selectedLayer || ""
948
+ }, /*#__PURE__*/React.createElement("option", {
949
+ disabled: true,
950
+ value: ""
951
+ }, LocaleUtils.tr("attribtable.selectlayer")), Object.keys(editConfig).map(function (layerId) {
952
+ var _this2$props$theme$tr, _this2$props$theme$tr2, _LayerUtils$searchLay, _LayerUtils$searchLay2;
953
+ var layerName = editConfig[layerId].layerName;
954
+ var layerTitle = editConfig[layerId].layerTitle ? (_this2$props$theme$tr = (_this2$props$theme$tr2 = _this2.props.theme.translations) === null || _this2$props$theme$tr2 === void 0 || (_this2$props$theme$tr2 = _this2$props$theme$tr2.layertree) === null || _this2$props$theme$tr2 === void 0 ? void 0 : _this2$props$theme$tr2[layerName]) !== null && _this2$props$theme$tr !== void 0 ? _this2$props$theme$tr : editConfig[layerId].layerTitle : (_LayerUtils$searchLay = (_LayerUtils$searchLay2 = LayerUtils.searchLayer(_this2.props.layers, _this2.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;
955
+ return /*#__PURE__*/React.createElement("option", {
956
+ key: layerId,
957
+ value: layerId
958
+ }, layerTitle);
959
+ })) : null, /*#__PURE__*/React.createElement("button", {
960
+ className: "button",
961
+ disabled: editing || nolayer || this.state.loading,
962
+ onClick: function onClick() {
963
+ return _this2.reload();
964
+ },
965
+ title: LocaleUtils.tr("attribtable.reload")
966
+ }, /*#__PURE__*/React.createElement(Icon, {
967
+ icon: "refresh"
968
+ })), showAddButton ? /*#__PURE__*/React.createElement("button", {
969
+ className: "button",
970
+ disabled: nolayer || editing || loading || layerChanged,
971
+ onClick: this.addFeature,
972
+ title: LocaleUtils.tr("attribtable.addfeature")
973
+ }, /*#__PURE__*/React.createElement(Icon, {
974
+ icon: "plus"
975
+ })) : null, /*#__PURE__*/React.createElement("button", {
976
+ className: "button",
977
+ disabled: layerChanged || !Object.values(this.state.selectedFeatures).find(function (entry) {
978
+ return entry === true;
979
+ }),
980
+ onClick: this.zoomToSelection,
981
+ title: LocaleUtils.tr("attribtable.zoomtoselection")
982
+ }, /*#__PURE__*/React.createElement(Icon, {
983
+ icon: "search"
984
+ })), showEditButton ? /*#__PURE__*/React.createElement("button", {
985
+ className: "button",
986
+ disabled: layerChanged || editing || Object.values(this.state.selectedFeatures).filter(function (entry) {
987
+ return entry === true;
988
+ }).length !== 1,
989
+ onClick: this.switchToFormEditMode,
990
+ title: LocaleUtils.tr("attribtable.formeditmode")
991
+ }, /*#__PURE__*/React.createElement(Icon, {
992
+ icon: "editing"
993
+ })) : null, this.state.confirmDelete ? /*#__PURE__*/React.createElement("button", {
994
+ className: "button button-accept",
995
+ disabled: captchaPending,
996
+ onClick: this.deleteSelectedFeatured
997
+ }, /*#__PURE__*/React.createElement(Icon, {
998
+ icon: "ok"
999
+ }), /*#__PURE__*/React.createElement("span", null, LocaleUtils.tr("attribtable.delete"))) : deleteButton, this.state.confirmDelete ? /*#__PURE__*/React.createElement("button", {
1000
+ className: "button button-reject",
1001
+ onClick: function onClick() {
1002
+ return _this2.setState({
1003
+ confirmDelete: false,
1004
+ captchaResponse: null
1005
+ });
1006
+ }
1007
+ }, /*#__PURE__*/React.createElement(Icon, {
1008
+ icon: "remove"
1009
+ }), /*#__PURE__*/React.createElement("span", null, LocaleUtils.tr("attribtable.nodelete"))) : null, this.state.changedFeatureIdx !== null ? /*#__PURE__*/React.createElement("button", {
1010
+ className: "button button-accept",
1011
+ disabled: captchaPending,
1012
+ onClick: this.commit
1013
+ }, /*#__PURE__*/React.createElement(Icon, {
1014
+ icon: "ok"
1015
+ }), /*#__PURE__*/React.createElement("span", null, LocaleUtils.tr("attribtable.commit"))) : null, this.state.changedFeatureIdx !== null ? /*#__PURE__*/React.createElement("button", {
1016
+ className: "button button-reject",
1017
+ onClick: this.discard
1018
+ }, /*#__PURE__*/React.createElement(Icon, {
1019
+ icon: "remove"
1020
+ }), /*#__PURE__*/React.createElement("span", null, LocaleUtils.tr("attribtable.discard"))) : null, /*#__PURE__*/React.createElement("button", {
1021
+ className: "button",
1022
+ disabled: isEmpty(this.state.features),
1023
+ onClick: function onClick() {
1024
+ return _this2.csvExport();
1025
+ },
1026
+ title: LocaleUtils.tr("attribtable.csvexport")
1027
+ }, /*#__PURE__*/React.createElement(Icon, {
1028
+ icon: "export"
1029
+ }))), captchaBar, /*#__PURE__*/React.createElement("div", {
1030
+ className: "attribtable-contents",
1031
+ ref: function ref(el) {
1032
+ _this2.attribTableContents = el;
1033
+ }
1034
+ }, table), footbar);
1035
+ }
1036
+ }]);
1037
+ }(React.Component);
1038
+ _defineProperty(AttributeTableWidget, "propTypes", {
1039
+ addLayerFeatures: PropTypes.func,
1040
+ /** Whether to allow adding records for datasets which have a geometry column. */
1041
+ allowAddForGeometryLayers: PropTypes.bool,
1042
+ filter: PropTypes.object,
1043
+ iface: PropTypes.object,
1044
+ initialLayer: PropTypes.string,
1045
+ layers: PropTypes.array,
1046
+ mapBbox: PropTypes.object,
1047
+ mapCrs: PropTypes.string,
1048
+ mapScales: PropTypes.array,
1049
+ removeLayer: PropTypes.func,
1050
+ setCurrentTask: PropTypes.func,
1051
+ setCurrentTaskBlocked: PropTypes.func,
1052
+ /** Whether to show a button to open the edit form for selected layer. Requires the Editing plugin to be enabled. */
1053
+ showEditFormButton: PropTypes.bool,
1054
+ /** Whether to show hidden Fields. */
1055
+ showHiddenFields: PropTypes.bool,
1056
+ /** Whether to show the layer selection menu. */
1057
+ showLayerSelection: PropTypes.bool,
1058
+ /** Whether to show the "Limit to extent" checkbox */
1059
+ showLimitToExtent: PropTypes.bool,
1060
+ theme: PropTypes.object,
1061
+ /** The zoom level for zooming to point features. */
1062
+ zoomLevel: PropTypes.number,
1063
+ zoomToExtent: PropTypes.func,
1064
+ zoomToPoint: PropTypes.func
1065
+ });
1066
+ _defineProperty(AttributeTableWidget, "defaultProps", {
1067
+ zoomLevel: 1000,
1068
+ showEditFormButton: true,
1069
+ showHiddenFields: true,
1070
+ showLayerSelection: true
1071
+ });
1072
+ _defineProperty(AttributeTableWidget, "defaultState", {
1073
+ loading: false,
1074
+ selectedLayer: "",
1075
+ loadedLayer: "",
1076
+ features: [],
1077
+ filteredSortedFeatures: [],
1078
+ selectedFeatures: {},
1079
+ highlightedFeature: null,
1080
+ changedFeatureIdx: null,
1081
+ originalFeatureProps: null,
1082
+ pageSize: 50,
1083
+ currentPage: 0,
1084
+ filterField: "id",
1085
+ filterOp: "~",
1086
+ filterVal: "",
1087
+ sortField: null,
1088
+ deleteTask: null,
1089
+ newFeature: false,
1090
+ confirmDelete: false,
1091
+ limitToExtent: false,
1092
+ captchaResponse: ''
1093
+ });
1094
+ export default connect(function (state) {
1095
+ return {
1096
+ layers: state.layers.flat,
1097
+ filter: state.layers.filter,
1098
+ mapBbox: state.map.bbox,
1099
+ mapCrs: state.map.projection,
1100
+ mapScales: state.map.scales,
1101
+ theme: state.theme.current
1102
+ };
1103
+ }, {
1104
+ addLayerFeatures: addLayerFeatures,
1105
+ removeLayer: removeLayer,
1106
+ setCurrentTask: setCurrentTask,
1107
+ setCurrentTaskBlocked: setCurrentTaskBlocked,
1108
+ zoomToExtent: zoomToExtent,
1109
+ zoomToPoint: zoomToPoint
1110
+ })(AttributeTableWidget);