@eeacms/volto-arcgis-block 0.1.429 → 0.1.431
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/CHANGELOG.md
CHANGED
|
@@ -4,10 +4,26 @@ All notable changes to this project will be documented in this file. Dates are d
|
|
|
4
4
|
|
|
5
5
|
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
6
6
|
|
|
7
|
+
### [0.1.431](https://github.com/eea/volto-arcgis-block/compare/0.1.430...0.1.431) - 3 March 2026
|
|
8
|
+
|
|
9
|
+
#### :house: Internal changes
|
|
10
|
+
|
|
11
|
+
- chore: [JENKINSFILE] add package version in sonarqube [valentinab25 - [`78addd9`](https://github.com/eea/volto-arcgis-block/commit/78addd9908a5a16eb8b8c984b6d98fe992af4449)]
|
|
12
|
+
- chore: [JENKINSFILE] add package version in sonarqube [EEA Jenkins - [`3001a9d`](https://github.com/eea/volto-arcgis-block/commit/3001a9d84c1ceb2072d2c8fdf42b75b0fa2a36c7)]
|
|
13
|
+
- chore: [JENKINSFILE] add sonarqube branches Refs #293878 [EEA Jenkins - [`3430596`](https://github.com/eea/volto-arcgis-block/commit/34305966fc548b9213d2a914cdd61fdb4ef3a973)]
|
|
14
|
+
|
|
15
|
+
### [0.1.430](https://github.com/eea/volto-arcgis-block/compare/0.1.429...0.1.430) - 19 February 2026
|
|
16
|
+
|
|
17
|
+
#### :hammer_and_wrench: Others
|
|
18
|
+
|
|
19
|
+
- Merge pull request #1106 from eea/develop [Unai Bolivar - [`d05af07`](https://github.com/eea/volto-arcgis-block/commit/d05af073c82e9137010ce0b2555a9405989e300f)]
|
|
20
|
+
- (bug): WFS fix [Unai Bolivar - [`dd08e60`](https://github.com/eea/volto-arcgis-block/commit/dd08e60240a885b9e611b6e096d413027a4d2b2c)]
|
|
21
|
+
- (bug): shapefileLimit error popup [Unai Bolivar - [`70d95a5`](https://github.com/eea/volto-arcgis-block/commit/70d95a5d58feed47bf027a0a213eb892a6d1a661)]
|
|
7
22
|
### [0.1.429](https://github.com/eea/volto-arcgis-block/compare/0.1.428...0.1.429) - 17 February 2026
|
|
8
23
|
|
|
9
24
|
#### :hammer_and_wrench: Others
|
|
10
25
|
|
|
26
|
+
- Merge pull request #1104 from eea/develop [Unai Bolivar - [`b5afb9b`](https://github.com/eea/volto-arcgis-block/commit/b5afb9bb2ca6486c1d0b72c87caebf4acc630e07)]
|
|
11
27
|
- (bug): styles for buttons in upload widget and error popup message for file size limit on hspae files [Unai Bolivar - [`d9ca59e`](https://github.com/eea/volto-arcgis-block/commit/d9ca59ec245fdc94a2d1bf678b6e3d610d5a792d)]
|
|
12
28
|
- (bug): reset upload widget to allow users to start from zero without finishing a process first [Unai Bolivar - [`1539a3a`](https://github.com/eea/volto-arcgis-block/commit/1539a3ada8fef0fbda5203b61ec2aed60ab014b5)]
|
|
13
29
|
- (bug): truncate title to 33 max char and add ellipsis for user created services and move trashcan icon to the right edge of the menu item div [Unai Bolivar - [`a31612d`](https://github.com/eea/volto-arcgis-block/commit/a31612df1ee629937e115b1fec1c50092b659626)]
|
package/Jenkinsfile
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
pipeline {
|
|
2
|
-
tools {
|
|
3
|
-
jdk 'Java17'
|
|
4
|
-
}
|
|
5
2
|
agent {
|
|
6
3
|
node { label 'docker-host' }
|
|
7
4
|
}
|
|
@@ -240,11 +237,17 @@ pipeline {
|
|
|
240
237
|
// script {
|
|
241
238
|
// def scannerHome = tool 'SonarQubeScanner'
|
|
242
239
|
// def nodeJS = tool 'NodeJS'
|
|
240
|
+
// if (env.CHANGE_ID) {
|
|
241
|
+
// env.sonarParams = " -Dsonar.pullrequest.base=${env.CHANGE_TARGET} -Dsonar.pullrequest.branch=${env.CHANGE_BRANCH} -Dsonar.pullrequest.key=${env.CHANGE_ID} "
|
|
242
|
+
// }
|
|
243
|
+
// else {
|
|
244
|
+
// env.sonarParams = " -Dsonar.branch.name=${env.BRANCH_NAME}"
|
|
245
|
+
// }
|
|
243
246
|
// withSonarQubeEnv('Sonarqube') {
|
|
244
247
|
// sh '''sed -i "s#/app/src/addons/${GIT_NAME}/##g" xunit-reports/coverage/lcov.info'''
|
|
245
248
|
// sh '''sed -i "s#src/addons/${GIT_NAME}/##g" xunit-reports/coverage/lcov.info'''
|
|
246
|
-
// sh "export PATH=${scannerHome}/bin:${nodeJS}/bin:$PATH; sonar-scanner -Dsonar.javascript.lcov.reportPaths=./xunit-reports/coverage/lcov.info,./cypress-coverage/coverage/lcov.info -Dsonar.sources=./src -Dsonar.projectKey=$GIT_NAME
|
|
247
|
-
// sh '''try=5; while [ \$try -gt 0 ]; do curl -s -XPOST -u "${SONAR_AUTH_TOKEN}:" "${SONAR_HOST_URL}api/project_tags/set?project=${GIT_NAME}
|
|
249
|
+
// sh "export PATH=${scannerHome}/bin:${nodeJS}/bin:$PATH; sonar-scanner -Dsonar.javascript.lcov.reportPaths=./xunit-reports/coverage/lcov.info,./cypress-coverage/coverage/lcov.info -Dsonar.sources=./src -Dsonar.projectKey=$GIT_NAME -Dsonar.projectName=$GIT_NAME -Dsonar.projectVersion=\$(jq -r '.version' package.json) ${env.sonarParams}"
|
|
250
|
+
// sh '''try=5; while [ \$try -gt 0 ]; do curl -s -XPOST -u "${SONAR_AUTH_TOKEN}:" "${SONAR_HOST_URL}api/project_tags/set?project=${GIT_NAME}&tags=${SONARQUBE_TAGS}" > set_tags_result; if [ \$(grep -ic error set_tags_result ) -eq 0 ]; then try=0; else cat set_tags_result; echo "... Will retry"; sleep 15; try=\$(( \$try - 1 )); fi; done'''
|
|
248
251
|
// }
|
|
249
252
|
// }
|
|
250
253
|
// }
|
|
@@ -268,7 +271,7 @@ pipeline {
|
|
|
268
271
|
// script {
|
|
269
272
|
// sh '''echo "Error" > checkresult.txt'''
|
|
270
273
|
// catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
|
|
271
|
-
// sh '''set -o pipefail; docker run -i --rm --pull always --name="$IMAGE_NAME-gitflow-sn" -e GIT_BRANCH="$BRANCH_NAME" -e GIT_NAME="$GIT_NAME" eeacms/gitflow /
|
|
274
|
+
// sh '''set -o pipefail; docker run -i --rm --pull always --name="$IMAGE_NAME-gitflow-sn" -e GIT_BRANCH="$BRANCH_NAME" -e GIT_NAME="$GIT_NAME" eeacms/gitflow /checkSonarqubemasterV2.sh | grep -v "Found script" | tee checkresult.txt'''
|
|
272
275
|
// }
|
|
273
276
|
|
|
274
277
|
// publishChecks name: 'SonarQube', title: 'Sonarqube Code Quality Check', summary: 'Quality check on the SonarQube metrics from branch develop, comparing it with the ones from master branch. No bugs are allowed',
|
package/README.md
CHANGED
|
@@ -3,16 +3,16 @@
|
|
|
3
3
|
[](https://github.com/eea/volto-arcgis-block/releases)
|
|
4
4
|
|
|
5
5
|
[](https://ci.eionet.europa.eu/view/Github/job/volto-addons/job/volto-arcgis-block/job/master/display/redirect)
|
|
6
|
-
[](https://sonarqube.eea.europa.eu/api/project_badges/measure?project=volto-arcgis-block
|
|
6
|
+
[](https://sonarqube.eea.europa.eu/dashboard?id=volto-arcgis-block)
|
|
7
|
+
[](https://sonarqube.eea.europa.eu/dashboard?id=volto-arcgis-block)
|
|
8
|
+
[](https://sonarqube.eea.europa.eu/dashboard?id=volto-arcgis-block)
|
|
9
|
+
[](https://sonarqube.eea.europa.eu/dashboard?id=volto-arcgis-block)
|
|
10
10
|
|
|
11
11
|
[](https://ci.eionet.europa.eu/view/Github/job/volto-addons/job/volto-arcgis-block/job/develop/display/redirect)
|
|
12
|
-
[](https://sonarqube.eea.europa.eu/api/project_badges/measure?project=volto-arcgis-block
|
|
12
|
+
[](https://sonarqube.eea.europa.eu/dashboard?id=volto-arcgis-block&branch=develop)
|
|
13
|
+
[](https://sonarqube.eea.europa.eu/dashboard?id=volto-arcgis-block&branch=develop)
|
|
14
|
+
[](https://sonarqube.eea.europa.eu/dashboard?id=volto-arcgis-block&branch=develop)
|
|
15
|
+
[](https://sonarqube.eea.europa.eu/dashboard?id=volto-arcgis-block&branch=develop)
|
|
16
16
|
|
|
17
17
|
## ArcGIS Map integration for Volto blocks
|
|
18
18
|
|
package/package.json
CHANGED
|
@@ -15,7 +15,9 @@ var Graphic,
|
|
|
15
15
|
SimpleLineSymbol,
|
|
16
16
|
SimpleFillSymbol,
|
|
17
17
|
SpatialReference,
|
|
18
|
-
Polygon
|
|
18
|
+
Polygon,
|
|
19
|
+
TextSymbol,
|
|
20
|
+
Point;
|
|
19
21
|
|
|
20
22
|
class AreaWidget extends React.Component {
|
|
21
23
|
/**
|
|
@@ -40,6 +42,12 @@ class AreaWidget extends React.Component {
|
|
|
40
42
|
east: '',
|
|
41
43
|
west: '',
|
|
42
44
|
},
|
|
45
|
+
areaCoordinates: {
|
|
46
|
+
originLat: '',
|
|
47
|
+
originLon: '',
|
|
48
|
+
cursorLat: '',
|
|
49
|
+
cursorLon: '',
|
|
50
|
+
},
|
|
43
51
|
};
|
|
44
52
|
this.menuClass =
|
|
45
53
|
'esri-icon-cursor-marquee esri-widget--button esri-widget esri-interactive';
|
|
@@ -74,6 +82,8 @@ class AreaWidget extends React.Component {
|
|
|
74
82
|
'esri/symbols/SimpleFillSymbol',
|
|
75
83
|
'esri/geometry/SpatialReference',
|
|
76
84
|
'esri/geometry/Polygon',
|
|
85
|
+
'esri/symbols/TextSymbol',
|
|
86
|
+
'esri/geometry/Point',
|
|
77
87
|
]).then(
|
|
78
88
|
([
|
|
79
89
|
_Graphic,
|
|
@@ -89,6 +99,8 @@ class AreaWidget extends React.Component {
|
|
|
89
99
|
_SimpleFillSymbol,
|
|
90
100
|
_SpatialReference,
|
|
91
101
|
_Polygon,
|
|
102
|
+
_TextSymbol,
|
|
103
|
+
_Point,
|
|
92
104
|
]) => {
|
|
93
105
|
[
|
|
94
106
|
Graphic,
|
|
@@ -104,6 +116,8 @@ class AreaWidget extends React.Component {
|
|
|
104
116
|
SimpleFillSymbol,
|
|
105
117
|
SpatialReference,
|
|
106
118
|
Polygon,
|
|
119
|
+
TextSymbol,
|
|
120
|
+
Point,
|
|
107
121
|
] = [
|
|
108
122
|
_Graphic,
|
|
109
123
|
_Extent,
|
|
@@ -118,6 +132,8 @@ class AreaWidget extends React.Component {
|
|
|
118
132
|
_SimpleFillSymbol,
|
|
119
133
|
_SpatialReference,
|
|
120
134
|
_Polygon,
|
|
135
|
+
_TextSymbol,
|
|
136
|
+
_Point,
|
|
121
137
|
];
|
|
122
138
|
},
|
|
123
139
|
);
|
|
@@ -922,12 +938,35 @@ class AreaWidget extends React.Component {
|
|
|
922
938
|
|
|
923
939
|
let extentGraphic = null;
|
|
924
940
|
let origin = null;
|
|
941
|
+
let originGraphic = null;
|
|
942
|
+
let cursorGraphic = null;
|
|
925
943
|
const drawGraphics = this.props.view.on('drag', (e) => {
|
|
926
944
|
if (this.props.mapViewer.pan_enabled) return;
|
|
927
945
|
e.stopPropagation();
|
|
928
946
|
if (e.action === 'start') {
|
|
929
947
|
if (extentGraphic) this.props.view.graphics.remove(extentGraphic);
|
|
948
|
+
if (originGraphic) this.props.view.graphics.remove(originGraphic);
|
|
930
949
|
origin = this.props.view.toMap(e);
|
|
950
|
+
this.setState({
|
|
951
|
+
areaCoordinates: {
|
|
952
|
+
originLat: origin.latitude.toFixed(3),
|
|
953
|
+
originLon: origin.longitude.toFixed(3),
|
|
954
|
+
},
|
|
955
|
+
});
|
|
956
|
+
let originTextSymbol = new TextSymbol(
|
|
957
|
+
this.state.areaCoordinates.originLon +
|
|
958
|
+
' , ' +
|
|
959
|
+
this.state.areaCoordinates.originLat,
|
|
960
|
+
);
|
|
961
|
+
originTextSymbol.horizontalAlignment = 'right';
|
|
962
|
+
originTextSymbol.verticalAlignment = 'bottom';
|
|
963
|
+
originTextSymbol.font.size = 8;
|
|
964
|
+
var point = new Point(
|
|
965
|
+
this.state.areaCoordinates.originLon,
|
|
966
|
+
this.state.areaCoordinates.originLat,
|
|
967
|
+
);
|
|
968
|
+
originGraphic = new Graphic(point, originTextSymbol);
|
|
969
|
+
this.props.view.graphics.add(originGraphic);
|
|
931
970
|
if (extentGraphic && this.checkExtent(extentGraphic.geometry)) {
|
|
932
971
|
this.setState({
|
|
933
972
|
showInfoPopup: true,
|
|
@@ -963,7 +1002,16 @@ class AreaWidget extends React.Component {
|
|
|
963
1002
|
}
|
|
964
1003
|
} else if (e.action === 'update') {
|
|
965
1004
|
if (extentGraphic) this.props.view.graphics.remove(extentGraphic);
|
|
1005
|
+
if (cursorGraphic) this.props.view.graphics.remove(cursorGraphic);
|
|
966
1006
|
let p = this.props.view.toMap(e);
|
|
1007
|
+
this.setState({
|
|
1008
|
+
areaCoordinates: {
|
|
1009
|
+
originLat: this.state.areaCoordinates.originLat,
|
|
1010
|
+
originLon: this.state.areaCoordinates.originLon,
|
|
1011
|
+
cursorLat: p.latitude.toFixed(3),
|
|
1012
|
+
cursorLon: p.longitude.toFixed(3),
|
|
1013
|
+
},
|
|
1014
|
+
});
|
|
967
1015
|
extentGraphic = new Graphic({
|
|
968
1016
|
geometry: new Extent({
|
|
969
1017
|
xmin: Math.min(p.x, origin.x),
|
|
@@ -1012,6 +1060,20 @@ class AreaWidget extends React.Component {
|
|
|
1012
1060
|
end: { x: p.longitude, y: p.latitude },
|
|
1013
1061
|
});
|
|
1014
1062
|
this.props.view.graphics.add(extentGraphic);
|
|
1063
|
+
let cursorTextSymbol = new TextSymbol(
|
|
1064
|
+
this.state.areaCoordinates.cursorLon +
|
|
1065
|
+
' , ' +
|
|
1066
|
+
this.state.areaCoordinates.cursorLat,
|
|
1067
|
+
);
|
|
1068
|
+
cursorTextSymbol.horizontalAlignment = 'left';
|
|
1069
|
+
cursorTextSymbol.verticalAlignment = 'top';
|
|
1070
|
+
cursorTextSymbol.font.size = 8;
|
|
1071
|
+
var point2 = new Point(
|
|
1072
|
+
this.state.areaCoordinates.cursorLon,
|
|
1073
|
+
this.state.areaCoordinates.cursorLat,
|
|
1074
|
+
);
|
|
1075
|
+
cursorGraphic = new Graphic(point2, cursorTextSymbol);
|
|
1076
|
+
this.props.view.graphics.add(cursorGraphic);
|
|
1015
1077
|
}
|
|
1016
1078
|
});
|
|
1017
1079
|
this.setState({
|
|
@@ -2474,6 +2474,17 @@ class MenuWidget extends React.Component {
|
|
|
2474
2474
|
const versionList = Array.from(versionSet);
|
|
2475
2475
|
const formatList = Array.from(formatSet);
|
|
2476
2476
|
const srsList = Array.from(srsSet);
|
|
2477
|
+
const normalizedSrsList = srsList
|
|
2478
|
+
.map((srsValue) => {
|
|
2479
|
+
const textValue = (srsValue || '').trim();
|
|
2480
|
+
const epsgMatch = textValue.match(/EPSG(?::|::|\/)(\d+)/i);
|
|
2481
|
+
if (epsgMatch && epsgMatch[1]) {
|
|
2482
|
+
return `EPSG:${epsgMatch[1]}`;
|
|
2483
|
+
}
|
|
2484
|
+
const normalizedSrsValue = textValue.toUpperCase();
|
|
2485
|
+
return normalizedSrsValue || null;
|
|
2486
|
+
})
|
|
2487
|
+
.filter(Boolean);
|
|
2477
2488
|
const requestVersion = versionList.includes('2.0.0')
|
|
2478
2489
|
? '2.0.0'
|
|
2479
2490
|
: versionList.includes('1.1.0')
|
|
@@ -2487,9 +2498,9 @@ class MenuWidget extends React.Component {
|
|
|
2487
2498
|
const preferredXmlFormat = formatList.find((item) =>
|
|
2488
2499
|
/text\/xml|xml|gml/i.test(item),
|
|
2489
2500
|
);
|
|
2490
|
-
const requestSrsName =
|
|
2501
|
+
const requestSrsName = normalizedSrsList.includes('EPSG:4326')
|
|
2491
2502
|
? 'EPSG:4326'
|
|
2492
|
-
:
|
|
2503
|
+
: normalizedSrsList[0] || 'EPSG:4326';
|
|
2493
2504
|
return {
|
|
2494
2505
|
requestVersion,
|
|
2495
2506
|
requestFormat: preferredJsonFormat || preferredXmlFormat || null,
|
|
@@ -2581,6 +2592,69 @@ class MenuWidget extends React.Component {
|
|
|
2581
2592
|
);
|
|
2582
2593
|
}
|
|
2583
2594
|
|
|
2595
|
+
resolveResponseData(responseData) {
|
|
2596
|
+
const resolveJsonData = (dataValue) => {
|
|
2597
|
+
if (!dataValue || typeof dataValue !== 'object') {
|
|
2598
|
+
return null;
|
|
2599
|
+
}
|
|
2600
|
+
if (
|
|
2601
|
+
dataValue.type === 'FeatureCollection' &&
|
|
2602
|
+
Array.isArray(dataValue.features)
|
|
2603
|
+
) {
|
|
2604
|
+
return {
|
|
2605
|
+
...dataValue,
|
|
2606
|
+
type: 'FeatureCollection',
|
|
2607
|
+
features: dataValue.features,
|
|
2608
|
+
};
|
|
2609
|
+
}
|
|
2610
|
+
if (Array.isArray(dataValue.features)) {
|
|
2611
|
+
return {
|
|
2612
|
+
...dataValue,
|
|
2613
|
+
type: 'FeatureCollection',
|
|
2614
|
+
features: dataValue.features,
|
|
2615
|
+
};
|
|
2616
|
+
}
|
|
2617
|
+
if (dataValue.type === 'Feature' && dataValue.geometry) {
|
|
2618
|
+
return {
|
|
2619
|
+
type: 'FeatureCollection',
|
|
2620
|
+
features: [dataValue],
|
|
2621
|
+
};
|
|
2622
|
+
}
|
|
2623
|
+
return null;
|
|
2624
|
+
};
|
|
2625
|
+
|
|
2626
|
+
if (typeof responseData === 'string') {
|
|
2627
|
+
const textValue = responseData.trim();
|
|
2628
|
+
if (!textValue) {
|
|
2629
|
+
return null;
|
|
2630
|
+
}
|
|
2631
|
+
if (this.hasExceptionResponse(textValue)) {
|
|
2632
|
+
const exceptionMessage = this.resolveExceptionMessage(textValue);
|
|
2633
|
+
throw new Error(exceptionMessage || 'WFS request failed');
|
|
2634
|
+
}
|
|
2635
|
+
let parsedData = null;
|
|
2636
|
+
try {
|
|
2637
|
+
parsedData = JSON.parse(textValue);
|
|
2638
|
+
} catch (e) {}
|
|
2639
|
+
const jsonData = resolveJsonData(parsedData);
|
|
2640
|
+
if (jsonData) {
|
|
2641
|
+
return jsonData;
|
|
2642
|
+
}
|
|
2643
|
+
const xmlData = this.processXmlData(textValue);
|
|
2644
|
+
return this.resolveFeatureCollection(xmlData);
|
|
2645
|
+
}
|
|
2646
|
+
|
|
2647
|
+
return resolveJsonData(responseData);
|
|
2648
|
+
}
|
|
2649
|
+
|
|
2650
|
+
hasResultData(resultData) {
|
|
2651
|
+
return Boolean(
|
|
2652
|
+
resultData &&
|
|
2653
|
+
Array.isArray(resultData.features) &&
|
|
2654
|
+
resultData.features.length > 0,
|
|
2655
|
+
);
|
|
2656
|
+
}
|
|
2657
|
+
|
|
2584
2658
|
processXmlData(xmlInput) {
|
|
2585
2659
|
let doc = xmlInput;
|
|
2586
2660
|
if (typeof xmlInput === 'string') {
|
|
@@ -2993,34 +3067,16 @@ class MenuWidget extends React.Component {
|
|
|
2993
3067
|
const requestParams = this.buildRequestParams(name, requestConfig);
|
|
2994
3068
|
if (requestConfig.hasJsonFormat && requestConfig.requestFormat) {
|
|
2995
3069
|
requestParams.outputFormat = requestConfig.requestFormat;
|
|
3070
|
+
requestParams.outputformat = requestConfig.requestFormat;
|
|
2996
3071
|
}
|
|
2997
3072
|
const requestQuery = new URLSearchParams(requestParams).toString();
|
|
2998
3073
|
const requestUrl = baseUrl + '?' + requestQuery;
|
|
2999
3074
|
|
|
3000
3075
|
const id = (name || baseUrl).toUpperCase().replace(/[: ]/g, '_');
|
|
3001
|
-
|
|
3002
|
-
const layer = new GeoJSONLayer({
|
|
3003
|
-
url: requestUrl,
|
|
3004
|
-
id: id,
|
|
3005
|
-
title: title || name,
|
|
3006
|
-
});
|
|
3007
|
-
layer.LayerId = id;
|
|
3008
|
-
layer.ViewService = baseUrl;
|
|
3009
|
-
layer.name = name;
|
|
3010
|
-
return layer;
|
|
3011
|
-
}
|
|
3012
|
-
|
|
3013
|
-
const xmlResponse = await esriRequest(requestUrl, {
|
|
3076
|
+
const response = await esriRequest(requestUrl, {
|
|
3014
3077
|
responseType: 'text',
|
|
3015
3078
|
});
|
|
3016
|
-
|
|
3017
|
-
const exceptionMessage = this.resolveExceptionMessage(
|
|
3018
|
-
xmlResponse.data,
|
|
3019
|
-
);
|
|
3020
|
-
throw new Error(exceptionMessage || 'WFS request failed');
|
|
3021
|
-
}
|
|
3022
|
-
const xmlData = this.processXmlData(xmlResponse.data);
|
|
3023
|
-
const featureCollection = this.resolveFeatureCollection(xmlData);
|
|
3079
|
+
const featureCollection = this.resolveResponseData(response.data);
|
|
3024
3080
|
if (
|
|
3025
3081
|
featureCollection &&
|
|
3026
3082
|
featureCollection.memberCount > 0 &&
|
|
@@ -3031,7 +3087,7 @@ class MenuWidget extends React.Component {
|
|
|
3031
3087
|
'Selected WFS feature type has no geometry and cannot be displayed on map',
|
|
3032
3088
|
);
|
|
3033
3089
|
}
|
|
3034
|
-
if (!featureCollection
|
|
3090
|
+
if (!this.hasResultData(featureCollection)) {
|
|
3035
3091
|
throw new Error('No WFS features were returned for this layer');
|
|
3036
3092
|
}
|
|
3037
3093
|
const blobData = new Blob([JSON.stringify(featureCollection)], {
|
|
@@ -4,6 +4,7 @@ import { loadModules } from 'esri-loader';
|
|
|
4
4
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
|
5
5
|
|
|
6
6
|
var WMSLayer, WMTSLayer, WFSLayer, esriRequest;
|
|
7
|
+
const SHAPEFILE_MAX_SIZE_BYTES = 2097152;
|
|
7
8
|
|
|
8
9
|
class UploadWidget extends React.Component {
|
|
9
10
|
/**
|
|
@@ -193,18 +194,39 @@ class UploadWidget extends React.Component {
|
|
|
193
194
|
if (!file) {
|
|
194
195
|
return;
|
|
195
196
|
}
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
197
|
+
this.processInputPayload(file);
|
|
198
|
+
e.target.value = null;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
resolveInputError(filePayload) {
|
|
202
|
+
const inputName = ((filePayload && filePayload.name) || '').toLowerCase();
|
|
203
|
+
const inputExtension = inputName.split('.').pop();
|
|
204
|
+
if (inputExtension !== 'zip') {
|
|
205
|
+
return 'fileUploadError';
|
|
206
|
+
}
|
|
207
|
+
const inputSize = (filePayload && filePayload.size) || 0;
|
|
208
|
+
if (inputSize > SHAPEFILE_MAX_SIZE_BYTES) {
|
|
209
|
+
return 'shapefileLimit';
|
|
210
|
+
}
|
|
211
|
+
return null;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
processInputPayload(filePayload) {
|
|
215
|
+
const inputError = this.resolveInputError(filePayload);
|
|
216
|
+
if (inputError) {
|
|
217
|
+
this.setState({
|
|
218
|
+
showInfoPopup: true,
|
|
219
|
+
infoPopupType: inputError,
|
|
220
|
+
selectedFile: null,
|
|
221
|
+
globalDragActive: false,
|
|
222
|
+
});
|
|
200
223
|
if (typeof this.uploadFileErrorHandler === 'function') {
|
|
201
|
-
this.uploadFileErrorHandler();
|
|
224
|
+
this.uploadFileErrorHandler(inputError);
|
|
202
225
|
}
|
|
203
|
-
|
|
204
|
-
return;
|
|
226
|
+
return false;
|
|
205
227
|
}
|
|
206
|
-
this.setState({ selectedFile:
|
|
207
|
-
|
|
228
|
+
this.setState({ selectedFile: filePayload, globalDragActive: false });
|
|
229
|
+
return true;
|
|
208
230
|
}
|
|
209
231
|
|
|
210
232
|
getNormalizedUrlForType = (serviceUrl, serviceType) => {
|
|
@@ -259,14 +281,13 @@ class UploadWidget extends React.Component {
|
|
|
259
281
|
) {
|
|
260
282
|
return queryService;
|
|
261
283
|
}
|
|
262
|
-
const
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
/(^|[^a-z])(wmts|wms|wfs)([^a-z]|$)/i,
|
|
284
|
+
const pathName = (parsedUrl.pathname || '').toLowerCase();
|
|
285
|
+
const pathSegments = pathName.split('/').filter(Boolean);
|
|
286
|
+
const serviceMatch = pathSegments.find((segment) =>
|
|
287
|
+
/^(wmts|wms|wfs)$/i.test(segment),
|
|
267
288
|
);
|
|
268
|
-
if (serviceMatch
|
|
269
|
-
return serviceMatch
|
|
289
|
+
if (serviceMatch) {
|
|
290
|
+
return serviceMatch.toUpperCase();
|
|
270
291
|
}
|
|
271
292
|
return null;
|
|
272
293
|
} catch (e) {
|
|
@@ -1095,25 +1116,28 @@ class UploadWidget extends React.Component {
|
|
|
1095
1116
|
const file =
|
|
1096
1117
|
e.dataTransfer && e.dataTransfer.files && e.dataTransfer.files[0];
|
|
1097
1118
|
if (!file) return;
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1119
|
+
this.processInputPayload(file);
|
|
1120
|
+
}
|
|
1121
|
+
|
|
1122
|
+
handleAddClick() {
|
|
1123
|
+
const file = this.state.selectedFile;
|
|
1124
|
+
if (!file) return;
|
|
1125
|
+
const inputError = this.resolveInputError(file);
|
|
1126
|
+
if (inputError) {
|
|
1101
1127
|
this.setState({
|
|
1102
1128
|
showInfoPopup: true,
|
|
1103
|
-
infoPopupType:
|
|
1129
|
+
infoPopupType: inputError,
|
|
1104
1130
|
selectedFile: null,
|
|
1131
|
+
globalDragActive: false,
|
|
1105
1132
|
});
|
|
1106
1133
|
if (typeof this.uploadFileErrorHandler === 'function') {
|
|
1107
|
-
this.uploadFileErrorHandler();
|
|
1134
|
+
this.uploadFileErrorHandler(inputError);
|
|
1135
|
+
}
|
|
1136
|
+
if (this.fileInput && this.fileInput.current) {
|
|
1137
|
+
this.fileInput.current.value = null;
|
|
1108
1138
|
}
|
|
1109
1139
|
return;
|
|
1110
1140
|
}
|
|
1111
|
-
this.setState({ selectedFile: file, globalDragActive: false });
|
|
1112
|
-
}
|
|
1113
|
-
|
|
1114
|
-
handleAddClick() {
|
|
1115
|
-
const file = this.state.selectedFile;
|
|
1116
|
-
if (!file) return;
|
|
1117
1141
|
try {
|
|
1118
1142
|
this.uploadUrlServiceHandler(file, 'FILE');
|
|
1119
1143
|
} catch (err) {
|