@eeacms/volto-arcgis-block 0.1.452 → 0.1.453
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 +15 -0
- package/Jenkinsfile +1 -1
- package/Makefile +13 -9
- package/package.json +3 -2
- package/src/components/MapViewer/AreaWidget.jsx +3 -2
- package/src/components/MapViewer/BasemapWidget.jsx +17 -15
- package/src/components/MapViewer/BookmarkWidget.jsx +8 -10
- package/src/components/MapViewer/HotspotWidget.jsx +10 -13
- package/src/components/MapViewer/MapViewer.jsx +12 -20
- package/src/components/MapViewer/MenuWidget.jsx +139 -58
- package/src/components/MapViewer/SwipeWidget.jsx +8 -5
- package/src/components/MapViewer/TimesliderWidget.jsx +28 -24
- package/src/components/MapViewer/css/ArcgisMap.css +7 -7
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,21 @@ 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.453](https://github.com/eea/volto-arcgis-block/compare/0.1.452...0.1.453) - 3 June 2026
|
|
8
|
+
|
|
9
|
+
#### :house: Internal changes
|
|
10
|
+
|
|
11
|
+
- style: Automated code fix [eea-jenkins - [`7e20e98`](https://github.com/eea/volto-arcgis-block/commit/7e20e98f5f5e497b79557453c464dee98753ea6e)]
|
|
12
|
+
- chore: upgrade Makefile to latest [valentinab25 - [`fb2e387`](https://github.com/eea/volto-arcgis-block/commit/fb2e387f9ec8cfac7be5894d775313dddaf80897)]
|
|
13
|
+
|
|
14
|
+
#### :hammer_and_wrench: Others
|
|
15
|
+
|
|
16
|
+
- (task): add stylelint dev dependency [Unai Bolivar - [`d11c354`](https://github.com/eea/volto-arcgis-block/commit/d11c3540d3eb4bfc064768cb70d9d1809c60ec3a)]
|
|
17
|
+
- (bug): fix isuess found by jenkins [Unai Bolivar - [`74638f9`](https://github.com/eea/volto-arcgis-block/commit/74638f9047b7868a7a64a7b3ca3bbdfa1ff8a8cd)]
|
|
18
|
+
- (bug): fix isuess found by jenkins [Unai Bolivar - [`98c1258`](https://github.com/eea/volto-arcgis-block/commit/98c125831bd9d0290087c244777c7b6764d406f0)]
|
|
19
|
+
- (task): update volto version in jenkinsfile [Unai Bolivar - [`f0c13e8`](https://github.com/eea/volto-arcgis-block/commit/f0c13e84a71063f4181d5cc59406132db7b29793)]
|
|
20
|
+
- (bug): Error handling when uploading external services [Unai Bolivar - [`f8f873d`](https://github.com/eea/volto-arcgis-block/commit/f8f873d53064def279101a711df99da09a4dd6b6)]
|
|
21
|
+
- (bug): In the legend widget, retrieve the legends from CDSE services [Unai Bolivar - [`b909191`](https://github.com/eea/volto-arcgis-block/commit/b9091910c676568f2070b3b689972d169d8a2880)]
|
|
7
22
|
### [0.1.452](https://github.com/eea/volto-arcgis-block/compare/0.1.451...0.1.452) - 28 May 2026
|
|
8
23
|
|
|
9
24
|
### [0.1.451](https://github.com/eea/volto-arcgis-block/compare/0.1.450...0.1.451) - 21 May 2026
|
package/Jenkinsfile
CHANGED
|
@@ -10,7 +10,7 @@ pipeline {
|
|
|
10
10
|
DEPENDENCIES = ""
|
|
11
11
|
BACKEND_PROFILES = "eea.kitkat:testing"
|
|
12
12
|
BACKEND_ADDONS = "clms.addon,clms.types,clms.downloadtool,clms.statstool"
|
|
13
|
-
VOLTO = "
|
|
13
|
+
VOLTO = "17"
|
|
14
14
|
IMAGE_NAME = BUILD_TAG.toLowerCase().replaceAll('[^a-z0-9]', '-')
|
|
15
15
|
NODEJS_VERSION = "22"
|
|
16
16
|
}
|
package/Makefile
CHANGED
|
@@ -46,7 +46,7 @@ endif
|
|
|
46
46
|
DIR=$(shell basename $$(pwd))
|
|
47
47
|
NODE_MODULES?="../../../node_modules"
|
|
48
48
|
PLONE_VERSION?=6
|
|
49
|
-
VOLTO_VERSION?=
|
|
49
|
+
VOLTO_VERSION?=17
|
|
50
50
|
ADDON_PATH="${DIR}"
|
|
51
51
|
ADDON_NAME="@eeacms/${ADDON_PATH}"
|
|
52
52
|
DOCKER_COMPOSE=PLONE_VERSION=${PLONE_VERSION} VOLTO_VERSION=${VOLTO_VERSION} ADDON_NAME=${ADDON_NAME} ADDON_PATH=${ADDON_PATH} docker compose
|
|
@@ -86,19 +86,19 @@ cypress-open: ## Open cypress integration tests
|
|
|
86
86
|
|
|
87
87
|
.PHONY: cypress-run
|
|
88
88
|
cypress-run: ## Run cypress integration tests
|
|
89
|
-
CYPRESS_API_PATH="${RAZZLE_DEV_PROXY_API_PATH}" NODE_ENV=development $(NODE_MODULES)/cypress/bin/cypress run
|
|
89
|
+
CYPRESS_API_PATH="${RAZZLE_DEV_PROXY_API_PATH}" NODE_ENV=development $(NODE_MODULES)/cypress/bin/cypress run
|
|
90
90
|
|
|
91
91
|
.PHONY: test
|
|
92
92
|
test: ## Run jest tests
|
|
93
|
-
${DOCKER_COMPOSE} run -e CI=1 frontend test
|
|
93
|
+
${DOCKER_COMPOSE} run --no-deps -e CI=1 frontend test
|
|
94
94
|
|
|
95
95
|
.PHONY: test-update
|
|
96
96
|
test-update: ## Update jest tests snapshots
|
|
97
|
-
${DOCKER_COMPOSE} run -e CI=1 frontend test -u
|
|
97
|
+
${DOCKER_COMPOSE} run --no-deps -e CI=1 frontend test -u
|
|
98
98
|
|
|
99
99
|
.PHONY: stylelint
|
|
100
100
|
stylelint: ## Stylelint
|
|
101
|
-
$(NODE_MODULES)
|
|
101
|
+
$(NODE_MODULES)/.bin/stylelint --allow-empty-input 'src/**/*.{css,less}'
|
|
102
102
|
|
|
103
103
|
.PHONY: stylelint-overrides
|
|
104
104
|
stylelint-overrides:
|
|
@@ -106,7 +106,7 @@ stylelint-overrides:
|
|
|
106
106
|
|
|
107
107
|
.PHONY: stylelint-fix
|
|
108
108
|
stylelint-fix: ## Fix stylelint
|
|
109
|
-
$(NODE_MODULES)
|
|
109
|
+
$(NODE_MODULES)/.bin/stylelint --allow-empty-input 'src/**/*.{css,less}' --fix
|
|
110
110
|
$(NODE_MODULES)/.bin/stylelint --custom-syntax less --allow-empty-input 'theme/**/*.overrides' 'src/**/*.overrides' --fix
|
|
111
111
|
|
|
112
112
|
.PHONY: prettier
|
|
@@ -119,11 +119,11 @@ prettier-fix: ## Fix prettier
|
|
|
119
119
|
|
|
120
120
|
.PHONY: lint
|
|
121
121
|
lint: ## ES Lint
|
|
122
|
-
$(NODE_MODULES)
|
|
122
|
+
$(NODE_MODULES)/.bin/eslint --max-warnings=0 'src/**/*.{js,jsx}'
|
|
123
123
|
|
|
124
124
|
.PHONY: lint-fix
|
|
125
125
|
lint-fix: ## Fix ES Lint
|
|
126
|
-
$(NODE_MODULES)
|
|
126
|
+
$(NODE_MODULES)/.bin/eslint --fix 'src/**/*.{js,jsx}'
|
|
127
127
|
|
|
128
128
|
.PHONY: i18n
|
|
129
129
|
i18n: ## i18n
|
|
@@ -155,7 +155,11 @@ start-ci:
|
|
|
155
155
|
cd ../..
|
|
156
156
|
yarn start
|
|
157
157
|
|
|
158
|
+
.PHONY: check-ci
|
|
159
|
+
check-ci:
|
|
160
|
+
$(NODE_MODULES)/.bin/wait-on -t 240000 http://localhost:3000
|
|
161
|
+
|
|
158
162
|
.PHONY: cypress-ci
|
|
159
163
|
cypress-ci:
|
|
160
164
|
$(NODE_MODULES)/.bin/wait-on -t 240000 http://localhost:3000
|
|
161
|
-
NODE_ENV=development
|
|
165
|
+
CYPRESS_API_PATH="${RAZZLE_DEV_PROXY_API_PATH}" NODE_ENV=development $(NODE_MODULES)/cypress/bin/cypress run --browser chromium
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eeacms/volto-arcgis-block",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.453",
|
|
4
4
|
"description": "volto-arcgis-block: Volto add-on",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"author": "European Environment Agency: CodeSyntax",
|
|
@@ -75,6 +75,7 @@
|
|
|
75
75
|
"dotenv": "^16.3.2",
|
|
76
76
|
"husky": "^8.0.3",
|
|
77
77
|
"lint-staged": "13.1.4",
|
|
78
|
-
"md5": "^2.3.0"
|
|
78
|
+
"md5": "^2.3.0",
|
|
79
|
+
"stylelint": "^13.12.0"
|
|
79
80
|
}
|
|
80
81
|
}
|
|
@@ -924,8 +924,9 @@ class AreaWidget extends React.Component {
|
|
|
924
924
|
}
|
|
925
925
|
|
|
926
926
|
checkExtent(extent) {
|
|
927
|
-
const areaLimit =
|
|
928
|
-
.Datasets[0]
|
|
927
|
+
const areaLimit =
|
|
928
|
+
this.mapviewer_config.Components[0].Products[0].Datasets[0]
|
|
929
|
+
.DownloadLimitAreaExtent;
|
|
929
930
|
if (
|
|
930
931
|
extent.width * extent.height > areaLimit ||
|
|
931
932
|
extent.width * extent.height === 0
|
|
@@ -169,21 +169,23 @@ class BasemapWidget extends React.Component {
|
|
|
169
169
|
}
|
|
170
170
|
url = this.parseCapabilities(layers[i], 'ResourceURL')[0].attributes
|
|
171
171
|
.template.textContent;
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
172
|
+
const basemap = new Basemap({
|
|
173
|
+
title: this.parseCapabilities(layers[i], 'ows:title')[0].innerText,
|
|
174
|
+
thumbnailUrl: url.replace(
|
|
175
|
+
'{TileMatrixSet}/{TileMatrix}/{TileCol}/{TileRow}',
|
|
176
|
+
`/${proj}/0/0/0`,
|
|
177
|
+
),
|
|
178
|
+
baseLayers: [
|
|
179
|
+
new WebTileLayer({
|
|
180
|
+
urlTemplate: url.replace(
|
|
181
|
+
'{TileMatrixSet}/{TileMatrix}/{TileCol}/{TileRow}',
|
|
182
|
+
`/${proj}/{z}/{x}/{y}`,
|
|
183
|
+
),
|
|
184
|
+
copyright: '© OpenStreetMap (and) contributors, CC-BY-SA',
|
|
185
|
+
}),
|
|
186
|
+
],
|
|
187
|
+
});
|
|
188
|
+
this.layerArray.push(basemap);
|
|
187
189
|
}
|
|
188
190
|
this.basemapGallery = new BasemapGallery({
|
|
189
191
|
view: this.props.view,
|
|
@@ -433,11 +433,10 @@ class BookmarkWidget extends React.Component {
|
|
|
433
433
|
) {
|
|
434
434
|
Object.keys(this.props.hotspotData.filteredLayers).forEach(
|
|
435
435
|
(key) => {
|
|
436
|
-
hotspotFilters.filteredLayers[
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
].customLayerParameters['CQL_FILTER'];
|
|
436
|
+
hotspotFilters.filteredLayers[key] =
|
|
437
|
+
this.props.hotspotData.filteredLayers[
|
|
438
|
+
key
|
|
439
|
+
].customLayerParameters['CQL_FILTER'];
|
|
441
440
|
},
|
|
442
441
|
);
|
|
443
442
|
}
|
|
@@ -619,11 +618,10 @@ class BookmarkWidget extends React.Component {
|
|
|
619
618
|
) {
|
|
620
619
|
Object.keys(this.props.hotspotData.filteredLayers).forEach(
|
|
621
620
|
(key) => {
|
|
622
|
-
hotspotFilters.filteredLayers[
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
].customLayerParameters['CQL_FILTER'];
|
|
621
|
+
hotspotFilters.filteredLayers[key] =
|
|
622
|
+
this.props.hotspotData.filteredLayers[
|
|
623
|
+
key
|
|
624
|
+
].customLayerParameters['CQL_FILTER'];
|
|
627
625
|
},
|
|
628
626
|
);
|
|
629
627
|
}
|
|
@@ -44,9 +44,8 @@ class HotspotWidget extends React.Component {
|
|
|
44
44
|
this.layerModelInit = this.layerModelInit.bind(this);
|
|
45
45
|
this.getBBoxData = this.getBBoxData.bind(this);
|
|
46
46
|
this.handleApplyFilter = this.handleApplyFilter.bind(this);
|
|
47
|
-
this.filteredLayersToHotspotData =
|
|
48
|
-
this
|
|
49
|
-
);
|
|
47
|
+
this.filteredLayersToHotspotData =
|
|
48
|
+
this.filteredLayersToHotspotData.bind(this);
|
|
50
49
|
this.mapCfg = this.props.mapCfg;
|
|
51
50
|
this.selectedArea = null;
|
|
52
51
|
this.lcYear = null;
|
|
@@ -268,8 +267,8 @@ class HotspotWidget extends React.Component {
|
|
|
268
267
|
let filterLayer;
|
|
269
268
|
|
|
270
269
|
if (type === 'lcc') {
|
|
271
|
-
let selectLccBoxTime =
|
|
272
|
-
.value;
|
|
270
|
+
let selectLccBoxTime =
|
|
271
|
+
document.getElementById('select-klc-lccTime').value;
|
|
273
272
|
//this.lccYear = selectLccBoxTime;
|
|
274
273
|
this.setState({ lccYear: selectLccBoxTime });
|
|
275
274
|
if (document.getElementById('select-klc-lccTime').value.match(/\d+/g)) {
|
|
@@ -300,9 +299,8 @@ class HotspotWidget extends React.Component {
|
|
|
300
299
|
filterLayer = this.esriLayer_lcc;
|
|
301
300
|
|
|
302
301
|
filterLayer.sublayers.items[0].name = this.addLegendName(typeLegend);
|
|
303
|
-
filterLayer.sublayers.items[0].legendUrl =
|
|
304
|
-
typeLegend
|
|
305
|
-
);
|
|
302
|
+
filterLayer.sublayers.items[0].legendUrl =
|
|
303
|
+
this.addLegendNameToUrl(typeLegend);
|
|
306
304
|
filterLayer.sublayers.items[0].title = title;
|
|
307
305
|
if (
|
|
308
306
|
bookmarkHotspotFilter !== null &&
|
|
@@ -334,8 +332,8 @@ class HotspotWidget extends React.Component {
|
|
|
334
332
|
}
|
|
335
333
|
}
|
|
336
334
|
|
|
337
|
-
let selectLcBoxTime =
|
|
338
|
-
.value;
|
|
335
|
+
let selectLcBoxTime =
|
|
336
|
+
document.getElementById('select-klc-lcTime').value;
|
|
339
337
|
|
|
340
338
|
this.addFilteredLayersData(
|
|
341
339
|
filteredLayersData,
|
|
@@ -356,9 +354,8 @@ class HotspotWidget extends React.Component {
|
|
|
356
354
|
filterLayer = this.esriLayer_lc;
|
|
357
355
|
|
|
358
356
|
filterLayer.sublayers.items[0].name = this.addLegendName(typeLegend);
|
|
359
|
-
filterLayer.sublayers.items[0].legendUrl =
|
|
360
|
-
typeLegend
|
|
361
|
-
);
|
|
357
|
+
filterLayer.sublayers.items[0].legendUrl =
|
|
358
|
+
this.addLegendNameToUrl(typeLegend);
|
|
362
359
|
filterLayer.sublayers.items[0].title = title;
|
|
363
360
|
if (
|
|
364
361
|
bookmarkHotspotFilter !== null &&
|
|
@@ -389,12 +389,10 @@ class MapViewer extends React.Component {
|
|
|
389
389
|
this.viewUiOperationState = null;
|
|
390
390
|
this.shouldClearSessionOnUnmount = true;
|
|
391
391
|
this.uploadErrorTimeoutTask = null;
|
|
392
|
-
this.scheduleViewModeButtonLoad =
|
|
393
|
-
this
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
this,
|
|
397
|
-
);
|
|
392
|
+
this.scheduleViewModeButtonLoad =
|
|
393
|
+
this.scheduleViewModeButtonLoad.bind(this);
|
|
394
|
+
this.processPendingWidgetActivation =
|
|
395
|
+
this.processPendingWidgetActivation.bind(this);
|
|
398
396
|
}
|
|
399
397
|
|
|
400
398
|
processPendingWidgetActivation() {
|
|
@@ -1051,9 +1049,8 @@ class MapViewer extends React.Component {
|
|
|
1051
1049
|
this.isComponentMounted &&
|
|
1052
1050
|
transitionTaskId === this.viewTransitionTaskId
|
|
1053
1051
|
) {
|
|
1054
|
-
const fallbackViewState =
|
|
1055
|
-
normalizedNextMode
|
|
1056
|
-
);
|
|
1052
|
+
const fallbackViewState =
|
|
1053
|
+
this.buildFallbackViewState(normalizedNextMode);
|
|
1057
1054
|
isViewCreated = await this.createView(
|
|
1058
1055
|
normalizedNextMode,
|
|
1059
1056
|
fallbackViewState,
|
|
@@ -1158,10 +1155,8 @@ class MapViewer extends React.Component {
|
|
|
1158
1155
|
// Method to handle session state updates when user authentication changes
|
|
1159
1156
|
handleSessionStateUpdate(newUserState, previousUserState) {
|
|
1160
1157
|
const { user_id: newUserId, isLoggedIn: newIsLoggedIn } = newUserState;
|
|
1161
|
-
const {
|
|
1162
|
-
|
|
1163
|
-
isLoggedIn: prevIsLoggedIn,
|
|
1164
|
-
} = previousUserState;
|
|
1158
|
+
const { user_id: prevUserId, isLoggedIn: prevIsLoggedIn } =
|
|
1159
|
+
previousUserState;
|
|
1165
1160
|
|
|
1166
1161
|
// Handle login/logout transitions
|
|
1167
1162
|
if (prevIsLoggedIn !== newIsLoggedIn) {
|
|
@@ -1293,9 +1288,8 @@ class MapViewer extends React.Component {
|
|
|
1293
1288
|
|
|
1294
1289
|
activeLayersHandler(newActiveLayers) {
|
|
1295
1290
|
try {
|
|
1296
|
-
const layersWithoutCircularReferences =
|
|
1297
|
-
newActiveLayers
|
|
1298
|
-
);
|
|
1291
|
+
const layersWithoutCircularReferences =
|
|
1292
|
+
this.removeCircularReferences(newActiveLayers);
|
|
1299
1293
|
this.activeLayers = layersWithoutCircularReferences;
|
|
1300
1294
|
mapStatus.activeLayers = layersWithoutCircularReferences;
|
|
1301
1295
|
sessionStorage.setItem('mapStatus', JSON.stringify(mapStatus));
|
|
@@ -1523,10 +1517,8 @@ class MapViewer extends React.Component {
|
|
|
1523
1517
|
}
|
|
1524
1518
|
|
|
1525
1519
|
// Handle user state changes from context
|
|
1526
|
-
const {
|
|
1527
|
-
|
|
1528
|
-
isLoggedIn: currentIsLoggedIn,
|
|
1529
|
-
} = this.context;
|
|
1520
|
+
const { user_id: currentUserId, isLoggedIn: currentIsLoggedIn } =
|
|
1521
|
+
this.context;
|
|
1530
1522
|
const { currentUserState: prevUserState } = prevState;
|
|
1531
1523
|
|
|
1532
1524
|
// Compare current context values with previous state
|
|
@@ -186,9 +186,8 @@ export const AddCartItem = ({
|
|
|
186
186
|
});
|
|
187
187
|
}
|
|
188
188
|
if ((check === 'area' || fileUpload) && isMapServer) {
|
|
189
|
-
const transformedLayerExtent =
|
|
190
|
-
layerExtent
|
|
191
|
-
);
|
|
189
|
+
const transformedLayerExtent =
|
|
190
|
+
WebMercatorUtils.webMercatorToGeographic(layerExtent);
|
|
192
191
|
if (transformedLayerExtent.intersects(areaExtent)) {
|
|
193
192
|
intersection = true;
|
|
194
193
|
}
|
|
@@ -2017,6 +2016,14 @@ class MenuWidget extends React.Component {
|
|
|
2017
2016
|
//For Legend request
|
|
2018
2017
|
const legendRequest =
|
|
2019
2018
|
'request=GetLegendGraphic&version=1.0.0&format=image/png&layer=';
|
|
2019
|
+
const isCdseService =
|
|
2020
|
+
!!viewService &&
|
|
2021
|
+
['/ogc/', '/cdse/'].some((segment) =>
|
|
2022
|
+
viewService.toLowerCase().includes(segment),
|
|
2023
|
+
);
|
|
2024
|
+
const cdseLegendUrl = isCdseService
|
|
2025
|
+
? this.buildCdseLegendUrl(viewService, layer.Title || layer.LayerId)
|
|
2026
|
+
: null;
|
|
2020
2027
|
//For each layer
|
|
2021
2028
|
let inheritedIndexLayer = inheritedIndex + '_' + layerIndex;
|
|
2022
2029
|
let style = this.props.download ? { paddingLeft: '4rem' } : {};
|
|
@@ -2025,16 +2032,15 @@ class MenuWidget extends React.Component {
|
|
|
2025
2032
|
!this.layers.hasOwnProperty(layer.LayerId + '_' + inheritedIndexLayer)
|
|
2026
2033
|
) {
|
|
2027
2034
|
if (viewService?.toLowerCase().endsWith('mapserver')) {
|
|
2028
|
-
this.layers[
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
});
|
|
2035
|
+
this.layers[layer.LayerId + '_' + inheritedIndexLayer] =
|
|
2036
|
+
new MapImageLayer({
|
|
2037
|
+
url: viewService,
|
|
2038
|
+
title: layer.Title,
|
|
2039
|
+
DatasetId: DatasetId,
|
|
2040
|
+
DatasetTitle: DatasetTitle,
|
|
2041
|
+
ProductId: ProductId,
|
|
2042
|
+
LayerTitle: layer.Title,
|
|
2043
|
+
});
|
|
2038
2044
|
//iterate sublayers fetching all sublayer data
|
|
2039
2045
|
} else if (viewService?.toLowerCase().includes('wms')) {
|
|
2040
2046
|
viewService = viewService?.includes('?')
|
|
@@ -2056,6 +2062,8 @@ class MenuWidget extends React.Component {
|
|
|
2056
2062
|
legendEnabled: true,
|
|
2057
2063
|
legendUrl: layer.StaticImageLegend
|
|
2058
2064
|
? layer.StaticImageLegend
|
|
2065
|
+
: cdseLegendUrl
|
|
2066
|
+
? cdseLegendUrl
|
|
2059
2067
|
: viewService + legendRequest + layer.LayerId,
|
|
2060
2068
|
featureInfoUrl: featureInfoUrl,
|
|
2061
2069
|
},
|
|
@@ -2068,9 +2076,10 @@ class MenuWidget extends React.Component {
|
|
|
2068
2076
|
ViewService: viewService,
|
|
2069
2077
|
});
|
|
2070
2078
|
} else if (viewService?.toLowerCase().includes('wmts')) {
|
|
2071
|
-
const resolveSentinelLayer =
|
|
2072
|
-
|
|
2073
|
-
|
|
2079
|
+
const resolveSentinelLayer =
|
|
2080
|
+
/(?:sh\.dataspace\.copernicus\.eu|services\.sentinel-hub\.com)\/ogc\/wmts/i.test(
|
|
2081
|
+
viewService || '',
|
|
2082
|
+
);
|
|
2074
2083
|
this.layers[layer.LayerId + '_' + inheritedIndexLayer] = new WMTSLayer({
|
|
2075
2084
|
url: viewService?.includes('?')
|
|
2076
2085
|
? viewService + '&'
|
|
@@ -2091,7 +2100,7 @@ class MenuWidget extends React.Component {
|
|
|
2091
2100
|
DatasetTitle: DatasetTitle,
|
|
2092
2101
|
ProductId: ProductId,
|
|
2093
2102
|
ViewService: viewService,
|
|
2094
|
-
StaticImageLegend: layer.StaticImageLegend,
|
|
2103
|
+
StaticImageLegend: layer.StaticImageLegend || cdseLegendUrl,
|
|
2095
2104
|
LayerTitle: layer.Title,
|
|
2096
2105
|
DatasetDownloadInformation: dataset_download_information || {},
|
|
2097
2106
|
customLayerParameters: {
|
|
@@ -2100,24 +2109,23 @@ class MenuWidget extends React.Component {
|
|
|
2100
2109
|
},
|
|
2101
2110
|
});
|
|
2102
2111
|
} else {
|
|
2103
|
-
this.layers[
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
layer.LayerId,
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
});
|
|
2112
|
+
this.layers[layer.LayerId + '_' + inheritedIndexLayer] =
|
|
2113
|
+
new FeatureLayer({
|
|
2114
|
+
url:
|
|
2115
|
+
viewService +
|
|
2116
|
+
(viewService?.endsWith('/') ? '' : '/') +
|
|
2117
|
+
layer.LayerId,
|
|
2118
|
+
id: layer.LayerId,
|
|
2119
|
+
title: layer.Title,
|
|
2120
|
+
featureInfoUrl: featureInfoUrl,
|
|
2121
|
+
popupEnabled: true,
|
|
2122
|
+
isTimeSeries: isTimeSeries,
|
|
2123
|
+
fields: layer.Fields,
|
|
2124
|
+
DatasetId: DatasetId,
|
|
2125
|
+
DatasetTitle: DatasetTitle,
|
|
2126
|
+
ProductId: ProductId,
|
|
2127
|
+
ViewService: viewService,
|
|
2128
|
+
});
|
|
2121
2129
|
}
|
|
2122
2130
|
}
|
|
2123
2131
|
// const isCDSE = !!this.url && this.url.toLowerCase().includes('/ogc/');
|
|
@@ -2312,6 +2320,26 @@ class MenuWidget extends React.Component {
|
|
|
2312
2320
|
return this.getProxyBase() + this.stripProtocol(url);
|
|
2313
2321
|
}
|
|
2314
2322
|
|
|
2323
|
+
buildCdseLegendUrl(serviceUrl, layerTitle) {
|
|
2324
|
+
if (!serviceUrl || !layerTitle) return null;
|
|
2325
|
+
const collectionMatch =
|
|
2326
|
+
/\/cdse\/([^/?#]+)/i.exec(serviceUrl) ||
|
|
2327
|
+
/\/ogc\/(?:wmts|wms)\/([^/?#]+)/i.exec(serviceUrl);
|
|
2328
|
+
if (!collectionMatch || !collectionMatch[1]) return null;
|
|
2329
|
+
const legendParams = new URLSearchParams({
|
|
2330
|
+
service: 'WMS',
|
|
2331
|
+
request: 'GetLegendGraphic',
|
|
2332
|
+
version: '1.3.0',
|
|
2333
|
+
format: 'image/png',
|
|
2334
|
+
layer: layerTitle,
|
|
2335
|
+
style: 'default',
|
|
2336
|
+
});
|
|
2337
|
+
return (
|
|
2338
|
+
this.getProxyBase() +
|
|
2339
|
+
`land.copernicus.eu/cdse/${collectionMatch[1]}?${legendParams.toString()}`
|
|
2340
|
+
);
|
|
2341
|
+
}
|
|
2342
|
+
|
|
2315
2343
|
parseWMSLayers(xml) {
|
|
2316
2344
|
let doc = xml;
|
|
2317
2345
|
try {
|
|
@@ -2708,13 +2736,14 @@ class MenuWidget extends React.Component {
|
|
|
2708
2736
|
if (!activeLayerData) {
|
|
2709
2737
|
return false;
|
|
2710
2738
|
}
|
|
2711
|
-
const resolveSentinelLayer =
|
|
2712
|
-
(
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
2739
|
+
const resolveSentinelLayer =
|
|
2740
|
+
/(?:sh\.dataspace\.copernicus\.eu|services\.sentinel-hub\.com)\/ogc\/wmts/i.test(
|
|
2741
|
+
(
|
|
2742
|
+
currentLayerData.ViewService ||
|
|
2743
|
+
currentLayerData.url ||
|
|
2744
|
+
''
|
|
2745
|
+
).toLowerCase(),
|
|
2746
|
+
);
|
|
2718
2747
|
const nextCustomLayerParameters = {
|
|
2719
2748
|
...(currentLayerData.customLayerParameters || {}),
|
|
2720
2749
|
SHOWLOGO: false,
|
|
@@ -3249,6 +3278,22 @@ class MenuWidget extends React.Component {
|
|
|
3249
3278
|
try {
|
|
3250
3279
|
const rawUrl = (proxiedUrl || '').trim();
|
|
3251
3280
|
const baseUrl = rawUrl.split('?')[0];
|
|
3281
|
+
const resolveCapabilitiesText = (xmlData) => {
|
|
3282
|
+
if (!xmlData) {
|
|
3283
|
+
return '';
|
|
3284
|
+
}
|
|
3285
|
+
if (typeof xmlData === 'string') {
|
|
3286
|
+
return xmlData;
|
|
3287
|
+
}
|
|
3288
|
+
try {
|
|
3289
|
+
return new XMLSerializer().serializeToString(xmlData);
|
|
3290
|
+
} catch (e) {
|
|
3291
|
+
return '';
|
|
3292
|
+
}
|
|
3293
|
+
};
|
|
3294
|
+
const isInvalidCapabilitiesData = (xmlData) => {
|
|
3295
|
+
return !xmlData || !xmlData.documentElement;
|
|
3296
|
+
};
|
|
3252
3297
|
const processBboxData = (xml) => {
|
|
3253
3298
|
const buildExtentResult = (xmin, ymin, xmax, ymax) => {
|
|
3254
3299
|
const numericValues = [xmin, ymin, xmax, ymax].map((value) =>
|
|
@@ -3407,10 +3452,21 @@ class MenuWidget extends React.Component {
|
|
|
3407
3452
|
if (serviceType === 'WMTS') {
|
|
3408
3453
|
this.xml = null;
|
|
3409
3454
|
await this.getCapabilities(viewService, 'WMTS');
|
|
3410
|
-
if (
|
|
3455
|
+
if (isInvalidCapabilitiesData(this.xml)) {
|
|
3411
3456
|
throw new Error('Unable to load WMTS capabilities');
|
|
3412
3457
|
}
|
|
3458
|
+
const wmtsCapabilitiesText = resolveCapabilitiesText(this.xml);
|
|
3459
|
+
if (this.hasExceptionResponse(wmtsCapabilitiesText)) {
|
|
3460
|
+
const exceptionMessage =
|
|
3461
|
+
this.resolveExceptionMessage(wmtsCapabilitiesText);
|
|
3462
|
+
throw new Error(exceptionMessage || 'Unable to load WMTS service');
|
|
3463
|
+
}
|
|
3413
3464
|
const wmtsLayers = this.parseWMTSLayers(this.xml);
|
|
3465
|
+
if (!Array.isArray(wmtsLayers) || wmtsLayers.length === 0) {
|
|
3466
|
+
throw new Error(
|
|
3467
|
+
'Selected service has no geometry data and cannot be displayed on map',
|
|
3468
|
+
);
|
|
3469
|
+
}
|
|
3414
3470
|
const active = this.resolveWmtsLayerData(wmtsLayers, serviceSelection);
|
|
3415
3471
|
const serviceTitle = this.parseWMTSServiceTitle(this.xml);
|
|
3416
3472
|
const isSceneViewActive = this.view && this.view.type === '3d';
|
|
@@ -3453,8 +3509,22 @@ class MenuWidget extends React.Component {
|
|
|
3453
3509
|
];
|
|
3454
3510
|
} else if (isWFS) {
|
|
3455
3511
|
await this.getCapabilities(viewService, 'WFS');
|
|
3512
|
+
if (isInvalidCapabilitiesData(this.xml)) {
|
|
3513
|
+
throw new Error('Unable to load WFS capabilities');
|
|
3514
|
+
}
|
|
3515
|
+
const wfsCapabilitiesText = resolveCapabilitiesText(this.xml);
|
|
3516
|
+
if (this.hasExceptionResponse(wfsCapabilitiesText)) {
|
|
3517
|
+
const exceptionMessage =
|
|
3518
|
+
this.resolveExceptionMessage(wfsCapabilitiesText);
|
|
3519
|
+
throw new Error(exceptionMessage || 'Unable to load WFS service');
|
|
3520
|
+
}
|
|
3456
3521
|
const requestConfig = this.resolveRequestConfig(this.xml);
|
|
3457
3522
|
const serviceEntries = Object.entries(serviceSelection || {});
|
|
3523
|
+
if (!serviceEntries.length) {
|
|
3524
|
+
throw new Error(
|
|
3525
|
+
'Selected service has no geometry data and cannot be displayed on map',
|
|
3526
|
+
);
|
|
3527
|
+
}
|
|
3458
3528
|
const layerResults = await Promise.all(
|
|
3459
3529
|
serviceEntries.map(async ([name, title]) => {
|
|
3460
3530
|
if (!name) return null;
|
|
@@ -3503,7 +3573,21 @@ class MenuWidget extends React.Component {
|
|
|
3503
3573
|
resourceLayers = layerResults.filter(Boolean);
|
|
3504
3574
|
} else {
|
|
3505
3575
|
await this.getCapabilities(viewService, 'WMS');
|
|
3576
|
+
if (isInvalidCapabilitiesData(this.xml)) {
|
|
3577
|
+
throw new Error('Unable to load WMS capabilities');
|
|
3578
|
+
}
|
|
3579
|
+
const wmsCapabilitiesText = resolveCapabilitiesText(this.xml);
|
|
3580
|
+
if (this.hasExceptionResponse(wmsCapabilitiesText)) {
|
|
3581
|
+
const exceptionMessage =
|
|
3582
|
+
this.resolveExceptionMessage(wmsCapabilitiesText);
|
|
3583
|
+
throw new Error(exceptionMessage || 'Unable to load WMS service');
|
|
3584
|
+
}
|
|
3506
3585
|
const wmsLayers = this.parseWMSLayers(this.xml);
|
|
3586
|
+
if (!Array.isArray(wmsLayers) || wmsLayers.length === 0) {
|
|
3587
|
+
throw new Error(
|
|
3588
|
+
'Selected service has no geometry data and cannot be displayed on map',
|
|
3589
|
+
);
|
|
3590
|
+
}
|
|
3507
3591
|
const serviceTitle = this.parseWMSServiceTitle(this.xml);
|
|
3508
3592
|
const legendRequest =
|
|
3509
3593
|
'request=GetLegendGraphic&version=1.0.0&format=image/png&layer=';
|
|
@@ -4210,9 +4294,8 @@ class MenuWidget extends React.Component {
|
|
|
4210
4294
|
for (let g = 1; g < dataSetContents.length; g++) {
|
|
4211
4295
|
if (dataSetContents[g].checked) {
|
|
4212
4296
|
currentDataSetLayer = dataSetContents[g];
|
|
4213
|
-
currentDataSetLayerSpan =
|
|
4214
|
-
'span'
|
|
4215
|
-
);
|
|
4297
|
+
currentDataSetLayerSpan =
|
|
4298
|
+
currentDataSetLayer.nextSibling?.querySelector('span');
|
|
4216
4299
|
currentElemContainerSpan = elemContainer.querySelector('span');
|
|
4217
4300
|
|
|
4218
4301
|
if (
|
|
@@ -4459,11 +4542,12 @@ class MenuWidget extends React.Component {
|
|
|
4459
4542
|
if (
|
|
4460
4543
|
this.layers[elem.id].ViewService.toLowerCase().includes('wmts')
|
|
4461
4544
|
) {
|
|
4462
|
-
const resolveSentinelLayer =
|
|
4463
|
-
|
|
4464
|
-
this.layers[elem.id].
|
|
4465
|
-
|
|
4466
|
-
|
|
4545
|
+
const resolveSentinelLayer =
|
|
4546
|
+
/(?:sh\.dataspace\.copernicus\.eu|services\.sentinel-hub\.com)\/ogc\/wmts/i.test(
|
|
4547
|
+
this.layers[elem.id].ViewService ||
|
|
4548
|
+
this.layers[elem.id].url ||
|
|
4549
|
+
'',
|
|
4550
|
+
);
|
|
4467
4551
|
const nextCustomLayerParameters = {
|
|
4468
4552
|
...(this.layers[elem.id].customLayerParameters || {}),
|
|
4469
4553
|
SHOWLOGO: false,
|
|
@@ -4488,8 +4572,8 @@ class MenuWidget extends React.Component {
|
|
|
4488
4572
|
ViewService: this.layers[elem.id].ViewService,
|
|
4489
4573
|
StaticImageLegend: this.layers[elem.id].StaticImageLegend,
|
|
4490
4574
|
LayerTitle: this.layers[elem.id].LayerTitle,
|
|
4491
|
-
DatasetDownloadInformation:
|
|
4492
|
-
.DatasetDownloadInformation,
|
|
4575
|
+
DatasetDownloadInformation:
|
|
4576
|
+
this.layers[elem.id].DatasetDownloadInformation,
|
|
4493
4577
|
customLayerParameters: nextCustomLayerParameters,
|
|
4494
4578
|
});
|
|
4495
4579
|
}
|
|
@@ -7201,11 +7285,8 @@ class MenuWidget extends React.Component {
|
|
|
7201
7285
|
if (this.props.download) return;
|
|
7202
7286
|
|
|
7203
7287
|
if (prevProps.userServiceUrl !== this.props.userServiceUrl) {
|
|
7204
|
-
const {
|
|
7205
|
-
|
|
7206
|
-
userServiceType,
|
|
7207
|
-
userServiceSelection,
|
|
7208
|
-
} = this.props;
|
|
7288
|
+
const { userServiceUrl, userServiceType, userServiceSelection } =
|
|
7289
|
+
this.props;
|
|
7209
7290
|
if (
|
|
7210
7291
|
userServiceUrl &&
|
|
7211
7292
|
typeof userServiceUrl === 'string' &&
|
|
@@ -186,7 +186,8 @@ class SwipeWidget extends React.Component {
|
|
|
186
186
|
this._isMounted = true;
|
|
187
187
|
await this.loader();
|
|
188
188
|
if (!this.container.current) return;
|
|
189
|
-
this.container.current.__mapViewerContainerParentNode =
|
|
189
|
+
this.container.current.__mapViewerContainerParentNode =
|
|
190
|
+
this.container.current.parentNode;
|
|
190
191
|
this.props.view.when(() => {
|
|
191
192
|
if (!this._isMounted || !this.props.view || !this.props.view.ui) {
|
|
192
193
|
return;
|
|
@@ -422,10 +423,12 @@ class SwipeWidget extends React.Component {
|
|
|
422
423
|
this.props.view.ui.remove(this.swipe);
|
|
423
424
|
this.props.view.ui.add(this.swipe);
|
|
424
425
|
this.hasSwipe = true;
|
|
425
|
-
let selectedLeadingLayer = document.getElementById(
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
426
|
+
let selectedLeadingLayer = document.getElementById(
|
|
427
|
+
'select-leading-layer',
|
|
428
|
+
).value;
|
|
429
|
+
let selectedTrailingLayer = document.getElementById(
|
|
430
|
+
'select-trailing-layer',
|
|
431
|
+
).value;
|
|
429
432
|
let selectedSwipeDirection = document.getElementById(
|
|
430
433
|
'select-swipe-direction',
|
|
431
434
|
).value;
|
|
@@ -196,8 +196,9 @@ class TimesliderWidget extends React.Component {
|
|
|
196
196
|
} else {
|
|
197
197
|
if (xml.querySelector('Dimension') !== null) {
|
|
198
198
|
// There is a common time dimension to all layers
|
|
199
|
-
dimension = xml
|
|
200
|
-
.
|
|
199
|
+
dimension = xml
|
|
200
|
+
.querySelector('Dimension')
|
|
201
|
+
.querySelector('Extent').innerText;
|
|
201
202
|
} else {
|
|
202
203
|
dimension = false;
|
|
203
204
|
}
|
|
@@ -275,7 +276,8 @@ class TimesliderWidget extends React.Component {
|
|
|
275
276
|
}
|
|
276
277
|
|
|
277
278
|
parserPeriod(iso8601Duration) {
|
|
278
|
-
var iso8601DurationRegex =
|
|
279
|
+
var iso8601DurationRegex =
|
|
280
|
+
/(-)?P(?:([.,\d]+)Y)?(?:([.,\d]+)M)?(?:([.,\d]+)W)?(?:([.,\d]+)D)?T?(?:([.,\d]+)H)?(?:([.,\d]+)M)?(?:([.,\d]+)S)?/;
|
|
279
281
|
var matches = iso8601Duration.match(iso8601DurationRegex);
|
|
280
282
|
return {
|
|
281
283
|
sign: matches[1] === undefined ? '+' : '-',
|
|
@@ -372,7 +374,8 @@ class TimesliderWidget extends React.Component {
|
|
|
372
374
|
? this.container.current.parentNode
|
|
373
375
|
: null;
|
|
374
376
|
if (this.container && this.container.current) {
|
|
375
|
-
this.container.current.__mapViewerContainerParentNode =
|
|
377
|
+
this.container.current.__mapViewerContainerParentNode =
|
|
378
|
+
this.containerParentNode;
|
|
376
379
|
}
|
|
377
380
|
await this.loader();
|
|
378
381
|
let playRateValue =
|
|
@@ -394,42 +397,40 @@ class TimesliderWidget extends React.Component {
|
|
|
394
397
|
}
|
|
395
398
|
if (value) {
|
|
396
399
|
const normal = new Intl.DateTimeFormat('en-gb');
|
|
400
|
+
const timeSelectedValuesC = Array.isArray(
|
|
401
|
+
this.state.timeSelectedValuesC,
|
|
402
|
+
)
|
|
403
|
+
? [...this.state.timeSelectedValuesC]
|
|
404
|
+
: [];
|
|
405
|
+
let timeSelectedValues = this.state.timeSelectedValues;
|
|
397
406
|
switch (type) {
|
|
398
407
|
case 'min':
|
|
399
|
-
if (
|
|
408
|
+
if (timeSelectedValuesC[0] == null)
|
|
400
409
|
// In case of first iteration
|
|
401
|
-
|
|
410
|
+
timeSelectedValuesC[0] = value;
|
|
402
411
|
element.innerText = normal.format(value).replaceAll('/', '.');
|
|
403
412
|
break;
|
|
404
413
|
case 'max':
|
|
405
|
-
if (
|
|
414
|
+
if (timeSelectedValuesC[1] == null)
|
|
406
415
|
// In case of first iteration
|
|
407
|
-
|
|
416
|
+
timeSelectedValuesC[1] = value;
|
|
408
417
|
element.innerText = normal.format(value).replaceAll('/', '.');
|
|
409
418
|
break;
|
|
410
419
|
case 'extent':
|
|
411
|
-
|
|
420
|
+
timeSelectedValues = value;
|
|
412
421
|
if (
|
|
413
|
-
normal
|
|
414
|
-
|
|
415
|
-
.replaceAll('/', '.') !==
|
|
416
|
-
normal
|
|
417
|
-
.format(this.state.timeSelectedValuesC[0])
|
|
418
|
-
.replaceAll('/', '.')
|
|
422
|
+
normal.format(timeSelectedValues[0]).replaceAll('/', '.') !==
|
|
423
|
+
normal.format(timeSelectedValuesC[0]).replaceAll('/', '.')
|
|
419
424
|
) {
|
|
420
|
-
|
|
425
|
+
timeSelectedValuesC[0] = value[0];
|
|
421
426
|
element.innerText = normal
|
|
422
427
|
.format(value[0])
|
|
423
428
|
.replaceAll('/', '.');
|
|
424
429
|
} else if (
|
|
425
|
-
normal
|
|
426
|
-
|
|
427
|
-
.replaceAll('/', '.') !==
|
|
428
|
-
normal
|
|
429
|
-
.format(this.state.timeSelectedValuesC[1])
|
|
430
|
-
.replaceAll('/', '.')
|
|
430
|
+
normal.format(timeSelectedValues[1]).replaceAll('/', '.') !==
|
|
431
|
+
normal.format(timeSelectedValuesC[1]).replaceAll('/', '.')
|
|
431
432
|
) {
|
|
432
|
-
|
|
433
|
+
timeSelectedValuesC[1] = value[1];
|
|
433
434
|
element.innerText = normal
|
|
434
435
|
.format(value[1])
|
|
435
436
|
.replaceAll('/', '.');
|
|
@@ -440,6 +441,8 @@ class TimesliderWidget extends React.Component {
|
|
|
440
441
|
break;
|
|
441
442
|
}
|
|
442
443
|
this.setState({
|
|
444
|
+
timeSelectedValues: timeSelectedValues,
|
|
445
|
+
timeSelectedValuesC: timeSelectedValuesC,
|
|
443
446
|
lockDatePanel: false,
|
|
444
447
|
});
|
|
445
448
|
}
|
|
@@ -478,7 +481,8 @@ class TimesliderWidget extends React.Component {
|
|
|
478
481
|
const isCDSE =
|
|
479
482
|
urlNorm.includes('/ogc/') || urlNorm.includes('/cdse/');
|
|
480
483
|
if (this.layer.type === 'feature') {
|
|
481
|
-
this.TimesliderWidget.fullTimeExtent =
|
|
484
|
+
this.TimesliderWidget.fullTimeExtent =
|
|
485
|
+
this.layer.timeInfo.fullTimeExtent;
|
|
482
486
|
this.TimesliderWidget.stops = {
|
|
483
487
|
interval: this.layer.timeInfo.interval,
|
|
484
488
|
};
|
|
@@ -751,12 +751,12 @@ div.upload-container div.wfs-features-list label.field input[type='checkbox'] {
|
|
|
751
751
|
box-sizing: border-box;
|
|
752
752
|
flex: 0 0 18px !important;
|
|
753
753
|
border: 1px solid #8a8a8a;
|
|
754
|
+
border-radius: 3px;
|
|
754
755
|
margin: 0 6px 0 0;
|
|
755
756
|
-webkit-appearance: none !important;
|
|
756
757
|
-moz-appearance: none !important;
|
|
757
758
|
appearance: none !important;
|
|
758
759
|
background-color: #ffffff;
|
|
759
|
-
border-radius: 3px;
|
|
760
760
|
vertical-align: middle;
|
|
761
761
|
}
|
|
762
762
|
|
|
@@ -1759,9 +1759,9 @@ div.upload-container
|
|
|
1759
1759
|
input[type='range'] {
|
|
1760
1760
|
width: 100%;
|
|
1761
1761
|
height: 4px;
|
|
1762
|
+
border-radius: 5px;
|
|
1762
1763
|
-webkit-appearance: none;
|
|
1763
1764
|
background: #c5c5c5;
|
|
1764
|
-
border-radius: 5px;
|
|
1765
1765
|
cursor: pointer;
|
|
1766
1766
|
}
|
|
1767
1767
|
|
|
@@ -1769,9 +1769,9 @@ input[type='range']::-webkit-slider-thumb {
|
|
|
1769
1769
|
width: 16px;
|
|
1770
1770
|
height: 16px;
|
|
1771
1771
|
border: solid 3px black;
|
|
1772
|
+
border-radius: 50%;
|
|
1772
1773
|
-webkit-appearance: none;
|
|
1773
1774
|
background: white;
|
|
1774
|
-
border-radius: 50%;
|
|
1775
1775
|
cursor: move;
|
|
1776
1776
|
transition: all 0.3s ease-in-out;
|
|
1777
1777
|
}
|
|
@@ -1780,9 +1780,9 @@ input[type='range']::-moz-range-thumb {
|
|
|
1780
1780
|
width: 16px;
|
|
1781
1781
|
height: 16px;
|
|
1782
1782
|
border: solid 3px black;
|
|
1783
|
+
border-radius: 50%;
|
|
1783
1784
|
-webkit-appearance: none;
|
|
1784
1785
|
background: white;
|
|
1785
|
-
border-radius: 50%;
|
|
1786
1786
|
cursor: grab;
|
|
1787
1787
|
transition: all 0.3s ease-in-out;
|
|
1788
1788
|
}
|
|
@@ -1791,9 +1791,9 @@ input[type='range']::-ms-thumb {
|
|
|
1791
1791
|
width: 16px;
|
|
1792
1792
|
height: 16px;
|
|
1793
1793
|
border: solid 3px black;
|
|
1794
|
+
border-radius: 50%;
|
|
1794
1795
|
-webkit-appearance: none;
|
|
1795
1796
|
background: white;
|
|
1796
|
-
border-radius: 50%;
|
|
1797
1797
|
cursor: grab;
|
|
1798
1798
|
transition: all 0.3s ease-in-out;
|
|
1799
1799
|
}
|
|
@@ -1844,9 +1844,9 @@ input[type='range']::-ms-track {
|
|
|
1844
1844
|
.hotspot-filter-message {
|
|
1845
1845
|
width: 247 !important;
|
|
1846
1846
|
padding: 0.3rem 0.6rem 0.1rem 0.6rem;
|
|
1847
|
+
border-radius: 10px;
|
|
1847
1848
|
margin-top: 0.2rem;
|
|
1848
1849
|
background: #a0b128;
|
|
1849
|
-
border-radius: 10px;
|
|
1850
1850
|
color: white;
|
|
1851
1851
|
font-size: 0.875rem;
|
|
1852
1852
|
text-align: center;
|
|
@@ -2023,9 +2023,9 @@ div.map-container.popup-block {
|
|
|
2023
2023
|
height: 2rem;
|
|
2024
2024
|
border-width: 1px;
|
|
2025
2025
|
border-color: rgba(110, 110, 110, 0.3);
|
|
2026
|
+
border-radius: 0;
|
|
2026
2027
|
margin-left: 0.5rem;
|
|
2027
2028
|
background-color: #a0b128;
|
|
2028
|
-
border-radius: 0;
|
|
2029
2029
|
color: white;
|
|
2030
2030
|
}
|
|
2031
2031
|
|