qwc2 2025.7.20 → 2025.7.23

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 (39) hide show
  1. package/components/AppMenu.js +1 -1
  2. package/components/AttributeForm.js +11 -9
  3. package/components/AttributeTableWidget.js +8 -7
  4. package/components/EditComboField.js +4 -4
  5. package/components/LinkFeatureForm.js +2 -2
  6. package/components/PickFeature.js +1 -1
  7. package/components/QtDesignerForm.js +11 -11
  8. package/components/map/OlMap.js +1 -1
  9. package/components/map/layers/MVTLayer.js +1 -1
  10. package/package.json +2 -1
  11. package/plugins/BottomBar.js +2 -2
  12. package/plugins/Editing.js +1 -1
  13. package/plugins/FeatureForm.js +1 -1
  14. package/plugins/Print.js +1 -1
  15. package/plugins/style/BottomBar.css +14 -6
  16. package/static/translations/bg-BG.json +1 -1
  17. package/static/translations/ca-ES.json +1 -1
  18. package/static/translations/cs-CZ.json +1 -1
  19. package/static/translations/de-CH.json +1 -1
  20. package/static/translations/de-DE.json +1 -1
  21. package/static/translations/en-US.json +1 -1
  22. package/static/translations/es-ES.json +1 -1
  23. package/static/translations/fi-FI.json +1 -1
  24. package/static/translations/fr-FR.json +1 -1
  25. package/static/translations/it-IT.json +1 -1
  26. package/static/translations/ja-JP.json +1 -1
  27. package/static/translations/nl-NL.json +1 -1
  28. package/static/translations/no-NO.json +1 -1
  29. package/static/translations/pl-PL.json +1 -1
  30. package/static/translations/pt-BR.json +1 -1
  31. package/static/translations/pt-PT.json +1 -1
  32. package/static/translations/ro-RO.json +1 -1
  33. package/static/translations/sv-SE.json +1 -1
  34. package/static/translations/tr-TR.json +1 -1
  35. package/utils/EditingInterface.js +86 -62
  36. package/utils/EditingUtils.js +11 -5
  37. package/utils/expr_grammar/grammar.js +1 -1
  38. package/utils/expr_grammar/grammar.ne +3 -1
  39. package/utils/expr_grammar/test.js +4 -2
@@ -4,5 +4,5 @@ function _typeof(o){"@babel/helpers - typeof";return _typeof="function"==typeof
4
4
  *
5
5
  * This source code is licensed under the BSD-style license found in the
6
6
  * LICENSE file in the root directory of this source tree.
7
- */import React from"react";import{connect}from"react-redux";import classnames from"classnames";import{remove as removeDiacritics}from"diacritics";import isEmpty from"lodash.isempty";import isEqual from"lodash.isequal";import mousetrap from"mousetrap";import PropTypes from"prop-types";import{setCurrentTask}from"../actions/task";import{setMenuMargin}from"../actions/windows";import InputContainer from"../components/widgets/InputContainer";import ConfigUtils from"../utils/ConfigUtils";import LocaleUtils from"../utils/LocaleUtils";import MiscUtils from"../utils/MiscUtils";import Icon from"./Icon";import"./style/AppMenu.css";var AppMenu=/*#__PURE__*/function(_React$Component){function AppMenu(props){var _this;_classCallCheck(this,AppMenu);_this=_callSuper(this,AppMenu,[props]);_defineProperty(_this,"state",{menuVisible:false,filter:"",submenusVisible:[],curEntry:null,keyNav:false});_defineProperty(_this,"addKeyBindings",function(items){items.forEach(function(item){if(item.subitems){_this.addKeyBindings(item.subitems)}else if(item.shortcut){mousetrap.bind(item.shortcut,function(){_this.onMenuitemClicked(item);return false});_this.boundShortcuts.push(item.shortcut)}})});_defineProperty(_this,"onKeyPress",function(ev){if(ev.key==="Enter"||ev.key==="ArrowLeft"||ev.key==="ArrowUp"||ev.key==="ArrowRight"||ev.key==="ArrowDown"){if(!_this.state.curEntry){if(ev.key==="ArrowUp"||ev.key==="ArrowDown"){_this.setState({curEntry:[ev.key==="ArrowUp"?_this.props.menuItems.length-1:0]})}}else{var curEntry=_toConsumableArray(_this.state.curEntry);var stack=[_this.props.menuItems];_this.state.curEntry.forEach(function(entry){stack.push(stack[stack.length-1][entry].subitems)});stack.pop();var leaf=curEntry.pop();var level=stack.length-1;if(ev.key==="Enter"){if(!isEmpty(stack[stack.length-1][leaf].subitems)){_this.onSubmenuClicked(stack[stack.length-1][leaf].key,level)}else{_this.onMenuitemClicked(stack[stack.length-1][leaf])}}else if(ev.key==="ArrowLeft"){if(!isEmpty(stack[stack.length-1][leaf].subitems)&&_this.state.submenusVisible[level]===stack[stack.length-1][leaf].key){_this.onSubmenuClicked(stack[stack.length-1][leaf].key,level)}}else if(ev.key==="ArrowUp"){leaf-=1;if(leaf>=0&&!isEmpty(stack[stack.length-1][leaf].subitems)&&_this.state.submenusVisible[level]===stack[stack.length-1][leaf].key){curEntry.push(leaf);leaf=stack[stack.length-1][leaf].subitems.length-1}else{while(leaf<0&&curEntry.length>0){leaf=curEntry.pop()}if(leaf<0){leaf=_this.props.menuItems.length-1}}}else if(ev.key==="ArrowRight"){if(!isEmpty(stack[stack.length-1][leaf].subitems)&&!_this.state.submenusVisible[level]){_this.onSubmenuClicked(stack[stack.length-1][leaf].key,level)}}else if(ev.key==="ArrowDown"){if(!isEmpty(stack[stack.length-1][leaf].subitems)&&_this.state.submenusVisible[level]===stack[stack.length-1][leaf].key){curEntry.push(leaf);leaf=0}else{leaf+=1;while(leaf>stack[stack.length-1].length-1&&curEntry.length>0){leaf=curEntry.pop()+1;stack.pop()}if(leaf>_this.props.menuItems.length-1){leaf=0}}}_this.setState({curEntry:[].concat(_toConsumableArray(curEntry),[leaf]),keyNav:true})}MiscUtils.killEvent(ev)}else if(ev.key==="Escape"){_this.toggleMenu();MiscUtils.killEvent(ev)}});_defineProperty(_this,"onMouseMove",function(ev){if(_this.state.keyNav){_this.setState({keyNav:false})}MiscUtils.killEvent(ev)});_defineProperty(_this,"toggleMenu",function(){if(!_this.state.menuVisible&&_this.props.currentTaskBlocked){return}if(!_this.state.menuVisible&&_this.props.appMenuClearsTask){_this.props.setCurrentTask(null)}if(!_this.props.keepMenuOpen){if(!_this.state.menuVisible){document.addEventListener("click",_this.checkCloseMenu);document.addEventListener("keydown",_this.onKeyPress,true);document.addEventListener("mousemove",_this.onMouseMove,true)}else{document.removeEventListener("click",_this.checkCloseMenu);document.removeEventListener("keydown",_this.onKeyPress,true);document.removeEventListener("mousemove",_this.onMouseMove,true)}}_this.props.onMenuToggled(!_this.state.menuVisible);if(_this.props.menuCompact){_this.props.setMenuMargin(!_this.state.menuVisible?MiscUtils.convertEmToPx(3.75):0,0)}_this.setState(function(state){return{menuVisible:!state.menuVisible,submenusVisible:[],filter:""}})});_defineProperty(_this,"checkCloseMenu",function(ev){if(_this.menuEl&&!_this.menuEl.contains(ev.target)&&!_this.props.keepMenuOpen){_this.toggleMenu()}MiscUtils.killEvent(ev)});_defineProperty(_this,"onSubmenuClicked",function(key,level){var a=_this.state.submenusVisible[level]===key?[]:[key];_this.setState(function(state){return{submenusVisible:state.submenusVisible.slice(0,level).concat(a)}})});_defineProperty(_this,"onMenuitemClicked",function(item){if(!_this.props.keepMenuOpen&&_this.state.menuVisible){_this.toggleMenu()}if(item.url){var label=item.title?LocaleUtils.tr(item.title):LocaleUtils.tr("appmenu.items."+item.key+(item.mode||""));_this.props.openExternalUrl(item.url,item.target,label,item.icon)}else{_this.props.setCurrentTask(item.task||item.key,item.mode,item.mapClickAction||(item.identifyEnabled?"identify":null))}});_defineProperty(_this,"renderMenuItems",function(items,level,filter,path){if(items){return items.map(function(item,idx){var active=isEqual(_this.state.curEntry,[].concat(_toConsumableArray(path),[idx]));if(item.subitems){var _item$key;var subitems=_this.renderMenuItems(item.subitems,level+1,filter,[].concat(_toConsumableArray(path),[idx]));if(filter&&isEmpty(subitems)){return null}var visible=filter&&!isEmpty(subitems)||_this.state.submenusVisible[level]===item.key;var className=classnames({"appmenu-submenu":true,"appmenu-submenu-active":active,"appmenu-submenu-expanded":visible});return/*#__PURE__*/React.createElement("li",{className:className,key:(_item$key=item.key)!==null&&_item$key!==void 0?_item$key:item.title,onClick:function onClick(){return _this.onSubmenuClicked(item.key,level)},onMouseEnter:function onMouseEnter(){if(!_this.state.keyNav){_this.setState({curEntry:[].concat(_toConsumableArray(path),[idx])})}},onMouseLeave:function onMouseLeave(){if(!_this.state.keyNav){_this.setState({curEntry:null})}},ref:function ref(el){if(active&&el&&_this.state.keyNav){el.scrollIntoView(false)}}},/*#__PURE__*/React.createElement(Icon,{icon:item.icon,size:"xlarge"}),item.title?LocaleUtils.tr(item.title):LocaleUtils.tr("appmenu.items."+item.key),/*#__PURE__*/React.createElement("ul",null,subitems))}else{var label=item.title?LocaleUtils.tr(item.title):LocaleUtils.tr("appmenu.items."+item.key+(item.mode||""));var comment=item.comment?LocaleUtils.tr("appmenu.items."+item.key+(item.mode||"")+"_comment"):"";if(!filter||removeDiacritics(label.toLowerCase()).match(filter)||comment&&removeDiacritics(comment.toLowerCase()).match(filter)){var _className=classnames({"appmenu-leaf":true,"appmenu-leaf-active":active});return/*#__PURE__*/React.createElement("li",{className:_className,key:item.key?item.key+(item.mode||""):item.title,onClick:function onClick(){return _this.onMenuitemClicked(item)},onMouseEnter:function onMouseEnter(){if(!_this.state.keyNav){_this.setState({curEntry:[].concat(_toConsumableArray(path),[idx])})}},onMouseLeave:function onMouseLeave(){if(!_this.state.keyNav){_this.setState({curEntry:null})}},ref:function ref(el){if(active&&el&&_this.state.keyNav){el.scrollIntoView(false)}}},/*#__PURE__*/React.createElement(Icon,{icon:item.icon,size:"xlarge"}),/*#__PURE__*/React.createElement("span",{className:"appmenu-leaf-label"},label,comment?/*#__PURE__*/React.createElement("div",{className:"appmenu-leaf-comment"},comment):null))}return null}}).filter(function(x){return x})}else{return null}});_defineProperty(_this,"setFilterField",function(el){_this.filterfield=el;if(_this.props.appMenuShortcut){mousetrap(el).bind(_this.props.appMenuShortcut,_this.toggleMenu)}});_this.menuEl=null;_this.filterfield=null;_this.boundShortcuts=[];return _this}_inherits(AppMenu,_React$Component);return _createClass(AppMenu,[{key:"componentDidMount",value:function componentDidMount(){if(this.props.showOnStartup){this.toggleMenu()}this.addKeyBindings(this.props.menuItems);if(this.props.appMenuShortcut){mousetrap.bind(this.props.appMenuShortcut,this.toggleMenu)}}},{key:"componentDidUpdate",value:function componentDidUpdate(prevProps,prevState){var _this2=this;if(this.state.menuVisible&&!prevState.menuVisible&&this.filterfield&&!this.props.menuCompact){// Need to wait until slide in transition is over
7
+ */import React from"react";import{connect}from"react-redux";import classnames from"classnames";import{remove as removeDiacritics}from"diacritics";import isEmpty from"lodash.isempty";import isEqual from"lodash.isequal";import mousetrap from"mousetrap";import PropTypes from"prop-types";import{setCurrentTask}from"../actions/task";import{setMenuMargin}from"../actions/windows";import InputContainer from"../components/widgets/InputContainer";import ConfigUtils from"../utils/ConfigUtils";import LocaleUtils from"../utils/LocaleUtils";import MiscUtils from"../utils/MiscUtils";import Icon from"./Icon";import"./style/AppMenu.css";var AppMenu=/*#__PURE__*/function(_React$Component){function AppMenu(props){var _this;_classCallCheck(this,AppMenu);_this=_callSuper(this,AppMenu,[props]);_defineProperty(_this,"state",{menuVisible:false,filter:"",submenusVisible:[],curEntry:null,keyNav:false});_defineProperty(_this,"addKeyBindings",function(items){items.forEach(function(item){if(item.subitems){_this.addKeyBindings(item.subitems)}else if(item.shortcut){mousetrap.bind(item.shortcut,function(){_this.onMenuitemClicked(item);return false});_this.boundShortcuts.push(item.shortcut)}})});_defineProperty(_this,"onKeyPress",function(ev){if(ev.key==="Enter"||ev.key==="ArrowLeft"||ev.key==="ArrowUp"||ev.key==="ArrowRight"||ev.key==="ArrowDown"){if(!_this.state.curEntry){if(ev.key==="ArrowUp"||ev.key==="ArrowDown"){_this.setState({curEntry:[ev.key==="ArrowUp"?_this.props.menuItems.length-1:0]})}}else{var curEntry=_toConsumableArray(_this.state.curEntry);var stack=[_this.props.menuItems];_this.state.curEntry.forEach(function(entry){stack.push(stack[stack.length-1][entry].subitems)});stack.pop();var leaf=curEntry.pop();var level=stack.length-1;if(ev.key==="Enter"){if(!isEmpty(stack[stack.length-1][leaf].subitems)){_this.onSubmenuClicked(stack[stack.length-1][leaf].key,level)}else{_this.onMenuitemClicked(stack[stack.length-1][leaf])}}else if(ev.key==="ArrowLeft"){if(!isEmpty(stack[stack.length-1][leaf].subitems)&&_this.state.submenusVisible[level]===stack[stack.length-1][leaf].key){_this.onSubmenuClicked(stack[stack.length-1][leaf].key,level)}}else if(ev.key==="ArrowUp"){leaf-=1;if(leaf>=0&&!isEmpty(stack[stack.length-1][leaf].subitems)&&_this.state.submenusVisible[level]===stack[stack.length-1][leaf].key){curEntry.push(leaf);leaf=stack[stack.length-1][leaf].subitems.length-1}else{while(leaf<0&&curEntry.length>0){leaf=curEntry.pop()}if(leaf<0){leaf=_this.props.menuItems.length-1}}}else if(ev.key==="ArrowRight"){if(!isEmpty(stack[stack.length-1][leaf].subitems)&&!_this.state.submenusVisible[level]){_this.onSubmenuClicked(stack[stack.length-1][leaf].key,level)}}else if(ev.key==="ArrowDown"){if(!isEmpty(stack[stack.length-1][leaf].subitems)&&_this.state.submenusVisible[level]===stack[stack.length-1][leaf].key){curEntry.push(leaf);leaf=0}else{leaf+=1;while(leaf>stack[stack.length-1].length-1&&curEntry.length>0){leaf=curEntry.pop()+1;stack.pop()}if(leaf>_this.props.menuItems.length-1){leaf=0}}}_this.setState({curEntry:[].concat(_toConsumableArray(curEntry),[leaf]),keyNav:true})}MiscUtils.killEvent(ev)}else if(ev.key==="Escape"){_this.toggleMenu();MiscUtils.killEvent(ev)}});_defineProperty(_this,"onMouseMove",function(ev){if(_this.state.keyNav){_this.setState({keyNav:false})}MiscUtils.killEvent(ev)});_defineProperty(_this,"toggleMenu",function(){if(!_this.state.menuVisible&&_this.props.currentTaskBlocked){return}if(!_this.state.menuVisible&&_this.props.appMenuClearsTask){_this.props.setCurrentTask(null)}if(!_this.props.keepMenuOpen){if(!_this.state.menuVisible){document.addEventListener("click",_this.checkCloseMenu);document.addEventListener("keydown",_this.onKeyPress,true);document.addEventListener("mousemove",_this.onMouseMove,true)}else{document.removeEventListener("click",_this.checkCloseMenu);document.removeEventListener("keydown",_this.onKeyPress,true);document.removeEventListener("mousemove",_this.onMouseMove,true)}}_this.props.onMenuToggled(!_this.state.menuVisible);if(_this.props.menuCompact){_this.props.setMenuMargin(!_this.state.menuVisible?MiscUtils.convertEmToPx(3.75):0,0)}_this.setState(function(state){return{menuVisible:!state.menuVisible,submenusVisible:[],filter:""}})});_defineProperty(_this,"checkCloseMenu",function(ev){if(_this.menuEl&&!_this.menuEl.contains(ev.target)&&!_this.props.keepMenuOpen){_this.toggleMenu()}MiscUtils.killEvent(ev)});_defineProperty(_this,"onSubmenuClicked",function(key,level){var a=_this.state.submenusVisible[level]===key?[]:[key];_this.setState(function(state){return{submenusVisible:state.submenusVisible.slice(0,level).concat(a)}})});_defineProperty(_this,"onMenuitemClicked",function(item){if(!_this.props.keepMenuOpen&&_this.state.menuVisible){_this.toggleMenu()}if(item.url){var label=item.title?LocaleUtils.tr(item.title):LocaleUtils.tr("appmenu.items."+item.key+(item.mode||""));_this.props.openExternalUrl(item.url,item.target,label,item.icon)}else{_this.props.setCurrentTask(item.task||item.key,item.mode,item.mapClickAction||(item.identifyEnabled?"identify":null))}});_defineProperty(_this,"renderMenuItems",function(items,level,filter,path){if(items){return items.map(function(item,idx){var active=isEqual(_this.state.curEntry,[].concat(_toConsumableArray(path),[idx]));if(item.subitems){var _item$key;var subitems=_this.renderMenuItems(item.subitems,level+1,filter,[].concat(_toConsumableArray(path),[idx]));if(filter&&isEmpty(subitems)){return null}var visible=filter&&!isEmpty(subitems)||_this.state.submenusVisible[level]===item.key;var className=classnames({"appmenu-submenu":true,"appmenu-submenu-active":active,"appmenu-submenu-expanded":visible});return/*#__PURE__*/React.createElement("li",{className:className,key:(_item$key=item.key)!==null&&_item$key!==void 0?_item$key:item.title,onClick:function onClick(){return _this.onSubmenuClicked(item.key,level)},onMouseEnter:function onMouseEnter(){if(!_this.state.keyNav){_this.setState({curEntry:[].concat(_toConsumableArray(path),[idx])})}},onMouseLeave:function onMouseLeave(){if(!_this.state.keyNav){_this.setState({curEntry:null})}},ref:function ref(el){if(active&&el&&_this.state.keyNav){el.scrollIntoView(false)}}},/*#__PURE__*/React.createElement(Icon,{icon:item.icon,size:"xlarge"}),item.title?LocaleUtils.tr(item.title):LocaleUtils.tr("appmenu.items."+item.key),/*#__PURE__*/React.createElement("ul",null,subitems))}else{var trargs=item.trargs||[];var label=item.title?LocaleUtils.tr.apply(LocaleUtils,[item.title].concat(_toConsumableArray(trargs))):LocaleUtils.tr.apply(LocaleUtils,["appmenu.items."+item.key+(item.mode||"")].concat(_toConsumableArray(trargs)));var comment=item.comment?LocaleUtils.tr.apply(LocaleUtils,["appmenu.items."+item.key+(item.mode||"")+"_comment"].concat(_toConsumableArray(trargs))):"";if(!filter||removeDiacritics(label.toLowerCase()).match(filter)||comment&&removeDiacritics(comment.toLowerCase()).match(filter)){var _className=classnames({"appmenu-leaf":true,"appmenu-leaf-active":active});return/*#__PURE__*/React.createElement("li",{className:_className,key:item.key?item.key+(item.mode||""):item.title,onClick:function onClick(){return _this.onMenuitemClicked(item)},onMouseEnter:function onMouseEnter(){if(!_this.state.keyNav){_this.setState({curEntry:[].concat(_toConsumableArray(path),[idx])})}},onMouseLeave:function onMouseLeave(){if(!_this.state.keyNav){_this.setState({curEntry:null})}},ref:function ref(el){if(active&&el&&_this.state.keyNav){el.scrollIntoView(false)}}},/*#__PURE__*/React.createElement(Icon,{icon:item.icon,size:"xlarge"}),/*#__PURE__*/React.createElement("span",{className:"appmenu-leaf-label"},label,comment?/*#__PURE__*/React.createElement("div",{className:"appmenu-leaf-comment"},comment):null))}return null}}).filter(function(x){return x})}else{return null}});_defineProperty(_this,"setFilterField",function(el){_this.filterfield=el;if(_this.props.appMenuShortcut){mousetrap(el).bind(_this.props.appMenuShortcut,_this.toggleMenu)}});_this.menuEl=null;_this.filterfield=null;_this.boundShortcuts=[];return _this}_inherits(AppMenu,_React$Component);return _createClass(AppMenu,[{key:"componentDidMount",value:function componentDidMount(){if(this.props.showOnStartup){this.toggleMenu()}this.addKeyBindings(this.props.menuItems);if(this.props.appMenuShortcut){mousetrap.bind(this.props.appMenuShortcut,this.toggleMenu)}}},{key:"componentDidUpdate",value:function componentDidUpdate(prevProps,prevState){var _this2=this;if(this.state.menuVisible&&!prevState.menuVisible&&this.filterfield&&!this.props.menuCompact){// Need to wait until slide in transition is over
8
8
  setTimeout(function(){_this2.filterfield.focus()},400)}}},{key:"componentWillUnmount",value:function componentWillUnmount(){this.boundShortcuts.forEach(function(shortcut){return mousetrap.unbind(shortcut)});if(this.props.appMenuShortcut){mousetrap.unbind(this.props.appMenuShortcut,this.toggleMenu)}if(this.state.menuVisible){document.removeEventListener("click",this.checkCloseMenu);document.removeEventListener("keydown",this.onKeyPress,true);document.removeEventListener("mousemove",this.onMouseMove,true)}}},{key:"render",value:function render(){var _this3=this;var isMobile=ConfigUtils.isMobile();var visible=!this.props.currentTaskBlocked&&this.state.menuVisible;var showLabel=!this.props.menuCompact&&!isMobile;var className=classnames({"AppMenu":true,"appmenu-blocked":this.props.currentTaskBlocked,"appmenu-visible":visible,"appmenu-compact":this.props.menuCompact,"appmenu-nolabel":!showLabel});var filter=this.state.filter?new RegExp(removeDiacritics(this.state.filter).replace(/[-[\]/{}()*+?.\\^$|]/g,"\\$&"),"i"):null;return/*#__PURE__*/React.createElement("div",{className:className,ref:function ref(el){_this3.menuEl=el;MiscUtils.setupKillTouchEvents(el)}},/*#__PURE__*/React.createElement("div",{className:"appmenu-button",onMouseDown:this.toggleMenu,title:this.props.buttonLabel},showLabel?/*#__PURE__*/React.createElement("span",{className:"appmenu-label"},this.props.buttonLabel):null,/*#__PURE__*/React.createElement("span",{className:"appmenu-icon"},/*#__PURE__*/React.createElement(Icon,{icon:"menu-hamburger"}))),/*#__PURE__*/React.createElement("div",{className:"appmenu-menu-container"},/*#__PURE__*/React.createElement("ul",{className:"appmenu-menu"},this.props.showFilterField?/*#__PURE__*/React.createElement("li",{className:"appmenu-leaf"},/*#__PURE__*/React.createElement(Icon,{icon:"search",size:"xlarge"}),/*#__PURE__*/React.createElement(InputContainer,{className:"appmenu-filter"},/*#__PURE__*/React.createElement("input",{onChange:function onChange(ev){return _this3.setState({filter:ev.target.value,curEntry:null})},placeholder:LocaleUtils.tr("appmenu.filter"),ref:this.setFilterField,role:"input",type:"text",value:this.state.filter}),/*#__PURE__*/React.createElement(Icon,{icon:"clear",onClick:function onClick(){return _this3.setState({filter:""})},role:"suffix"}))):null,this.renderMenuItems(this.props.menuItems,0,filter,[]))))}}])}(React.Component);_defineProperty(AppMenu,"propTypes",{appMenuClearsTask:PropTypes.bool,appMenuShortcut:PropTypes.string,buttonLabel:PropTypes.string,currentTaskBlocked:PropTypes.bool,keepMenuOpen:PropTypes.bool,menuCompact:PropTypes.bool,menuItems:PropTypes.array,onMenuToggled:PropTypes.func,openExternalUrl:PropTypes.func,setCurrentTask:PropTypes.func,setMenuMargin:PropTypes.func,showFilterField:PropTypes.bool,showOnStartup:PropTypes.bool});_defineProperty(AppMenu,"defaultProps",{onMenuToggled:function onMenuToggled(){}});export default connect(function(state){return{currentTaskBlocked:state.task.blocked}},{setCurrentTask:setCurrentTask,setMenuMargin:setMenuMargin})(AppMenu);
@@ -5,27 +5,29 @@ function _typeof(o){"@babel/helpers - typeof";return _typeof="function"==typeof
5
5
  * This source code is licensed under the BSD-style license found in the
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  */import React from"react";import{connect}from"react-redux";import clone from"clone";import isEmpty from"lodash.isempty";import PropTypes from"prop-types";import{v1 as uuidv1}from"uuid";import{setEditContext,clearEditContext}from"../actions/editing";import{LayerRole,refreshLayer}from"../actions/layers";import{setCurrentTaskBlocked}from"../actions/task";import ConfigUtils from"../utils/ConfigUtils";import CoordinatesUtils from"../utils/CoordinatesUtils";import{getFeatureTemplate,parseExpressionsAsync}from"../utils/EditingUtils";import LocaleUtils from"../utils/LocaleUtils";import AutoEditForm from"./AutoEditForm";import LinkFeatureForm from"./LinkFeatureForm";import QtDesignerForm from"./QtDesignerForm";import ButtonBar from"./widgets/ButtonBar";import ReCaptchaWidget from"./widgets/ReCaptchaWidget";import"./style/AttributeForm.css";var AttributeForm=/*#__PURE__*/function(_React$Component){function AttributeForm(props){var _this;_classCallCheck(this,AttributeForm);_this=_callSuper(this,AttributeForm,[props]);_defineProperty(_this,"state",{busy:false,deleteClicked:false,childEdit:null,relationTables:{},formValid:true,captchaResponse:null});_defineProperty(_this,"editLayerId",function(layerId){return _this.props.editConfig||layerId});_defineProperty(_this,"render",function(){var captchaRequired=ConfigUtils.getConfigProp("editServiceCaptchaSiteKey")&&!ConfigUtils.getConfigProp("username");var captchaPending=captchaRequired&&!_this.state.captchaResponse;var commitBar=null;if(_this.props.editContext.changed){var commitButtons=[{key:"Commit",icon:_this.state.formValid?"ok":"warning",label:_this.state.formValid?LocaleUtils.tr("editing.commit"):LocaleUtils.tr("editing.invalidform"),extraClasses:_this.state.formValid?"button-accept":"button-warning",type:"submit",disabled:!_this.state.formValid||captchaPending},{key:"Discard",icon:"remove",label:LocaleUtils.tr("editing.discard"),extraClasses:"button-reject"}];commitBar=/*#__PURE__*/React.createElement(ButtonBar,{buttons:commitButtons,onClick:_this.onDiscard});/* submit is handled via onSubmit in the form */}var curConfig=_this.props.editConfig;var editPermissions=curConfig.permissions||{};var readOnly=_this.props.readOnly||editPermissions.updatable===false&&_this.props.editContext.action==="Pick";var deleteBar=null;if(!_this.props.hideDelete&&_this.props.editContext.action==="Pick"&&_this.props.editContext.feature&&!_this.props.editContext.changed&&editPermissions.deletable!==false&&!_this.props.readOnly){// Delete button bar will appear by default if no permissions are defined in editConfig or when deletable permission is set
8
- if(!_this.state.deleteClicked){var _this$props$deleteLab;var deleteButtons=[{key:"Delete",icon:"trash",label:(_this$props$deleteLab=_this.props.deleteLabel)!==null&&_this$props$deleteLab!==void 0?_this$props$deleteLab:LocaleUtils.tr("editing.delete")}];deleteBar=/*#__PURE__*/React.createElement(ButtonBar,{buttons:deleteButtons,onClick:_this.deleteClicked})}else{var _deleteButtons=[{key:"Yes",icon:"ok",label:LocaleUtils.tr("editing.reallydelete"),extraClasses:"button-accept",disabled:captchaPending},{key:"No",icon:"remove",label:LocaleUtils.tr("editing.canceldelete"),extraClasses:"button-reject"}];deleteBar=/*#__PURE__*/React.createElement(ButtonBar,{buttons:_deleteButtons,onClick:_this.deleteFeature})}}var busyDiv=null;if(_this.state.busy){busyDiv=/*#__PURE__*/React.createElement("div",{className:"attrib-form-busy"})}var childAttributeForm=null;if(_this.state.childEdit){childAttributeForm=/*#__PURE__*/React.createElement("div",{className:"link-feature-form-container"},/*#__PURE__*/React.createElement(LinkFeatureForm,_extends({},_this.state.childEdit,{finished:_this.state.childEdit.finishCallback,iface:_this.props.iface,pickFilter:_this.props.childPickFilter,readOnly:_this.props.readOnly})))}var captchaButton=null;if(captchaRequired&&(_this.props.editContext.changed||_this.state.deleteClicked)){captchaButton=/*#__PURE__*/React.createElement(ReCaptchaWidget,{onChange:function onChange(value){return _this.setState({captchaResponse:value})},sitekey:ConfigUtils.getConfigProp("editServiceCaptchaSiteKey")})}var readOnlyMsg=null;if(!readOnly&&_this.props.editContext.geomReadOnly){readOnlyMsg=LocaleUtils.tr("editing.geomreadonly")}else if(!readOnly&&_this.props.editContext.geomNonZeroZ){readOnlyMsg=LocaleUtils.tr("editing.geomnonzeroz")}return/*#__PURE__*/React.createElement("div",{className:"AttributeForm"},readOnlyMsg?/*#__PURE__*/React.createElement("div",{className:"attrib-form-geom-readonly"},readOnlyMsg):null,/*#__PURE__*/React.createElement("form",{action:"",onChange:function onChange(ev){return _this.formChanged(ev)},onSubmit:_this.onSubmit,ref:_this.setupChangedObserver},_this.props.editConfig.form?/*#__PURE__*/React.createElement(QtDesignerForm,{addRelationRecord:_this.addRelationRecord,editConfig:_this.props.theme.editConfig,editLayerId:_this.props.editConfig.editDataset,editRelationRecord:_this.editRelationRecord,feature:_this.props.editContext.feature,fields:_this.fieldsMap(_this.props.editConfig.fields),form:_this.props.editConfig.form,iface:_this.props.iface,mapCrs:_this.props.map.projection,mapPrefix:_this.editMapPrefix(),readOnly:readOnly,removeRelationRecord:_this.removeRelationRecord,reorderRelationRecord:_this.reorderRelationRecord,report:_this.props.report,setFormBusy:_this.setFormBusy,setRelationTables:_this.setRelationTables,switchEditContext:_this.startChildEdit,updateField:_this.updateField,updateRelationField:_this.updateRelationField}):/*#__PURE__*/React.createElement(AutoEditForm,{editLayerId:_this.props.editConfig.editDataset,fields:_this.props.editConfig.fields,iface:_this.props.iface,readOnly:readOnly,touchFriendly:_this.props.touchFriendly,updateField:_this.updateField,values:_this.props.editContext.feature.properties}),captchaButton,commitBar),deleteBar,busyDiv,childAttributeForm)});_defineProperty(_this,"setFormBusy",function(busy){_this.setState({busy:busy})});_defineProperty(_this,"fieldsMap",function(fields){return fields.reduce(function(res,field){return _objectSpread(_objectSpread({},res),{},_defineProperty({},field.id,field))},{})});_defineProperty(_this,"updateField",function(key,value){var newProperties=_objectSpread(_objectSpread({},_this.props.editContext.feature.properties),{},_defineProperty({},key,value));var newFeature=_objectSpread(_objectSpread({},_this.props.editContext.feature),{},{properties:newProperties});_this.props.setEditContext(_this.props.editContext.id,{feature:newFeature,changed:true});_this.validateFieldConstraints(newFeature)});_defineProperty(_this,"editMapPrefix",function(){return(_this.props.editConfig.editDataset.match(/^[^.]+\./)||[""])[0]});_defineProperty(_this,"setRelationTables",function(relationTables){_this.setState({relationTables:relationTables})});_defineProperty(_this,"loadRelationValues",function(feature,callback){if(!isEmpty(_this.state.relationTables)){if(feature.id){var relTables=Object.entries(_this.state.relationTables).map(function(_ref){var _ref2=_slicedToArray(_ref,2),name=_ref2[0],entry=_ref2[1];if(entry.sortcol){return name+":"+entry.fk+":"+entry.sortcol}else{return name+":"+entry.fk}}).join(",");_this.props.iface.getRelations(_this.props.editConfig.editDataset,feature.id,relTables,_this.props.map.projection,function(relationValues){var newFeature=_objectSpread(_objectSpread({},feature),{},{relationValues:relationValues});callback(newFeature)})}else{var relationValues=_objectSpread(_objectSpread({},Object.entries(_this.state.relationTables).reduce(function(res,_ref3){var _ref4=_slicedToArray(_ref3,2),name=_ref4[0],entry=_ref4[1];return _objectSpread(_objectSpread({},res),{},_defineProperty({},name,{fk:entry.fk,features:[]}))},{})),feature.relationValues);var newFeature=_objectSpread(_objectSpread({},feature),{},{relationValues:relationValues});callback(newFeature)}}});_defineProperty(_this,"addRelationRecord",function(table){var newRelationValues=_objectSpread({},_this.props.editContext.feature.relationValues);var editConfig=_this.props.theme.editConfig[table.split(".").slice(-1)];var mapPrefix=(editConfig.editDataset.match(/^[^.]+\./)||[""])[0];getFeatureTemplate(editConfig,{type:"Feature",properties:{}},_this.props.iface,mapPrefix,_this.props.map.projection,function(newRelFeature){newRelFeature.__status__="empty";if(editConfig.geomType===null){newRelFeature.geometry=null}// If feature id is known, i.e. not when drawing new feature, set foreign key
8
+ if(!_this.state.deleteClicked){var _this$props$deleteLab;var deleteButtons=[{key:"Delete",icon:"trash",label:(_this$props$deleteLab=_this.props.deleteLabel)!==null&&_this$props$deleteLab!==void 0?_this$props$deleteLab:LocaleUtils.tr("editing.delete")}];deleteBar=/*#__PURE__*/React.createElement(ButtonBar,{buttons:deleteButtons,onClick:_this.deleteClicked})}else{var _deleteButtons=[{key:"Yes",icon:"ok",label:LocaleUtils.tr("editing.reallydelete"),extraClasses:"button-accept",disabled:captchaPending},{key:"No",icon:"remove",label:LocaleUtils.tr("editing.canceldelete"),extraClasses:"button-reject"}];deleteBar=/*#__PURE__*/React.createElement(ButtonBar,{buttons:_deleteButtons,onClick:_this.deleteFeature})}}var busyDiv=null;if(_this.state.busy){busyDiv=/*#__PURE__*/React.createElement("div",{className:"attrib-form-busy"})}var childAttributeForm=null;if(_this.state.childEdit){childAttributeForm=/*#__PURE__*/React.createElement("div",{className:"link-feature-form-container"},/*#__PURE__*/React.createElement(LinkFeatureForm,_extends({},_this.state.childEdit,{finished:_this.state.childEdit.finishCallback,iface:_this.props.iface,pickFilter:_this.props.childPickFilter,readOnly:_this.props.readOnly})))}var captchaButton=null;if(captchaRequired&&(_this.props.editContext.changed||_this.state.deleteClicked)){captchaButton=/*#__PURE__*/React.createElement(ReCaptchaWidget,{onChange:function onChange(value){return _this.setState({captchaResponse:value})},sitekey:ConfigUtils.getConfigProp("editServiceCaptchaSiteKey")})}var readOnlyMsg=null;if(!readOnly&&_this.props.editContext.geomReadOnly){readOnlyMsg=LocaleUtils.tr("editing.geomreadonly")}else if(!readOnly&&_this.props.editContext.geomNonZeroZ){readOnlyMsg=LocaleUtils.tr("editing.geomnonzeroz")}return/*#__PURE__*/React.createElement("div",{className:"AttributeForm"},readOnlyMsg?/*#__PURE__*/React.createElement("div",{className:"attrib-form-geom-readonly"},readOnlyMsg):null,/*#__PURE__*/React.createElement("form",{action:"",onChange:function onChange(ev){return _this.formChanged(ev)},onSubmit:_this.onSubmit,ref:_this.setupChangedObserver},_this.props.editConfig.form?/*#__PURE__*/React.createElement(QtDesignerForm,{addRelationRecord:_this.addRelationRecord,editConfig:_this.props.editConfig,editConfigs:_this.props.theme.editConfig,editRelationRecord:_this.editRelationRecord,feature:_this.props.editContext.feature,iface:_this.props.iface,mapCrs:_this.props.map.projection,mapPrefix:_this.editMapPrefix(),readOnly:readOnly,removeRelationRecord:_this.removeRelationRecord,reorderRelationRecord:_this.reorderRelationRecord,report:_this.props.report,setFormBusy:_this.setFormBusy,setRelationTables:_this.setRelationTables,switchEditContext:_this.startChildEdit,updateField:_this.updateField,updateRelationField:_this.updateRelationField}):/*#__PURE__*/React.createElement(AutoEditForm,{editLayerId:_this.props.editConfig.editDataset,fields:_this.props.editConfig.fields,iface:_this.props.iface,readOnly:readOnly,touchFriendly:_this.props.touchFriendly,updateField:_this.updateField,values:_this.props.editContext.feature.properties}),captchaButton,commitBar),deleteBar,busyDiv,childAttributeForm)});_defineProperty(_this,"setFormBusy",function(busy){_this.setState({busy:busy})});_defineProperty(_this,"updateField",function(key,value){var newProperties=_objectSpread(_objectSpread({},_this.props.editContext.feature.properties),{},_defineProperty({},key,value));var newFeature=_objectSpread(_objectSpread({},_this.props.editContext.feature),{},{properties:newProperties});_this.props.setEditContext(_this.props.editContext.id,{feature:newFeature,changed:true});_this.validateFieldConstraints(newFeature)});_defineProperty(_this,"editMapPrefix",function(){return(_this.props.editConfig.editDataset.match(/^[^.]+\./)||[""])[0]});_defineProperty(_this,"setRelationTables",function(relationTables){_this.setState({relationTables:relationTables})});_defineProperty(_this,"loadRelationValues",function(feature,callback){if(!isEmpty(_this.state.relationTables)){if(feature.id){var relTables=Object.entries(_this.state.relationTables).map(function(_ref){var _ref2=_slicedToArray(_ref,2),name=_ref2[0],entry=_ref2[1];if(entry.sortcol){return name+":"+entry.fk+":"+entry.sortcol}else{return name+":"+entry.fk}}).join(",");_this.props.iface.getRelations(_this.props.editConfig,feature.id,_this.props.map.projection,relTables,_this.props.theme.editConfig,function(relationValues){var newFeature=_objectSpread(_objectSpread({},feature),{},{relationValues:relationValues});callback(newFeature)})}else{var relationValues=_objectSpread(_objectSpread({},Object.entries(_this.state.relationTables).reduce(function(res,_ref3){var _ref4=_slicedToArray(_ref3,2),name=_ref4[0],entry=_ref4[1];return _objectSpread(_objectSpread({},res),{},_defineProperty({},name,{fk:entry.fk,features:[]}))},{})),feature.relationValues);var newFeature=_objectSpread(_objectSpread({},feature),{},{relationValues:relationValues});callback(newFeature)}}});_defineProperty(_this,"addRelationRecord",function(table){var newRelationValues=_objectSpread({},_this.props.editContext.feature.relationValues);var editConfig=_this.props.theme.editConfig[table.split(".").slice(-1)];var mapPrefix=(editConfig.editDataset.match(/^[^.]+\./)||[""])[0];getFeatureTemplate(editConfig,{type:"Feature",properties:{}},_this.props.iface,mapPrefix,_this.props.map.projection,function(newRelFeature){newRelFeature.__status__="empty";if(editConfig.geomType===null){newRelFeature.geometry=null}// If feature id is known, i.e. not when drawing new feature, set foreign key
9
9
  if(_this.props.editContext.action!=="Draw"){newRelFeature.properties[_this.state.relationTables[table].fk]=_this.props.editContext.feature.id}newRelationValues[table]=_objectSpread({},newRelationValues[table]);newRelationValues[table].features=newRelationValues[table].features.concat([newRelFeature]);var newFeature=_objectSpread(_objectSpread({},_this.props.editContext.feature),{},{relationValues:newRelationValues});_this.props.setEditContext(_this.props.editContext.id,{feature:newFeature,changed:true})})});_defineProperty(_this,"reorderRelationRecord",function(table,idx,dir){var nFeatures=_this.props.editContext.feature.relationValues[table].features.length;if(dir<0&&idx===0||dir>0&&idx>=nFeatures-1){return}var newRelationValues=_objectSpread({},_this.props.editContext.feature.relationValues);newRelationValues[table]=_objectSpread({},newRelationValues[table]);var newFeatures=newRelationValues[table].features.slice(0);var offset=dir<0?0:1;newFeatures.splice(idx-1+offset,2,newFeatures[idx+offset],newFeatures[idx-1+offset]);newFeatures[idx-1+offset].properties=_objectSpread({},newFeatures[idx-1+offset].properties);newFeatures[idx+offset].properties=_objectSpread({},newFeatures[idx+offset].properties);newFeatures[idx-1+offset].__status__=["new","empty"].includes(newFeatures[idx-1+offset].__status__)?"new":"changed";newFeatures[idx+offset].__status__=["new","empty"].includes(newFeatures[idx+offset].__status__)?"new":"changed";newRelationValues[table].features=newFeatures;var newFeature=_objectSpread(_objectSpread({},_this.props.editContext.feature),{},{relationValues:newRelationValues});_this.props.setEditContext(_this.props.editContext.id,{feature:newFeature,changed:true})});_defineProperty(_this,"removeRelationRecord",function(table,idx){var newRelationValues=_objectSpread({},_this.props.editContext.feature.relationValues);newRelationValues[table]=_objectSpread({},newRelationValues[table]);newRelationValues[table].features=newRelationValues[table].features.slice(0);var fieldStatus=newRelationValues[table].features[idx].__status__||"";// If field was new, delete it directly, else mark it as deleted
10
10
  if(["new","empty"].includes(fieldStatus)){newRelationValues[table].features.splice(idx,1)}else{newRelationValues[table].features[idx]=_objectSpread(_objectSpread({},newRelationValues[table].features[idx]),{},{__status__:fieldStatus.startsWith("deleted")?fieldStatus.substr(8):"deleted:"+fieldStatus})}var newFeature=_objectSpread(_objectSpread({},_this.props.editContext.feature),{},{relationValues:newRelationValues});_this.props.setEditContext(_this.props.editContext.id,{feature:newFeature,changed:true})});_defineProperty(_this,"updateRelationField",function(table,idx,key,value){var newRelationValues=_objectSpread({},_this.props.editContext.feature.relationValues);newRelationValues[table]=_objectSpread({},newRelationValues[table]);newRelationValues[table].features=newRelationValues[table].features.slice(0);newRelationValues[table].features[idx]=_objectSpread(_objectSpread({},newRelationValues[table].features[idx]),{},{properties:_objectSpread(_objectSpread({},newRelationValues[table].features[idx].properties),{},_defineProperty({},key,value)),__status__:["new","empty"].includes(newRelationValues[table].features[idx].__status__)?"new":"changed"});var newFeature=_objectSpread(_objectSpread({},_this.props.editContext.feature),{},{relationValues:newRelationValues});_this.props.setEditContext(_this.props.editContext.id,{feature:newFeature,changed:true})});_defineProperty(_this,"editRelationRecord",function(action,layer,dataset,idx,displayField){var editConfig=(_this.props.theme.editConfig||{})[layer];var feature=_this.props.editContext.feature.relationValues[dataset].features[idx];_this.setState({childEdit:{action:action,editConfig:editConfig,editContextId:":"+layer,dataset:dataset,idx:idx,feature:feature,finishCallback:_this.finishEditRelationRecord,displayField:displayField,hideDelete:true}})});_defineProperty(_this,"finishEditRelationRecord",function(feature){_this.props.clearEditContext(_this.state.childEdit.editContextId,_this.props.editContext.id);if(feature){var table=_this.state.childEdit.dataset;var idx=_this.state.childEdit.idx;var newRelationValues=_objectSpread({},_this.props.editContext.feature.relationValues);newRelationValues[table]=_objectSpread({},newRelationValues[table]);newRelationValues[table].features=newRelationValues[table].features.slice(0);newRelationValues[table].features[idx]=_objectSpread(_objectSpread({},feature),{},{properties:_objectSpread({},feature.properties)});// If feature id is known, i.e. not when drawing new feature, set foreign key
11
11
  var changed=_this.props.editContext.changed;var fk=_this.state.relationTables[table].fk;if(_this.props.editContext.action!=="Draw"&&feature.properties[fk]!==_this.props.editContext.feature.id){newRelationValues[table].features[idx].properties[fk]=_this.props.editContext.feature.id;newRelationValues[table].features[idx].__status__="changed";changed=true}var newFeature=_objectSpread(_objectSpread({},_this.props.editContext.feature),{},{relationValues:newRelationValues});_this.props.setEditContext(_this.props.editContext.id,{feature:newFeature,changed:changed})}_this.setState({childEdit:null})});_defineProperty(_this,"onDiscard",function(action){if(action==="Discard"){_this.props.setCurrentTaskBlocked(false);if(!_this.props.onDiscard||!_this.props.onDiscard()){if(_this.props.editContext.action==="Pick"){// Re-query the original feature
12
- _this.setState({busy:true});_this.props.iface.getFeatureById(_this.props.editConfig.editDataset,_this.props.editContext.feature.id,_this.props.map.projection,function(feature){_this.setState({busy:false});if(!isEmpty(_this.state.relationTables)){// Re-load relation values
12
+ _this.setState({busy:true});_this.props.iface.getFeatureById(_this.props.editConfig,_this.props.editContext.feature.id,_this.props.map.projection,function(feature){_this.setState({busy:false});if(!isEmpty(_this.state.relationTables)){// Re-load relation values
13
13
  _this.loadRelationValues(feature,function(newFeature){_this.props.setEditContext(_this.props.editContext.id,{feature:newFeature,changed:false})});// Re-validate feature field constraints
14
- _this.validateFieldConstraints(feature)}else{_this.props.setEditContext(_this.props.editContext.id,{feature:feature,changed:false})}})}else{var featureSkel={type:"Feature",properties:{}};var mapPrefix=(_this.props.editConfig.editDataset.match(/^[^.]+\./)||[""])[0];getFeatureTemplate(_this.props.editConfig,featureSkel,_this.props.iface,mapPrefix,_this.props.map.projection,function(feature){_this.props.setEditContext(_this.props.editContext.id,{feature:feature,changed:false})})}}}});_defineProperty(_this,"setupChangedObserver",function(form){_this.form=form;if(form){form.observer=new MutationObserver(function(){_this.setState({formValid:form.checkValidity()})});form.observer.observe(form,{subtree:true,childList:true,attributes:true})}});_defineProperty(_this,"formChanged",function(ev){var _ev$target;var form=ev.currentTarget;if((_ev$target=ev.target)!==null&&_ev$target!==void 0&&_ev$target.setCustomValidity){ev.target.setCustomValidity("")}if(form){_this.setState({formValid:form.checkValidity()});_this.props.setEditContext(_this.props.editContext.id,{changed:true})}});_defineProperty(_this,"validateFieldConstraints",function(feature){var validCallback=arguments.length>1&&arguments[1]!==undefined?arguments[1]:null;var invalidCallback=arguments.length>2&&arguments[2]!==undefined?arguments[2]:null;var constraintExpressions=_this.props.editConfig.fields.reduce(function(res,cur){var _cur$constraints;if((_cur$constraints=cur.constraints)!==null&&_cur$constraints!==void 0&&_cur$constraints.expression){var _cur$constraints2;return _objectSpread(_objectSpread({},res),{},_defineProperty({},cur.id,(_cur$constraints2=cur.constraints)===null||_cur$constraints2===void 0?void 0:_cur$constraints2.expression))}return res},{});parseExpressionsAsync(constraintExpressions,feature,_this.props.editConfig.editDataset,_this.props.iface,_this.editMapPrefix(),_this.props.map.projection,false).then(function(result){var valid=true;Object.entries(result).forEach(function(_ref5){var _ref6=_slicedToArray(_ref5,2),key=_ref6[0],value=_ref6[1];var element=_this.form.elements.namedItem(key);if(element){if(value===false){var _this$props$editConfi,_this$props$editConfi2;valid=false;element.setCustomValidity((_this$props$editConfi=(_this$props$editConfi2=_this.props.editConfig.fields.find(function(field){return field.id===key}))===null||_this$props$editConfi2===void 0||(_this$props$editConfi2=_this$props$editConfi2.constraints)===null||_this$props$editConfi2===void 0?void 0:_this$props$editConfi2.placeholder)!==null&&_this$props$editConfi!==void 0?_this$props$editConfi:LocaleUtils.tr("editing.contraintviolation"))}else{element.setCustomValidity("")}}});if(!valid){_this.setState({formValid:false});if(invalidCallback){invalidCallback()}}else{if(validCallback){validCallback()}}})});_defineProperty(_this,"onSubmit",function(ev){ev.preventDefault();_this.validateFieldConstraints(_this.props.editContext.feature,_this.doSubmit,function(){/* eslint-disable-next-line */alert(LocaleUtils.tr("editing.contraintviolation"))})});_defineProperty(_this,"doSubmit",function(){_this.setState({busy:true});var feature=_this.props.editContext.feature;// Ensure properties is not null
14
+ _this.validateFieldConstraints(feature)}else{_this.props.setEditContext(_this.props.editContext.id,{feature:feature,changed:false})}})}else{var featureSkel={type:"Feature",properties:{}};var mapPrefix=(_this.props.editConfig.editDataset.match(/^[^.]+\./)||[""])[0];getFeatureTemplate(_this.props.editConfig,featureSkel,_this.props.iface,mapPrefix,_this.props.map.projection,function(feature){_this.props.setEditContext(_this.props.editContext.id,{feature:feature,changed:false})})}}}});_defineProperty(_this,"setupChangedObserver",function(form){_this.form=form;if(form){form.observer=new MutationObserver(function(){_this.setState({formValid:form.checkValidity()})});form.observer.observe(form,{subtree:true,childList:true,attributes:true})}});_defineProperty(_this,"formChanged",function(ev){var _ev$target;var form=ev.currentTarget;if((_ev$target=ev.target)!==null&&_ev$target!==void 0&&_ev$target.setCustomValidity){ev.target.setCustomValidity("")}if(form){_this.setState({formValid:form.checkValidity()});_this.props.setEditContext(_this.props.editContext.id,{changed:true})}});_defineProperty(_this,"validateFieldConstraints",function(feature){var validCallback=arguments.length>1&&arguments[1]!==undefined?arguments[1]:null;var invalidCallback=arguments.length>2&&arguments[2]!==undefined?arguments[2]:null;var constraintExpressions=_this.props.editConfig.fields.reduce(function(res,cur){var _cur$constraints;if((_cur$constraints=cur.constraints)!==null&&_cur$constraints!==void 0&&_cur$constraints.expression){return[].concat(_toConsumableArray(res),[{field:cur.id,expression:cur.constraints.expression}])}return res},[]);parseExpressionsAsync(constraintExpressions,feature,_this.props.editConfig,_this.props.iface,_this.editMapPrefix(),_this.props.map.projection,false).then(function(result){var valid=true;var reasons=[];Object.entries(result).forEach(function(_ref5){var _ref6=_slicedToArray(_ref5,2),key=_ref6[0],value=_ref6[1];var element=_this.form.elements.namedItem(key);if(element){if(value===false){var _this$props$editConfi,_this$props$editConfi2;valid=false;var reason=(_this$props$editConfi=(_this$props$editConfi2=_this.props.editConfig.fields.find(function(field){return field.id===key}))===null||_this$props$editConfi2===void 0||(_this$props$editConfi2=_this$props$editConfi2.constraints)===null||_this$props$editConfi2===void 0?void 0:_this$props$editConfi2.placeholder)!==null&&_this$props$editConfi!==void 0?_this$props$editConfi:LocaleUtils.tr("editing.contraintviolation");reasons.push(reason);element.setCustomValidity(reason)}else{element.setCustomValidity("")}}});if(!valid){_this.setState({formValid:false});if(invalidCallback){invalidCallback(reasons)}}else{if(validCallback){validCallback()}}})});_defineProperty(_this,"onSubmit",function(ev){ev.preventDefault();_this.validateFieldConstraints(_this.props.editContext.feature,_this.doSubmit,function(reasons){/* eslint-disable-next-line */alert(LocaleUtils.tr("editing.contraintviolation")+":\n"+reasons.join("\n"))})});_defineProperty(_this,"doSubmit",function(){_this.setState({busy:true});var feature=_this.props.editContext.feature;// Ensure properties is not null
15
15
  feature=_objectSpread(_objectSpread({},feature),{},{type:"Feature",properties:_objectSpread({},feature.properties||{}),crs:{type:"name",properties:{name:CoordinatesUtils.toOgcUrnCrs(_this.props.map.projection)}}});// Omit geometry if it is read-only
16
16
  if(_this.props.editContext.geomReadOnly){delete feature.geometry}var curConfig=_this.props.editConfig;var mapPrefix=_this.editMapPrefix();var textNullValue=ConfigUtils.getConfigProp("editTextNullValue");// Keep relation values separate
17
17
  var relationValues=clone(feature.relationValues||{});delete feature.relationValues;var relationUploads={};var featureUploads={};// Collect all values from form fields
18
- var fieldnames=Array.from(_this.form.elements).map(function(element){return element.name}).filter(function(x){return x&&x!=="g-recaptcha-response"});fieldnames.forEach(function(name){var fieldConfig=(curConfig.fields||[]).find(function(field){return field.id===name})||{};var element=_this.form.elements.namedItem(name);if(element){var parts=name.split("__");var value=element.type==="radio"||element.type==="checkbox"?element.checked:element.value;var nullElements=["date","number","radio"];var nullFieldTypes=["date","number"];if(parts.length>=3){var _nrelFieldConfig$data;// Relation value
18
+ var fieldnames=Array.from(_this.form.elements).map(function(element){return element.name}).filter(function(x){return x&&x!=="g-recaptcha-response"});fieldnames.forEach(function(name){var element=_this.form.elements.namedItem(name);if(element){var parts=name.split("__");var value=element.type==="radio"||element.type==="checkbox"?element.checked:element.value;var nullElements=["date","number","radio"];var nullFieldTypes=["date","number"];if(parts.length>=3){var _this$props$theme$edi,_this$props$theme$edi2,_this$props$theme$edi3;// Relation value
19
19
  // Usually <table>__<field>__<index>, but <field> might also contain __ (i.e. upload__user)
20
- var tablename=parts[0];var datasetname=mapPrefix+tablename;var field=parts.slice(1,parts.length-1).join("__");var nrelFieldConfig=(_this.props.theme.editConfig[tablename].fields||[]).find(function(f){return f.id===field})||{};var nrelFieldDataType=(_nrelFieldConfig$data=nrelFieldConfig.data_type)!==null&&_nrelFieldConfig$data!==void 0?_nrelFieldConfig$data:fieldConfig.type;if((element instanceof RadioNodeList||nullElements.includes(element.type)||nullFieldTypes.includes(nrelFieldDataType))&&element.value===""){// Set empty value to null instead of empty string
20
+ var tablename=parts[0];var datasetname=mapPrefix+tablename;var field=parts.slice(1,parts.length-1).join("__");var index=parseInt(parts[parts.length-1],10);var nrelFieldConfig=(_this$props$theme$edi=(_this$props$theme$edi2=_this.props.theme.editConfig[tablename].fields)===null||_this$props$theme$edi2===void 0||(_this$props$theme$edi3=_this$props$theme$edi2.find)===null||_this$props$theme$edi3===void 0?void 0:_this$props$theme$edi3.call(_this$props$theme$edi2,function(f){return f.id===field}))!==null&&_this$props$theme$edi!==void 0?_this$props$theme$edi:{};var nrelFieldDataType=nrelFieldConfig.data_type;if(nrelFieldConfig.expression){// Skip virtual fields
21
+ delete relationValues[datasetname].features[index][field];return}if((element instanceof RadioNodeList||nullElements.includes(element.type)||nullFieldTypes.includes(nrelFieldDataType))&&element.value===""){// Set empty value to null instead of empty string
21
22
  value=null}if(nrelFieldDataType==="text"&&textNullValue!==undefined&&element.value===textNullValue){// Convert text NULL to null
22
- value=null}var index=parseInt(parts[parts.length-1],10);// relationValues for table must exist as rows are either pre-existing or were added
23
- if(!(field in relationValues[datasetname].features[index].properties)){relationValues[datasetname].features[index].defaultedProperties=[].concat(_toConsumableArray(relationValues[datasetname].features[index].defaultedProperties||[]),[field])}relationValues[datasetname].features[index].properties[field]=value;if(relationValues[datasetname].features[index].__status__==="empty"){relationValues[datasetname].features[index].__status__="new"}if(element.type==="file"&&element.files.length>0){relationUploads[name]=element.files[0];relationValues[datasetname].features[index].properties[field]=""}else if(element.type==="hidden"&&element.value.startsWith("data:")){var filename=element.dataset.filename;var type=element.value.match(/image\/\w+/)[0];if(!filename){var ext=type.split("/")[1];filename=uuidv1()+"."+ext}relationUploads[name]=new File([_this.dataUriToBlob(element.value)],filename,{type:type});relationValues[datasetname].features[index].properties[field]=""}}else{var _fieldConfig$data_typ;var dataType=(_fieldConfig$data_typ=fieldConfig.data_type)!==null&&_fieldConfig$data_typ!==void 0?_fieldConfig$data_typ:fieldConfig.type;if((element instanceof RadioNodeList||nullElements.includes(element.type)||nullFieldTypes.includes(dataType))&&element.value===""){// Set empty value to null instead of empty string
23
+ value=null}// relationValues for table must exist as rows are either pre-existing or were added
24
+ if(!(field in relationValues[datasetname].features[index].properties)){relationValues[datasetname].features[index].defaultedProperties=[].concat(_toConsumableArray(relationValues[datasetname].features[index].defaultedProperties||[]),[field])}relationValues[datasetname].features[index].properties[field]=value;if(relationValues[datasetname].features[index].__status__==="empty"){relationValues[datasetname].features[index].__status__="new"}if(element.type==="file"&&element.files.length>0){relationUploads[name]=element.files[0];relationValues[datasetname].features[index].properties[field]=""}else if(element.type==="hidden"&&element.value.startsWith("data:")){var filename=element.dataset.filename;var type=element.value.match(/image\/\w+/)[0];if(!filename){var ext=type.split("/")[1];filename=uuidv1()+"."+ext}relationUploads[name]=new File([_this.dataUriToBlob(element.value)],filename,{type:type});relationValues[datasetname].features[index].properties[field]=""}}else{var _fieldConfig$data_typ;var fieldConfig=(curConfig.fields||[]).find(function(field){return field.id===name})||{};if(fieldConfig.expression){// Skip virtual fields
25
+ delete feature.properties[name];return}var dataType=(_fieldConfig$data_typ=fieldConfig.data_type)!==null&&_fieldConfig$data_typ!==void 0?_fieldConfig$data_typ:fieldConfig.type;if((element instanceof RadioNodeList||nullElements.includes(element.type)||nullFieldTypes.includes(dataType))&&element.value===""){// Set empty value to null instead of empty string
24
26
  value=null}if(dataType==="text"&&textNullValue!==undefined&&element.value===textNullValue){// Convert text NULL to null
25
27
  value=null}if(!(name in feature.properties)){feature.defaultedProperties=[].concat(_toConsumableArray(feature.defaultedProperties||[]),[name])}feature.properties[name]=value;if(element.type==="file"&&element.files.length>0){featureUploads[name]=element.files[0];feature.properties[name]=""}else if(element.type==="hidden"&&element.value.startsWith("data:")){var _filename=element.dataset.filename;var _type=element.value.match(/image\/\w+/)[0];if(!_filename){var _ext=_type.split("/")[1];_filename=uuidv1()+"."+_ext}featureUploads[name]=new File([_this.dataUriToBlob(element.value)],_filename,{type:_type});feature.properties[name]=""}}}});// Set relation values CRS and sort index if necessary
26
- Object.keys(relationValues).forEach(function(relTable){relationValues[relTable].features=relationValues[relTable].features.filter(function(relFeature){return relFeature.__status__!=="empty"}).map(function(relFeature,idx){var newRelFeature=_objectSpread(_objectSpread({},relFeature),{},{crs:{type:"name",properties:{name:CoordinatesUtils.toOgcUrnCrs(_this.props.map.projection)}}});var sortcol=_this.state.relationTables[relTable].sortcol;var noreorder=_this.state.relationTables[relTable].noreorder;if(sortcol&&!noreorder){newRelFeature.__status__=feature.__status__||(newRelFeature.properties[sortcol]!==idx?"changed":"");newRelFeature.properties[sortcol]=idx}return newRelFeature})});feature.relationValues=relationValues;var featureData=new FormData;featureData.set("feature",JSON.stringify(feature));Object.entries(featureUploads).forEach(function(_ref7){var _ref8=_slicedToArray(_ref7,2),key=_ref8[0],value=_ref8[1];return featureData.set("file:"+key,value)});Object.entries(relationUploads).forEach(function(_ref9){var _ref10=_slicedToArray(_ref9,2),key=_ref10[0],value=_ref10[1];return featureData.set("relfile:"+mapPrefix+key,value)});if(_this.state.captchaResponse){featureData.set("g-recaptcha-response",_this.state.captchaResponse)}if(_this.props.editContext.action==="Draw"){if(_this.props.iface.addFeatureMultipart){_this.props.iface.addFeatureMultipart(_this.props.editConfig.editDataset,featureData,function(success,result){return _this.featureCommited(success,result)})}else{_this.props.iface.addFeature(_this.props.editConfig.editDataset,feature,_this.props.map.projection,function(success,result){return _this.featureCommited(success,result)})}}else if(_this.props.editContext.action==="Pick"){if(_this.props.iface.editFeatureMultipart){_this.props.iface.editFeatureMultipart(_this.props.editConfig.editDataset,feature.id,featureData,function(success,result){return _this.featureCommited(success,result)})}else{_this.props.iface.editFeature(_this.props.editConfig.editDataset,feature,_this.props.map.projection,function(success,result){return _this.featureCommited(success,result)})}}});_defineProperty(_this,"featureCommited",function(success,result){if(!success){_this.commitFinished(false,result);return}// Check for relation records which failed to commit
28
+ Object.keys(relationValues).forEach(function(relTable){relationValues[relTable].features=relationValues[relTable].features.filter(function(relFeature){return relFeature.__status__!=="empty"}).map(function(relFeature,idx){var newRelFeature=_objectSpread(_objectSpread({},relFeature),{},{crs:{type:"name",properties:{name:CoordinatesUtils.toOgcUrnCrs(_this.props.map.projection)}}});var sortcol=_this.state.relationTables[relTable].sortcol;var noreorder=_this.state.relationTables[relTable].noreorder;if(sortcol&&!noreorder){newRelFeature.__status__=feature.__status__||(newRelFeature.properties[sortcol]!==idx?"changed":"");newRelFeature.properties[sortcol]=idx}return newRelFeature})});feature.relationValues=relationValues;var featureData=new FormData;featureData.set("feature",JSON.stringify(feature));Object.entries(featureUploads).forEach(function(_ref7){var _ref8=_slicedToArray(_ref7,2),key=_ref8[0],value=_ref8[1];return featureData.set("file:"+key,value)});Object.entries(relationUploads).forEach(function(_ref9){var _ref10=_slicedToArray(_ref9,2),key=_ref10[0],value=_ref10[1];return featureData.set("relfile:"+mapPrefix+key,value)});if(_this.state.captchaResponse){featureData.set("g-recaptcha-response",_this.state.captchaResponse)}if(_this.props.editContext.action==="Draw"){if(_this.props.iface.addFeatureMultipart){_this.props.iface.addFeatureMultipart(_this.props.editConfig,_this.props.map.projection,featureData,function(success,result){return _this.featureCommited(success,result)})}else{_this.props.iface.addFeature(_this.props.editConfig.editDataset,feature,_this.props.map.projection,function(success,result){return _this.featureCommited(success,result)})}}else if(_this.props.editContext.action==="Pick"){if(_this.props.iface.editFeatureMultipart){_this.props.iface.editFeatureMultipart(_this.props.editConfig,_this.props.map.projection,feature.id,featureData,function(success,result){return _this.featureCommited(success,result)})}else{_this.props.iface.editFeature(_this.props.editConfig.editDataset,feature,_this.props.map.projection,function(success,result){return _this.featureCommited(success,result)})}}});_defineProperty(_this,"featureCommited",function(success,result){if(!success){_this.commitFinished(false,result);return}// Check for relation records which failed to commit
27
29
  var relationValueErrors=Object.values(result.relationValues||[]).find(function(entry){return(entry.features||[]).find(function(f){return f.error})})!==undefined;if(relationValueErrors){// Relation values commit failed, switch to pick to avoid adding feature again on next attempt
28
- _this.commitFinished(false,LocaleUtils.tr("editing.relationcommitfailed"));_this.props.setEditContext(_this.props.editContext.id,{action:"Pick",feature:result,changed:true})}else{_this.commitFinished(true,result)}});_defineProperty(_this,"deleteClicked",function(){_this.setState({deleteClicked:true});_this.props.setCurrentTaskBlocked(true,LocaleUtils.tr("editing.unsavedchanged"))});_defineProperty(_this,"deleteFeature",function(action){if(action==="Yes"){_this.setState({busy:true});var recaptchaResponse=null;if(_this.state.captchaResponse){recaptchaResponse=_this.state.captchaResponse}_this.props.iface.deleteFeature(_this.props.editConfig.editDataset,_this.props.editContext.feature.id,_this.deleteFinished,recaptchaResponse)}else{_this.setState({deleteClicked:false});_this.props.setCurrentTaskBlocked(false)}});_defineProperty(_this,"commitFinished",function(success,result){_this.setState({busy:false});if(success){_this.props.refreshLayer(function(layer){return layer.role===LayerRole.THEME});_this.props.setCurrentTaskBlocked(false);if(!_this.props.onCommit||!_this.props.onCommit(result)){if(!isEmpty(_this.state.relationTables)){// Re-load relation values
30
+ _this.commitFinished(false,LocaleUtils.tr("editing.relationcommitfailed"));_this.props.setEditContext(_this.props.editContext.id,{action:"Pick",feature:result,changed:true})}else{_this.commitFinished(true,result)}});_defineProperty(_this,"deleteClicked",function(){_this.setState({deleteClicked:true});_this.props.setCurrentTaskBlocked(true,LocaleUtils.tr("editing.unsavedchanged"))});_defineProperty(_this,"deleteFeature",function(action){if(action==="Yes"){_this.setState({busy:true});var recaptchaResponse=null;if(_this.state.captchaResponse){recaptchaResponse=_this.state.captchaResponse}_this.props.iface.deleteFeature(_this.props.editConfig,_this.props.editContext.feature.id,_this.deleteFinished,recaptchaResponse)}else{_this.setState({deleteClicked:false});_this.props.setCurrentTaskBlocked(false)}});_defineProperty(_this,"commitFinished",function(success,result){_this.setState({busy:false});if(success){_this.props.refreshLayer(function(layer){return layer.role===LayerRole.THEME});_this.props.setCurrentTaskBlocked(false);if(!_this.props.onCommit||!_this.props.onCommit(result)){if(!isEmpty(_this.state.relationTables)){// Re-load relation values
29
31
  _this.loadRelationValues(result,function(newFeature){_this.props.setEditContext(_this.props.editContext.id,{action:"Pick",feature:newFeature,changed:false})});// Re-validate feature field constraints
30
32
  _this.validateFieldConstraints(result)}else{_this.props.setEditContext(_this.props.editContext.id,{action:"Pick",feature:result,changed:false})}}}else{// eslint-disable-next-line
31
33
  alert(result)}});_defineProperty(_this,"deleteFinished",function(success,result){_this.setState({busy:false});if(success){_this.setState({deleteClicked:false});_this.props.setCurrentTaskBlocked(false);_this.props.refreshLayer(function(layer){return layer.role===LayerRole.THEME});if(!_this.props.onDelete||!_this.props.onDelete(result)){_this.props.setEditContext(_this.props.editContext.id,{feature:null,changed:false})}}else{// eslint-disable-next-line
@@ -4,14 +4,15 @@ function _typeof(o){"@babel/helpers - typeof";return _typeof="function"==typeof
4
4
  *
5
5
  * This source code is licensed under the BSD-style license found in the
6
6
  * 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,{KeyValCache}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{ExpressionFeatureCache,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;KeyValCache.clear();ExpressionFeatureCache.clear();var bbox=_this.state.limitToExtent?_this.props.mapBbox.bounds:null;_this.props.iface.getFeatures(_this.editLayerId(selectedLayer),_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,"editLayerId",function(layerId){if(_this.props.theme&&_this.props.theme.editConfig&&_this.props.theme.editConfig[layerId]){return _this.props.theme.editConfig[layerId].editDataset||layerId}return layerId});_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 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){var mapPrefix=(currentEditConfig.editDataset.match(/^[^.]+\./)||[""])[0];filterExpr=parseExpression(field.filterExpression,feature,_this.editLayerId(_this.state.selectedLayer),_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,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:_this.editLayerId(_this.state.selectedLayer),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});features.forEach(function(feature){_this.props.iface.deleteFeature(_this.editLayerId(state.selectedLayer),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)}}});// Omit geometry if it is read-only
12
- var editConfig=_this.props.theme.editConfig||{};var currentEditConfig=editConfig[_this.state.loadedLayer];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(_this.editLayerId(_this.state.selectedLayer),featureData,function(success,result){return _this.featureCommited(success,result)})}else{_this.props.iface.editFeatureMultipart(_this.editLayerId(_this.state.loadedLayer),feature.id,featureData,function(success,result){return _this.featureCommited(success,result)})}});_defineProperty(_this,"featureCommited",function(success,result){if(!success){// eslint-disable-next-line
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,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
13
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
14
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
15
- 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(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")});_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
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")});_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
16
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
17
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.reduce(function(res,field){if(field.id!=="id"){res.push(field)}return res},[]);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")}},/*#__PURE__*/React.createElement("span",null,/*#__PURE__*/React.createElement("span",{className:"attribtable-table-headername"},"id"),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:field.name},/*#__PURE__*/React.createElement("span",null,_this2.renderColumnResizeHandle(idx+1,"l"),/*#__PURE__*/React.createElement("span",{className:"attribtable-table-headername"},field.name),_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"},"id"),fields.map(function(field){return/*#__PURE__*/React.createElement("option",{key:field.id,value:field.id},field.name)})),/*#__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 _match$sublayer$title,_match$sublayer;var layerName=editConfig[layerId].layerName;var match=LayerUtils.searchLayer(_this2.props.layers,_this2.props.theme.url,layerName);return/*#__PURE__*/React.createElement("option",{key:layerId,value:layerId},(_match$sublayer$title=match===null||match===void 0||(_match$sublayer=match.sublayer)===null||_match$sublayer===void 0?void 0:_match$sublayer.title)!==null&&_match$sublayer$title!==void 0?_match$sublayer$title:layerName)})):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 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,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);
@@ -1,11 +1,11 @@
1
- var _KeyValCache;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 _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 _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 _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 _classCallCheck(a,n){if(!(a instanceof n))throw new TypeError("Cannot call a class as a function")}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)}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 _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)}/**
2
2
  * Copyright 2024 Sourcepole AG
3
3
  * All rights reserved.
4
4
  *
5
5
  * This source code is licensed under the BSD-style license found in the
6
6
  * LICENSE file in the root directory of this source tree.
7
- */import React from"react";import PropTypes from"prop-types";import{v5 as uuidv5}from"uuid";import LocaleUtils from"../utils/LocaleUtils";import"./style/EditComboField.css";var UUID_NS="5ae5531d-8e21-4456-b45d-77e9840a5bb7";export var KeyValCache=/*#__PURE__*/_createClass(function KeyValCache(){_classCallCheck(this,KeyValCache)});_KeyValCache=KeyValCache;_defineProperty(KeyValCache,"store",{});_defineProperty(KeyValCache,"requests",{});_defineProperty(KeyValCache,"get",function(editIface,keyvalrel,filterExpr,callback){var key=keyvalrel+uuidv5(JSON.stringify(filterExpr!==null&&filterExpr!==void 0?filterExpr:null),UUID_NS);if(key in _KeyValCache.store){callback(_KeyValCache.store[key])}else if(key in _KeyValCache.requests){_KeyValCache.requests[key].push(callback)}else{_KeyValCache.requests[key]=[callback];editIface.getKeyValues(keyvalrel,function(result){if(key in _KeyValCache.requests){var dataSet=keyvalrel.split(":")[0];if(result.keyvalues&&result.keyvalues[dataSet]){var values=result.keyvalues[dataSet].map(function(entry){return{value:entry.key,label:entry.value}});_KeyValCache.store[key]=values}else{_KeyValCache.store[key]=[]}_KeyValCache.requests[key].forEach(function(cb){return cb(_KeyValCache.store[key])});delete _KeyValCache.requests[key]}},filterExpr?[filterExpr]:null)}});_defineProperty(KeyValCache,"getSync",function(keyvalrel,filterExpr){var key=keyvalrel+uuidv5(JSON.stringify(filterExpr!==null&&filterExpr!==void 0?filterExpr:null),UUID_NS);if(key in _KeyValCache.store){return _KeyValCache.store[key]}else{return[]}});_defineProperty(KeyValCache,"clear",function(){_KeyValCache.store={};_KeyValCache.requests={}});var EditComboField=/*#__PURE__*/function(_React$Component){function EditComboField(){var _this;_classCallCheck(this,EditComboField);for(var _len=arguments.length,args=new Array(_len),_key=0;_key<_len;_key++){args[_key]=arguments[_key]}_this=_callSuper(this,EditComboField,[].concat(args));_defineProperty(_this,"state",{showPlaceholder:true,values:[]});_defineProperty(_this,"hasEmptyValue",function(values){for(var i=0;i<values.length;++i){if(typeof values[i]==="string"){if(values[i]===""){return true}}else if(values[i].value===""){return true}}return false});_defineProperty(_this,"renderMultiSelect",function(){var items=new Set;try{items=new Set(JSON.parse("["+_this.props.value.slice(1,-1)+"]"))}catch(e){// pass
7
+ */import React from"react";import PropTypes from"prop-types";import{KeyValCache}from"../utils/EditingUtils";import LocaleUtils from"../utils/LocaleUtils";import"./style/EditComboField.css";var EditComboField=/*#__PURE__*/function(_React$Component){function EditComboField(){var _this;_classCallCheck(this,EditComboField);for(var _len=arguments.length,args=new Array(_len),_key=0;_key<_len;_key++){args[_key]=arguments[_key]}_this=_callSuper(this,EditComboField,[].concat(args));_defineProperty(_this,"state",{showPlaceholder:true,values:[]});_defineProperty(_this,"hasEmptyValue",function(values){for(var i=0;i<values.length;++i){if(typeof values[i]==="string"){if(values[i]===""){return true}}else if(values[i].value===""){return true}}return false});_defineProperty(_this,"renderMultiSelect",function(){var items=new Set;try{items=new Set(JSON.parse("["+_this.props.value.slice(1,-1)+"]"))}catch(e){// pass
8
8
  }var serializeValue=function serializeValue(value,enabled){if(enabled){return"{"+JSON.stringify(_toConsumableArray(items).concat([value])).slice(1,-1)+"}"}else{return"{"+JSON.stringify(_toConsumableArray(items).filter(function(x){return x!==value})).slice(1,-1)+"}"}};return/*#__PURE__*/React.createElement("div",{className:"edit-multi-select"},_this.state.values.map(function(item,index){var _this$itemValueLabel=_this.itemValueLabel(item),value=_this$itemValueLabel.value,label=_this$itemValueLabel.label;return/*#__PURE__*/React.createElement("div",{key:_this.props.fieldId+index},/*#__PURE__*/React.createElement("label",null,/*#__PURE__*/React.createElement("input",{checked:items.has(value),onChange:function onChange(ev){return _this.props.updateField(_this.props.fieldId,serializeValue(value,ev.target.checked))},type:"checkbox"}),label))}))});_defineProperty(_this,"renderComboSelect",function(){var _this$props$placehold;return/*#__PURE__*/React.createElement("select",{disabled:_this.props.readOnly,name:_this.props.name,onChange:function onChange(ev){return _this.props.updateField(_this.props.fieldId,ev.target.selectedIndex===0&&_this.state.showPlaceholder?null:ev.target.value)},required:_this.props.required,style:_this.props.style,value:String(_this.props.value)},_this.state.showPlaceholder?/*#__PURE__*/React.createElement("option",{disabled:_this.props.required,value:""},(_this$props$placehold=_this.props.placeholder)!==null&&_this$props$placehold!==void 0?_this$props$placehold:LocaleUtils.tr("editing.select")):null,_this.state.values.map(function(item,index){var _this$itemValueLabel2=_this.itemValueLabel(item),value=_this$itemValueLabel2.value,label=_this$itemValueLabel2.label;return/*#__PURE__*/React.createElement("option",{key:_this.props.fieldId+index,value:String(value)},label)}))});_defineProperty(_this,"itemValueLabel",function(item){var value="";var label="";if(typeof item==="string"){value=label=item}else{value=item.value;label=item.label}return{value:value,label:label}});return _this}_inherits(EditComboField,_React$Component);return _createClass(EditComboField,[{key:"componentDidMount",value:function componentDidMount(){var _this2=this;if(this.props.values){// eslint-disable-next-line
9
- this.setState({values:this.props.values,showPlaceholder:!this.hasEmptyValue(this.props.values)})}else if(this.props.keyvalrel){var _this$props$filterExp;KeyValCache.get(this.props.editIface,this.props.keyvalrel,(_this$props$filterExp=this.props.filterExpr)!==null&&_this$props$filterExp!==void 0?_this$props$filterExp:null,function(values){// eslint-disable-next-line
10
- _this2.setState({values:values,showPlaceholder:!_this2.hasEmptyValue(values)})})}}},{key:"componentDidUpdate",value:function componentDidUpdate(prevProps){var _this3=this;if(this.props.keyvalrel&&this.props.filterExpr!==prevProps.filterExpr){var _this$props$filterExp2;KeyValCache.get(this.props.editIface,this.props.keyvalrel,(_this$props$filterExp2=this.props.filterExpr)!==null&&_this$props$filterExp2!==void 0?_this$props$filterExp2:null,function(values){// eslint-disable-next-line
9
+ this.setState({values:this.props.values,showPlaceholder:!this.hasEmptyValue(this.props.values)})}else if(this.props.keyvalrel){var _this$props$filterExp;KeyValCache.get(this.props.editIface,this.props.keyvalrel,(_this$props$filterExp=this.props.filterExpr)!==null&&_this$props$filterExp!==void 0?_this$props$filterExp:null).then(function(values){// eslint-disable-next-line
10
+ _this2.setState({values:values,showPlaceholder:!_this2.hasEmptyValue(values)})})}}},{key:"componentDidUpdate",value:function componentDidUpdate(prevProps){var _this3=this;if(this.props.keyvalrel&&this.props.filterExpr!==prevProps.filterExpr){var _this$props$filterExp2;KeyValCache.get(this.props.editIface,this.props.keyvalrel,(_this$props$filterExp2=this.props.filterExpr)!==null&&_this$props$filterExp2!==void 0?_this$props$filterExp2:null).then(function(values){// eslint-disable-next-line
11
11
  _this3.setState({values:values,showPlaceholder:!_this3.hasEmptyValue(values)})})}}},{key:"render",value:function render(){if(this.props.multiSelect){return this.renderMultiSelect()}else{return this.renderComboSelect()}}}])}(React.Component);_defineProperty(EditComboField,"propTypes",{editIface:PropTypes.object,fieldId:PropTypes.string,filterExpr:PropTypes.array,keyvalrel:PropTypes.string,multiSelect:PropTypes.bool,name:PropTypes.string,placeholder:PropTypes.string,readOnly:PropTypes.bool,required:PropTypes.bool,style:PropTypes.object,updateField:PropTypes.func,value:PropTypes.oneOfType([PropTypes.string,PropTypes.number]),values:PropTypes.array});export{EditComboField as default};
@@ -4,7 +4,7 @@ function _typeof(o){"@babel/helpers - typeof";return _typeof="function"==typeof
4
4
  *
5
5
  * This source code is licensed under the BSD-style license found in the
6
6
  * LICENSE file in the root directory of this source tree.
7
- */import React from"react";import{connect}from"react-redux";import PropTypes from"prop-types";import{setEditContext}from"../actions/editing";import{LayerRole,addLayerFeatures,removeLayer}from"../actions/layers";import{getFeatureTemplate}from"../utils/EditingUtils";import LocaleUtils from"../utils/LocaleUtils";import MapUtils from"../utils/MapUtils";import AttributeForm from"./AttributeForm";import"./style/LinkFeatureForm.css";var LinkFeatureForm=/*#__PURE__*/function(_React$Component){function LinkFeatureForm(){var _this;_classCallCheck(this,LinkFeatureForm);for(var _len=arguments.length,args=new Array(_len),_key=0;_key<_len;_key++){args[_key]=arguments[_key]}_this=_callSuper(this,LinkFeatureForm,[].concat(args));_defineProperty(_this,"state",{editContext:{},pickedFeatures:null,highlightedFeature:null});_defineProperty(_this,"childPickQuery",function(coordinate){var scale=Math.round(MapUtils.computeForZoom(_this.props.map.scales,_this.props.map.zoom));_this.props.iface.getFeature(_this.props.editConfig.editDataset,coordinate,_this.props.map.projection,scale,96,function(featureCollection){var features=featureCollection?featureCollection.features:null;if(features&&features.length===1){if(!_this.props.pickFilter){_this.props.finished(features[0])}else{var newFeature=_this.props.pickFilter(features[0]);if(newFeature){_this.props.finished(newFeature)}}}else{_this.setState({pickedFeatures:features})}})});_defineProperty(_this,"finish",function(){var editContext=_this.props.editing.contexts[_this.props.editContextId];_this.props.finished(editContext.feature)});_defineProperty(_this,"hoverFeature",function(feature){var layer={id:_this.props.editContextId+"-pick-selection",role:LayerRole.SELECTION};_this.props.addLayerFeatures(layer,[feature],true);_this.setState({highlightedFeature:feature.id})});_defineProperty(_this,"unhoverFeature",function(feature){if(_this.state.highlightedFeature===feature.id){_this.props.removeLayer(_this.props.editContextId+"-pick-selection");_this.setState({highlightedFeature:null})}});_defineProperty(_this,"pickFeatureSelected",function(feature){_this.unhoverFeature(feature);if(!_this.props.pickFilter){_this.props.finished(feature)}else{var newFeature=_this.props.pickFilter(feature);if(newFeature){_this.props.finished(newFeature)}}});_defineProperty(_this,"onDiscard",function(){var editContext=_this.props.editing.contexts[_this.props.editContextId];if(editContext.action==="Draw"){// Discarded draw = cancel
8
- _this.props.finished(null)}});return _this}_inherits(LinkFeatureForm,_React$Component);return _createClass(LinkFeatureForm,[{key:"componentDidMount",value:function componentDidMount(){var _this2=this;if(this.props.action==="Edit"){if(this.props.feature){this.props.setEditContext(this.props.editContextId,{action:"Pick",feature:this.props.feature,geomType:this.props.editConfig.geomType})}else{this.props.iface.getFeatureById(this.props.editConfig.editDataset,this.props.featureId,this.props.map.projection,function(result){if(result){_this2.props.setEditContext(_this2.props.editContextId,{action:"Pick",feature:result,geomType:_this2.props.editConfig.geomType})}})}}else if(this.props.action==="Create"){var featureSkel=_objectSpread({type:"Feature",properties:{}},this.props.feature);var mapPrefix=(this.props.editConfig.editDataset.match(/^[^.]+\./)||[""])[0];getFeatureTemplate(this.props.editConfig,featureSkel,this.props.iface,mapPrefix,this.props.map.projection,function(feature){_this2.props.setEditContext(_this2.props.editContextId,{action:"Draw",geomType:_this2.props.editConfig.geomType,feature:feature})})}else if(this.props.action==="Pick"){this.props.setEditContext(this.props.editContextId,{action:null})}}},{key:"componentDidUpdate",value:function componentDidUpdate(prevProps){// Handle drawPick
7
+ */import React from"react";import{connect}from"react-redux";import PropTypes from"prop-types";import{setEditContext}from"../actions/editing";import{LayerRole,addLayerFeatures,removeLayer}from"../actions/layers";import{getFeatureTemplate}from"../utils/EditingUtils";import LocaleUtils from"../utils/LocaleUtils";import MapUtils from"../utils/MapUtils";import AttributeForm from"./AttributeForm";import"./style/LinkFeatureForm.css";var LinkFeatureForm=/*#__PURE__*/function(_React$Component){function LinkFeatureForm(){var _this;_classCallCheck(this,LinkFeatureForm);for(var _len=arguments.length,args=new Array(_len),_key=0;_key<_len;_key++){args[_key]=arguments[_key]}_this=_callSuper(this,LinkFeatureForm,[].concat(args));_defineProperty(_this,"state",{editContext:{},pickedFeatures:null,highlightedFeature:null});_defineProperty(_this,"childPickQuery",function(coordinate){var scale=Math.round(MapUtils.computeForZoom(_this.props.map.scales,_this.props.map.zoom));_this.props.iface.getFeature(_this.props.editConfig,coordinate,_this.props.map.projection,scale,96,function(featureCollection){var features=featureCollection?featureCollection.features:null;if(features&&features.length===1){if(!_this.props.pickFilter){_this.props.finished(features[0])}else{var newFeature=_this.props.pickFilter(features[0]);if(newFeature){_this.props.finished(newFeature)}}}else{_this.setState({pickedFeatures:features})}})});_defineProperty(_this,"finish",function(){var editContext=_this.props.editing.contexts[_this.props.editContextId];_this.props.finished(editContext.feature)});_defineProperty(_this,"hoverFeature",function(feature){var layer={id:_this.props.editContextId+"-pick-selection",role:LayerRole.SELECTION};_this.props.addLayerFeatures(layer,[feature],true);_this.setState({highlightedFeature:feature.id})});_defineProperty(_this,"unhoverFeature",function(feature){if(_this.state.highlightedFeature===feature.id){_this.props.removeLayer(_this.props.editContextId+"-pick-selection");_this.setState({highlightedFeature:null})}});_defineProperty(_this,"pickFeatureSelected",function(feature){_this.unhoverFeature(feature);if(!_this.props.pickFilter){_this.props.finished(feature)}else{var newFeature=_this.props.pickFilter(feature);if(newFeature){_this.props.finished(newFeature)}}});_defineProperty(_this,"onDiscard",function(){var editContext=_this.props.editing.contexts[_this.props.editContextId];if(editContext.action==="Draw"){// Discarded draw = cancel
8
+ _this.props.finished(null)}});return _this}_inherits(LinkFeatureForm,_React$Component);return _createClass(LinkFeatureForm,[{key:"componentDidMount",value:function componentDidMount(){var _this2=this;if(this.props.action==="Edit"){if(this.props.feature){this.props.setEditContext(this.props.editContextId,{action:"Pick",feature:this.props.feature,geomType:this.props.editConfig.geomType})}else{this.props.iface.getFeatureById(this.props.editConfig,this.props.featureId,this.props.map.projection,function(result){if(result){_this2.props.setEditContext(_this2.props.editContextId,{action:"Pick",feature:result,geomType:_this2.props.editConfig.geomType})}})}}else if(this.props.action==="Create"){var featureSkel=_objectSpread({type:"Feature",properties:{}},this.props.feature);var mapPrefix=(this.props.editConfig.editDataset.match(/^[^.]+\./)||[""])[0];getFeatureTemplate(this.props.editConfig,featureSkel,this.props.iface,mapPrefix,this.props.map.projection,function(feature){_this2.props.setEditContext(_this2.props.editContextId,{action:"Draw",geomType:_this2.props.editConfig.geomType,feature:feature})})}else if(this.props.action==="Pick"){this.props.setEditContext(this.props.editContextId,{action:null})}}},{key:"componentDidUpdate",value:function componentDidUpdate(prevProps){// Handle drawPick
9
9
  var editContext=this.props.editing.contexts[this.props.editContextId];if(editContext&&editContext.action===null&&this.props.map.click&&this.props.map.click!==prevProps.map.click){this.childPickQuery(this.props.map.click.coordinate)}}},{key:"render",value:function render(){var _this3=this;var editContext=this.props.editing.contexts[this.props.editContextId];if(!editContext){return null}if(editContext.action===null){// Picking
10
10
  return/*#__PURE__*/React.createElement("div",{className:"link-feature-form"},!this.state.pickedFeatures?/*#__PURE__*/React.createElement("div",{className:"link-feature-form-hint"},/*#__PURE__*/React.createElement("span",null,LocaleUtils.tr("linkfeatureform.pickhint"))):/*#__PURE__*/React.createElement("div",{className:"link-feature-form-feature-list"},this.state.pickedFeatures.map(function(feature){var _feature$properties$_;return/*#__PURE__*/React.createElement("div",{key:feature.id,onClick:function onClick(){return _this3.pickFeatureSelected(feature)},onMouseOut:function onMouseOut(){return _this3.unhoverFeature(feature)},onMouseOver:function onMouseOver(){return _this3.hoverFeature(feature)}},(_feature$properties$_=feature.properties[_this3.props.displayField])!==null&&_feature$properties$_!==void 0?_feature$properties$_:feature.id)})),/*#__PURE__*/React.createElement("div",{className:"link-feature-form-close"},/*#__PURE__*/React.createElement("button",{className:"button",disabled:editContext.changed,onClick:this.finish},LocaleUtils.tr("linkfeatureform.cancel"))))}else if(editContext.feature){var drawing=editContext.action==="Draw"&&!editContext.feature.geometry&&this.props.editConfig.geomType;return/*#__PURE__*/React.createElement("div",{className:"link-feature-form"},drawing?/*#__PURE__*/React.createElement("div",{className:"link-feature-form-hint"},/*#__PURE__*/React.createElement("span",null,LocaleUtils.tr("linkfeatureform.drawhint"))):/*#__PURE__*/React.createElement(AttributeForm,{editConfig:this.props.editConfig,editContext:editContext,hideDelete:this.props.hideDelete,iface:this.props.iface,onDiscard:this.onDiscard,readOnly:this.props.readOnly}),/*#__PURE__*/React.createElement("div",{className:"link-feature-form-close"},/*#__PURE__*/React.createElement("button",{className:"button",disabled:editContext.changed,onClick:this.finish},drawing?LocaleUtils.tr("linkfeatureform.cancel"):LocaleUtils.tr("linkfeatureform.close"))))}else{return null}}}])}(React.Component);_defineProperty(LinkFeatureForm,"propTypes",{action:PropTypes.string,addLayerFeatures:PropTypes.func,displayField:PropTypes.string,editConfig:PropTypes.object,editContextId:PropTypes.string,editing:PropTypes.object,feature:PropTypes.object,featureId:PropTypes.oneOfType([PropTypes.string,PropTypes.number]),finished:PropTypes.func,hideDelete:PropTypes.bool,iface:PropTypes.object,map:PropTypes.object,pickFilter:PropTypes.func,readOnly:PropTypes.bool,removeLayer:PropTypes.func,setEditContext:PropTypes.func});export default connect(function(state){return{editing:state.editing,map:state.map}},{addLayerFeatures:addLayerFeatures,removeLayer:removeLayer,setEditContext:setEditContext})(LinkFeatureForm);
@@ -4,4 +4,4 @@ function _typeof(o){"@babel/helpers - typeof";return _typeof="function"==typeof
4
4
  *
5
5
  * This source code is licensed under the BSD-style license found in the
6
6
  * LICENSE file in the root directory of this source tree.
7
- */import React from"react";import{connect}from"react-redux";import isEmpty from"lodash.isempty";import PropTypes from"prop-types";import{v1 as uuidv1}from"uuid";import{LayerRole,addLayerFeatures,clearLayer}from"../actions/layers";import IdentifyUtils from"../utils/IdentifyUtils";import LocaleUtils from"../utils/LocaleUtils";import MapUtils from"../utils/MapUtils";import VectorLayerUtils from"../utils/VectorLayerUtils";import MapSelection from"./MapSelection";import PopupMenu from"./widgets/PopupMenu";import Spinner from"./widgets/Spinner";import"./style/PickFeature.css";var PickFeature=/*#__PURE__*/function(_React$Component){function PickFeature(props){var _this;_classCallCheck(this,PickFeature);_this=_callSuper(this,PickFeature,[props]);_defineProperty(_this,"handleIdentifyResponse",function(response,reqId,layer,infoFormat){if(_this.state.reqId!==reqId){return}var result=IdentifyUtils.parseResponse(response,layer,infoFormat,_this.state.clickPos,_this.props.map.projection,false);if(_this.props.featureFilter){Object.entries(result).forEach(function(_ref){var _ref2=_slicedToArray(_ref,2),layername=_ref2[0],features=_ref2[1];result[layername]=features.filter(_this.props.featureFilter)})}else{Object.entries(result).forEach(function(_ref3){var _ref4=_slicedToArray(_ref3,2),layername=_ref4[0],features=_ref4[1];result[layername]=features.filter(function(feature){return!!feature.geometry})})}_this.setState(function(state){var newState={pickResults:_objectSpread(_objectSpread({},state.pickResults),result),pendingQueries:state.pendingQueries-1};if(newState.pendingQueries===0){var entries=Object.entries(newState.pickResults);if(entries.length===1&&entries[0][1].length===1){_this.props.featurePicked(entries[0][0],entries[0][1][0]);newState.pickResults=null;newState.pickGeom=null}else if(entries.reduce(function(sum,entry){return sum+entry[1].length},0)===0){newState.pickResults=null;newState.pickGeom=null}}return newState})});_defineProperty(_this,"highlightFeature",function(key,feature){var layer={id:"pick-feature-selection",role:LayerRole.SELECTION};_this.props.addLayerFeatures(layer,[feature],true);_this.setState({highlightedFeature:key+":"+feature.id})});_defineProperty(_this,"clearHighlight",function(key,feature){if(_this.state.highlightedFeature===key+":"+feature.id){_this.setState({highlightFeature:null});_this.props.clearLayer("pick-feature-selection")}});_defineProperty(_this,"onClose",function(){_this.setState(PickFeature.defaultState);_this.props.clearLayer("pick-feature-selection")});_this.state=PickFeature.defaultState;return _this}_inherits(PickFeature,_React$Component);return _createClass(PickFeature,[{key:"componentDidUpdate",value:function componentDidUpdate(prevProps,prevState){var _this2=this;if(this.state.pickGeom&&this.state.pickGeom!==prevState.pickGeom){var queryLayers=[];if(this.props.layerFilter){queryLayers=[this.props.layers.find(function(l){return l.url===_this2.props.layerFilter.url})].filter(Boolean)}else{queryLayers=IdentifyUtils.getQueryLayers(this.props.layers,this.props.map)}if(!isEmpty(queryLayers)){this.setState(function(state){var getPixelFromCoordinate=MapUtils.getHook(MapUtils.GET_PIXEL_FROM_COORDINATES_HOOK);var coordinates=_this2.props.pickGeomType==="Point"?[[state.pickGeom.coordinates]]:state.pickGeom.coordinates;var maxX=coordinates[0][0][0];var maxY=coordinates[0][0][1];for(var i=1;i<coordinates[0].length;++i){if(coordinates[0][i][0]>maxX){maxX=coordinates[0][i][0];maxY=coordinates[0][i][1]}}var clickPos=getPixelFromCoordinate([maxX,maxY]);var reqId=uuidv1();queryLayers.forEach(function(layer){var request=null;if(_this2.props.pickGeomType==="Point"){var _this2$props$layerFil;request=IdentifyUtils.buildRequest(layer,((_this2$props$layerFil=_this2.props.layerFilter)===null||_this2$props$layerFil===void 0?void 0:_this2$props$layerFil.name)||layer.queryLayers.join(","),state.pickGeom.coordinates,_this2.props.map)}else if(_this2.props.pickGeomType==="Polygon"){var _this2$props$layerFil2;var filter=VectorLayerUtils.geoJSONGeomToWkt(_this2.state.pickGeom);request=IdentifyUtils.buildFilterRequest(layer,((_this2$props$layerFil2=_this2.props.layerFilter)===null||_this2$props$layerFil2===void 0?void 0:_this2$props$layerFil2.name)||layer.queryLayers.join(","),filter,_this2.props.map)}else{return}IdentifyUtils.sendRequest(request,function(response){return _this2.handleIdentifyResponse(response,reqId,layer,request.params.info_format)})});return{pickResults:{},clickPos:clickPos,pendingQueries:queryLayers.length,reqId:reqId}})}}}},{key:"render",value:function render(){var _this3=this;var resultsMenu=null;if(this.state.pickResults){resultsMenu=/*#__PURE__*/React.createElement(PopupMenu,{className:"PickFeatureMenu",key:"PickResultMenu",onClose:this.onClose,x:this.state.clickPos[0],y:this.state.clickPos[1]},this.state.pendingQueries===0?Object.entries(this.state.pickResults).map(function(_ref5){var _ref6=_slicedToArray(_ref5,2),layername=_ref6[0],features=_ref6[1];return features.map(function(feature){return/*#__PURE__*/React.createElement("div",{key:layername+":"+feature.id,onClickCapture:function onClickCapture(){return _this3.props.featurePicked(layername,feature)},onMouseOut:function onMouseOut(){return _this3.clearHighlight(layername,feature)},onMouseOver:function onMouseOver(){return _this3.highlightFeature(layername,feature)}},layername+": "+feature.displayname)})}):/*#__PURE__*/React.createElement("div",{className:"pick-feature-menu-querying"},/*#__PURE__*/React.createElement(Spinner,null),LocaleUtils.tr("pickfeature.querying")))}return[resultsMenu,/*#__PURE__*/React.createElement(MapSelection,{active:true,geomType:this.props.pickGeomType,geometry:this.state.pickGeom,geometryChanged:function geometryChanged(geom){return _this3.setState({pickGeom:geom})},key:"MapSelection",styleOptions:this.props.highlightStyle})]}}])}(React.Component);_defineProperty(PickFeature,"propTypes",{addLayerFeatures:PropTypes.func,clearLayer:PropTypes.func,/** Optional: Function which accepts a GeoJSON feature and returns whether it should be accepted (true) or discarded (false) */featureFilter:PropTypes.func,featurePicked:PropTypes.func,/** 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}),/** Optional: Restrict pick to specified layer name */layerFilter:PropTypes.shape({url:PropTypes.string,name:PropTypes.string}),layers:PropTypes.array,map:PropTypes.object,/** Pick geometry type: Point, Polygon, ... (default: Point) */pickGeomType:PropTypes.string});_defineProperty(PickFeature,"defaultProps",{pickGeomType:"Point",highlightStyle:{strokeColor:[0,0,0],fillColor:[255,255,0,0.25]}});_defineProperty(PickFeature,"defaultState",{pickGeom:null,pickResults:null,clickPos:null,highlightedFeature:null,pendingQueries:0,reqId:null});export default connect(function(state){return{layers:state.layers.flat,map:state.map}},{addLayerFeatures:addLayerFeatures,clearLayer:clearLayer})(PickFeature);
7
+ */import React from"react";import{connect}from"react-redux";import isEmpty from"lodash.isempty";import PropTypes from"prop-types";import{v1 as uuidv1}from"uuid";import{LayerRole,addLayerFeatures,clearLayer}from"../actions/layers";import IdentifyUtils from"../utils/IdentifyUtils";import LocaleUtils from"../utils/LocaleUtils";import MapUtils from"../utils/MapUtils";import VectorLayerUtils from"../utils/VectorLayerUtils";import MapSelection from"./MapSelection";import PopupMenu from"./widgets/PopupMenu";import Spinner from"./widgets/Spinner";import"./style/PickFeature.css";var PickFeature=/*#__PURE__*/function(_React$Component){function PickFeature(props){var _this;_classCallCheck(this,PickFeature);_this=_callSuper(this,PickFeature,[props]);_defineProperty(_this,"handleIdentifyResponse",function(response,reqId,layer,infoFormat){if(_this.state.reqId!==reqId){return}var result=IdentifyUtils.parseResponse(response,layer,infoFormat,_this.state.clickPos,_this.props.map.projection,false);if(_this.props.featureFilter){Object.entries(result).forEach(function(_ref){var _ref2=_slicedToArray(_ref,2),layername=_ref2[0],features=_ref2[1];result[layername]=features.filter(_this.props.featureFilter)})}else{Object.entries(result).forEach(function(_ref3){var _ref4=_slicedToArray(_ref3,2),layername=_ref4[0],features=_ref4[1];result[layername]=features.filter(function(feature){return!!feature.geometry})})}_this.setState(function(state){var newState={pickResults:_objectSpread(_objectSpread({},state.pickResults),result),pendingQueries:state.pendingQueries-1};if(newState.pendingQueries===0){var entries=Object.entries(newState.pickResults);if(entries.length===1&&entries[0][1].length===1){_this.props.featurePicked(entries[0][0],entries[0][1][0]);newState.pickResults=null;newState.pickGeom=null}else if(entries.reduce(function(sum,entry){return sum+entry[1].length},0)===0){newState.pickResults=null;newState.pickGeom=null}}return newState})});_defineProperty(_this,"highlightFeature",function(key,feature){var layer={id:"pick-feature-selection",role:LayerRole.SELECTION};_this.props.addLayerFeatures(layer,[feature],true);_this.setState({highlightedFeature:key+":"+feature.id})});_defineProperty(_this,"clearHighlight",function(key,feature){if(_this.state.highlightedFeature===key+":"+feature.id){_this.setState({highlightFeature:null});_this.props.clearLayer("pick-feature-selection")}});_defineProperty(_this,"onClose",function(){_this.setState(PickFeature.defaultState);_this.props.clearLayer("pick-feature-selection")});_this.state=PickFeature.defaultState;return _this}_inherits(PickFeature,_React$Component);return _createClass(PickFeature,[{key:"componentDidUpdate",value:function componentDidUpdate(prevProps,prevState){var _this2=this;if(this.state.pickGeom&&this.state.pickGeom!==prevState.pickGeom){var queryLayers=[];if(this.props.layerFilter){queryLayers=[this.props.layers.find(function(l){return l.url===_this2.props.layerFilter.url})].filter(Boolean)}else{queryLayers=IdentifyUtils.getQueryLayers(this.props.layers,this.props.map)}if(!isEmpty(queryLayers)){this.setState(function(state){var getPixelFromCoordinate=MapUtils.getHook(MapUtils.GET_PIXEL_FROM_COORDINATES_HOOK);var coordinates=_this2.props.pickGeomType==="Point"?[[state.pickGeom.coordinates]]:state.pickGeom.coordinates;var maxX=coordinates[0][0][0];var maxY=coordinates[0][0][1];for(var i=1;i<coordinates[0].length;++i){if(coordinates[0][i][0]>maxX){maxX=coordinates[0][i][0];maxY=coordinates[0][i][1]}}var clickPos=getPixelFromCoordinate([maxX,maxY],false);var reqId=uuidv1();queryLayers.forEach(function(layer){var request=null;if(_this2.props.pickGeomType==="Point"){var _this2$props$layerFil;request=IdentifyUtils.buildRequest(layer,((_this2$props$layerFil=_this2.props.layerFilter)===null||_this2$props$layerFil===void 0?void 0:_this2$props$layerFil.name)||layer.queryLayers.join(","),state.pickGeom.coordinates,_this2.props.map)}else if(_this2.props.pickGeomType==="Polygon"){var _this2$props$layerFil2;var filter=VectorLayerUtils.geoJSONGeomToWkt(_this2.state.pickGeom);request=IdentifyUtils.buildFilterRequest(layer,((_this2$props$layerFil2=_this2.props.layerFilter)===null||_this2$props$layerFil2===void 0?void 0:_this2$props$layerFil2.name)||layer.queryLayers.join(","),filter,_this2.props.map)}else{return}IdentifyUtils.sendRequest(request,function(response){return _this2.handleIdentifyResponse(response,reqId,layer,request.params.info_format)})});return{pickResults:{},clickPos:clickPos,pendingQueries:queryLayers.length,reqId:reqId}})}}}},{key:"render",value:function render(){var _this3=this;var resultsMenu=null;if(this.state.pickResults){resultsMenu=/*#__PURE__*/React.createElement(PopupMenu,{className:"PickFeatureMenu",key:"PickResultMenu",onClose:this.onClose,x:this.state.clickPos[0],y:this.state.clickPos[1]},this.state.pendingQueries===0?Object.entries(this.state.pickResults).map(function(_ref5){var _ref6=_slicedToArray(_ref5,2),layername=_ref6[0],features=_ref6[1];return features.map(function(feature){return/*#__PURE__*/React.createElement("div",{key:layername+":"+feature.id,onClickCapture:function onClickCapture(){return _this3.props.featurePicked(layername,feature)},onMouseOut:function onMouseOut(){return _this3.clearHighlight(layername,feature)},onMouseOver:function onMouseOver(){return _this3.highlightFeature(layername,feature)}},layername+": "+feature.displayname)})}):/*#__PURE__*/React.createElement("div",{className:"pick-feature-menu-querying"},/*#__PURE__*/React.createElement(Spinner,null),LocaleUtils.tr("pickfeature.querying")))}return[resultsMenu,/*#__PURE__*/React.createElement(MapSelection,{active:true,geomType:this.props.pickGeomType,geometry:this.state.pickGeom,geometryChanged:function geometryChanged(geom){return _this3.setState({pickGeom:geom})},key:"MapSelection",styleOptions:this.props.highlightStyle})]}}])}(React.Component);_defineProperty(PickFeature,"propTypes",{addLayerFeatures:PropTypes.func,clearLayer:PropTypes.func,/** Optional: Function which accepts a GeoJSON feature and returns whether it should be accepted (true) or discarded (false) */featureFilter:PropTypes.func,featurePicked:PropTypes.func,/** 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}),/** Optional: Restrict pick to specified layer name */layerFilter:PropTypes.shape({url:PropTypes.string,name:PropTypes.string}),layers:PropTypes.array,map:PropTypes.object,/** Pick geometry type: Point, Polygon, ... (default: Point) */pickGeomType:PropTypes.string});_defineProperty(PickFeature,"defaultProps",{pickGeomType:"Point",highlightStyle:{strokeColor:[0,0,0],fillColor:[255,255,0,0.25]}});_defineProperty(PickFeature,"defaultState",{pickGeom:null,pickResults:null,clickPos:null,highlightedFeature:null,pendingQueries:0,reqId:null});export default connect(function(state){return{layers:state.layers.flat,map:state.map}},{addLayerFeatures:addLayerFeatures,clearLayer:clearLayer})(PickFeature);