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.
- package/components/AppMenu.js +1 -1
- package/components/AttributeForm.js +11 -9
- package/components/AttributeTableWidget.js +8 -7
- package/components/EditComboField.js +4 -4
- package/components/LinkFeatureForm.js +2 -2
- package/components/PickFeature.js +1 -1
- package/components/QtDesignerForm.js +11 -11
- package/components/map/OlMap.js +1 -1
- package/components/map/layers/MVTLayer.js +1 -1
- package/package.json +2 -1
- package/plugins/BottomBar.js +2 -2
- package/plugins/Editing.js +1 -1
- package/plugins/FeatureForm.js +1 -1
- package/plugins/Print.js +1 -1
- package/plugins/style/BottomBar.css +14 -6
- package/static/translations/bg-BG.json +1 -1
- package/static/translations/ca-ES.json +1 -1
- package/static/translations/cs-CZ.json +1 -1
- package/static/translations/de-CH.json +1 -1
- package/static/translations/de-DE.json +1 -1
- package/static/translations/en-US.json +1 -1
- package/static/translations/es-ES.json +1 -1
- package/static/translations/fi-FI.json +1 -1
- package/static/translations/fr-FR.json +1 -1
- package/static/translations/it-IT.json +1 -1
- package/static/translations/ja-JP.json +1 -1
- package/static/translations/nl-NL.json +1 -1
- package/static/translations/no-NO.json +1 -1
- package/static/translations/pl-PL.json +1 -1
- package/static/translations/pt-BR.json +1 -1
- package/static/translations/pt-PT.json +1 -1
- package/static/translations/ro-RO.json +1 -1
- package/static/translations/sv-SE.json +1 -1
- package/static/translations/tr-TR.json +1 -1
- package/utils/EditingInterface.js +86 -62
- package/utils/EditingUtils.js +11 -5
- package/utils/expr_grammar/grammar.js +1 -1
- package/utils/expr_grammar/grammar.ne +3 -1
- package/utils/expr_grammar/test.js +4 -2
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"ThemeSwitcher": "Theme",
|
|
31
31
|
"AttributeTable": "Attribute Table",
|
|
32
32
|
"AuthenticationLogin": "Login",
|
|
33
|
-
"AuthenticationLogout": "Logout",
|
|
33
|
+
"AuthenticationLogout": "Logout - {0}",
|
|
34
34
|
"Cyclomedia": "Cyclomedia",
|
|
35
35
|
"Draw3D": "Draw",
|
|
36
36
|
"FeatureForm": "Feature Form",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"ThemeSwitcher": "Tema",
|
|
31
31
|
"AttributeTable": "Tabla de Atributos",
|
|
32
32
|
"AuthenticationLogin": "Inicio de sesión",
|
|
33
|
-
"AuthenticationLogout": "Cierre de sesión",
|
|
33
|
+
"AuthenticationLogout": "Cierre de sesión - {0}",
|
|
34
34
|
"Cyclomedia": "Visor Cyclomedia",
|
|
35
35
|
"Draw3D": "Dibujar",
|
|
36
36
|
"FeatureForm": "Formulario de Elemento",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"ThemeSwitcher": "Thèmes",
|
|
31
31
|
"AttributeTable": "Table d'attributs",
|
|
32
32
|
"AuthenticationLogin": "Connexion",
|
|
33
|
-
"AuthenticationLogout": "Déconnexion",
|
|
33
|
+
"AuthenticationLogout": "Déconnexion - {0}",
|
|
34
34
|
"Cyclomedia": "Cyclomedia",
|
|
35
35
|
"Draw3D": "Dessiner",
|
|
36
36
|
"FeatureForm": "Formulaire d'objet",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"ThemeSwitcher": "Temi",
|
|
31
31
|
"AttributeTable": "Tabella attributi",
|
|
32
32
|
"AuthenticationLogin": "Accedi",
|
|
33
|
-
"AuthenticationLogout": "Disconnetti",
|
|
33
|
+
"AuthenticationLogout": "Disconnetti - {0}",
|
|
34
34
|
"Cyclomedia": "Cyclomedia",
|
|
35
35
|
"Draw3D": "Disegnare",
|
|
36
36
|
"FeatureForm": "Formulario oggetto",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"ThemeSwitcher": "Kaartselectie",
|
|
31
31
|
"AttributeTable": "Attributentabel",
|
|
32
32
|
"AuthenticationLogin": "Inloggen",
|
|
33
|
-
"AuthenticationLogout": "Uitloggen",
|
|
33
|
+
"AuthenticationLogout": "Uitloggen - {0}",
|
|
34
34
|
"Cyclomedia": "Cyclomedia",
|
|
35
35
|
"Draw3D": "",
|
|
36
36
|
"FeatureForm": "Objectgegevens",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"ThemeSwitcher": "Tema",
|
|
31
31
|
"AttributeTable": "Tabela de atributos",
|
|
32
32
|
"AuthenticationLogin": "Inicio da sessão",
|
|
33
|
-
"AuthenticationLogout": "Fim da sessão",
|
|
33
|
+
"AuthenticationLogout": "Fim da sessão - {0}",
|
|
34
34
|
"Cyclomedia": "Cyclomedia",
|
|
35
35
|
"Draw3D": "",
|
|
36
36
|
"FeatureForm": "Atributos da feição",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"ThemeSwitcher": "Tema",
|
|
31
31
|
"AttributeTable": "Tabela de Atributos",
|
|
32
32
|
"AuthenticationLogin": "Iniciar Sessão",
|
|
33
|
-
"AuthenticationLogout": "Terminar Sessão",
|
|
33
|
+
"AuthenticationLogout": "Terminar Sessão - {0}",
|
|
34
34
|
"Cyclomedia": "Cyclomedia",
|
|
35
35
|
"Draw3D": "",
|
|
36
36
|
"FeatureForm": "Formulário de Recurso",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"ThemeSwitcher": "Hărți tematice",
|
|
31
31
|
"AttributeTable": "Tabela de atribute",
|
|
32
32
|
"AuthenticationLogin": "Conectează-te",
|
|
33
|
-
"AuthenticationLogout": "Deconectează-te",
|
|
33
|
+
"AuthenticationLogout": "Deconectează-te - {0}",
|
|
34
34
|
"Cyclomedia": "Cyclomedia",
|
|
35
35
|
"Draw3D": "",
|
|
36
36
|
"FeatureForm": "Editare atribute",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"ThemeSwitcher": "Tema",
|
|
31
31
|
"AttributeTable": "Öznitelik Tablosu",
|
|
32
32
|
"AuthenticationLogin": "Giriş",
|
|
33
|
-
"AuthenticationLogout": "Çıkış",
|
|
33
|
+
"AuthenticationLogout": "Çıkış - {0}",
|
|
34
34
|
"Cyclomedia": "Siklomedya",
|
|
35
35
|
"Draw3D": "Çizim",
|
|
36
36
|
"FeatureForm": "Obje Formu",
|
|
@@ -1,4 +1,4 @@
|
|
|
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 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 _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 _slicedToArray(r,e){return _arrayWithHoles(r)||_iterableToArrayLimit(r,e)||_unsupportedIterableToArray(r,e)||_nonIterableRest()}function _nonIterableRest(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _unsupportedIterableToArray(r,a){if(r){if("string"==typeof r)return _arrayLikeToArray(r,a);var t={}.toString.call(r).slice(8,-1);return"Object"===t&&r.constructor&&(t=r.constructor.name),"Map"===t||"Set"===t?Array.from(r):"Arguments"===t||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t)?_arrayLikeToArray(r,a):void 0}}function _arrayLikeToArray(r,a){(null==a||a>r.length)&&(a=r.length);for(var e=0,n=Array(a);e<a;e++)n[e]=r[e];return n}function _iterableToArrayLimit(r,l){var t=null==r?null:"undefined"!=typeof Symbol&&r[Symbol.iterator]||r["@@iterator"];if(null!=t){var e,n,i,u,a=[],f=!0,o=!1;try{if(i=(t=t.call(r)).next,0===l){if(Object(t)!==t)return;f=!1}else for(;!(f=(e=i.call(t)).done)&&(a.push(e.value),a.length!==l);f=!0);}catch(r){o=!0,n=r}finally{try{if(!f&&null!=t["return"]&&(u=t["return"](),Object(u)!==u))return}finally{if(o)throw n}}return a}}function _arrayWithHoles(r){if(Array.isArray(r))return r}function ownKeys(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);r&&(o=o.filter(function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable})),t.push.apply(t,o)}return t}function _objectSpread(e){for(var r=1;r<arguments.length;r++){var t=null!=arguments[r]?arguments[r]:{};r%2?ownKeys(Object(t),!0).forEach(function(r){_defineProperty(e,r,t[r])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):ownKeys(Object(t)).forEach(function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(t,r))})}return e}function _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 2017-2024 Sourcepole AG
|
|
3
3
|
* All rights reserved.
|
|
4
4
|
*
|
|
@@ -7,64 +7,88 @@ function _typeof(o){"@babel/helpers - typeof";return _typeof="function"==typeof
|
|
|
7
7
|
*//**
|
|
8
8
|
* NOTE: This sample editing interface is designed to work with the counterpart at
|
|
9
9
|
* https://github.com/qwc-services/qwc-data-service
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
mapCrs:
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
10
|
+
*/import axios from"axios";import isEmpty from"lodash.isempty";import ConfigUtils from"./ConfigUtils";import{computeExpressionFields}from"./EditingUtils";import LocaleUtils from"./LocaleUtils";var EditingInterface={buildErrMsg:function buildErrMsg(err){var message=LocaleUtils.tr("editing.commitfailed");if(err.response&&err.response.data&&err.response.data.message){message=err.response.data.message;if(!isEmpty(err.response.data.geometry_errors)){message+=":\n";message+=err.response.data.geometry_errors.map(function(entry){var entrymsg=" - "+entry.reason;if(entry.location){entrymsg+=" at "+entry.location}return entrymsg})}if(!isEmpty(err.response.data.data_errors)){message+=":\n - "+err.response.data.data_errors.join("\n - ")}if(!isEmpty(err.response.data.validation_errors)){message+=":\n - "+err.response.data.validation_errors.join("\n - ")}if(!isEmpty(err.response.data.attachment_errors)){message+=":\n - "+err.response.data.attachment_errors.join("\n - ")}}else if(err.response&&err.response.statusText){message+=": "+err.response.statusText}return message},/**
|
|
11
|
+
* Gets features at the specified map position.
|
|
12
|
+
*
|
|
13
|
+
* @param editConfig The edit config of the dataset to query features from
|
|
14
|
+
* @param mapPos The [x, y] map position
|
|
15
|
+
* @param mapCrs The CRS of the map, as an EPSG code
|
|
16
|
+
* @param mapScale The scale denominator, used to compute the pick tolerance
|
|
17
|
+
* @param dpi The screen dpi, used to compute the pick tolerance
|
|
18
|
+
* @param callback Callback invoked with the picked features, taking `{features: [...]}` on success and `null` on failure
|
|
19
|
+
* @param filter An optional feature attribute filter expression
|
|
20
|
+
* @param filterGeom An optional filter geometry
|
|
21
|
+
*/getFeature:function getFeature(editConfig,mapPos,mapCrs,mapScale,dpi,callback){var filter=arguments.length>6&&arguments[6]!==undefined?arguments[6]:null;var filterGeom=arguments.length>7&&arguments[7]!==undefined?arguments[7]:null;var editServiceUrl=ConfigUtils.getConfigProp("editServiceUrl").replace(/\/$/,"");var requestUrl=editServiceUrl+"/"+editConfig.editDataset+"/";// 10px tolerance
|
|
22
|
+
var tol=10/dpi*0.0254*mapScale;var bbox=mapPos[0]-tol+","+(mapPos[1]-tol)+","+(mapPos[0]+tol)+","+(mapPos[1]+tol);var params={bbox:bbox,crs:mapCrs,filter:filter?JSON.stringify(filter):undefined,filter_geom:filterGeom?JSON.stringify(_objectSpread(_objectSpread({},filterGeom),{},{crs:{type:"name",properties:{name:mapCrs}}})):undefined};var headers={"Accept-Language":LocaleUtils.lang()};axios.get(requestUrl,{headers:headers,params:params}).then(function(response){var _response$data;if(!isEmpty(response===null||response===void 0||(_response$data=response.data)===null||_response$data===void 0?void 0:_response$data.features)){var version=+new Date;var promises=response.data.features.map(function(feature){return new Promise(function(resolve){computeExpressionFields(editConfig,feature,EditingInterface,mapCrs,function(newfeature){return resolve(_objectSpread(_objectSpread({},newfeature),{},{__version__:version}))})})});Promise.all(promises).then(function(features){return callback({features:features})})}else{callback(null)}})["catch"](function(){callback(null)})},/**
|
|
23
|
+
* Queries a feature by id
|
|
24
|
+
*
|
|
25
|
+
* @param editConfig The edit config of the dataset to query the feature from
|
|
26
|
+
* @param featureId The feature id
|
|
27
|
+
* @param mapCrs The CRS of the map, as an EPSG code
|
|
28
|
+
* @param callback Callback invoked with the picked feature, taking `{<feature>}` on success and `null` on failure
|
|
29
|
+
*/getFeatureById:function getFeatureById(editConfig,featureId,mapCrs,callback){var editServiceUrl=ConfigUtils.getConfigProp("editServiceUrl").replace(/\/$/,"");var requestUrl=editServiceUrl+"/"+editConfig.editDataset+"/"+featureId;var params={crs:mapCrs};var headers={"Accept-Language":LocaleUtils.lang()};axios.get(requestUrl,{headers:headers,params:params}).then(function(response){computeExpressionFields(editConfig,response.data,EditingInterface,mapCrs,function(newfeature){return callback(_objectSpread(_objectSpread({},newfeature),{},{__version__:+new Date}))})})["catch"](function(){callback(null)})},/**
|
|
30
|
+
* Gets the dataset features
|
|
31
|
+
*
|
|
32
|
+
* @param editConfig The edit config of the dataset to query features from
|
|
33
|
+
* @param mapCrs The CRS of the map, as an EPSG code
|
|
34
|
+
* @param callback Callback invoked with the picked features, taking `{features: [...]}` on success and `null` on failure
|
|
35
|
+
* @param filter An optional feature attribute filter expression
|
|
36
|
+
* @param filterGeom An optional filter geometry
|
|
37
|
+
*/getFeatures:function getFeatures(editConfig,mapCrs,callback){var bbox=arguments.length>3&&arguments[3]!==undefined?arguments[3]:null;var filter=arguments.length>4&&arguments[4]!==undefined?arguments[4]:null;var filterGeom=arguments.length>5&&arguments[5]!==undefined?arguments[5]:null;var editServiceUrl=ConfigUtils.getConfigProp("editServiceUrl").replace(/\/$/,"");var requestUrl=editServiceUrl+"/"+editConfig.editDataset+"/";var params={crs:mapCrs,bbox:bbox?bbox.join(","):undefined,filter:filter?JSON.stringify(filter):undefined,filter_geom:filterGeom?JSON.stringify(_objectSpread(_objectSpread({},filterGeom),{},{crs:{type:"name",properties:{name:mapCrs}}})):undefined};var headers={"Accept-Language":LocaleUtils.lang()};axios.get(requestUrl,{headers:headers,params:params}).then(function(response){var _response$data2;if(!isEmpty(response===null||response===void 0||(_response$data2=response.data)===null||_response$data2===void 0?void 0:_response$data2.features)){var version=+new Date;var promises=response.data.features.map(function(feature){return new Promise(function(resolve){computeExpressionFields(editConfig,feature,EditingInterface,mapCrs,function(newfeature){return resolve(_objectSpread(_objectSpread({},newfeature),{},{__version__:version}))})})});Promise.all(promises).then(function(features){return callback({features:features})})}else{callback(null)}})["catch"](function(){return callback(null)})},/**
|
|
38
|
+
* Query the extent of the dataset features
|
|
39
|
+
* @param editConfig The edit config of the dataset to query features from
|
|
40
|
+
* @param mapCrs The CRS of the map, as an EPSG code
|
|
41
|
+
* @param callback Callback invoked with the feature extent, taking `{bbox: [xmin, ymin, xmax, ymax]}` on success and `null` on failure
|
|
42
|
+
* @param filter An optional feature attribute filter expression
|
|
43
|
+
* @param filterGeom An optional filter geometry
|
|
44
|
+
*/getExtent:function getExtent(editConfig,mapCrs,callback){var filter=arguments.length>3&&arguments[3]!==undefined?arguments[3]:null;var filterGeom=arguments.length>4&&arguments[4]!==undefined?arguments[4]:null;var editServiceUrl=ConfigUtils.getConfigProp("editServiceUrl").replace(/\/$/,"");var requestUrl=editServiceUrl+"/"+editConfig.editDataset+"/extent";var params={crs:mapCrs,filter:filter?JSON.stringify(filter):undefined,filter_geom:filterGeom?JSON.stringify(_objectSpread(_objectSpread({},filterGeom),{},{crs:{type:"name",properties:{name:mapCrs}}})):undefined};var headers={"Accept-Language":LocaleUtils.lang()};axios.get(requestUrl,{headers:headers,params:params}).then(function(response){callback(response.data)})["catch"](function(){callback(null)})},/**
|
|
45
|
+
* Adds a feature to the dataset
|
|
46
|
+
* @param editConfig The edit config of the dataset to add the feature to
|
|
47
|
+
* @param mapCrs The CRS of the map, as an EPSG code
|
|
48
|
+
* @param featureData A FormData instance, with:
|
|
49
|
+
* - A 'feature' entry containing the GeoJSON serialized feature
|
|
50
|
+
* - Zero or more 'file:' prefixed file upload entries
|
|
51
|
+
* - Zero or more 'relfile:' prefixed file upload entries
|
|
52
|
+
* - Optionally a 'g-recaptcha-response' entry with the captcha response
|
|
53
|
+
* @param callback Callback invoked with the added feature, taking `(true, {<feature>}` on success and `(false, <Error Message>}` on failure
|
|
54
|
+
*/addFeatureMultipart:function addFeatureMultipart(editConfig,mapCrs,featureData,callback){var editServiceUrl=ConfigUtils.getConfigProp("editServiceUrl").replace(/\/$/,"");var requestUrl=editServiceUrl+"/"+editConfig.editDataset+"/multipart";var headers={"Content-Type":"multipart/form-data","Accept-Language":LocaleUtils.lang()};axios.post(requestUrl,featureData,{headers:headers}).then(function(response){computeExpressionFields(editConfig,response.data,EditingInterface,mapCrs,function(newfeature){return callback(true,_objectSpread(_objectSpread({},newfeature),{},{__version__:+new Date}))})})["catch"](function(err){callback(false,EditingInterface.buildErrMsg(err))})},/**
|
|
55
|
+
* Edits a feature of the dataset
|
|
56
|
+
* @param editConfig The edit config of the edited dataset
|
|
57
|
+
* @param mapCrs The CRS of the map, as an EPSG code
|
|
58
|
+
* @param featureId The ID of the edited feature
|
|
59
|
+
* @param featureData A FormData instance, with:
|
|
60
|
+
* - A 'feature' entry containing the GeoJSON serialized feature
|
|
61
|
+
* - Zero or more 'file:' prefixed file upload entries
|
|
62
|
+
* - Zero or more 'relfile:' prefixed file upload entries
|
|
63
|
+
* - Optionally a 'g-recaptcha-response' entry with the captcha response
|
|
64
|
+
* @param callback Callback invoked with the edited feature, taking `(true, {<feature>}` on success and `(false, <Error Message>}` on failure
|
|
65
|
+
*/editFeatureMultipart:function editFeatureMultipart(editConfig,mapCrs,featureId,featureData,callback){var editServiceUrl=ConfigUtils.getConfigProp("editServiceUrl").replace(/\/$/,"");var requestUrl=editServiceUrl+"/"+editConfig.editDataset+"/multipart/"+featureId;var headers={"Content-Type":"multipart/form-data","Accept-Language":LocaleUtils.lang()};axios.put(requestUrl,featureData,{headers:headers}).then(function(response){computeExpressionFields(editConfig,response.data,EditingInterface,mapCrs,function(newfeature){return callback(true,_objectSpread(_objectSpread({},newfeature),{},{__version__:+new Date}))})})["catch"](function(err){callback(false,EditingInterface.buildErrMsg(err))})},/*
|
|
66
|
+
layerId: The edit layer id
|
|
67
|
+
featureId: The id of the feature to delete
|
|
68
|
+
callback: function(success, result), if success = true, result is null, if success = false, result is an error message
|
|
69
|
+
recaptchaResponse: Optional, captcha challenge response
|
|
70
|
+
*//**
|
|
71
|
+
* Deletes a feature from the dataset
|
|
72
|
+
* @param editConfig The edit config of the dataset from which to delete the feature
|
|
73
|
+
* @param featureId The ID of the edited feature
|
|
74
|
+
* @param callback Callback invoked with the id of the deleted feature, taking `(true, <feature_id>` on success and `(false, <Error Message>}` on failure
|
|
75
|
+
* @param recaptchaResponse Optional captcha challenge response
|
|
76
|
+
*/deleteFeature:function deleteFeature(editConfig,featureId,callback){var recaptchaResponse=arguments.length>3&&arguments[3]!==undefined?arguments[3]:null;var editServiceUrl=ConfigUtils.getConfigProp("editServiceUrl").replace(/\/$/,"");var req=editServiceUrl+"/"+editConfig.editDataset+"/"+featureId;var headers={"Accept-Language":LocaleUtils.lang()};var data={};if(recaptchaResponse){data["g-recaptcha-response"]=recaptchaResponse}axios["delete"](req,{headers:headers,data:data}).then(function(){callback(true,featureId)})["catch"](function(err){callback(false,EditingInterface.buildErrMsg(err))})},/**
|
|
77
|
+
* Queries relation values of a feature
|
|
78
|
+
* @param editConfig The edit config of the feature dataset
|
|
79
|
+
* @param featureId The feature ID
|
|
80
|
+
* @param mapCrs The CRS of the map, as an EPSG code
|
|
81
|
+
* @param tables Comma separated string of relation table names
|
|
82
|
+
* @param editConfigs The theme editConfig block, containing all theme dataset edit configs
|
|
83
|
+
* @param callback Callback invoked with the relation values, taking `{<tablename>: {<relation_values>}}` on success and `{}` on failure
|
|
84
|
+
*/getRelations:function getRelations(editConfig,featureId,mapCrs,tables,editConfigs,callback){var editServiceUrl=ConfigUtils.getConfigProp("editServiceUrl").replace(/\/$/,"");var req=editServiceUrl+"/"+editConfig.editDataset+"/"+featureId+"/relations";var params={tables:tables,crs:mapCrs};var headers={"Accept-Language":LocaleUtils.lang()};axios.get(req,{headers:headers,params:params}).then(function(response){Promise.all(Object.entries(response.data).map(function(_ref){var _ref2=_slicedToArray(_ref,2),reldataset=_ref2[0],relvalues=_ref2[1];return new Promise(function(resolveTable){Promise.all(relvalues.features.map(function(feature){return new Promise(function(resolveFeature){var relEditConfig=Object.values(editConfigs).find(function(entry){return entry.editDataset===reldataset});computeExpressionFields(relEditConfig,feature,EditingInterface,mapCrs,resolveFeature)})})).then(function(newfeatures){return resolveTable([reldataset,_objectSpread(_objectSpread({},relvalues),{},{features:newfeatures})])})})})).then(function(entries){return callback(Object.fromEntries(entries))})})["catch"](function(){return callback({})})},/**
|
|
85
|
+
* Query key-value-pairs of a key-value-relation
|
|
86
|
+
* @param keyvalues The keyval string `<keyvaldataset>:<keyfield>:<valuefield>`
|
|
87
|
+
* @param callback Callback invoked with the key-value pairs, taking `{keyvalues: {<keyvaldataset>: [{key: <key>, value: <value>}]}}` on success and `{}` on failure
|
|
88
|
+
* @param filter An optional filter expression, as `[[["<name>", "<op>", <value>],"and|or",["<name>","<op>",<value>],...]]` (one filter expr per keyvalue entry)
|
|
89
|
+
*/getKeyValues:function getKeyValues(keyvalues,callback){var filter=arguments.length>2&&arguments[2]!==undefined?arguments[2]:null;var editServiceUrl=ConfigUtils.getConfigProp("editServiceUrl").replace(/\/$/,"");var req=editServiceUrl+"/"+"keyvals?tables="+keyvalues;var params={filter:filter?JSON.stringify(filter):undefined};var headers={"Accept-Language":LocaleUtils.lang()};axios.get(req,{headers:headers,params:params}).then(function(response){callback(response.data)})["catch"](function(){return callback({})})},/**
|
|
90
|
+
* Resolve an attachment value to a full URL
|
|
91
|
+
*
|
|
92
|
+
* @param dataset The dataset name
|
|
93
|
+
* @param fileValue The attachment value
|
|
94
|
+
*/resolveAttachmentUrl:function resolveAttachmentUrl(dataset,fileValue){var editServiceUrl=ConfigUtils.getConfigProp("editServiceUrl").replace(/\/$/,"");return editServiceUrl+"/"+dataset+"/attachment?file="+encodeURIComponent(fileValue)}};export default EditingInterface;
|
package/utils/EditingUtils.js
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
|
-
var
|
|
1
|
+
var _FeatureCache,_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 _slicedToArray(r,e){return _arrayWithHoles(r)||_iterableToArrayLimit(r,e)||_unsupportedIterableToArray(r,e)||_nonIterableRest()}function _nonIterableRest(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _iterableToArrayLimit(r,l){var t=null==r?null:"undefined"!=typeof Symbol&&r[Symbol.iterator]||r["@@iterator"];if(null!=t){var e,n,i,u,a=[],f=!0,o=!1;try{if(i=(t=t.call(r)).next,0===l){if(Object(t)!==t)return;f=!1}else for(;!(f=(e=i.call(t)).done)&&(a.push(e.value),a.length!==l);f=!0);}catch(r){o=!0,n=r}finally{try{if(!f&&null!=t["return"]&&(u=t["return"](),Object(u)!==u))return}finally{if(o)throw n}}return a}}function _arrayWithHoles(r){if(Array.isArray(r))return r}function _toConsumableArray(r){return _arrayWithoutHoles(r)||_iterableToArray(r)||_unsupportedIterableToArray(r)||_nonIterableSpread()}function _nonIterableSpread(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _unsupportedIterableToArray(r,a){if(r){if("string"==typeof r)return _arrayLikeToArray(r,a);var t={}.toString.call(r).slice(8,-1);return"Object"===t&&r.constructor&&(t=r.constructor.name),"Map"===t||"Set"===t?Array.from(r):"Arguments"===t||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t)?_arrayLikeToArray(r,a):void 0}}function _iterableToArray(r){if("undefined"!=typeof Symbol&&null!=r[Symbol.iterator]||null!=r["@@iterator"])return Array.from(r)}function _arrayWithoutHoles(r){if(Array.isArray(r))return _arrayLikeToArray(r)}function _arrayLikeToArray(r,a){(null==a||a>r.length)&&(a=r.length);for(var e=0,n=Array(a);e<a;e++)n[e]=r[e];return n}function 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 _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)}/**
|
|
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 nearley from"nearley";import ConfigUtils from"./ConfigUtils";import LocaleUtils from"./LocaleUtils";import grammar from"./expr_grammar/grammar";export var
|
|
8
|
-
|
|
9
|
-
Promise.all(promises).then(
|
|
10
|
-
|
|
7
|
+
*/import nearley from"nearley";import toposort from"toposort";import{v5 as uuidv5}from"uuid";import StandardApp from"../components/StandardApp";import ConfigUtils from"./ConfigUtils";import LocaleUtils from"./LocaleUtils";import grammar from"./expr_grammar/grammar";var UUID_NS="5ae5531d-8e21-4456-b45d-77e9840a5bb7";export var FeatureCache=/*#__PURE__*/_createClass(function FeatureCache(){_classCallCheck(this,FeatureCache)});_FeatureCache=FeatureCache;_defineProperty(FeatureCache,"store",{});_defineProperty(FeatureCache,"requestPromises",{});_defineProperty(FeatureCache,"get",function(editIface,layerName,mapCrs,filterExpr){var key=layerName+uuidv5(JSON.stringify(filterExpr!==null&&filterExpr!==void 0?filterExpr:null),UUID_NS);if(key in _FeatureCache.store){return new Promise(function(resolve){return resolve(_FeatureCache.store[key])})}else if(key in _FeatureCache.requestPromises){return _FeatureCache.requestPromises[key]}else{_FeatureCache.requestPromises[key]=new Promise(function(resolve){var _StandardApp$store$ge,_StandardApp$store$ge2;var editConfig=(_StandardApp$store$ge=(_StandardApp$store$ge2=StandardApp.store.getState().theme.current.editConfig)===null||_StandardApp$store$ge2===void 0?void 0:_StandardApp$store$ge2[layerName])!==null&&_StandardApp$store$ge!==void 0?_StandardApp$store$ge:{};editIface.getFeatures(editConfig,mapCrs,function(result){if(key in _FeatureCache.requestPromises){if(((result===null||result===void 0?void 0:result.features)||[]).length===1){_FeatureCache.store[key]=result.features[0]}else{_FeatureCache.store[key]=null}if(key in _FeatureCache.requestPromises){resolve(_FeatureCache.store[key]);delete _FeatureCache.requestPromises[key]}}else{resolve(null)}},null,filterExpr)});return _FeatureCache.requestPromises[key]}});_defineProperty(FeatureCache,"getSync",function(editIface,layerName,mapCrs,filterExpr){var promises=arguments.length>4&&arguments[4]!==undefined?arguments[4]:[];var key=layerName+uuidv5(JSON.stringify(filterExpr!==null&&filterExpr!==void 0?filterExpr:null),UUID_NS);if(key in _FeatureCache.store){return _FeatureCache.store[key]}else{promises.push(_FeatureCache.get(editIface,layerName,mapCrs,filterExpr));return null}});_defineProperty(FeatureCache,"clear",function(){_FeatureCache.store={};_FeatureCache.requests=new Set});export var KeyValCache=/*#__PURE__*/_createClass(function KeyValCache(){_classCallCheck(this,KeyValCache)});_KeyValCache=KeyValCache;_defineProperty(KeyValCache,"store",{});_defineProperty(KeyValCache,"requestPromises",{});_defineProperty(KeyValCache,"get",function(editIface,keyvalrel,filterExpr){var key=keyvalrel+uuidv5(JSON.stringify(filterExpr!==null&&filterExpr!==void 0?filterExpr:null),UUID_NS);if(key in _KeyValCache.store){return new Promise(function(resolve){return resolve(_KeyValCache.store[key])})}else if(key in _KeyValCache.requestPromises){return _KeyValCache.requestPromises[key]}else{_KeyValCache.requestPromises[key]=new Promise(function(resolve){editIface.getKeyValues(keyvalrel,function(result){if(key in _KeyValCache.requestPromises){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]=[]}resolve(_KeyValCache.store[key]);delete _KeyValCache.requestPromises[key]}else{resolve([])}},filterExpr?[filterExpr]:null)});return _KeyValCache.requestPromises[key]}});_defineProperty(KeyValCache,"getSync",function(editIface,keyvalrel,filterExpr){var promises=arguments.length>3&&arguments[3]!==undefined?arguments[3]:[];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{promises.push(_KeyValCache.get(editIface,keyvalrel,filterExpr));return[]}});_defineProperty(KeyValCache,"clear",function(){_KeyValCache.store={};_KeyValCache.requestPromises={}});function _representValue(attr,editConfig,editIface,promises){var _window$qwc2Expressio,_field$constraints;// Resolve kvrel
|
|
8
|
+
var field=(editConfig.fields||[]).find(function(f){return f.id===attr});var value=(_window$qwc2Expressio=window.qwc2ExpressionParserContext.feature)===null||_window$qwc2Expressio===void 0||(_window$qwc2Expressio=_window$qwc2Expressio.properties)===null||_window$qwc2Expressio===void 0?void 0:_window$qwc2Expressio[attr];var keyvalrel=field===null||field===void 0||(_field$constraints=field.constraints)===null||_field$constraints===void 0?void 0:_field$constraints.keyvalrel;if(!keyvalrel){return value}var keyvals=KeyValCache.getSync(editIface,keyvalrel,null,promises).reduce(function(res,entry){return _objectSpread(_objectSpread({},res),{},_defineProperty({},entry.value,entry.label))},{});if(field.constraints.allowMulti){return"{"+_toConsumableArray(new Set(JSON.parse("["+value.slice(1,-1)+"]"))).map(function(x){var _keyvals$x;return(_keyvals$x=keyvals[x])!==null&&_keyvals$x!==void 0?_keyvals$x:x}).join(", ")+"}"}else{var _keyvals$value;return(_keyvals$value=keyvals[value])!==null&&_keyvals$value!==void 0?_keyvals$value:value}}export function parseExpression(expr,feature,editConfig,editIface,mapPrefix,mapCrs,reevaluateCallback){var asFilter=arguments.length>7&&arguments[7]!==undefined?arguments[7]:false;var reevaluate=arguments.length>8&&arguments[8]!==undefined?arguments[8]:false;var parser=new nearley.Parser(nearley.Grammar.fromCompiled(grammar));var promises=[];window.qwc2ExpressionParserContext={feature:feature,getFeature:function getFeature(layerName,attr,value){return FeatureCache.getSync(editIface,layerName,mapCrs,[[attr,"=",value]],promises)},representValue:function representValue(attr){return _representValue(attr,editConfig,editIface,promises)},asFilter:asFilter,username:ConfigUtils.getConfigProp("username"),layer:editConfig.layerName,projection:mapCrs,mapPrefix:mapPrefix,lang:LocaleUtils.lang()};var result=null;try{parser.feed(expr.replace(/\n/," "));result=parser.results[0]}catch(e){/* eslint-disable-next-line */console.warn("Failed to evaluate expression "+expr.replace(/\n/," "))}delete window.qwc2ExpressionParserContext;if(promises.length>0){// Expression evaluation is incomplete due to pending feature requests, reevaluate when promises are resolved
|
|
9
|
+
Promise.all(promises).then(function(){return parseExpression(expr,feature,editConfig,editIface,mapPrefix,mapCrs,reevaluateCallback,asFilter,true)});return null}else{if(reevaluate){reevaluateCallback()}if(asFilter){result=[result]}return result}}export function parseExpressionsAsync(fieldExpressions,feature,editConfig,editIface,mapPrefix,mapCrs,asFilter){var promises=[];return new Promise(function(resolve){var newfeature=_objectSpread(_objectSpread({},feature),{},{properties:_objectSpread({},feature.properties)});window.qwc2ExpressionParserContext={feature:newfeature,getFeature:function getFeature(layerName,attr,value){return FeatureCache.getSync(editIface,layerName,mapCrs,[[attr,"=",value]],promises)},representValue:function representValue(attr){return _representValue(attr,editConfig,editIface,promises)},asFilter:asFilter,username:ConfigUtils.getConfigProp("username"),layer:editConfig.layerName,projection:mapCrs,mapPrefix:mapPrefix,lang:LocaleUtils.lang()};var results=fieldExpressions.reduce(function(res,_ref){var field=_ref.field,expression=_ref.expression;var parser=new nearley.Parser(nearley.Grammar.fromCompiled(grammar));try{parser.feed(expression.replace(/\n/," "));// NOTE: include intermediate results in next context feature
|
|
10
|
+
newfeature.properties[field]=parser.results[0];return _objectSpread(_objectSpread({},res),{},_defineProperty({},field,parser.results[0]))}catch(e){/* eslint-disable-next-line */console.warn("Failed to evaluate expression "+expr.replace(/\n/," "));return res}},{});delete window.qwc2ExpressionParserContext;if(promises.length>0){// Expression evaluation is incomplete due to pending feature requests, reevaluate when promises are resolved
|
|
11
|
+
Promise.all(promises).then(function(){parseExpressionsAsync(fieldExpressions,newfeature,editConfig,editIface,mapPrefix,mapCrs,asFilter).then(function(results2){return resolve(results2)})})}else{resolve(results)}})}var FeatureTemplateFactories={};export function setFeatureTemplateFactory(dataset,factory){FeatureTemplateFactories[dataset]=factory}export function getFeatureTemplate(editConfig,feature,editIface,mapPrefix,mapCrs,callback){if(editConfig.editDataset in FeatureTemplateFactories){feature=FeatureTemplateFactories[editConfig.editDataset](feature)}// Apply default values
|
|
12
|
+
var defaultFieldExpressions=editConfig.fields.reduce(function(res,field){if(field.defaultValue){return[].concat(_toConsumableArray(res),[{field:field.id,expression:field.defaultValue.replace(/^expr:/,"")}])}return res},[]);FeatureCache.clear();parseExpressionsAsync(defaultFieldExpressions,feature,editConfig,editIface,mapPrefix,mapCrs).then(function(result){// Adjust values based on field type
|
|
13
|
+
editConfig.fields.forEach(function(field){if(field.id in result&&field.type==="date"){result[field.id]=result[field.id].split("T")[0]}});callback(_objectSpread(_objectSpread({},feature),{},{properties:_objectSpread(_objectSpread({},feature.properties),result)}))})}export function computeExpressionFields(editConfig,feature,editIface,mapCrs,callback){// Collect field expressions and dependencies
|
|
14
|
+
var dependencies={};var fieldExpressions=editConfig.fields.reduce(function(res,field){if(field.expression){var matches=_toConsumableArray(field.expression.matchAll(/"([^"]+)"/g)).map(function(m){return m[1]});dependencies[field.id]=_toConsumableArray(new Set(matches));return _objectSpread(_objectSpread({},res),{},_defineProperty({},field.id,field.expression))}return res},{});// Topologically sort expressions so that fields depending on other fields are evaluated later
|
|
15
|
+
var edges=[];Object.entries(dependencies).forEach(function(_ref2){var _ref3=_slicedToArray(_ref2,2),parent=_ref3[0],children=_ref3[1];children.forEach(function(child){return edges.push([child,parent])})});try{var sortededges=toposort(edges);fieldExpressions=sortededges.reduce(function(res,field){if(field in fieldExpressions){return[].concat(_toConsumableArray(res),[{field:field,expression:fieldExpressions[field]}])}else{return res}},[])}catch(e){/* eslint-disable-next-line */console.warn("Failed to sort expressions, they probably contain cyclic dependencies");fieldExpressions=Object.entries(fieldExpressions).map(function(res,_ref4){var _ref5=_slicedToArray(_ref4,2),field=_ref5[0],expression=_ref5[1];return[].concat(_toConsumableArray(res),[{field:field,expression:expression}])},{})}// Evaluate expressions
|
|
16
|
+
FeatureCache.clear();var mapPrefix=(editConfig.editDataset.match(/^[^.]+\./)||[""])[0];parseExpressionsAsync(fieldExpressions,feature,editConfig,editIface,mapPrefix,mapCrs).then(function(result){// Adjust values based on field type
|
|
11
17
|
editConfig.fields.forEach(function(field){if(field.id in result&&field.type==="date"){result[field.id]=result[field.id].split("T")[0]}});callback(_objectSpread(_objectSpread({},feature),{},{properties:_objectSpread(_objectSpread({},feature.properties),result)}))})}
|