@eeacms/volto-arcgis-block 0.1.448 → 0.1.450

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,6 +4,14 @@ 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.450](https://github.com/eea/volto-arcgis-block/compare/0.1.449...0.1.450) - 13 May 2026
8
+
9
+ #### :hammer_and_wrench: Others
10
+
11
+ - (bug): fix swipe, hotspot filter, TOC CDSE [Unai Bolivar - [`0065fef`](https://github.com/eea/volto-arcgis-block/commit/0065fef63b0690aac79472d2b97b06243ccfa123)]
12
+ - (bug): swipe fix [Unai Bolivar - [`685648f`](https://github.com/eea/volto-arcgis-block/commit/685648f17cfa38ddc8bad66aaba9ee0165f7410e)]
13
+ ### [0.1.449](https://github.com/eea/volto-arcgis-block/compare/0.1.448...0.1.449) - 12 May 2026
14
+
7
15
  ### [0.1.448](https://github.com/eea/volto-arcgis-block/compare/0.1.447...0.1.448) - 11 May 2026
8
16
 
9
17
  #### :hammer_and_wrench: Others
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eeacms/volto-arcgis-block",
3
- "version": "0.1.448",
3
+ "version": "0.1.450",
4
4
  "description": "volto-arcgis-block: Volto add-on",
5
5
  "main": "src/index.js",
6
6
  "author": "European Environment Agency: CodeSyntax",
@@ -596,9 +596,9 @@ class HotspotWidget extends React.Component {
596
596
  if (lcContainer === null || lccContainer === null) return;
597
597
  if (
598
598
  (lcContainer.style.display === 'block' &&
599
- lcTimeSelect.value === 'default') ||
599
+ (lcTimeSelect.value === 'default' || lcTimeSelect.value === '')) ||
600
600
  (lccContainer.style.display === 'block' &&
601
- lccTimeSelect.value === 'default') ||
601
+ (lccTimeSelect.value === 'default' || lccTimeSelect.value === '')) ||
602
602
  klcSelect.value === 'default'
603
603
  ) {
604
604
  document.querySelector('#applyFilterButton').disabled = true;
@@ -759,10 +759,20 @@ class HotspotWidget extends React.Component {
759
759
  } else {
760
760
  selectBox.value = this.state.selectedArea;
761
761
  if (this.state.lcYear !== null) {
762
- selectBoxLcTime.value = this.state.lcYear;
762
+ const hasLcYearOption = Array.from(
763
+ selectBoxLcTime.options,
764
+ ).some((option) => option.value === this.state.lcYear);
765
+ selectBoxLcTime.value = hasLcYearOption
766
+ ? this.state.lcYear
767
+ : 'default';
763
768
  }
764
769
  if (this.state.lccYear !== null) {
765
- selectBoxLccTime.value = this.state.lccYear;
770
+ const hasLccYearOption = Array.from(
771
+ selectBoxLccTime.options,
772
+ ).some((option) => option.value === this.state.lccYear);
773
+ selectBoxLccTime.value = hasLccYearOption
774
+ ? this.state.lccYear
775
+ : 'default';
766
776
  }
767
777
  break; // move break statement inside the if block
768
778
  }
@@ -783,10 +793,20 @@ class HotspotWidget extends React.Component {
783
793
  } else {
784
794
  selectBox.value = this.state.selectedArea;
785
795
  if (this.state.lcYear !== null) {
786
- selectBoxLcTime.value = this.state.lcYear;
796
+ const hasLcYearOption = Array.from(
797
+ selectBoxLcTime.options,
798
+ ).some((option) => option.value === this.state.lcYear);
799
+ selectBoxLcTime.value = hasLcYearOption
800
+ ? this.state.lcYear
801
+ : 'default';
787
802
  }
788
803
  if (this.state.lccYear !== null) {
789
- selectBoxLccTime.value = this.state.lccYear;
804
+ const hasLccYearOption = Array.from(
805
+ selectBoxLccTime.options,
806
+ ).some((option) => option.value === this.state.lccYear);
807
+ selectBoxLccTime.value = hasLccYearOption
808
+ ? this.state.lccYear
809
+ : 'default';
790
810
  }
791
811
  break;
792
812
  }
@@ -714,6 +714,7 @@ class MapViewer extends React.Component {
714
714
  }
715
715
  this.syncViewWidgetContainers();
716
716
  this.syncViewTask = null;
717
+ this.restorePanelScroll(true);
717
718
  });
718
719
  }
719
720
 
@@ -1552,6 +1553,33 @@ class MapViewer extends React.Component {
1552
1553
  this.processPendingWidgetActivation();
1553
1554
  }
1554
1555
 
1556
+ restorePanelScroll(skipTimeout) {
1557
+ let paneles = document.querySelector('div#paneles.panels');
1558
+ var selected_tab = document.querySelector('.tab-selected');
1559
+
1560
+ if (!paneles || !selected_tab) {
1561
+ return;
1562
+ }
1563
+
1564
+ let toc_panel_scrolls =
1565
+ JSON.parse(sessionStorage.getItem('toc_panel_scrolls')) ?? {};
1566
+ let scroll = toc_panel_scrolls[selected_tab.id];
1567
+ if (scroll !== undefined) {
1568
+ scroll = parseInt(scroll);
1569
+ if (skipTimeout) {
1570
+ if (paneles) {
1571
+ paneles.scrollTop = scroll;
1572
+ }
1573
+ } else {
1574
+ setTimeout(() => {
1575
+ if (paneles) {
1576
+ paneles.scrollTop = scroll;
1577
+ }
1578
+ }, 1000);
1579
+ }
1580
+ }
1581
+ }
1582
+
1555
1583
  componentWillUnmount() {
1556
1584
  this.isComponentMounted = false;
1557
1585
  this.viewTransitionTaskId += 1;
@@ -2173,6 +2201,7 @@ export const CheckUserID = ({ reference }) => {
2173
2201
  tax={reference.tax}
2174
2202
  catalogapi={reference.props.catalogapi}
2175
2203
  fetchCatalogApiDates={reference.props.fetchCatalogApiDates}
2204
+ restorePanelScroll={reference.restorePanelScroll}
2176
2205
  />
2177
2206
  </>
2178
2207
  )}
@@ -762,23 +762,6 @@ class MenuWidget extends React.Component {
762
762
  }
763
763
  }
764
764
 
765
- restorePanelScroll() {
766
- let paneles = document.querySelector('#paneles');
767
- var selected_tab = document.querySelector('.tab-selected');
768
-
769
- if (!paneles || !selected_tab) {
770
- return;
771
- }
772
-
773
- let toc_panel_scrolls =
774
- JSON.parse(sessionStorage.getItem('toc_panel_scrolls')) ?? {};
775
- let scroll = toc_panel_scrolls[selected_tab.id];
776
- if (scroll !== undefined) {
777
- scroll = parseInt(scroll);
778
- paneles.scrollTop = scroll;
779
- }
780
- }
781
-
782
765
  /**
783
766
  * Method that will be invoked when the
784
767
  * button is clicked. It controls the open
@@ -841,7 +824,7 @@ class MenuWidget extends React.Component {
841
824
  timeSliderContainer.style.display = 'block';
842
825
  }
843
826
 
844
- this.restorePanelScroll();
827
+ this.props.restorePanelScroll();
845
828
  }
846
829
 
847
830
  this.setState({ showMapMenu: true });
@@ -2085,10 +2068,14 @@ class MenuWidget extends React.Component {
2085
2068
  ViewService: viewService,
2086
2069
  });
2087
2070
  } else if (viewService?.toLowerCase().includes('wmts')) {
2071
+ const resolveSentinelLayer = /(?:sh\.dataspace\.copernicus\.eu|services\.sentinel-hub\.com)\/ogc\/wmts/i.test(
2072
+ viewService || '',
2073
+ );
2088
2074
  this.layers[layer.LayerId + '_' + inheritedIndexLayer] = new WMTSLayer({
2089
2075
  url: viewService?.includes('?')
2090
2076
  ? viewService + '&'
2091
2077
  : viewService + '?',
2078
+ serviceMode: 'KVP',
2092
2079
  spatialReference: this.view?.spatialReference,
2093
2080
  //id: layer.LayerId,
2094
2081
  title: '',
@@ -2109,6 +2096,7 @@ class MenuWidget extends React.Component {
2109
2096
  DatasetDownloadInformation: dataset_download_information || {},
2110
2097
  customLayerParameters: {
2111
2098
  SHOWLOGO: false,
2099
+ ...(resolveSentinelLayer ? { PREVIEW: 2 } : {}),
2112
2100
  },
2113
2101
  });
2114
2102
  } else {
@@ -2720,6 +2708,18 @@ class MenuWidget extends React.Component {
2720
2708
  if (!activeLayerData) {
2721
2709
  return false;
2722
2710
  }
2711
+ const resolveSentinelLayer = /(?:sh\.dataspace\.copernicus\.eu|services\.sentinel-hub\.com)\/ogc\/wmts/i.test(
2712
+ (
2713
+ currentLayerData.ViewService ||
2714
+ currentLayerData.url ||
2715
+ ''
2716
+ ).toLowerCase(),
2717
+ );
2718
+ const nextCustomLayerParameters = {
2719
+ ...(currentLayerData.customLayerParameters || {}),
2720
+ SHOWLOGO: false,
2721
+ ...(resolveSentinelLayer ? { PREVIEW: 2 } : {}),
2722
+ };
2723
2723
 
2724
2724
  const nextLayerData = new WMTSLayer({
2725
2725
  id: currentLayerData.id || layerId,
@@ -2731,9 +2731,7 @@ class MenuWidget extends React.Component {
2731
2731
  this.view?.spatialReference || currentLayerData.spatialReference,
2732
2732
  activeLayer: activeLayerData,
2733
2733
  ViewService: currentLayerData.ViewService || currentLayerData.url,
2734
- customLayerParameters: currentLayerData.customLayerParameters || {
2735
- SHOWLOGO: false,
2736
- },
2734
+ customLayerParameters: nextCustomLayerParameters,
2737
2735
  });
2738
2736
 
2739
2737
  const customKeys = [
@@ -4461,8 +4459,23 @@ class MenuWidget extends React.Component {
4461
4459
  if (
4462
4460
  this.layers[elem.id].ViewService.toLowerCase().includes('wmts')
4463
4461
  ) {
4462
+ const resolveSentinelLayer = /(?:sh\.dataspace\.copernicus\.eu|services\.sentinel-hub\.com)\/ogc\/wmts/i.test(
4463
+ this.layers[elem.id].ViewService ||
4464
+ this.layers[elem.id].url ||
4465
+ '',
4466
+ );
4467
+ const nextCustomLayerParameters = {
4468
+ ...(this.layers[elem.id].customLayerParameters || {}),
4469
+ SHOWLOGO: false,
4470
+ ...(resolveSentinelLayer ? { PREVIEW: 2 } : {}),
4471
+ TIME:
4472
+ payload.dates[payload.dates.length - 1] +
4473
+ '/' +
4474
+ payload.dates[payload.dates.length - 1] || '',
4475
+ };
4464
4476
  this.layers[elem.id] = new WMTSLayer({
4465
4477
  url: this.layers[elem.id].url,
4478
+ serviceMode: this.layers[elem.id].serviceMode || 'KVP',
4466
4479
  spatialReference: this.layers[elem.id].spatialReference,
4467
4480
  title: this.layers[elem.id].title,
4468
4481
  _wmtsTitle: this.layers[elem.id]._wmtsTitle,
@@ -4477,13 +4490,7 @@ class MenuWidget extends React.Component {
4477
4490
  LayerTitle: this.layers[elem.id].LayerTitle,
4478
4491
  DatasetDownloadInformation: this.layers[elem.id]
4479
4492
  .DatasetDownloadInformation,
4480
- customLayerParameters: {
4481
- SHOWLOGO: false,
4482
- TIME:
4483
- payload.dates[payload.dates.length - 1] +
4484
- '/' +
4485
- payload.dates[payload.dates.length - 1] || '',
4486
- },
4493
+ customLayerParameters: nextCustomLayerParameters,
4487
4494
  });
4488
4495
  }
4489
4496
  }
@@ -4649,26 +4656,97 @@ class MenuWidget extends React.Component {
4649
4656
  sessionStorage.removeItem('downloadButtonClicked');
4650
4657
  sessionStorage.removeItem('timeSliderTag');
4651
4658
  this.deleteCheckedLayer(elem.id);
4652
- this.layers[elem.id].opacity = 1;
4653
- this.layers[elem.id].visible = false;
4659
+ const currentLayerData = this.layers[elem.id];
4660
+ currentLayerData.opacity = 1;
4661
+ currentLayerData.visible = false;
4654
4662
  if (!userService) this.deleteFilteredLayer(elem.id);
4655
- let mapLayer = this.map.findLayerById(elem.id);
4663
+ const mapLayersToRemove = [];
4664
+ const mapLayer = this.map.findLayerById(elem.id);
4656
4665
  if (mapLayer) {
4666
+ mapLayersToRemove.push(mapLayer);
4667
+ }
4668
+ if (
4669
+ currentLayerData &&
4670
+ this.map &&
4671
+ this.map.layers &&
4672
+ typeof this.map.layers.includes === 'function' &&
4673
+ this.map.layers.includes(currentLayerData)
4674
+ ) {
4675
+ mapLayersToRemove.push(currentLayerData);
4676
+ }
4677
+ const currentLayerService = String(
4678
+ currentLayerData?.ViewService || currentLayerData?.url || '',
4679
+ ).toLowerCase();
4680
+ const currentLayerActive = currentLayerData?.activeLayer?.id || null;
4681
+ const currentLayerDataset = currentLayerData?.DatasetId || null;
4682
+ const mapLayerItems = this.map?.layers?.items || [];
4683
+ mapLayerItems.forEach((candidateLayer) => {
4684
+ if (!candidateLayer) {
4685
+ return;
4686
+ }
4687
+ if (candidateLayer === currentLayerData) {
4688
+ mapLayersToRemove.push(candidateLayer);
4689
+ return;
4690
+ }
4691
+ if (
4692
+ candidateLayer.LayerId === elem.id ||
4693
+ candidateLayer.id === elem.id
4694
+ ) {
4695
+ mapLayersToRemove.push(candidateLayer);
4696
+ return;
4697
+ }
4698
+ const candidateService = String(
4699
+ candidateLayer.ViewService || candidateLayer.url || '',
4700
+ ).toLowerCase();
4701
+ if (!currentLayerService || currentLayerService !== candidateService) {
4702
+ return;
4703
+ }
4704
+ if (
4705
+ currentLayerActive &&
4706
+ candidateLayer.activeLayer &&
4707
+ candidateLayer.activeLayer.id === currentLayerActive
4708
+ ) {
4709
+ mapLayersToRemove.push(candidateLayer);
4710
+ return;
4711
+ }
4712
+ if (
4713
+ currentLayerDataset &&
4714
+ candidateLayer.DatasetId &&
4715
+ candidateLayer.DatasetId === currentLayerDataset
4716
+ ) {
4717
+ mapLayersToRemove.push(candidateLayer);
4718
+ }
4719
+ });
4720
+ const removedLayerIds = new Set();
4721
+ mapLayersToRemove.forEach((layerToRemove) => {
4722
+ if (!layerToRemove) {
4723
+ return;
4724
+ }
4725
+ const layerIdentity = layerToRemove.uid || layerToRemove.id;
4726
+ if (layerIdentity && removedLayerIds.has(layerIdentity)) {
4727
+ return;
4728
+ }
4657
4729
  if (!userService) {
4658
4730
  if (
4659
- mapLayer.type &&
4660
- mapLayer.type !== 'base-tile' &&
4661
- mapLayer.type !== 'wmts'
4662
- )
4663
- mapLayer.clear();
4664
- if (mapLayer.type !== 'wmts') {
4665
- mapLayer.destroy();
4731
+ layerToRemove.type &&
4732
+ layerToRemove.type !== 'base-tile' &&
4733
+ layerToRemove.type !== 'wmts' &&
4734
+ typeof layerToRemove.clear === 'function'
4735
+ ) {
4736
+ layerToRemove.clear();
4737
+ }
4738
+ if (
4739
+ layerToRemove.type !== 'wmts' &&
4740
+ typeof layerToRemove.destroy === 'function'
4741
+ ) {
4742
+ layerToRemove.destroy();
4666
4743
  }
4667
- this.map.remove(this.layers[elem.id]);
4668
- } else {
4669
- this.map.remove(mapLayer);
4670
4744
  }
4671
- }
4745
+ this.map.remove(layerToRemove);
4746
+ if (layerIdentity) {
4747
+ removedLayerIds.add(layerIdentity);
4748
+ }
4749
+ });
4672
4750
  if (this.uploadedGraphics && this.uploadedGraphics[elem.id]) {
4673
4751
  try {
4674
4752
  this.view.graphics.removeMany(this.uploadedGraphics[elem.id]);
@@ -7653,7 +7731,7 @@ class MenuWidget extends React.Component {
7653
7731
  if (document.querySelector('.opacity-panel').style.display === 'block') {
7654
7732
  this.closeOpacity();
7655
7733
  }
7656
- this.restorePanelScroll();
7734
+ this.props.restorePanelScroll();
7657
7735
  }
7658
7736
  }
7659
7737
 
@@ -152,8 +152,9 @@ class SwipeWidget extends React.Component {
152
152
  // CLOSE
153
153
  this.props.mapViewer.setActiveWidget();
154
154
  this.cleanupSwipeState();
155
- this.loadVisibleLayers();
155
+ this.removeLayerChangeListener();
156
156
  this.cleanupSwipeResource();
157
+ this.loadVisibleLayers();
157
158
  this.setState({ showMapMenu: false });
158
159
  if (shouldReturnToThreeDimensionalView) {
159
160
  this.props.mapViewer.switchViewMode('3d');
@@ -434,11 +435,15 @@ class SwipeWidget extends React.Component {
434
435
  let cl = JSON.parse(sessionStorage.getItem('checkedLayers'));
435
436
  if (cl) {
436
437
  cl.forEach((layer) => {
437
- if (layers[layer].id === selectedLeadingLayer) {
438
- this.swipe.leadingLayers.add(layers[layer]);
438
+ const selectedLayer = layers[layer];
439
+ if (!selectedLayer) {
440
+ return;
441
+ }
442
+ if (selectedLayer.id === selectedLeadingLayer) {
443
+ this.swipe.leadingLayers.add(selectedLayer);
439
444
  }
440
- if (layers[layer].id === selectedTrailingLayer) {
441
- this.swipe.trailingLayers.add(layers[layer]);
445
+ if (selectedLayer.id === selectedTrailingLayer) {
446
+ this.swipe.trailingLayers.add(selectedLayer);
442
447
  }
443
448
  });
444
449
  }
@@ -488,7 +493,9 @@ class SwipeWidget extends React.Component {
488
493
  let cl = JSON.parse(sessionStorage.getItem('checkedLayers'));
489
494
  if (cl) {
490
495
  cl.forEach((layer) => {
491
- this.map.layers.add(layers[layer]);
496
+ if (layers[layer]) {
497
+ this.map.layers.add(layers[layer]);
498
+ }
492
499
  });
493
500
  }
494
501
  if (layers['lcc_filter']) {