qwc2 2025.10.13 → 2025.10.15

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 +768 -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,20 +1,876 @@
1
- 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 _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 _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 _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 _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 _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 _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 _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 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 _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); }
2
+ 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); }
3
+ function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
4
+ 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."); }
5
+ function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
6
+ function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
7
+ function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
8
+ 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."); }
9
+ 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; } }
10
+ 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; }
11
+ 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; } }
12
+ function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
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 axios from"axios";import isEmpty from"lodash.isempty";import isEqual from"lodash.isequal";import PropTypes from"prop-types";import{v4 as uuidv4}from"uuid";import{LayerRole,setFilter}from"../actions/layers";import{setPermalinkParameters}from"../actions/localConfig";import{setCurrentTask}from"../actions/task";import Icon from"../components/Icon";import MapButton from"../components/MapButton";import MapSelection from"../components/MapSelection";import PickFeature from"../components/PickFeature";import SideBar from"../components/SideBar";import ButtonBar from"../components/widgets/ButtonBar";import ComboBox from"../components/widgets/ComboBox";import DateTimeInput from"../components/widgets/DateTimeInput";import TextInput from"../components/widgets/TextInput";import ToggleSwitch from"../components/widgets/ToggleSwitch";import ConfigUtils from"../utils/ConfigUtils";import LayerUtils from"../utils/LayerUtils";import LocaleUtils from"../utils/LocaleUtils";import MiscUtils from"../utils/MiscUtils";import"./style/MapFilter.css";/**
34
+ */
35
+
36
+ import React from 'react';
37
+ import { connect } from 'react-redux';
38
+ import axios from 'axios';
39
+ import isEmpty from 'lodash.isempty';
40
+ import isEqual from 'lodash.isequal';
41
+ import PropTypes from 'prop-types';
42
+ import { v4 as uuidv4 } from 'uuid';
43
+ import { LayerRole, setFilter } from '../actions/layers';
44
+ import { setPermalinkParameters } from '../actions/localConfig';
45
+ import { setCurrentTask } from '../actions/task';
46
+ import Icon from '../components/Icon';
47
+ import MapButton from '../components/MapButton';
48
+ import MapSelection from '../components/MapSelection';
49
+ import PickFeature from '../components/PickFeature';
50
+ import SideBar from '../components/SideBar';
51
+ import ButtonBar from '../components/widgets/ButtonBar';
52
+ import ComboBox from '../components/widgets/ComboBox';
53
+ import DateTimeInput from '../components/widgets/DateTimeInput';
54
+ import TextInput from '../components/widgets/TextInput';
55
+ import ToggleSwitch from '../components/widgets/ToggleSwitch';
56
+ import ConfigUtils from '../utils/ConfigUtils';
57
+ import LayerUtils from '../utils/LayerUtils';
58
+ import LocaleUtils from '../utils/LocaleUtils';
59
+ import MiscUtils from '../utils/MiscUtils';
60
+ import './style/MapFilter.css';
61
+
62
+ /**
8
63
  * Allows filtering the map content via QGIS Server WMS FILTER.
9
64
  *
10
65
  * See [Map filtering](../../topics/MapFilter).
11
- */var MapFilter=/*#__PURE__*/function(_React$Component){function MapFilter(props){var _this;_classCallCheck(this,MapFilter);_this=_callSuper(this,MapFilter,[props]);_defineProperty(_this,"state",{filters:{},geomFilter:{},customFilters:{},filterEditor:null,filterInvalid:false});_defineProperty(_this,"collectPredefinedFilters",function(layers){return layers.reduce(function(res,layer){return _objectSpread(_objectSpread({},res),(layer.predefinedFilters||[]).reduce(function(res2,config){return _objectSpread(_objectSpread({},res2),{},_defineProperty({},config.id,config))},{}))},{})});_defineProperty(_this,"initializeFilters",function(predefinedFilters,prevFilters){clearTimeout(_this.applyFilterTimeout);_this.applyFilterTimeout=null;var filters=Object.values(predefinedFilters).reduce(function(res,filterConfig){var _prevFilters$filterCo;return _objectSpread(_objectSpread({},res),{},_defineProperty({},filterConfig.id,(_prevFilters$filterCo=prevFilters===null||prevFilters===void 0?void 0:prevFilters[filterConfig.id])!==null&&_prevFilters$filterCo!==void 0?_prevFilters$filterCo:{active:false,filter:filterConfig.filter,values:filterConfig.fields.reduce(function(values,valueConfig){return _objectSpread(_objectSpread({},values),{},_defineProperty({},valueConfig.id,valueConfig.defaultValue))},{})}))},{});var timeFilter={};_this.props.layers.forEach(function(layer){return _this.buildTimeFilter(layer,timeFilter)});if(!isEmpty(timeFilter)&&_this.props.allowFilterByTime){var _prevFilters$__timefi,_prevFilters$__timefi2,_prevFilters$__timefi3,_prevFilters$__timefi4;filters.__timefilter={active:(_prevFilters$__timefi=(_prevFilters$__timefi2=prevFilters.__timefilter)===null||_prevFilters$__timefi2===void 0?void 0:_prevFilters$__timefi2.active)!==null&&_prevFilters$__timefi!==void 0?_prevFilters$__timefi:false,filter:timeFilter,values:(_prevFilters$__timefi3=(_prevFilters$__timefi4=prevFilters.__timefilter)===null||_prevFilters$__timefi4===void 0?void 0:_prevFilters$__timefi4.values)!==null&&_prevFilters$__timefi3!==void 0?_prevFilters$__timefi3:{tstart:"",tend:""},defaultValues:{tstart:"1800-01-01",tend:"9999-12-31"}}}return filters});_defineProperty(_this,"applyFilter",function(){var _this$state$filters$_;_this.applyFilterTimeout=null;var layerExpressions={};// Recompute filter expressions
12
- Object.values(_this.state.filters).forEach(function(entry){if(entry.active){Object.entries(entry.filter).forEach(function(_ref){var _ref2=_slicedToArray(_ref,2),layer=_ref2[0],expression=_ref2[1];var replacedExpr=_this.replaceExpressionVariables(expression,entry.values,entry.defaultValues||{});if(replacedExpr===null){/* eslint-disable-next-line */console.warn("Invalid filter expression: "+JSON.stringify(expression))}else if(layerExpressions[layer]){layerExpressions[layer].push("and",replacedExpr)}else{layerExpressions[layer]=[replacedExpr]}})}},{});Object.values(_this.state.customFilters).forEach(function(entry){if(entry.active&&entry.layer){var expr="";try{expr=JSON.parse(entry.expr)}catch(e){return}if(layerExpressions[entry.layer]){layerExpressions[entry.layer].push("and",expr)}else{layerExpressions[entry.layer]=[expr]}}});var timeRange=(_this$state$filters$_=_this.state.filters.__timefilter)!==null&&_this$state$filters$_!==void 0&&_this$state$filters$_.active?{tstart:_this.state.filters.__timefilter.values.tstart,tend:_this.state.filters.__timefilter.values.tend}:null;_this.props.setFilter(layerExpressions,_this.state.geomFilter.geom,timeRange);// Validate parameters with test request
13
- var themeLayer=_this.props.layers.find(function(layer){return layer.role===LayerRole.THEME});if(themeLayer){var wmsParams=LayerUtils.buildWMSLayerParams(themeLayer,{filterParams:layerExpressions,filterGeom:_this.state.geomFilter.geom}).params;var wmsLayers=wmsParams.LAYERS.split(",");var reqParams={SERVICE:"WMS",REQUEST:"GetMap",VERSION:"1.3.0",CRS:"EPSG:4326",WIDTH:10,HEIGHT:10,BBOX:"-0.5,-0.5,0.5,0.5",LAYERS:Object.keys(layerExpressions).filter(function(layer){return wmsLayers.includes(layer)}).join(","),csrf_token:MiscUtils.getCsrfToken()};if(wmsParams.FILTER){reqParams.FILTER=wmsParams.FILTER}if(wmsParams.FILTER_GEOM){reqParams.FILTER_GEOM=wmsParams.FILTER_GEOM}var options={headers:{"content-type":"application/x-www-form-urlencoded"},responseType:"blob"};axios.post(themeLayer.url,new URLSearchParams(reqParams).toString(),options).then(function(){_this.setState({filterInvalid:false})})["catch"](function(){_this.setState({filterInvalid:true})})}var permalinkState=Object.entries(_this.state.filters).reduce(function(res,_ref3){var _ref4=_slicedToArray(_ref3,2),key=_ref4[0],value=_ref4[1];if(value.active){return _objectSpread(_objectSpread({},res),{},_defineProperty({},key,value.values))}else{return res}},{});if(_this.state.geomFilter.geom){permalinkState.__geomfilter=_this.state.geomFilter.geom.coordinates}permalinkState.__custom=Object.values(_this.state.customFilters).map(function(entry){if(!entry.active){return null}var expr=null;try{expr=JSON.parse(entry.expr)}catch(e){return null}return{title:entry.title,layer:entry.layer,expr:expr}}).filter(Boolean);_this.props.setPermalinkParameters({f:JSON.stringify(permalinkState)})});_defineProperty(_this,"buildTimeFilter",function(layer,filters){if(layer.sublayers){layer.sublayers.forEach(function(sublayer){return _this.buildTimeFilter(sublayer,filters)})}else{var timeDimension=(layer.dimensions||[]).find(function(dimension){return dimension.units==="ISO8601"});if(timeDimension){filters[layer.name]=[[[timeDimension.fieldName,">=","$tstart$"],"or",[timeDimension.fieldName,"IS",null]],"and",[[timeDimension.endFieldName,"<=","$tend$"],"or",[timeDimension.endFieldName,"IS",null]]]}}});_defineProperty(_this,"filterMapButtonClicked",function(){var mapClickAction=ConfigUtils.getPluginConfig("MapFilter").mapClickAction;_this.props.setCurrentTask(_this.props.currentTask==="MapFilter"?null:"MapFilter",null,mapClickAction)});_defineProperty(_this,"onSidebarHide",function(){_this.setState(function(state){var newState=_objectSpread({},state);if(!state.geomFilter.geom&&state.geomFilter.geomType){newState.geomFilter.geomType=null}if(state.geomFilter.picking){newState.geomFilter.picking=false}return newState})});_defineProperty(_this,"renderBody",function(){if(_this.state.filterEditor){return _this.renderFilterEditor()}else{return[_this.renderInvalidWarning()].concat(_toConsumableArray(_this.renderPredefinedFilters()),[_this.props.allowFilterByTime?_this.renderTimeFilter():null,_this.props.allowFilterByGeom?_this.renderGeomFilter():null],_toConsumableArray(_this.renderCustomFilters()))}});_defineProperty(_this,"renderInvalidWarning",function(){if(_this.state.filterInvalid){return/*#__PURE__*/React.createElement("div",{className:"map-filter-invalid-warning",key:"InvalidFilterWarning"},/*#__PURE__*/React.createElement(Icon,{icon:"warning"})," ",/*#__PURE__*/React.createElement("div",null,LocaleUtils.tr("mapfilter.brokenrendering")))}return null});_defineProperty(_this,"renderFilterEditor",function(){var commitButtons=[{key:"Save",icon:"ok",label:LocaleUtils.tr("mapfilter.save"),extraClasses:"button-accept"},{key:"Cancel",icon:"remove",label:LocaleUtils.tr("mapfilter.cancel"),extraClasses:"button-reject"}];var sampleFilters="[\"field\", \"=\", \"val\"]\n"+"[[\"field\", \">\", \"val1\"], \"and\", [\"field\", \"<\", \"val2\"]]";return/*#__PURE__*/React.createElement("div",{className:"map-filter-editor-container"},/*#__PURE__*/React.createElement(TextInput,{className:"map-filter-editor "+(_this.state.filterEditor.invalid?"map-filter-editor-invalid":""),multiline:true,onChange:function onChange(value){return _this.setState(function(state){return{filterEditor:_objectSpread(_objectSpread({},state.filterEditor),{},{value:value,invalid:false})}})},placeholder:sampleFilters,value:_this.state.filterEditor.value}),_this.state.filterEditor.invalid?/*#__PURE__*/React.createElement("div",null,/*#__PURE__*/React.createElement(Icon,{icon:"warning"})," ",/*#__PURE__*/React.createElement("span",null,LocaleUtils.tr("mapfilter.invalidfilter"))):null,/*#__PURE__*/React.createElement(ButtonBar,{buttons:commitButtons,onClick:_this.commitFilterEditor}))});_defineProperty(_this,"commitFilterEditor",function(action){if(action==="Save"){// Validate expression
14
- var _validateExpression=function validateExpression(values){if(Array.isArray(values[0])){// Even entries must be arrays, odd entries must be 'and' or 'or'
15
- return values.every(function(value,idx){return idx%2===0?Array.isArray(value)&&_validateExpression(value):["and","or"].includes(value.toLowerCase())},true)}else{return values.length===3&&typeof values[0]==="string"&&typeof values[1]==="string"&&["string","number"].includes(_typeof(values[2]))}};var filterexpr=null;try{filterexpr=JSON.parse(_this.state.filterEditor.value)}catch(e){// Pass
16
- }if(!Array.isArray(filterexpr)||!_validateExpression(filterexpr)){_this.setState(function(state){return{filterEditor:_objectSpread(_objectSpread({},state.filterEditor),{},{invalid:true})}});return}_this.updateCustomFilter(_this.state.filterEditor.filterId,"expr",_this.state.filterEditor.value)}_this.setState({filterEditor:null})});_defineProperty(_this,"renderPredefinedFilters",function(){var predefinedFilters=_this.collectPredefinedFilters(_this.props.layers);return Object.values(predefinedFilters).map(function(config){var _config$title,_this$state$filters$c;return/*#__PURE__*/React.createElement("div",{className:"map-filter-entry",key:config.id},/*#__PURE__*/React.createElement("div",{className:"map-filter-entry-titlebar"},/*#__PURE__*/React.createElement("span",{className:"map-filter-entry-title"},(_config$title=config.title)!==null&&_config$title!==void 0?_config$title:LocaleUtils.tr(config.titlemsgid)),/*#__PURE__*/React.createElement(ToggleSwitch,{active:(_this$state$filters$c=_this.state.filters[config.id])===null||_this$state$filters$c===void 0?void 0:_this$state$filters$c.active,onChange:function onChange(active){return _this.toggleFilter(config.id,active)}})),/*#__PURE__*/React.createElement("div",{className:"map-filter-entry-body"},/*#__PURE__*/React.createElement("table",{className:"map-filter-entry-fields"},/*#__PURE__*/React.createElement("tbody",null,config.fields.map(function(field){var _field$title;return/*#__PURE__*/React.createElement("tr",{key:field.id},/*#__PURE__*/React.createElement("td",null,(_field$title=field.title)!==null&&_field$title!==void 0?_field$title:LocaleUtils.tr(field.titlemsgid),": "),/*#__PURE__*/React.createElement("td",null,field.inputConfig.type==="select"?/*#__PURE__*/React.createElement("select",{onChange:function onChange(ev){return _this.updateFieldValue(config.id,field.id,ev.target.value)},value:_this.state.filters[config.id].values[field.id]},!field.defaultValue?/*#__PURE__*/React.createElement("option",{value:""},LocaleUtils.tr("mapfilter.select")):null,field.inputConfig.options.map(function(entry){var _entry$value,_entry$value2,_entry$label;return/*#__PURE__*/React.createElement("option",{key:(_entry$value=entry.value)!==null&&_entry$value!==void 0?_entry$value:entry,value:(_entry$value2=entry.value)!==null&&_entry$value2!==void 0?_entry$value2:entry},(_entry$label=entry.label)!==null&&_entry$label!==void 0?_entry$label:entry.labelmsgid?LocaleUtils.tr(entry.labelmsgid):entry)})):/*#__PURE__*/React.createElement("input",_extends({onChange:function onChange(ev){return _this.updateFieldValue(config.id,field.id,ev.target.value)},type:"text",value:_this.state.filters[config.id].values[field.id]||""},field.inputConfig))))})))))})});_defineProperty(_this,"renderTimeFilter",function(){var timeFilter=_this.state.filters.__timefilter;if(!timeFilter){return null}return/*#__PURE__*/React.createElement("div",{className:"map-filter-entry",key:"__timefilter"},/*#__PURE__*/React.createElement("div",{className:"map-filter-entry-titlebar"},/*#__PURE__*/React.createElement("span",{className:"map-filter-entry-title"},LocaleUtils.tr("mapfilter.timefilter")),/*#__PURE__*/React.createElement(ToggleSwitch,{active:timeFilter.active,onChange:function onChange(active){return _this.toggleFilter("__timefilter",active)}})),/*#__PURE__*/React.createElement("div",{className:"map-filter-entry-body"},/*#__PURE__*/React.createElement("table",{className:"map-filter-entry-fields"},/*#__PURE__*/React.createElement("tbody",null,/*#__PURE__*/React.createElement("tr",null,/*#__PURE__*/React.createElement("td",null,LocaleUtils.tr("mapfilter.timefrom"),": "),/*#__PURE__*/React.createElement("td",null,/*#__PURE__*/React.createElement(DateTimeInput,{onChange:function onChange(value){return _this.updateFieldValue("__timefilter","tstart",value)},value:timeFilter.values.tstart}))),/*#__PURE__*/React.createElement("tr",null,/*#__PURE__*/React.createElement("td",null,LocaleUtils.tr("mapfilter.timeto"),": "),/*#__PURE__*/React.createElement("td",null,/*#__PURE__*/React.createElement(DateTimeInput,{onChange:function onChange(value){return _this.updateFieldValue("__timefilter","tend",value)},value:timeFilter.values.tend})))))))});_defineProperty(_this,"renderCustomFilters",function(){if(!_this.props.allowCustomFilters){return[]}var layerNames=_this.props.layers.reduce(function(res,layer){if(layer.role===LayerRole.THEME){return[].concat(_toConsumableArray(res),_toConsumableArray(LayerUtils.getSublayerNames(layer,true,function(lyr){return!!lyr.geometryType})))}return res},[]);var customFilters=Object.entries(_this.state.customFilters).map(function(_ref5){var _ref6=_slicedToArray(_ref5,2),key=_ref6[0],entry=_ref6[1];return/*#__PURE__*/React.createElement("div",{className:"map-filter-entry",key:key},/*#__PURE__*/React.createElement("div",{className:"map-filter-entry-titlebar map-filter-custom-entry-titlebar"},/*#__PURE__*/React.createElement(TextInput,{className:"map-filter-entry-title",onChange:function onChange(value){return _this.updateCustomFilter(key,"title",value)},value:entry.title}),/*#__PURE__*/React.createElement(ToggleSwitch,{active:entry.active,onChange:function onChange(active){return _this.updateCustomFilter(key,"active",active)}}),/*#__PURE__*/React.createElement(Icon,{icon:"trash",onClick:function onClick(){return _this.deleteCustomFilter(key)}})),/*#__PURE__*/React.createElement("div",{className:"map-filter-entry-body"},/*#__PURE__*/React.createElement("table",{className:"map-filter-entry-fields"},/*#__PURE__*/React.createElement("tbody",null,/*#__PURE__*/React.createElement("tr",null,/*#__PURE__*/React.createElement("td",null,/*#__PURE__*/React.createElement(ComboBox,{onChange:function onChange(value){return _this.updateCustomFilter(key,"layer",value)},placeholder:LocaleUtils.tr("mapfilter.selectlayer"),value:entry.layer},layerNames.map(function(layerName){return/*#__PURE__*/React.createElement("div",{key:layerName,value:layerName},layerName)}))),/*#__PURE__*/React.createElement("td",null,/*#__PURE__*/React.createElement("input",{className:"map-filter-custom-entry-expr",onChange:function onChange(){},onClick:function onClick(){return _this.setState({filterEditor:{filterId:key,value:entry.expr}})},readOnly:true,value:entry.expr})))))))});return[].concat(_toConsumableArray(customFilters),[/*#__PURE__*/React.createElement("div",{className:"map-filter-add-custom",key:"addcustomfilter"},/*#__PURE__*/React.createElement("button",{className:"button",onClick:_this.addCustomFilter,type:"button"},LocaleUtils.tr("mapfilter.addcustomfilter")))])});_defineProperty(_this,"renderGeomFilter",function(){var geomFilter=_this.state.geomFilter;var filterButtons=[{key:"Polygon",tooltip:LocaleUtils.tr("redlining.polygon"),icon:"polygon",label:LocaleUtils.tr("redlining.polygon")},{key:"Circle",tooltip:LocaleUtils.tr("redlining.circle"),icon:"circle",label:LocaleUtils.tr("redlining.circle")},{key:"Pick",tooltip:LocaleUtils.tr("redlining.pick"),icon:"pick",label:LocaleUtils.tr("redlining.pick")}];var active=geomFilter.picking?"Pick":geomFilter.geomType||"";return/*#__PURE__*/React.createElement("div",{className:"map-filter-entry",key:"__geomfilter"},/*#__PURE__*/React.createElement("div",{className:"map-filter-entry-titlebar"},/*#__PURE__*/React.createElement("span",{className:"map-filter-entry-title"},LocaleUtils.tr("mapfilter.geomfilter"))),/*#__PURE__*/React.createElement("div",{className:"map-filter-entry-body"},/*#__PURE__*/React.createElement(ButtonBar,{active:active,buttons:filterButtons,onClick:_this.triggerGeometryFilter}),/*#__PURE__*/React.createElement("div",null,/*#__PURE__*/React.createElement("label",null,/*#__PURE__*/React.createElement("input",{checked:!!geomFilter.hideFilterGeom,onChange:_this.toggleHideFilterGeom,type:"checkbox"})," ",LocaleUtils.tr("mapfilter.hidefiltergeom")))))});_defineProperty(_this,"triggerGeometryFilter",function(action){if(action==="Pick"){_this.setState(function(state){return{geomFilter:_objectSpread(_objectSpread({},state.geomFilter),{},{geom:null,picking:!state.geomFilter.picking,geomType:null})}})}else{_this.setState(function(state){return{geomFilter:_objectSpread(_objectSpread({},state.geomFilter),{},{geom:null,picking:false,geomType:state.geomFilter.geomType===action?null:action})}})}});_defineProperty(_this,"setFilterGeometry",function(geom){_this.setState(function(state){return{geomFilter:_objectSpread(_objectSpread({},state.geomFilter),{},{geom:geom})}})});_defineProperty(_this,"filterGeomPicked",function(layer,feature){_this.setState(function(state){return{geomFilter:_objectSpread(_objectSpread({},state.geomFilter),{},{geom:feature.geometry,geomType:feature.geometry.type})}})});_defineProperty(_this,"toggleHideFilterGeom",function(ev){_this.setState(function(state){return{geomFilter:_objectSpread(_objectSpread({},state.geomFilter),{},{hideFilterGeom:ev.target.checked})}})});_defineProperty(_this,"toggleFilter",function(filterId,active){_this.setState(function(state){return{filters:_objectSpread(_objectSpread({},state.filters),{},_defineProperty({},filterId,_objectSpread(_objectSpread({},state.filters[filterId]),{},{active:active})))}})});_defineProperty(_this,"updateFieldValue",function(filterId,fieldId,value){_this.setState(function(state){return{filters:_objectSpread(_objectSpread({},state.filters),{},_defineProperty({},filterId,_objectSpread(_objectSpread({},state.filters[filterId]),{},{values:_objectSpread(_objectSpread({},state.filters[filterId].values),{},_defineProperty({},fieldId,value))})))}})});_defineProperty(_this,"updateCustomFilter",function(filterId,key,value){_this.setState(function(state){return{customFilters:_objectSpread(_objectSpread({},state.customFilters),{},_defineProperty({},filterId,_objectSpread(_objectSpread({},state.customFilters[filterId]),{},_defineProperty({},key,value))))}})});_defineProperty(_this,"addCustomFilter",function(){var key=uuidv4();_this.setState(function(state){return{customFilters:_objectSpread(_objectSpread({},state.customFilters),{},_defineProperty({},key,{active:false,title:"",layer:"",expr:""}))}})});_defineProperty(_this,"deleteCustomFilter",function(key){_this.setState(function(state){var newCustomFilters=_objectSpread({},state.customFilters);delete newCustomFilters[key];return{customFilters:newCustomFilters}})});_defineProperty(_this,"replaceExpressionVariables",function(expr,values,defaultValues){if(expr.length<3||expr.length%2===0||typeof expr[1]!=="string"){// Invalid expression: array must have at least three and odd number of entries,
17
- // mid entry must be a string (operator)
18
- return null}var op=expr[1].toLowerCase();if(typeof expr[0]==="string"){if(typeof expr[2]==="string"){var right=Object.entries(values).reduce(function(res,_ref7){var _ref9;var _ref8=_slicedToArray(_ref7,2),key=_ref8[0],value=_ref8[1];return res.replace("$".concat(key,"$"),(_ref9=value||defaultValues[key])!==null&&_ref9!==void 0?_ref9:value)},expr[2]);return[expr[0],op,right]}else{return[expr[0],op,expr[2]]}}else{// Even indices must be arrays, odd and|or strings
19
- var isAndOr=function isAndOr(entry){return["and","or"].includes(String(entry).toLowerCase())};var invalid=expr.find(function(entry,idx){return idx%2===0?!Array.isArray(entry):!isAndOr(entry)});if(invalid){return null}return expr.map(function(entry,idx){return idx%2===0?_this.replaceExpressionVariables(entry,values,defaultValues):entry})}});_this.applyFilterTimeout=null;return _this}_inherits(MapFilter,_React$Component);return _createClass(MapFilter,[{key:"componentDidUpdate",value:function componentDidUpdate(prevProps,prevState){var _this2=this;if(this.props.theme!==prevProps.theme){var _this$props$startupPa;// Initialize filter state
20
- var predefinedFilters=this.collectPredefinedFilters(this.props.layers);var filters=this.initializeFilters(predefinedFilters,{});var geomFilter={};var customFilters={};if(!prevProps.theme&&(_this$props$startupPa=this.props.startupParams)!==null&&_this$props$startupPa!==void 0&&_this$props$startupPa.f){try{var startupConfig=JSON.parse(this.props.startupParams.f);Object.entries(startupConfig).forEach(function(_ref10){var _ref11=_slicedToArray(_ref10,2),filterId=_ref11[0],values=_ref11[1];if(filterId in filters){filters[filterId].active=true;Object.entries(values).forEach(function(_ref12){var _ref13=_slicedToArray(_ref12,2),fieldId=_ref13[0],value=_ref13[1];filters[filterId].values[fieldId]=value})}});if("__geomfilter"in startupConfig){geomFilter={geomType:"Polygon",geom:{type:"Polygon",coordinates:startupConfig.__geomfilter}}}if("__custom"in startupConfig){customFilters=startupConfig.__custom.reduce(function(res,entry){return _objectSpread(_objectSpread({},res),{},_defineProperty({},uuidv4(),{title:entry.title||"",layer:entry.layer,expr:JSON.stringify(entry.expr),active:true}))},{})}}catch(e){/* eslint-disable-next-line */console.log("Error while parsing startup filter")}}this.setState({filters:filters,geomFilter:geomFilter,customFilters:customFilters})}else if(this.props.layers!==prevProps.layers){var _predefinedFilters=this.collectPredefinedFilters(this.props.layers);var prevPredefinedFilters=this.collectPredefinedFilters(prevProps.layers);if(!isEqual(Object.keys(_predefinedFilters).sort(),Object.keys(prevPredefinedFilters).sort())){this.setState(function(state){return{filters:_this2.initializeFilters(_predefinedFilters,state.filters)}})}}if(this.state.filters!==prevState.filters||this.state.customFilters!==prevState.customFilters||this.state.geomFilter.geom!==prevState.geomFilter.geom){clearTimeout(this.applyFilterTimeout);this.applyFilterTimeout=setTimeout(this.applyFilter,500)}}},{key:"render",value:function render(){var _this$state$geomFilte,_this$state$geomFilte2,_this3=this,_this$state$geomFilte3,_this$state$geomFilte4;var button=null;var taskActive=this.props.currentTask==="MapFilter";if(this.props.position>=0){var filterActive=!isEmpty(this.props.filter.filterParams)||!!this.props.filter.filterGeom;var title=LocaleUtils.tr("appmenu.items.MapFilter");var className=filterActive&&this.state.filterInvalid?"filter-map-button-error":"";button=/*#__PURE__*/React.createElement(MapButton,{active:taskActive,className:className,engaged:filterActive&&!this.state.filterInvalid,icon:"filter",key:"MapFilterButton",onClick:this.filterMapButtonClicked,position:this.props.position,tooltip:title})}var selGeomType=(_this$state$geomFilte=this.state.geomFilter)!==null&&_this$state$geomFilte!==void 0&&_this$state$geomFilte.picking?null:(_this$state$geomFilte2=this.state.geomFilter)===null||_this$state$geomFilte2===void 0?void 0:_this$state$geomFilte2.geomType;return[button,/*#__PURE__*/React.createElement(SideBar,{icon:"filter",id:"MapFilter",key:"MapFilterSidebar",onHide:this.onSidebarHide,side:this.props.side,title:LocaleUtils.tr("appmenu.items.MapFilter"),width:"20em"},function(){return{body:_this3.renderBody()}}),this.state.geomFilter.picking?/*#__PURE__*/React.createElement(PickFeature,{featureFilter:function featureFilter(feature){var _feature$geometry;return((feature===null||feature===void 0||(_feature$geometry=feature.geometry)===null||_feature$geometry===void 0?void 0:_feature$geometry.type)||"").endsWith("Polygon")},featurePicked:this.filterGeomPicked,highlightStyle:this.props.highlightStyle,key:"FeaturePicker"}):null,/*#__PURE__*/React.createElement(MapSelection,{active:taskActive&&!!selGeomType,geomType:selGeomType,geometry:(_this$state$geomFilte3=this.state.geomFilter)===null||_this$state$geomFilte3===void 0?void 0:_this$state$geomFilte3.geom,geometryChanged:this.setFilterGeometry,hideGeometry:(_this$state$geomFilte4=this.state.geomFilter)===null||_this$state$geomFilte4===void 0?void 0:_this$state$geomFilte4.hideFilterGeom,key:"MapSelection",styleOptions:this.props.highlightStyle})]}}])}(React.Component);_defineProperty(MapFilter,"propTypes",{/** Whether to allow custom filters. */allowCustomFilters:PropTypes.bool,/** Whether to allow filter by geometry. Requires the filter_geom plugin from qwc-qgis-server-plugins, and the filter will only be applied to postgis layers. */allowFilterByGeom:PropTypes.bool,/** Whether to display the temporal filter if temporal dimensions are found. */allowFilterByTime:PropTypes.bool,currentTask:PropTypes.string,filter:PropTypes.object,/** The style used for highlighting filter geometries. */highlightStyle:PropTypes.shape({/* Stroke color rgba array, i.e. [255, 0, 0, 0.5] */strokeColor:PropTypes.array,/* Stroke width */strokeWidth:PropTypes.number,/* Stroke dash/gap pattern array. Empty for solid line. */strokeDash:PropTypes.array,/* Fill color rgba array, i.e. [255, 0, 0, 0.33] */fillColor:PropTypes.array}),layers:PropTypes.array,/** The position slot index of the map button, from the bottom (0: bottom slot). Set to -1 to hide the button. */position:PropTypes.number,setCurrentTask:PropTypes.func,setFilter:PropTypes.func,setPermalinkParameters:PropTypes.func,/** The side of the application on which to display the sidebar. */side:PropTypes.string,startupParams:PropTypes.object,theme:PropTypes.object});_defineProperty(MapFilter,"defaultProps",{allowFilterByTime:true,position:5,predefinedFilters:[],highlightStyle:{strokeColor:[0,0,0],fillColor:[255,255,0,0.25]}});export default connect(function(state){return{currentTask:state.task.id,theme:state.theme.current,layers:state.layers.flat,filter:state.layers.filter,startupParams:state.localConfig.startupParams}},{setFilter:setFilter,setCurrentTask:setCurrentTask,setPermalinkParameters:setPermalinkParameters})(MapFilter);
66
+ */
67
+ var MapFilter = /*#__PURE__*/function (_React$Component) {
68
+ function MapFilter(props) {
69
+ var _this;
70
+ _classCallCheck(this, MapFilter);
71
+ _this = _callSuper(this, MapFilter, [props]);
72
+ _defineProperty(_this, "state", {
73
+ filters: {},
74
+ geomFilter: {},
75
+ customFilters: {},
76
+ filterEditor: null,
77
+ filterInvalid: false
78
+ });
79
+ _defineProperty(_this, "collectPredefinedFilters", function (layers) {
80
+ return layers.reduce(function (res, layer) {
81
+ return _objectSpread(_objectSpread({}, res), (layer.predefinedFilters || []).reduce(function (res2, config) {
82
+ return _objectSpread(_objectSpread({}, res2), {}, _defineProperty({}, config.id, config));
83
+ }, {}));
84
+ }, {});
85
+ });
86
+ _defineProperty(_this, "initializeFilters", function (predefinedFilters, prevFilters) {
87
+ clearTimeout(_this.applyFilterTimeout);
88
+ _this.applyFilterTimeout = null;
89
+ var filters = Object.values(predefinedFilters).reduce(function (res, filterConfig) {
90
+ var _prevFilters$filterCo;
91
+ return _objectSpread(_objectSpread({}, res), {}, _defineProperty({}, filterConfig.id, (_prevFilters$filterCo = prevFilters === null || prevFilters === void 0 ? void 0 : prevFilters[filterConfig.id]) !== null && _prevFilters$filterCo !== void 0 ? _prevFilters$filterCo : {
92
+ active: false,
93
+ filter: filterConfig.filter,
94
+ values: filterConfig.fields.reduce(function (values, valueConfig) {
95
+ return _objectSpread(_objectSpread({}, values), {}, _defineProperty({}, valueConfig.id, valueConfig.defaultValue));
96
+ }, {})
97
+ }));
98
+ }, {});
99
+ var timeFilter = {};
100
+ _this.props.layers.forEach(function (layer) {
101
+ return _this.buildTimeFilter(layer, timeFilter);
102
+ });
103
+ if (!isEmpty(timeFilter) && _this.props.allowFilterByTime) {
104
+ var _prevFilters$__timefi, _prevFilters$__timefi2, _prevFilters$__timefi3, _prevFilters$__timefi4;
105
+ filters.__timefilter = {
106
+ active: (_prevFilters$__timefi = (_prevFilters$__timefi2 = prevFilters.__timefilter) === null || _prevFilters$__timefi2 === void 0 ? void 0 : _prevFilters$__timefi2.active) !== null && _prevFilters$__timefi !== void 0 ? _prevFilters$__timefi : false,
107
+ filter: timeFilter,
108
+ values: (_prevFilters$__timefi3 = (_prevFilters$__timefi4 = prevFilters.__timefilter) === null || _prevFilters$__timefi4 === void 0 ? void 0 : _prevFilters$__timefi4.values) !== null && _prevFilters$__timefi3 !== void 0 ? _prevFilters$__timefi3 : {
109
+ tstart: "",
110
+ tend: ""
111
+ },
112
+ defaultValues: {
113
+ tstart: '1800-01-01',
114
+ tend: '9999-12-31'
115
+ }
116
+ };
117
+ }
118
+ return filters;
119
+ });
120
+ _defineProperty(_this, "applyFilter", function () {
121
+ var _this$state$filters$_;
122
+ _this.applyFilterTimeout = null;
123
+ var layerExpressions = {};
124
+ // Recompute filter expressions
125
+ Object.values(_this.state.filters).forEach(function (entry) {
126
+ if (entry.active) {
127
+ Object.entries(entry.filter).forEach(function (_ref) {
128
+ var _ref2 = _slicedToArray(_ref, 2),
129
+ layer = _ref2[0],
130
+ expression = _ref2[1];
131
+ var replacedExpr = _this.replaceExpressionVariables(expression, entry.values, entry.defaultValues || {});
132
+ if (replacedExpr === null) {
133
+ /* eslint-disable-next-line */
134
+ console.warn("Invalid filter expression: " + JSON.stringify(expression));
135
+ } else if (layerExpressions[layer]) {
136
+ layerExpressions[layer].push('and', replacedExpr);
137
+ } else {
138
+ layerExpressions[layer] = [replacedExpr];
139
+ }
140
+ });
141
+ }
142
+ }, {});
143
+ Object.values(_this.state.customFilters).forEach(function (entry) {
144
+ if (entry.active && entry.layer) {
145
+ var expr = '';
146
+ try {
147
+ expr = JSON.parse(entry.expr);
148
+ } catch (e) {
149
+ return;
150
+ }
151
+ if (layerExpressions[entry.layer]) {
152
+ layerExpressions[entry.layer].push('and', expr);
153
+ } else {
154
+ layerExpressions[entry.layer] = [expr];
155
+ }
156
+ }
157
+ });
158
+ var timeRange = (_this$state$filters$_ = _this.state.filters.__timefilter) !== null && _this$state$filters$_ !== void 0 && _this$state$filters$_.active ? {
159
+ tstart: _this.state.filters.__timefilter.values.tstart,
160
+ tend: _this.state.filters.__timefilter.values.tend
161
+ } : null;
162
+ _this.props.setFilter(layerExpressions, _this.state.geomFilter.geom, timeRange);
163
+ // Validate parameters with test request
164
+ var themeLayer = _this.props.layers.find(function (layer) {
165
+ return layer.role === LayerRole.THEME;
166
+ });
167
+ if (themeLayer) {
168
+ var wmsParams = LayerUtils.buildWMSLayerParams(themeLayer, {
169
+ filterParams: layerExpressions,
170
+ filterGeom: _this.state.geomFilter.geom
171
+ }).params;
172
+ var wmsLayers = wmsParams.LAYERS.split(",");
173
+ var reqParams = {
174
+ SERVICE: 'WMS',
175
+ REQUEST: 'GetMap',
176
+ VERSION: '1.3.0',
177
+ CRS: 'EPSG:4326',
178
+ WIDTH: 10,
179
+ HEIGHT: 10,
180
+ BBOX: "-0.5,-0.5,0.5,0.5",
181
+ LAYERS: Object.keys(layerExpressions).filter(function (layer) {
182
+ return wmsLayers.includes(layer);
183
+ }).join(","),
184
+ csrf_token: MiscUtils.getCsrfToken()
185
+ };
186
+ if (wmsParams.FILTER) {
187
+ reqParams.FILTER = wmsParams.FILTER;
188
+ }
189
+ if (wmsParams.FILTER_GEOM) {
190
+ reqParams.FILTER_GEOM = wmsParams.FILTER_GEOM;
191
+ }
192
+ var options = {
193
+ headers: {
194
+ 'content-type': 'application/x-www-form-urlencoded'
195
+ },
196
+ responseType: "blob"
197
+ };
198
+ axios.post(themeLayer.url, new URLSearchParams(reqParams).toString(), options).then(function () {
199
+ _this.setState({
200
+ filterInvalid: false
201
+ });
202
+ })["catch"](function () {
203
+ _this.setState({
204
+ filterInvalid: true
205
+ });
206
+ });
207
+ }
208
+ var permalinkState = Object.entries(_this.state.filters).reduce(function (res, _ref3) {
209
+ var _ref4 = _slicedToArray(_ref3, 2),
210
+ key = _ref4[0],
211
+ value = _ref4[1];
212
+ if (value.active) {
213
+ return _objectSpread(_objectSpread({}, res), {}, _defineProperty({}, key, value.values));
214
+ } else {
215
+ return res;
216
+ }
217
+ }, {});
218
+ if (_this.state.geomFilter.geom) {
219
+ permalinkState.__geomfilter = _this.state.geomFilter.geom.coordinates;
220
+ }
221
+ permalinkState.__custom = Object.values(_this.state.customFilters).map(function (entry) {
222
+ if (!entry.active) {
223
+ return null;
224
+ }
225
+ var expr = null;
226
+ try {
227
+ expr = JSON.parse(entry.expr);
228
+ } catch (e) {
229
+ return null;
230
+ }
231
+ return {
232
+ title: entry.title,
233
+ layer: entry.layer,
234
+ expr: expr
235
+ };
236
+ }).filter(Boolean);
237
+ _this.props.setPermalinkParameters({
238
+ f: JSON.stringify(permalinkState)
239
+ });
240
+ });
241
+ _defineProperty(_this, "buildTimeFilter", function (layer, filters) {
242
+ if (layer.sublayers) {
243
+ layer.sublayers.forEach(function (sublayer) {
244
+ return _this.buildTimeFilter(sublayer, filters);
245
+ });
246
+ } else {
247
+ var timeDimension = (layer.dimensions || []).find(function (dimension) {
248
+ return dimension.units === "ISO8601";
249
+ });
250
+ if (timeDimension) {
251
+ filters[layer.name] = [[[timeDimension.fieldName, '>=', "$tstart$"], 'or', [timeDimension.fieldName, 'IS', null]], 'and', [[timeDimension.endFieldName, '<=', "$tend$"], 'or', [timeDimension.endFieldName, 'IS', null]]];
252
+ }
253
+ }
254
+ });
255
+ _defineProperty(_this, "filterMapButtonClicked", function () {
256
+ var mapClickAction = ConfigUtils.getPluginConfig("MapFilter").mapClickAction;
257
+ _this.props.setCurrentTask(_this.props.currentTask === "MapFilter" ? null : "MapFilter", null, mapClickAction);
258
+ });
259
+ _defineProperty(_this, "onSidebarHide", function () {
260
+ _this.setState(function (state) {
261
+ var newState = _objectSpread({}, state);
262
+ if (!state.geomFilter.geom && state.geomFilter.geomType) {
263
+ newState.geomFilter.geomType = null;
264
+ }
265
+ if (state.geomFilter.picking) {
266
+ newState.geomFilter.picking = false;
267
+ }
268
+ return newState;
269
+ });
270
+ });
271
+ _defineProperty(_this, "renderBody", function () {
272
+ if (_this.state.filterEditor) {
273
+ return _this.renderFilterEditor();
274
+ } else {
275
+ return [_this.renderInvalidWarning()].concat(_toConsumableArray(_this.renderPredefinedFilters()), [_this.props.allowFilterByTime ? _this.renderTimeFilter() : null, _this.props.allowFilterByGeom ? _this.renderGeomFilter() : null], _toConsumableArray(_this.renderCustomFilters()));
276
+ }
277
+ });
278
+ _defineProperty(_this, "renderInvalidWarning", function () {
279
+ if (_this.state.filterInvalid) {
280
+ return /*#__PURE__*/React.createElement("div", {
281
+ className: "map-filter-invalid-warning",
282
+ key: "InvalidFilterWarning"
283
+ }, /*#__PURE__*/React.createElement(Icon, {
284
+ icon: "warning"
285
+ }), " ", /*#__PURE__*/React.createElement("div", null, LocaleUtils.tr("mapfilter.brokenrendering")));
286
+ }
287
+ return null;
288
+ });
289
+ _defineProperty(_this, "renderFilterEditor", function () {
290
+ var commitButtons = [{
291
+ key: 'Save',
292
+ icon: 'ok',
293
+ label: LocaleUtils.tr("mapfilter.save"),
294
+ extraClasses: "button-accept"
295
+ }, {
296
+ key: 'Cancel',
297
+ icon: 'remove',
298
+ label: LocaleUtils.tr("mapfilter.cancel"),
299
+ extraClasses: "button-reject"
300
+ }];
301
+ var sampleFilters = '["field", "=", "val"]\n' + '[["field", ">", "val1"], "and", ["field", "<", "val2"]]';
302
+ return /*#__PURE__*/React.createElement("div", {
303
+ className: "map-filter-editor-container"
304
+ }, /*#__PURE__*/React.createElement(TextInput, {
305
+ className: "map-filter-editor " + (_this.state.filterEditor.invalid ? "map-filter-editor-invalid" : ""),
306
+ multiline: true,
307
+ onChange: function onChange(value) {
308
+ return _this.setState(function (state) {
309
+ return {
310
+ filterEditor: _objectSpread(_objectSpread({}, state.filterEditor), {}, {
311
+ value: value,
312
+ invalid: false
313
+ })
314
+ };
315
+ });
316
+ },
317
+ placeholder: sampleFilters,
318
+ value: _this.state.filterEditor.value
319
+ }), _this.state.filterEditor.invalid ? /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(Icon, {
320
+ icon: "warning"
321
+ }), " ", /*#__PURE__*/React.createElement("span", null, LocaleUtils.tr("mapfilter.invalidfilter"))) : null, /*#__PURE__*/React.createElement(ButtonBar, {
322
+ buttons: commitButtons,
323
+ onClick: _this.commitFilterEditor
324
+ }));
325
+ });
326
+ _defineProperty(_this, "commitFilterEditor", function (action) {
327
+ if (action === 'Save') {
328
+ // Validate expression
329
+ var _validateExpression = function validateExpression(values) {
330
+ if (Array.isArray(values[0])) {
331
+ // Even entries must be arrays, odd entries must be 'and' or 'or'
332
+ return values.every(function (value, idx) {
333
+ return idx % 2 === 0 ? Array.isArray(value) && _validateExpression(value) : ["and", "or"].includes(value.toLowerCase());
334
+ }, true);
335
+ } else {
336
+ return values.length === 3 && typeof values[0] === 'string' && typeof values[1] === 'string' && ['string', 'number'].includes(_typeof(values[2]));
337
+ }
338
+ };
339
+ var filterexpr = null;
340
+ try {
341
+ filterexpr = JSON.parse(_this.state.filterEditor.value);
342
+ } catch (e) {
343
+ // Pass
344
+ }
345
+ if (!Array.isArray(filterexpr) || !_validateExpression(filterexpr)) {
346
+ _this.setState(function (state) {
347
+ return {
348
+ filterEditor: _objectSpread(_objectSpread({}, state.filterEditor), {}, {
349
+ invalid: true
350
+ })
351
+ };
352
+ });
353
+ return;
354
+ }
355
+ _this.updateCustomFilter(_this.state.filterEditor.filterId, 'expr', _this.state.filterEditor.value);
356
+ }
357
+ _this.setState({
358
+ filterEditor: null
359
+ });
360
+ });
361
+ _defineProperty(_this, "renderPredefinedFilters", function () {
362
+ var predefinedFilters = _this.collectPredefinedFilters(_this.props.layers);
363
+ return Object.values(predefinedFilters).map(function (config) {
364
+ var _config$title, _this$state$filters$c;
365
+ return /*#__PURE__*/React.createElement("div", {
366
+ className: "map-filter-entry",
367
+ key: config.id
368
+ }, /*#__PURE__*/React.createElement("div", {
369
+ className: "map-filter-entry-titlebar"
370
+ }, /*#__PURE__*/React.createElement("span", {
371
+ className: "map-filter-entry-title"
372
+ }, (_config$title = config.title) !== null && _config$title !== void 0 ? _config$title : LocaleUtils.tr(config.titlemsgid)), /*#__PURE__*/React.createElement(ToggleSwitch, {
373
+ active: (_this$state$filters$c = _this.state.filters[config.id]) === null || _this$state$filters$c === void 0 ? void 0 : _this$state$filters$c.active,
374
+ onChange: function onChange(active) {
375
+ return _this.toggleFilter(config.id, active);
376
+ }
377
+ })), /*#__PURE__*/React.createElement("div", {
378
+ className: "map-filter-entry-body"
379
+ }, /*#__PURE__*/React.createElement("table", {
380
+ className: "map-filter-entry-fields"
381
+ }, /*#__PURE__*/React.createElement("tbody", null, config.fields.map(function (field) {
382
+ var _field$title;
383
+ return /*#__PURE__*/React.createElement("tr", {
384
+ key: field.id
385
+ }, /*#__PURE__*/React.createElement("td", null, (_field$title = field.title) !== null && _field$title !== void 0 ? _field$title : LocaleUtils.tr(field.titlemsgid), ": "), /*#__PURE__*/React.createElement("td", null, field.inputConfig.type === 'select' ? /*#__PURE__*/React.createElement("select", {
386
+ onChange: function onChange(ev) {
387
+ return _this.updateFieldValue(config.id, field.id, ev.target.value);
388
+ },
389
+ value: _this.state.filters[config.id].values[field.id]
390
+ }, !field.defaultValue ? /*#__PURE__*/React.createElement("option", {
391
+ value: ""
392
+ }, LocaleUtils.tr("mapfilter.select")) : null, field.inputConfig.options.map(function (entry) {
393
+ var _entry$value, _entry$value2, _entry$label;
394
+ return /*#__PURE__*/React.createElement("option", {
395
+ key: (_entry$value = entry.value) !== null && _entry$value !== void 0 ? _entry$value : entry,
396
+ value: (_entry$value2 = entry.value) !== null && _entry$value2 !== void 0 ? _entry$value2 : entry
397
+ }, (_entry$label = entry.label) !== null && _entry$label !== void 0 ? _entry$label : entry.labelmsgid ? LocaleUtils.tr(entry.labelmsgid) : entry);
398
+ })) : /*#__PURE__*/React.createElement("input", _extends({
399
+ onChange: function onChange(ev) {
400
+ return _this.updateFieldValue(config.id, field.id, ev.target.value);
401
+ },
402
+ type: "text",
403
+ value: _this.state.filters[config.id].values[field.id] || ""
404
+ }, field.inputConfig))));
405
+ })))));
406
+ });
407
+ });
408
+ _defineProperty(_this, "renderTimeFilter", function () {
409
+ var timeFilter = _this.state.filters.__timefilter;
410
+ if (!timeFilter) {
411
+ return null;
412
+ }
413
+ return /*#__PURE__*/React.createElement("div", {
414
+ className: "map-filter-entry",
415
+ key: "__timefilter"
416
+ }, /*#__PURE__*/React.createElement("div", {
417
+ className: "map-filter-entry-titlebar"
418
+ }, /*#__PURE__*/React.createElement("span", {
419
+ className: "map-filter-entry-title"
420
+ }, LocaleUtils.tr("mapfilter.timefilter")), /*#__PURE__*/React.createElement(ToggleSwitch, {
421
+ active: timeFilter.active,
422
+ onChange: function onChange(active) {
423
+ return _this.toggleFilter("__timefilter", active);
424
+ }
425
+ })), /*#__PURE__*/React.createElement("div", {
426
+ className: "map-filter-entry-body"
427
+ }, /*#__PURE__*/React.createElement("table", {
428
+ className: "map-filter-entry-fields"
429
+ }, /*#__PURE__*/React.createElement("tbody", null, /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("td", null, LocaleUtils.tr("mapfilter.timefrom"), ": "), /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement(DateTimeInput, {
430
+ onChange: function onChange(value) {
431
+ return _this.updateFieldValue("__timefilter", "tstart", value);
432
+ },
433
+ value: timeFilter.values.tstart
434
+ }))), /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("td", null, LocaleUtils.tr("mapfilter.timeto"), ": "), /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement(DateTimeInput, {
435
+ onChange: function onChange(value) {
436
+ return _this.updateFieldValue("__timefilter", "tend", value);
437
+ },
438
+ value: timeFilter.values.tend
439
+ })))))));
440
+ });
441
+ _defineProperty(_this, "renderCustomFilters", function () {
442
+ if (!_this.props.allowCustomFilters) {
443
+ return [];
444
+ }
445
+ var layerNames = _this.props.layers.reduce(function (res, layer) {
446
+ if (layer.role === LayerRole.THEME) {
447
+ return [].concat(_toConsumableArray(res), _toConsumableArray(LayerUtils.getSublayerNames(layer, true, function (lyr) {
448
+ return !!lyr.geometryType;
449
+ })));
450
+ }
451
+ return res;
452
+ }, []);
453
+ var customFilters = Object.entries(_this.state.customFilters).map(function (_ref5) {
454
+ var _ref6 = _slicedToArray(_ref5, 2),
455
+ key = _ref6[0],
456
+ entry = _ref6[1];
457
+ return /*#__PURE__*/React.createElement("div", {
458
+ className: "map-filter-entry",
459
+ key: key
460
+ }, /*#__PURE__*/React.createElement("div", {
461
+ className: "map-filter-entry-titlebar map-filter-custom-entry-titlebar"
462
+ }, /*#__PURE__*/React.createElement(TextInput, {
463
+ className: "map-filter-entry-title",
464
+ onChange: function onChange(value) {
465
+ return _this.updateCustomFilter(key, 'title', value);
466
+ },
467
+ value: entry.title
468
+ }), /*#__PURE__*/React.createElement(ToggleSwitch, {
469
+ active: entry.active,
470
+ onChange: function onChange(active) {
471
+ return _this.updateCustomFilter(key, 'active', active);
472
+ }
473
+ }), /*#__PURE__*/React.createElement(Icon, {
474
+ icon: "trash",
475
+ onClick: function onClick() {
476
+ return _this.deleteCustomFilter(key);
477
+ }
478
+ })), /*#__PURE__*/React.createElement("div", {
479
+ className: "map-filter-entry-body"
480
+ }, /*#__PURE__*/React.createElement("table", {
481
+ className: "map-filter-entry-fields"
482
+ }, /*#__PURE__*/React.createElement("tbody", null, /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement(ComboBox, {
483
+ onChange: function onChange(value) {
484
+ return _this.updateCustomFilter(key, 'layer', value);
485
+ },
486
+ placeholder: LocaleUtils.tr("mapfilter.selectlayer"),
487
+ value: entry.layer
488
+ }, layerNames.map(function (layerName) {
489
+ return /*#__PURE__*/React.createElement("div", {
490
+ key: layerName,
491
+ value: layerName
492
+ }, layerName);
493
+ }))), /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement("input", {
494
+ className: "map-filter-custom-entry-expr",
495
+ onChange: function onChange() {},
496
+ onClick: function onClick() {
497
+ return _this.setState({
498
+ filterEditor: {
499
+ filterId: key,
500
+ value: entry.expr
501
+ }
502
+ });
503
+ },
504
+ readOnly: true,
505
+ value: entry.expr
506
+ })))))));
507
+ });
508
+ return [].concat(_toConsumableArray(customFilters), [/*#__PURE__*/React.createElement("div", {
509
+ className: "map-filter-add-custom",
510
+ key: "addcustomfilter"
511
+ }, /*#__PURE__*/React.createElement("button", {
512
+ className: "button",
513
+ onClick: _this.addCustomFilter,
514
+ type: "button"
515
+ }, LocaleUtils.tr("mapfilter.addcustomfilter")))]);
516
+ });
517
+ _defineProperty(_this, "renderGeomFilter", function () {
518
+ var geomFilter = _this.state.geomFilter;
519
+ var filterButtons = [{
520
+ key: "Polygon",
521
+ tooltip: LocaleUtils.tr("redlining.polygon"),
522
+ icon: "polygon",
523
+ label: LocaleUtils.tr("redlining.polygon")
524
+ }, {
525
+ key: "Circle",
526
+ tooltip: LocaleUtils.tr("redlining.circle"),
527
+ icon: "circle",
528
+ label: LocaleUtils.tr("redlining.circle")
529
+ }, {
530
+ key: "Pick",
531
+ tooltip: LocaleUtils.tr("redlining.pick"),
532
+ icon: "pick",
533
+ label: LocaleUtils.tr("redlining.pick")
534
+ }];
535
+ var active = geomFilter.picking ? "Pick" : geomFilter.geomType || "";
536
+ return /*#__PURE__*/React.createElement("div", {
537
+ className: "map-filter-entry",
538
+ key: "__geomfilter"
539
+ }, /*#__PURE__*/React.createElement("div", {
540
+ className: "map-filter-entry-titlebar"
541
+ }, /*#__PURE__*/React.createElement("span", {
542
+ className: "map-filter-entry-title"
543
+ }, LocaleUtils.tr("mapfilter.geomfilter"))), /*#__PURE__*/React.createElement("div", {
544
+ className: "map-filter-entry-body"
545
+ }, /*#__PURE__*/React.createElement(ButtonBar, {
546
+ active: active,
547
+ buttons: filterButtons,
548
+ onClick: _this.triggerGeometryFilter
549
+ }), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, /*#__PURE__*/React.createElement("input", {
550
+ checked: !!geomFilter.hideFilterGeom,
551
+ onChange: _this.toggleHideFilterGeom,
552
+ type: "checkbox"
553
+ }), " ", LocaleUtils.tr("mapfilter.hidefiltergeom")))));
554
+ });
555
+ _defineProperty(_this, "triggerGeometryFilter", function (action) {
556
+ if (action === 'Pick') {
557
+ _this.setState(function (state) {
558
+ return {
559
+ geomFilter: _objectSpread(_objectSpread({}, state.geomFilter), {}, {
560
+ geom: null,
561
+ picking: !state.geomFilter.picking,
562
+ geomType: null
563
+ })
564
+ };
565
+ });
566
+ } else {
567
+ _this.setState(function (state) {
568
+ return {
569
+ geomFilter: _objectSpread(_objectSpread({}, state.geomFilter), {}, {
570
+ geom: null,
571
+ picking: false,
572
+ geomType: state.geomFilter.geomType === action ? null : action
573
+ })
574
+ };
575
+ });
576
+ }
577
+ });
578
+ _defineProperty(_this, "setFilterGeometry", function (geom) {
579
+ _this.setState(function (state) {
580
+ return {
581
+ geomFilter: _objectSpread(_objectSpread({}, state.geomFilter), {}, {
582
+ geom: geom
583
+ })
584
+ };
585
+ });
586
+ });
587
+ _defineProperty(_this, "filterGeomPicked", function (layer, feature) {
588
+ _this.setState(function (state) {
589
+ return {
590
+ geomFilter: _objectSpread(_objectSpread({}, state.geomFilter), {}, {
591
+ geom: feature.geometry,
592
+ geomType: feature.geometry.type
593
+ })
594
+ };
595
+ });
596
+ });
597
+ _defineProperty(_this, "toggleHideFilterGeom", function (ev) {
598
+ _this.setState(function (state) {
599
+ return {
600
+ geomFilter: _objectSpread(_objectSpread({}, state.geomFilter), {}, {
601
+ hideFilterGeom: ev.target.checked
602
+ })
603
+ };
604
+ });
605
+ });
606
+ _defineProperty(_this, "toggleFilter", function (filterId, active) {
607
+ _this.setState(function (state) {
608
+ return {
609
+ filters: _objectSpread(_objectSpread({}, state.filters), {}, _defineProperty({}, filterId, _objectSpread(_objectSpread({}, state.filters[filterId]), {}, {
610
+ active: active
611
+ })))
612
+ };
613
+ });
614
+ });
615
+ _defineProperty(_this, "updateFieldValue", function (filterId, fieldId, value) {
616
+ _this.setState(function (state) {
617
+ return {
618
+ filters: _objectSpread(_objectSpread({}, state.filters), {}, _defineProperty({}, filterId, _objectSpread(_objectSpread({}, state.filters[filterId]), {}, {
619
+ values: _objectSpread(_objectSpread({}, state.filters[filterId].values), {}, _defineProperty({}, fieldId, value))
620
+ })))
621
+ };
622
+ });
623
+ });
624
+ _defineProperty(_this, "updateCustomFilter", function (filterId, key, value) {
625
+ _this.setState(function (state) {
626
+ return {
627
+ customFilters: _objectSpread(_objectSpread({}, state.customFilters), {}, _defineProperty({}, filterId, _objectSpread(_objectSpread({}, state.customFilters[filterId]), {}, _defineProperty({}, key, value))))
628
+ };
629
+ });
630
+ });
631
+ _defineProperty(_this, "addCustomFilter", function () {
632
+ var key = uuidv4();
633
+ _this.setState(function (state) {
634
+ return {
635
+ customFilters: _objectSpread(_objectSpread({}, state.customFilters), {}, _defineProperty({}, key, {
636
+ active: false,
637
+ title: '',
638
+ layer: '',
639
+ expr: ''
640
+ }))
641
+ };
642
+ });
643
+ });
644
+ _defineProperty(_this, "deleteCustomFilter", function (key) {
645
+ _this.setState(function (state) {
646
+ var newCustomFilters = _objectSpread({}, state.customFilters);
647
+ delete newCustomFilters[key];
648
+ return {
649
+ customFilters: newCustomFilters
650
+ };
651
+ });
652
+ });
653
+ _defineProperty(_this, "replaceExpressionVariables", function (expr, values, defaultValues) {
654
+ if (expr.length < 3 || expr.length % 2 === 0 || typeof expr[1] !== 'string') {
655
+ // Invalid expression: array must have at least three and odd number of entries,
656
+ // mid entry must be a string (operator)
657
+ return null;
658
+ }
659
+ var op = expr[1].toLowerCase();
660
+ if (typeof expr[0] === 'string') {
661
+ if (typeof expr[2] === 'string') {
662
+ var right = Object.entries(values).reduce(function (res, _ref7) {
663
+ var _ref9;
664
+ var _ref8 = _slicedToArray(_ref7, 2),
665
+ key = _ref8[0],
666
+ value = _ref8[1];
667
+ return res.replace("$".concat(key, "$"), (_ref9 = value || defaultValues[key]) !== null && _ref9 !== void 0 ? _ref9 : value);
668
+ }, expr[2]);
669
+ return [expr[0], op, right];
670
+ } else {
671
+ return [expr[0], op, expr[2]];
672
+ }
673
+ } else {
674
+ // Even indices must be arrays, odd and|or strings
675
+ var isAndOr = function isAndOr(entry) {
676
+ return ["and", "or"].includes(String(entry).toLowerCase());
677
+ };
678
+ var invalid = expr.find(function (entry, idx) {
679
+ return idx % 2 === 0 ? !Array.isArray(entry) : !isAndOr(entry);
680
+ });
681
+ if (invalid) {
682
+ return null;
683
+ }
684
+ return expr.map(function (entry, idx) {
685
+ return idx % 2 === 0 ? _this.replaceExpressionVariables(entry, values, defaultValues) : entry;
686
+ });
687
+ }
688
+ });
689
+ _this.applyFilterTimeout = null;
690
+ return _this;
691
+ }
692
+ _inherits(MapFilter, _React$Component);
693
+ return _createClass(MapFilter, [{
694
+ key: "componentDidUpdate",
695
+ value: function componentDidUpdate(prevProps, prevState) {
696
+ var _this2 = this;
697
+ if (this.props.theme !== prevProps.theme) {
698
+ var _this$props$startupPa;
699
+ // Initialize filter state
700
+ var predefinedFilters = this.collectPredefinedFilters(this.props.layers);
701
+ var filters = this.initializeFilters(predefinedFilters, {});
702
+ var geomFilter = {};
703
+ var customFilters = {};
704
+ if (!prevProps.theme && (_this$props$startupPa = this.props.startupParams) !== null && _this$props$startupPa !== void 0 && _this$props$startupPa.f) {
705
+ try {
706
+ var startupConfig = JSON.parse(this.props.startupParams.f);
707
+ Object.entries(startupConfig).forEach(function (_ref10) {
708
+ var _ref11 = _slicedToArray(_ref10, 2),
709
+ filterId = _ref11[0],
710
+ values = _ref11[1];
711
+ if (filterId in filters) {
712
+ filters[filterId].active = true;
713
+ Object.entries(values).forEach(function (_ref12) {
714
+ var _ref13 = _slicedToArray(_ref12, 2),
715
+ fieldId = _ref13[0],
716
+ value = _ref13[1];
717
+ filters[filterId].values[fieldId] = value;
718
+ });
719
+ }
720
+ });
721
+ if ("__geomfilter" in startupConfig) {
722
+ geomFilter = {
723
+ geomType: "Polygon",
724
+ geom: {
725
+ type: "Polygon",
726
+ coordinates: startupConfig.__geomfilter
727
+ }
728
+ };
729
+ }
730
+ if ("__custom" in startupConfig) {
731
+ customFilters = startupConfig.__custom.reduce(function (res, entry) {
732
+ return _objectSpread(_objectSpread({}, res), {}, _defineProperty({}, uuidv4(), {
733
+ title: entry.title || "",
734
+ layer: entry.layer,
735
+ expr: JSON.stringify(entry.expr),
736
+ active: true
737
+ }));
738
+ }, {});
739
+ }
740
+ } catch (e) {
741
+ /* eslint-disable-next-line */
742
+ console.log("Error while parsing startup filter");
743
+ }
744
+ }
745
+ this.setState({
746
+ filters: filters,
747
+ geomFilter: geomFilter,
748
+ customFilters: customFilters
749
+ });
750
+ } else if (this.props.layers !== prevProps.layers) {
751
+ var _predefinedFilters = this.collectPredefinedFilters(this.props.layers);
752
+ var prevPredefinedFilters = this.collectPredefinedFilters(prevProps.layers);
753
+ if (!isEqual(Object.keys(_predefinedFilters).sort(), Object.keys(prevPredefinedFilters).sort())) {
754
+ this.setState(function (state) {
755
+ return {
756
+ filters: _this2.initializeFilters(_predefinedFilters, state.filters)
757
+ };
758
+ });
759
+ }
760
+ }
761
+ if (this.state.filters !== prevState.filters || this.state.customFilters !== prevState.customFilters || this.state.geomFilter.geom !== prevState.geomFilter.geom) {
762
+ clearTimeout(this.applyFilterTimeout);
763
+ this.applyFilterTimeout = setTimeout(this.applyFilter, 500);
764
+ }
765
+ }
766
+ }, {
767
+ key: "render",
768
+ value: function render() {
769
+ var _this$state$geomFilte,
770
+ _this$state$geomFilte2,
771
+ _this3 = this,
772
+ _this$state$geomFilte3,
773
+ _this$state$geomFilte4;
774
+ var button = null;
775
+ var taskActive = this.props.currentTask === "MapFilter";
776
+ if (this.props.position >= 0) {
777
+ var filterActive = !isEmpty(this.props.filter.filterParams) || !!this.props.filter.filterGeom;
778
+ var title = LocaleUtils.tr("appmenu.items.MapFilter");
779
+ var className = filterActive && this.state.filterInvalid ? "filter-map-button-error" : "";
780
+ button = /*#__PURE__*/React.createElement(MapButton, {
781
+ active: taskActive,
782
+ className: className,
783
+ engaged: filterActive && !this.state.filterInvalid,
784
+ icon: "filter",
785
+ key: "MapFilterButton",
786
+ onClick: this.filterMapButtonClicked,
787
+ position: this.props.position,
788
+ tooltip: title
789
+ });
790
+ }
791
+ var selGeomType = (_this$state$geomFilte = this.state.geomFilter) !== null && _this$state$geomFilte !== void 0 && _this$state$geomFilte.picking ? null : (_this$state$geomFilte2 = this.state.geomFilter) === null || _this$state$geomFilte2 === void 0 ? void 0 : _this$state$geomFilte2.geomType;
792
+ return [button, /*#__PURE__*/React.createElement(SideBar, {
793
+ icon: "filter",
794
+ id: "MapFilter",
795
+ key: "MapFilterSidebar",
796
+ onHide: this.onSidebarHide,
797
+ side: this.props.side,
798
+ title: LocaleUtils.tr("appmenu.items.MapFilter"),
799
+ width: "20em"
800
+ }, function () {
801
+ return {
802
+ body: _this3.renderBody()
803
+ };
804
+ }), this.state.geomFilter.picking ? /*#__PURE__*/React.createElement(PickFeature, {
805
+ featureFilter: function featureFilter(feature) {
806
+ var _feature$geometry;
807
+ return ((feature === null || feature === void 0 || (_feature$geometry = feature.geometry) === null || _feature$geometry === void 0 ? void 0 : _feature$geometry.type) || "").endsWith("Polygon");
808
+ },
809
+ featurePicked: this.filterGeomPicked,
810
+ highlightStyle: this.props.highlightStyle,
811
+ key: "FeaturePicker"
812
+ }) : null, /*#__PURE__*/React.createElement(MapSelection, {
813
+ active: taskActive && !!selGeomType,
814
+ geomType: selGeomType,
815
+ geometry: (_this$state$geomFilte3 = this.state.geomFilter) === null || _this$state$geomFilte3 === void 0 ? void 0 : _this$state$geomFilte3.geom,
816
+ geometryChanged: this.setFilterGeometry,
817
+ hideGeometry: (_this$state$geomFilte4 = this.state.geomFilter) === null || _this$state$geomFilte4 === void 0 ? void 0 : _this$state$geomFilte4.hideFilterGeom,
818
+ key: "MapSelection",
819
+ styleOptions: this.props.highlightStyle
820
+ })];
821
+ }
822
+ }]);
823
+ }(React.Component);
824
+ _defineProperty(MapFilter, "propTypes", {
825
+ /** Whether to allow custom filters. */
826
+ allowCustomFilters: PropTypes.bool,
827
+ /** Whether to allow filter by geometry. Requires the filter_geom plugin from qwc-qgis-server-plugins, and the filter will only be applied to postgis layers. */
828
+ allowFilterByGeom: PropTypes.bool,
829
+ /** Whether to display the temporal filter if temporal dimensions are found. */
830
+ allowFilterByTime: PropTypes.bool,
831
+ currentTask: PropTypes.string,
832
+ filter: PropTypes.object,
833
+ /** The style used for highlighting filter geometries. */
834
+ highlightStyle: PropTypes.shape({
835
+ /* Stroke color rgba array, i.e. [255, 0, 0, 0.5] */
836
+ strokeColor: PropTypes.array,
837
+ /* Stroke width */
838
+ strokeWidth: PropTypes.number,
839
+ /* Stroke dash/gap pattern array. Empty for solid line. */
840
+ strokeDash: PropTypes.array,
841
+ /* Fill color rgba array, i.e. [255, 0, 0, 0.33] */
842
+ fillColor: PropTypes.array
843
+ }),
844
+ layers: PropTypes.array,
845
+ /** The position slot index of the map button, from the bottom (0: bottom slot). Set to -1 to hide the button. */
846
+ position: PropTypes.number,
847
+ setCurrentTask: PropTypes.func,
848
+ setFilter: PropTypes.func,
849
+ setPermalinkParameters: PropTypes.func,
850
+ /** The side of the application on which to display the sidebar. */
851
+ side: PropTypes.string,
852
+ startupParams: PropTypes.object,
853
+ theme: PropTypes.object
854
+ });
855
+ _defineProperty(MapFilter, "defaultProps", {
856
+ allowFilterByTime: true,
857
+ position: 5,
858
+ predefinedFilters: [],
859
+ highlightStyle: {
860
+ strokeColor: [0, 0, 0],
861
+ fillColor: [255, 255, 0, 0.25]
862
+ }
863
+ });
864
+ export default connect(function (state) {
865
+ return {
866
+ currentTask: state.task.id,
867
+ theme: state.theme.current,
868
+ layers: state.layers.flat,
869
+ filter: state.layers.filter,
870
+ startupParams: state.localConfig.startupParams
871
+ };
872
+ }, {
873
+ setFilter: setFilter,
874
+ setCurrentTask: setCurrentTask,
875
+ setPermalinkParameters: setPermalinkParameters
876
+ })(MapFilter);