UNPKG

qwc2

Version:
957 lines (956 loc) 57.8 kB
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); } function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); } function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); } function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); } function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } } function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; } function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } } function _arrayWithHoles(r) { if (Array.isArray(r)) return r; } function _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); } /** * Copyright 2024 Sourcepole AG * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. */ 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 MiscUtils from '../utils/MiscUtils'; 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 selectedLayer = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; _this.setState(function (state) { var _this$props$filter$fi; selectedLayer = selectedLayer || state.selectedLayer; var _selectedLayer$split = selectedLayer.split("#"), _selectedLayer$split2 = _slicedToArray(_selectedLayer$split, 2), wmsName = _selectedLayer$split2[0], layerName = _selectedLayer$split2[1]; var editConfig = _this.props.editConfigs[wmsName][layerName]; KeyValCache.clear(); FeatureCache.clear(); var bbox = _this.state.limitToExtent ? _this.props.mapBbox.bounds : null; _this.props.iface.getFeatures(editConfig, _this.props.mapCrs, function (result) { if (result) { var _this$props$layers$fi, _this$props$layers$fi2; var features = result.features || []; var fieldTranslations = (_this$props$layers$fi = (_this$props$layers$fi2 = _this.props.layers.find(function (layer) { return layer.wms_name === wmsName; })) === null || _this$props$layers$fi2 === void 0 || (_this$props$layers$fi2 = _this$props$layers$fi2.translations) === null || _this$props$layers$fi2 === void 0 || (_this$props$layers$fi2 = _this$props$layers$fi2.layers) === null || _this$props$layers$fi2 === void 0 || (_this$props$layers$fi2 = _this$props$layers$fi2[layerName]) === null || _this$props$layers$fi2 === void 0 ? void 0 : _this$props$layers$fi2.fields) !== null && _this$props$layers$fi !== void 0 ? _this$props$layers$fi : {}; _this.setState(function (state2) { return { loading: false, features: features, filteredSortedFeatures: _this.filteredSortedFeatures(features, state2), loadedLayer: selectedLayer, curEditConfig: editConfig, fieldTranslations: fieldTranslations }; }); } else { // eslint-disable-next-line alert(LocaleUtils.tr("attribtable.loadfailed")); _this.setState({ loading: false }); } }, 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, _this.props.showDisplayFieldOnly ? [editConfig.displayField, "geometry"] : null); 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 (editConfig, mapPrefix, 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) { filterExpr = parseExpression(field.filterExpression, feature, editConfig, _this.props.iface, mapPrefix, _this.props.mapCrs, function () { return _this.setState({ reevaluate: +new Date() }); }, true); } input = /*#__PURE__*/React.createElement(EditComboField, { editIface: _this.props.iface, fieldId: field.id, filterExpr: filterExpr, keyvalrel: constraints.keyvalrel, multiSelect: constraints.allowMulti === true, name: field.id, readOnly: constraints.readOnly || disabled, required: constraints.required, updateField: updateField, value: value, values: constraints.values }); } else if (field.type === "number") { var _constraints$prec, _constraints$step; var precision = (_constraints$prec = constraints.prec) !== null && _constraints$prec !== void 0 ? _constraints$prec : 0; var step = (_constraints$step = constraints.step) !== null && _constraints$step !== void 0 ? _constraints$step : 1; input = /*#__PURE__*/React.createElement(NumberInput, { decimals: precision, disabled: disabled, fitParent: true, max: constraints.max, min: constraints.min, name: field.id, onChange: function onChange(v) { return updateField(field.id, v, true); }, readOnly: constraints.readOnly, required: constraints.required, step: step, value: value }); } else if (field.type === "date") { // Truncate time portion of ISO date string 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: editConfig.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 hasGeometry = _this.state.curEditConfig.geomType !== null; if (!_this.props.allowAddForGeometryLayers && hasGeometry) { // eslint-disable-next-line alert(LocaleUtils.tr("attribtable.geomnoadd")); return; } var featureSkel = { type: "Feature", geometry: null, properties: _this.state.curEditConfig.fields.reduce(function (res, field) { if (field.id !== "id") { res[field.id] = field.type === "text" ? "" : null; } return res; }, {}) }; var mapPrefix = _this.state.curEditConfig.editDataset.split(".")[0]; getFeatureTemplate(_this.state.curEditConfig, 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(state.curEditConfig, 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 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) } } }); Object.keys(feature.properties || {}).forEach(function (name) { var _this$state$curEditCo, _this$state$curEditCo2, _this$state$curEditCo3; var fieldConfig = (_this$state$curEditCo = (_this$state$curEditCo2 = _this.state.curEditConfig.fields) === null || _this$state$curEditCo2 === void 0 || (_this$state$curEditCo3 = _this$state$curEditCo2.find) === null || _this$state$curEditCo3 === void 0 ? void 0 : _this$state$curEditCo3.call(_this$state$curEditCo2, function (f) { return f.id === name; })) !== null && _this$state$curEditCo !== void 0 ? _this$state$curEditCo : {}; if (fieldConfig.expression) { // Skip virtual fields delete feature.properties[name]; } }); // Omit geometry if it is read-only var canEditGeometry = ['Point', 'LineString', 'Polygon'].includes((_this.state.curEditConfig.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.state.curEditConfig, _this.props.mapCrs, featureData, function (success, result) { return _this.featureCommited(success, result); }); } else { _this.props.iface.editFeatureMultipart(_this.state.curEditConfig, _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 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 hasGeometry = _this.state.curEditConfig.geomType !== null; if (!hasGeometry) { // eslint-disable-next-line 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 var valueLookup = _this.state.curEditConfig.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 fields = _this.props.showDisplayFieldOnly ? _this.state.curEditConfig.fields.filter(function (field) { return field.name === _this.state.curEditConfig.displayField; }) : _this.state.curEditConfig.fields.filter(function (field) { return field.id !== 'id'; }); var data = ""; data += "id," + fields.map(function (field) { return "\"".concat(field.name.replaceAll('"', '""'), "\""); }).join(",") + "\n"; _this.state.features.forEach(function (feature) { data += feature.id + "," + fields.map(function (field) { var value = feature.properties[field.id]; if (value === null || value === undefined) { return "null"; } else { return "\"".concat(String(feature.properties[field.id]).replaceAll('"', '""'), "\""); } }).join(",") + "\n"; }); FileSaver.saveAs(new Blob([data], { type: "text/plain;charset=utf-8" }), _this.state.loadedLayer + ".csv"); }); _defineProperty(_this, "translateFieldName", function (fieldName) { var _this$state$fieldTran, _this$state$fieldTran2; return (_this$state$fieldTran = (_this$state$fieldTran2 = _this.state.fieldTranslations) === null || _this$state$fieldTran2 === void 0 ? void 0 : _this$state$fieldTran2[fieldName]) !== null && _this$state$fieldTran !== void 0 ? _this$state$fieldTran : fieldName; }); _this.changedFiles = {}; _this.state = AttributeTableWidget.defaultState; _this.table = null; _this.attribTableContents = null; _this.state.limitToExtent = props.limitToExtent; 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 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 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 curEditConfig = this.state.curEditConfig; var editPermissions = (curEditConfig === null || curEditConfig === void 0 ? void 0 : curEditConfig.permissions) || {}; var readOnly = this.props.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("common.loading"))); } else { loadOverlay = /*#__PURE__*/React.createElement("div", { className: "attribtable-overlay" }, /*#__PURE__*/React.createElement("span", null, LocaleUtils.tr("attribtable.pleasereload"))); } } else if (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 (curEditConfig && this.state.features) { var mapPrefix = this.state.curEditConfig.editDataset.split(".")[0]; var fields = this.props.showDisplayFieldOnly ? curEditConfig.fields.filter(function (field) { return field.name === curEditConfig.displayField; }) : curEditConfig.fields.filter(function (field) { var _field$constraints; return field.id !== "id" && (_this2.props.showHiddenFields || ((_field$constraints = field.constraints) === null || _field$constraints === void 0 ? void 0 : _field$constraints.hidden) !== true); }); var indexOffset = this.state.currentPage * this.state.pageSize; var features = this.state.filteredSortedFeatures.slice(indexOffset, indexOffset + this.state.pageSize); table = /*#__PURE__*/React.createElement("table", { className: "attribtable-table", ref: function ref(el) { _this2.table = el; } }, /*#__PURE__*/React.createElement("thead", null, /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("th", null), !this.props.showDisplayFieldOnly ? /*#__PURE__*/React.createElement("th", { onClick: function onClick() { return _this2.sortBy("id"); }, onKeyDown: MiscUtils.checkKeyActivate, tabIndex: 0, title: this.translateFieldName("id") }, /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement("span", { className: "attribtable-table-headername" }, this.translateFieldName("id")), this.renderSortIndicator("id"), this.renderColumnResizeHandle(1, 'r'))) : null, fields.map(function (field, idx) { return /*#__PURE__*/React.createElement("th", { key: field.id, onClick: function onClick() { return _this2.sortBy(field.id); }, onKeyDown: MiscUtils.checkKeyActivate, tabIndex: 0, title: _this2.translateFieldName(field.name) }, /*#__PURE__*/React.createElement("span", null, _this2.renderColumnResizeHandle(idx + 1, 'l'), /*#__PURE__*/React.createElement("span", { className: "attribtable-table-headername" }, _this2.translateFieldName(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 && !_this2.props.readOnly ? "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'))), !_this2.props.showDisplayFieldOnly ? /*#__PURE__*/React.createElement("td", null, feature.id) : null, fields.map(function (field) { return /*#__PURE__*/React.createElement("td", { key: field.id }, _this2.renderField(curEditConfig, mapPrefix, field, featureidx, indexOffset + filteredIndex, disabled || !!_this2.state.filterVal && field.id === _this2.state.filterField)); })); }))); var npages = Math.ceil(this.state.filteredSortedFeatures.length / this.state.pageSize); var pages = [this.state.currentPage]; var extraright = Math.max(0, 2 - this.state.currentPage); var extraleft = Math.max(0, this.state.currentPage - (npages - 3)); for (var i = 0; i < 3 + extraleft; ++i) { if (this.state.currentPage - i > 0) { pages.unshift(this.state.currentPage - i); } } for (var _i = 0; _i < 3 + extraright; ++_i) { if (this.state.currentPage + _i < npages - 1) { pages.push(this.state.currentPage - _i + 1); } } footbar = /*#__PURE__*/React.createElement("div", { className: "attribtable-footbar" }, /*#__PURE__*/React.createElement(NavBar, { currentPage: this.state.currentPage, disabled: this.state.changedFeatureIdx !== null, nPages: npages, pageChanged: function pageChanged(currentPage) { return _this2.setState({ currentPage: currentPage }); }, pageSize: this.state.pageSize, pageSizeChanged: function pageSizeChanged(pageSize) { return _this2.setState({ pageSize: pageSize }); } }), /*#__PURE__*/React.createElement("div", { className: "attribtable-filter controlgroup" }, /*#__PURE__*/React.createElement(Icon, { icon: "filter" }), /*#__PURE__*/React.createElement("select", { disabled: this.state.changedFeatureIdx !== null, onChange: function onChange(ev) { return _this2.updateFilter("filterField", ev.target.value); }, value: this.state.filterField }, /*#__PURE__*/React.createElement("option", { value: "id" }, this.translateFieldName("id")), fields.map(function (field) { return /*#__PURE__*/React.createElement("option", { key: field.id, value: field.id }, _this2.translateFieldName(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 = curEditConfig === null; var loading = this.state.loading; var editing = this.state.changedFeatureIdx !== null; var layerChanged = this.state.selectedLayer !== this.state.loadedLayer; var hasGeometry = (curEditConfig || {}).geomType !== null; var showAddButton = !this.props.readOnly && editPermissions.creatable !== false && (this.props.allowAddForGeometryLayers || !hasGeometry); var showDelButton = !this.props.readOnly && editPermissions.deletable !== false; var showEditButton = !this.props.readOnly && 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("common.selectlayer")), Object.entries(this.props.editConfigs).map(function (_ref4) { var _ref5 = _slicedToArray(_ref4, 2), wmsName = _ref5[0], serviceConfigs = _ref5[1]; return Object.entries(serviceConfigs).map(function (_ref6) { var _ref7 = _slicedToArray(_ref6, 2), layerName = _ref7[0], editConfig = _ref7[1]; var match = LayerUtils.searchLayer(_this2.props.layers, 'wms_name', wmsName, 'name', layerName); var layerTitle = layerName; if (match) { var _ref8, _ref9, _match$layer$translat, _match$layer$translat2, _match$sublayer; layerTitle = (_ref8 = (_ref9 = (_match$layer$translat = (_match$layer$translat2 = match.layer.translations) === null || _match$layer$translat2 === void 0 || (_match$layer$t