@eeacms/volto-arcgis-block 0.1.334 → 0.1.336

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,15 @@ 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.336](https://github.com/eea/volto-arcgis-block/compare/0.1.335...0.1.336) - 10 February 2025
8
+
9
+ ### [0.1.335](https://github.com/eea/volto-arcgis-block/compare/0.1.334...0.1.335) - 7 February 2025
10
+
11
+ #### :hammer_and_wrench: Others
12
+
13
+ - CLMS-282421 (bug): solving for null version 1 for separate local host testing [Unai Bolivar - [`0cbd11c`](https://github.com/eea/volto-arcgis-block/commit/0cbd11cc6b49562bd9221cf4aeb34e2e29ac1f6f)]
14
+ - commiting latest change [Unai Bolivar - [`6c88ed5`](https://github.com/eea/volto-arcgis-block/commit/6c88ed5897d72ecc2373fca07fcacf08f3934480)]
15
+ - CLMS-282421 (bug): solving for null continue on metodProcessLayer line 1700 [Unai Bolivar - [`fd934f4`](https://github.com/eea/volto-arcgis-block/commit/fd934f4528db043a4c25cc78d1a8c19d510d27c7)]
7
16
  ### [0.1.334](https://github.com/eea/volto-arcgis-block/compare/0.1.333...0.1.334) - 31 January 2025
8
17
 
9
18
  ### [0.1.333](https://github.com/eea/volto-arcgis-block/compare/0.1.332...0.1.333) - 30 January 2025
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eeacms/volto-arcgis-block",
3
- "version": "0.1.334",
3
+ "version": "0.1.336",
4
4
  "description": "volto-arcgis-block: Volto add-on",
5
5
  "main": "src/index.js",
6
6
  "author": "European Environment Agency: CodeSyntax",
@@ -65,7 +65,7 @@
65
65
  "esri-loader": "3.4.0",
66
66
  "highcharts": "^9.3.2",
67
67
  "highcharts-react-official": "^3.1.0",
68
- "react-datepicker": "4.10.0"
68
+ "react-datepicker": "4.15.0"
69
69
  },
70
70
  "devDependencies": {
71
71
  "@cypress/code-coverage": "^3.9.5",
@@ -53,17 +53,17 @@ export const AddCartItem = ({
53
53
  } else {
54
54
  area.type = 'polygon';
55
55
  area.value = [
56
- areaData.origin.x,
57
- areaData.origin.y,
58
- areaData.end.x,
59
- areaData.end.y,
56
+ areaData?.origin?.x,
57
+ areaData?.origin?.y,
58
+ areaData?.end?.x,
59
+ areaData?.end?.y,
60
60
  ];
61
61
  }
62
62
  } else {
63
63
  if (areaData) {
64
64
  area.type = 'nuts';
65
- if (areaData.geometry.type === 'polygon') {
66
- if (areaData.attributes.ISO_2DIGIT !== undefined) {
65
+ if (areaData?.geometry?.type === 'polygon') {
66
+ if (areaData?.attributes?.ISO_2DIGIT !== undefined) {
67
67
  area.value = areaData.attributes.ISO_2DIGIT;
68
68
  } else {
69
69
  area.value = areaData.attributes.NUTS_ID;
@@ -75,15 +75,17 @@ export const AddCartItem = ({
75
75
  }
76
76
  let data = checkCartData(cartData, area, dataset);
77
77
  addCartItem(data).then(() => {
78
- if (dataset.IsTimeSeries) {
79
- let id = dataset.DatasetId;
78
+ if (dataset?.IsTimeSeries) {
79
+ let id = dataset?.DatasetId;
80
80
  let datasetElem = document.querySelector('[datasetid="' + id + '"]');
81
81
  let datasetInput = document.querySelector(
82
82
  '#active_' +
83
83
  datasetElem.querySelector('.map-menu-layer input:checked').id,
84
84
  );
85
- datasetInput.removeAttribute('time-start');
86
- datasetInput.removeAttribute('time-end');
85
+ if (datasetInput) {
86
+ datasetInput.removeAttribute('time-start');
87
+ datasetInput.removeAttribute('time-end');
88
+ }
87
89
  }
88
90
  });
89
91
  };
@@ -97,20 +99,20 @@ export const AddCartItem = ({
97
99
  : false;
98
100
  if (check === 'area' || fileUpload) {
99
101
  areaExtent = new Extent({
100
- xmin: Math.min(areaData.end.x, areaData.origin.x),
101
- xmax: Math.max(areaData.end.x, areaData.origin.x),
102
- ymin: Math.min(areaData.end.y, areaData.origin.y),
103
- ymax: Math.max(areaData.end.y, areaData.origin.y),
102
+ xmin: Math.min(areaData?.end?.x, areaData?.origin?.x),
103
+ xmax: Math.max(areaData?.end?.x, areaData?.origin?.x),
104
+ ymin: Math.min(areaData?.end?.y, areaData?.origin?.y),
105
+ ymax: Math.max(areaData?.end?.y, areaData?.origin?.y),
104
106
  });
105
107
  } else if (isMapServer) {
106
108
  areaExtent = new Extent({
107
- xmin: areaData.geometry.extent.xmin,
108
- ymin: areaData.geometry.extent.ymin,
109
- xmax: areaData.geometry.extent.xmax,
110
- ymax: areaData.geometry.extent.ymax,
109
+ xmin: areaData?.geometry?.extent?.xmin,
110
+ ymin: areaData?.geometry?.extent?.ymin,
111
+ xmax: areaData?.geometry?.extent?.xmax,
112
+ ymax: areaData?.geometry?.extent?.ymax,
111
113
  });
112
114
  } else {
113
- areaExtent = areaData.geometry;
115
+ areaExtent = areaData?.geometry;
114
116
  }
115
117
  if (dataset?.DatasetTitle) {
116
118
  Object.keys(props.layers).forEach((id) => {
@@ -159,15 +161,21 @@ export const AddCartItem = ({
159
161
  if (intersection) {
160
162
  checkArea();
161
163
  } else {
162
- e.currentTarget.appendChild(document.querySelector('.popup-container'));
163
- handleOpenPopup();
164
+ const popupContainer = document.querySelector('.popup-container');
165
+ if (popupContainer) {
166
+ e.currentTarget.appendChild(popupContainer);
167
+ handleOpenPopup();
168
+ }
164
169
  }
165
170
  }
166
171
  };
167
172
 
168
173
  const checkCartData = (cartData, area, dataset) => {
169
174
  if (!dataset) {
170
- dataset = cartData[0].Products[0].Datasets[0];
175
+ dataset = cartData?.[0]?.Products?.[0]?.Datasets?.[0];
176
+ }
177
+ if (!dataset) {
178
+ return [];
171
179
  }
172
180
  let id = dataset.DatasetId;
173
181
  let datasetData = {
@@ -181,13 +189,15 @@ export const AddCartItem = ({
181
189
  };
182
190
 
183
191
  if (!dataset) {
184
- dataset = cartData[0].Products[0].Datasets[0];
192
+ dataset = cartData?.[0]?.Products?.[0]?.Datasets?.[0];
185
193
  }
186
194
 
187
195
  const setDownloadTag = (val) => {
188
- if (!sessionStorage.key('downloadButtonClicked'))
196
+ if (!sessionStorage.key('downloadButtonClicked')) {
189
197
  sessionStorage.setItem('downloadButtonClicked', 'true');
190
- else sessionStorage.setItem('downloadButtonClicked', val);
198
+ } else {
199
+ sessionStorage.setItem('downloadButtonClicked', val);
200
+ }
191
201
  };
192
202
 
193
203
  return (
@@ -463,12 +473,14 @@ class MenuWidget extends React.Component {
463
473
  let checksList = [...checks];
464
474
  if (checksList && checksList !== null) {
465
475
  checksList.forEach((check) => {
466
- if (check !== null) {
476
+ if (check && check !== null) {
467
477
  if (check.querySelector('[type="checkbox"]').checked) {
468
478
  let node = [
469
479
  ...check.getElementsByClassName('zoom-in-message-dataset'),
470
480
  ][0];
471
- node.style.display = zoom > 6 ? 'none' : 'block';
481
+ if (node && node !== null) {
482
+ node.style.display = zoom > 6 ? 'none' : 'block';
483
+ }
472
484
  }
473
485
  }
474
486
  });
@@ -537,8 +549,11 @@ class MenuWidget extends React.Component {
537
549
  }
538
550
 
539
551
  stringMatch(str1, str2) {
552
+ if (!str1 || !str2) {
553
+ return '';
554
+ }
540
555
  let matchingPart = '';
541
- for (let i = 0; i < str1.length; i++) {
556
+ for (let i = 0; i < str1.length && i < str2.length; i++) {
542
557
  if (str1[i] === str2[i]) {
543
558
  matchingPart += str1[i];
544
559
  } else {
@@ -559,27 +574,31 @@ class MenuWidget extends React.Component {
559
574
  hotspotProduct.Datasets.forEach((dataset) => {
560
575
  const layerObj = {};
561
576
  dataset.Layer.forEach((layer) => {
562
- layerObj[layer.LayerId] = layer;
577
+ if (layer && layer.LayerId) {
578
+ layerObj[layer.LayerId] = layer;
579
+ }
563
580
  });
564
581
  let key;
565
582
  if (dataset.Layer.length === 1) {
566
- key = dataset.Layer[0].LayerId;
583
+ key = dataset.Layer[0]?.LayerId;
567
584
  } else if (dataset.Layer.length === 2) {
568
585
  key = this.stringMatch(
569
- dataset.Layer[0].LayerId,
570
- dataset.Layer[1].LayerId,
586
+ dataset.Layer[0]?.LayerId,
587
+ dataset.Layer[1]?.LayerId,
571
588
  );
572
- if (key.endsWith('_')) {
589
+ if (key?.endsWith('_')) {
573
590
  key = key.slice(0, -1);
574
591
  }
575
592
  } else if (dataset.Layer.length > 2) {
576
- key = dataset.DatasetTitle.toLowerCase()
593
+ key = dataset.DatasetTitle?.toLowerCase()
577
594
  .split(' ')
578
595
  .join('_')
579
596
  .split('_(')[0]
580
597
  .split('_for')[0];
581
598
  }
582
- datasetObj[key] = layerObj;
599
+ if (key) {
600
+ datasetObj[key] = layerObj;
601
+ }
583
602
  });
584
603
  return this.props.hotspotDataHandler(datasetObj);
585
604
  }
@@ -597,12 +616,15 @@ class MenuWidget extends React.Component {
597
616
  .then((response) => {
598
617
  if (!response.ok) {
599
618
  //console.error(`HTTP error, status = ${response.status}`);
619
+ return null;
600
620
  }
601
621
  return response.json();
602
622
  })
603
623
  .then((data) => {
604
- // fill dataset.Layer manually
605
- dataset.Layer = data.Layers;
624
+ if (data) {
625
+ // fill dataset.Layer manually
626
+ dataset.Layer = data.Layers;
627
+ }
606
628
  })
607
629
  .catch((error) => {
608
630
  //console.error(error);
@@ -649,9 +671,9 @@ class MenuWidget extends React.Component {
649
671
 
650
672
  if (!paneles || !selected_tab) {
651
673
  return;
652
- } else if (paneles && selected_tab) {
674
+ } else {
653
675
  let toc_panel_scrolls =
654
- JSON.parse(sessionStorage.getItem('toc_panel_scrolls')) || {};
676
+ JSON.parse(sessionStorage.getItem('toc_panel_scrolls')) ?? {};
655
677
  toc_panel_scrolls[selected_tab.id] = paneles.scrollTop;
656
678
  sessionStorage.setItem(
657
679
  'toc_panel_scrolls',
@@ -669,7 +691,7 @@ class MenuWidget extends React.Component {
669
691
  }
670
692
 
671
693
  let toc_panel_scrolls =
672
- JSON.parse(sessionStorage.getItem('toc_panel_scrolls')) || {};
694
+ JSON.parse(sessionStorage.getItem('toc_panel_scrolls')) ?? {};
673
695
  let scroll = toc_panel_scrolls[selected_tab.id];
674
696
  if (scroll !== undefined) {
675
697
  scroll = parseInt(scroll);
@@ -683,64 +705,65 @@ class MenuWidget extends React.Component {
683
705
  * and close actions of the component
684
706
  */
685
707
  openMenu() {
686
- // setTimeout(() => {
687
708
  if (this.state.showMapMenu) {
688
- this.container.current.querySelector('#tabcontainer').style.display =
689
- 'none';
690
- this.container.current.querySelector('#paneles').style.display = 'none';
691
- this.container.current
692
- .querySelector('.esri-widget--button')
693
- .classList.replace('esri-icon-close', 'esri-icon-drag-horizontal');
694
- if (document.contains(document.querySelector('.timeslider-container'))) {
695
- document.querySelector('.timeslider-container').style.display = 'none';
696
- }
697
- if (document.querySelector('.opacity-panel').style.display === 'block') {
698
- this.closeOpacity();
709
+ const container = this.container.current;
710
+ if (container) {
711
+ const tabContainer = container.querySelector('#tabcontainer');
712
+ const paneles = container.querySelector('#paneles');
713
+ const esriWidgetButton = container.querySelector(
714
+ '.esri-widget--button',
715
+ );
716
+ const timeSliderContainer = document.querySelector(
717
+ '.timeslider-container',
718
+ );
719
+ const opacityPanel = document.querySelector('.opacity-panel');
720
+
721
+ if (tabContainer) tabContainer.style.display = 'none';
722
+ if (paneles) paneles.style.display = 'none';
723
+ if (esriWidgetButton) {
724
+ esriWidgetButton.classList.replace(
725
+ 'esri-icon-close',
726
+ 'esri-icon-drag-horizontal',
727
+ );
728
+ }
729
+ if (timeSliderContainer && document.contains(timeSliderContainer)) {
730
+ timeSliderContainer.style.display = 'none';
731
+ }
732
+ if (opacityPanel && opacityPanel.style.display === 'block') {
733
+ this.closeOpacity();
734
+ }
699
735
  }
700
736
 
701
737
  // By invoking the setState, we notify the state we want to reach
702
738
  // and ensure that the component is rendered again
703
739
  this.setState({ showMapMenu: false });
704
740
  } else {
705
- /*
706
- The following variables have been changed from container
707
- to this.container.current to avoid data viewer crash
708
- when client comes from dataset / product pages or refreshing
709
- */
710
- const tabContainer = this.container.current.querySelector(
711
- '#tabcontainer',
712
- );
713
- const paneles = this.container.current.querySelector('#paneles');
714
- const esriWidgetButton = this.container.current.querySelector(
715
- '.esri-widget--button',
716
- );
717
- const timeSliderContainer = document.querySelector(
718
- '.timeslider-container',
719
- );
720
-
721
- if (tabContainer) {
722
- tabContainer.style.display = 'block';
723
- }
724
-
725
- if (paneles) {
726
- paneles.style.display = 'block';
727
- }
728
-
729
- if (esriWidgetButton) {
730
- esriWidgetButton.classList.replace(
731
- 'esri-icon-drag-horizontal',
732
- 'esri-icon-close',
741
+ const container = this.container.current;
742
+ if (container) {
743
+ const tabContainer = container.querySelector('#tabcontainer');
744
+ const paneles = container.querySelector('#paneles');
745
+ const esriWidgetButton = container.querySelector(
746
+ '.esri-widget--button',
747
+ );
748
+ const timeSliderContainer = document.querySelector(
749
+ '.timeslider-container',
733
750
  );
734
- }
735
751
 
736
- if (timeSliderContainer && document.contains(timeSliderContainer)) {
737
- timeSliderContainer.style.display = 'block';
738
- }
752
+ if (tabContainer) tabContainer.style.display = 'block';
753
+ if (paneles) paneles.style.display = 'block';
754
+ if (esriWidgetButton) {
755
+ esriWidgetButton.classList.replace(
756
+ 'esri-icon-drag-horizontal',
757
+ 'esri-icon-close',
758
+ );
759
+ }
760
+ if (timeSliderContainer && document.contains(timeSliderContainer)) {
761
+ timeSliderContainer.style.display = 'block';
762
+ }
739
763
 
740
- this.restorePanelScroll();
764
+ this.restorePanelScroll();
765
+ }
741
766
 
742
- // By invoking the setState, we notify the state we want to reach
743
- // and ensure that the component is rendered again
744
767
  this.setState({ showMapMenu: true });
745
768
  }
746
769
  // if (this.loadFirst && this.container.current) {
@@ -755,66 +778,65 @@ class MenuWidget extends React.Component {
755
778
  let checkedLayers = JSON.parse(sessionStorage.getItem('checkedLayers'));
756
779
 
757
780
  // "Active on map" section and the time slider opened by default if user is logged in and timeSliderTag is true
758
- if (checkedLayers && !this.props.download) {
759
- // "Active on map" section and the time slider opened by default if user is logged in and timeSliderTag is true
781
+ if (checkedLayers?.length && !this.props.download) {
760
782
  if (authToken && timeSliderTag) {
761
- for (let i = 0; i < checkedLayers.length; i++) {
762
- let layerid = checkedLayers[i];
783
+ for (const layerid of checkedLayers) {
763
784
  if (
764
785
  layerid &&
765
- this.layers[layerid].isTimeSeries &&
786
+ this.layers[layerid]?.isTimeSeries &&
766
787
  !this.container.current
767
788
  .querySelector('.esri-widget')
768
789
  .classList.contains('esri-icon-drag-horizontal')
769
790
  ) {
770
- // select active on map tab
771
- let event = new MouseEvent('click', {
791
+ const event = new MouseEvent('click', {
772
792
  view: window,
773
793
  bubbles: true,
774
794
  cancelable: false,
775
795
  });
776
- let el = document.getElementById('download_label');
777
- el.dispatchEvent(event);
796
+ const el = document.getElementById('download_label');
797
+ if (el) {
798
+ el.dispatchEvent(event);
799
+ }
778
800
  break;
779
801
  }
780
802
  }
781
- }
782
- // "Area widget" opened by default if user is logged in and downloadTag is true
783
- else if (authToken && downloadTag) {
784
- for (let i = 0; i < checkedLayers.length; i++) {
785
- let layerid = checkedLayers[i];
803
+ } else if (authToken && downloadTag) {
804
+ for (const layerid of checkedLayers) {
786
805
  if (
787
806
  layerid &&
788
- !this.layers[layerid].isTimeSeries &&
807
+ !this.layers[layerid]?.isTimeSeries &&
789
808
  !this.container.current
790
809
  .querySelector('.esri-widget')
791
810
  .classList.contains('esri-icon-drag-horizontal')
792
811
  ) {
793
- //open area widget
794
- let event = new MouseEvent('click', {
812
+ const event = new MouseEvent('click', {
795
813
  view: window,
796
814
  bubbles: true,
797
815
  cancelable: false,
798
816
  });
799
- document
800
- .querySelector('.map-menu-icon-login.logged')
801
- .dispatchEvent(event);
817
+ const loginIcon = document.querySelector(
818
+ '.map-menu-icon-login.logged',
819
+ );
820
+ if (loginIcon) {
821
+ loginIcon.dispatchEvent(event);
822
+ }
802
823
  break;
803
824
  } else if (
804
825
  layerid &&
805
- this.layers[layerid].isTimeSeries &&
826
+ this.layers[layerid]?.isTimeSeries &&
806
827
  !this.container.current
807
828
  .querySelector('.esri-widget')
808
829
  .classList.contains('esri-icon-drag-horizontal')
809
830
  ) {
810
- // select active on map tab
811
- let event = new MouseEvent('click', {
831
+ const event = new MouseEvent('click', {
812
832
  view: window,
813
833
  bubbles: true,
814
834
  cancelable: false,
815
835
  });
816
- let el = document.getElementById('download_label');
817
- el.dispatchEvent(event);
836
+ const el = document.getElementById('download_label');
837
+ if (el) {
838
+ el.dispatchEvent(event);
839
+ }
818
840
  break;
819
841
  }
820
842
  }
@@ -823,27 +845,26 @@ class MenuWidget extends React.Component {
823
845
  // CLMS-1389
824
846
  // "Active on map" section and the time slider opened by default if download and timeseries == true
825
847
 
826
- if (this.layers)
827
- if (this.props.download && this.layers) {
828
- let layerid = Object.keys(this.layers)[0];
829
- if (
830
- layerid &&
831
- this.layers[layerid].isTimeSeries &&
832
- !this.container.current
833
- .querySelector('.esri-widget')
834
- .classList.contains('esri-icon-drag-horizontal')
835
- ) {
836
- // select active on map tab
837
- let event = new MouseEvent('click', {
838
- view: window,
839
- bubbles: true,
840
- cancelable: false,
841
- });
842
- let el = document.getElementById('download_label');
848
+ if (this.props.download && this.layers) {
849
+ const layerid = Object.keys(this.layers)[0];
850
+ if (
851
+ layerid &&
852
+ this.layers[layerid]?.isTimeSeries &&
853
+ !this.container.current
854
+ .querySelector('.esri-widget')
855
+ .classList.contains('esri-icon-drag-horizontal')
856
+ ) {
857
+ const event = new MouseEvent('click', {
858
+ view: window,
859
+ bubbles: true,
860
+ cancelable: false,
861
+ });
862
+ const el = document.getElementById('download_label');
863
+ if (el) {
843
864
  el.dispatchEvent(event);
844
865
  }
845
866
  }
846
- // }, 1000);
867
+ }
847
868
  }
848
869
 
849
870
  /**
@@ -860,10 +881,17 @@ class MenuWidget extends React.Component {
860
881
  this.props.view.ui.add(this.container.current, 'top-left');
861
882
  });
862
883
  if (this.props.download) {
863
- // setTimeout(() => {
864
- document.querySelector('.area-panel input:checked').click();
865
- if (document.querySelector('.map-product-checkbox input')) {
866
- document.querySelector('.map-product-checkbox input').click();
884
+ const areaPanelInput = document.querySelector(
885
+ '.area-panel input:checked',
886
+ );
887
+ if (areaPanelInput) {
888
+ areaPanelInput.click();
889
+ }
890
+ const mapProductCheckboxInput = document.querySelector(
891
+ '.map-product-checkbox input',
892
+ );
893
+ if (mapProductCheckboxInput) {
894
+ mapProductCheckboxInput.click();
867
895
  let dropdown = document.querySelector(
868
896
  '.map-menu-dropdown .ccl-expandable__button',
869
897
  );
@@ -872,13 +900,12 @@ class MenuWidget extends React.Component {
872
900
  dropdown = document.querySelector(
873
901
  '.map-menu-product-dropdown .ccl-expandable__button',
874
902
  );
875
- dropdown.setAttribute('aria-expanded', 'true');
903
+ if (dropdown) {
904
+ dropdown.setAttribute('aria-expanded', 'true');
905
+ }
876
906
  }
877
907
  }
878
- // }, 1000);
879
908
  }
880
- //to watch the component
881
- //this.setState({});
882
909
  this.openMenu();
883
910
  this.loadComponentFilters();
884
911
  this.expandDropdowns();
@@ -888,85 +915,70 @@ class MenuWidget extends React.Component {
888
915
  this.handleRasterVectorLegend();
889
916
  this.map.when(() => {
890
917
  this.map.layers.on('change', (e) => {
891
- if (
892
- this.props.bookmarkData === null ||
893
- this.props.bookmarkData === undefined
894
- ) {
895
- return;
896
- } else if (
897
- this.props.bookmarkData &&
898
- this.props.bookmarkData.active === true
899
- ) {
900
- this.map.layers.removeAll();
901
- let layers = JSON.parse(sessionStorage.getItem('checkedLayers'));
902
- for (const layer in this.layers) {
903
- let node = document.getElementById(layer);
904
- if (node) {
905
- if (layers.includes(layer)) {
906
- let index = layers.indexOf(layer);
907
- let visible;
908
- if (this.props.bookmarkData.position !== null) {
909
- let pos = this.props.bookmarkData.position;
910
- let visibleArray = this.props.bookmarkData.visible[pos];
911
- visible =
912
- String(visibleArray[index]) === 'true' ? true : false;
913
- if (this.layers[layer]) {
914
- let opacityArray = this.props.bookmarkData.opacity[pos];
915
- this.layers[layer].opacity = opacityArray[index];
916
- }
917
- }
918
- node.checked = true;
919
- this.toggleLayer(node);
920
- if (visible === false) {
921
- this.eyeLayer(node);
918
+ if (!this.props.bookmarkData?.active) return;
919
+
920
+ this.map.layers.removeAll();
921
+ const layers =
922
+ JSON.parse(sessionStorage.getItem('checkedLayers')) ?? [];
923
+ for (const layer in this.layers) {
924
+ const node = document.getElementById(layer);
925
+ if (node) {
926
+ if (layers.includes(layer)) {
927
+ const index = layers.indexOf(layer);
928
+ let visible;
929
+ if (this.props.bookmarkData.position !== null) {
930
+ let pos = this.props.bookmarkData.position;
931
+ let visibleArray = this.props.bookmarkData.visible[pos];
932
+ visible = String(visibleArray[index]) === 'true';
933
+ if (this.layers[layer]) {
934
+ let opacityArray = this.props.bookmarkData.opacity[pos];
935
+ this.layers[layer].opacity = opacityArray[index];
922
936
  }
923
- } else if (node.checked) {
924
- node.checked = false;
925
- this.toggleLayer(node);
926
937
  }
938
+ node.checked = true;
939
+ this.toggleLayer(node);
940
+ if (visible === false) {
941
+ this.eyeLayer(node);
942
+ }
943
+ } else if (node.checked) {
944
+ node.checked = false;
945
+ this.toggleLayer(node);
927
946
  }
928
947
  }
929
- let counter = layers.length - 1;
930
- layers.forEach((layer, index) => {
931
- let order = counter - index;
932
- let activeLayers = document.querySelectorAll('.active-layer');
933
- activeLayers.forEach((item) => {
934
- if (
935
- item.parentElement &&
936
- layer === item.getAttribute('layer-id')
937
- ) {
938
- item.parentElement.insertBefore(item, activeLayers[order]);
939
- }
940
- });
941
- });
942
- this.layersReorder();
943
- this.saveLayerOrder();
944
- let elementOpacities = document.querySelectorAll(
945
- '.active-layer-opacity',
946
- );
947
- let layerOpacities = JSON.parse(
948
- sessionStorage.getItem('layerOpacities'),
949
- );
950
- elementOpacities.forEach((element) => {
951
- let parentElement = element.parentElement?.parentElement;
952
- if (parentElement) {
953
- let id = element.parentElement.parentElement.getAttribute(
954
- 'layer-id',
955
- );
956
- if (layerOpacities && layerOpacities[id]) {
957
- element.dataset.opacity = layerOpacities[id] * 100;
958
- } else {
959
- element.dataset.opacity = 100;
960
- }
948
+ }
949
+ const counter = layers.length - 1;
950
+ layers.forEach((layer, index) => {
951
+ const order = counter - index;
952
+ const activeLayers = document.querySelectorAll('.active-layer');
953
+ activeLayers.forEach((item) => {
954
+ if (item.parentElement && layer === item.getAttribute('layer-id')) {
955
+ item.parentElement.insertBefore(item, activeLayers[order]);
961
956
  }
962
957
  });
963
- let bookmarkData = {
964
- ...(this.props.bookmarkData || {}),
965
- active: false,
966
- position: null,
967
- };
968
- this.props.bookmarkHandler(bookmarkData);
969
- }
958
+ });
959
+ this.layersReorder();
960
+ this.saveLayerOrder();
961
+ const elementOpacities = document.querySelectorAll(
962
+ '.active-layer-opacity',
963
+ );
964
+ const layerOpacities = JSON.parse(
965
+ sessionStorage.getItem('layerOpacities'),
966
+ );
967
+ elementOpacities.forEach((element) => {
968
+ const parentElement = element.parentElement?.parentElement;
969
+ if (parentElement) {
970
+ const id = parentElement.getAttribute('layer-id');
971
+ element.dataset.opacity = layerOpacities[id]
972
+ ? layerOpacities[id] * 100
973
+ : 100;
974
+ }
975
+ });
976
+ let bookmarkData = {
977
+ ...(this.props.bookmarkData || {}),
978
+ active: false,
979
+ position: null,
980
+ };
981
+ this.props.bookmarkHandler(bookmarkData);
970
982
  });
971
983
  });
972
984
  }
@@ -974,7 +986,9 @@ class MenuWidget extends React.Component {
974
986
  setSliderTag(val) {
975
987
  if (!sessionStorage.key('timeSliderTag'))
976
988
  sessionStorage.setItem('timeSliderTag', 'true');
977
- else sessionStorage.setItem('timeSliderTag', val);
989
+ else {
990
+ sessionStorage.setItem('timeSliderTag', val);
991
+ }
978
992
  }
979
993
 
980
994
  getAuthToken() {
@@ -997,7 +1011,7 @@ class MenuWidget extends React.Component {
997
1011
  !!(elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length);
998
1012
  let element = document.querySelector('.opacity-panel');
999
1013
  const outsideClickListener = (event) => {
1000
- if (!element.contains(event.target) && isVisible(element)) {
1014
+ if (element && !element.contains(event.target) && isVisible(element)) {
1001
1015
  // or use: event.target.closest(selector) === null
1002
1016
  this.closeOpacity();
1003
1017
  removeClickListener();
@@ -1037,35 +1051,38 @@ class MenuWidget extends React.Component {
1037
1051
  let node = document.querySelector(elem + ' input');
1038
1052
  if (node) {
1039
1053
  node.dispatchEvent(event);
1040
- let dropdown = document
1041
- .querySelector(elem + ' input')
1042
- .closest('.map-menu-dropdown');
1043
- dropdown
1044
- .querySelector('.ccl-expandable__button')
1045
- .setAttribute('aria-expanded', 'true');
1046
- let scrollPosition = document
1047
- .querySelector(elem + ' input')
1048
- .closest('.map-menu-product-dropdown').offsetTop;
1049
- if (dataset) {
1050
- dropdown = document
1051
- .querySelector(elem + ' input')
1052
- .closest('.map-menu-product-dropdown');
1053
- dropdown
1054
- .querySelector('.ccl-expandable__button')
1055
- .setAttribute('aria-expanded', 'true');
1056
- let mapMenu = document
1057
- .querySelector(elem + ' input')
1058
- .closest('.map-menu-dataset-dropdown');
1059
- if (mapMenu) {
1060
- // mapMenu is null for Corine and was blocking.
1061
- scrollPosition = mapMenu.offsetTop;
1054
+ let dropdown = node.closest('.map-menu-dropdown');
1055
+ if (dropdown) {
1056
+ let button = dropdown.querySelector('.ccl-expandable__button');
1057
+ if (button) {
1058
+ button.setAttribute('aria-expanded', 'true');
1062
1059
  }
1063
1060
  }
1064
- setTimeout(() => {
1065
- document.querySelector(
1066
- 'div#paneles.panels',
1067
- ).scrollTop = scrollPosition;
1068
- }, 1000);
1061
+ let productDropdown = node.closest('.map-menu-product-dropdown');
1062
+ if (productDropdown) {
1063
+ let scrollPosition = productDropdown.offsetTop;
1064
+ if (dataset) {
1065
+ let datasetDropdown = node.closest('.map-menu-product-dropdown');
1066
+ if (datasetDropdown) {
1067
+ let button = datasetDropdown.querySelector(
1068
+ '.ccl-expandable__button',
1069
+ );
1070
+ if (button) {
1071
+ button.setAttribute('aria-expanded', 'true');
1072
+ }
1073
+ }
1074
+ let mapMenu = node.closest('.map-menu-dataset-dropdown');
1075
+ if (mapMenu) {
1076
+ scrollPosition = mapMenu.offsetTop;
1077
+ }
1078
+ }
1079
+ setTimeout(() => {
1080
+ let panels = document.querySelector('div#paneles.panels');
1081
+ if (panels) {
1082
+ panels.scrollTop = scrollPosition;
1083
+ }
1084
+ }, 1000);
1085
+ }
1069
1086
  }
1070
1087
  }
1071
1088
  }
@@ -1085,11 +1102,19 @@ class MenuWidget extends React.Component {
1085
1102
  },
1086
1103
  ];
1087
1104
  buttons.forEach((element, index) => {
1088
- element.setAttribute('aria-label', element.getAttribute('title'));
1089
- element.removeAttribute('title');
1090
- Object.keys(attributes[index]).forEach((attr) => {
1091
- element.setAttribute(attr, attributes[index][attr]);
1092
- });
1105
+ if (element) {
1106
+ const title = element.getAttribute('title');
1107
+ if (title) {
1108
+ element.setAttribute('aria-label', title);
1109
+ element.removeAttribute('title');
1110
+ }
1111
+ const attrs = attributes[index];
1112
+ if (attrs) {
1113
+ Object.keys(attrs).forEach((attr) => {
1114
+ element.setAttribute(attr, attrs[attr]);
1115
+ });
1116
+ }
1117
+ }
1093
1118
  });
1094
1119
  }
1095
1120
 
@@ -1101,9 +1126,13 @@ class MenuWidget extends React.Component {
1101
1126
  if (!WMSLayer && !WMTSLayer && !FeatureLayer) return;
1102
1127
  var components = [];
1103
1128
  var index = 0;
1104
- for (var i in this.compCfg) {
1105
- components.push(this.metodProcessComponent(this.compCfg[i], index));
1106
- index++;
1129
+ if (this.compCfg && Array.isArray(this.compCfg)) {
1130
+ for (var i in this.compCfg) {
1131
+ if (this.compCfg[i]) {
1132
+ components.push(this.metodProcessComponent(this.compCfg[i], index));
1133
+ index++;
1134
+ }
1135
+ }
1107
1136
  }
1108
1137
  return components;
1109
1138
  }
@@ -1124,23 +1153,27 @@ class MenuWidget extends React.Component {
1124
1153
  ? component.ComponentDescription.substr(0, 300) + '...'
1125
1154
  : component.ComponentDescription;
1126
1155
 
1127
- for (var i in component.Products) {
1128
- // CLMS-1544
1129
- // dont show the product if all of its datasets has the auxiliary service as its ViewService URL
1130
- //CLMS-1756
1131
- //don´t show the product if MarkAsDownloadableNoServiceToVisualize is true
1132
- // const isAuxiliary = (dataset) =>
1133
- // dataset.MarkAsDownloadableNoServiceToVisualize;
1134
- // if (!component.Products[i].Datasets.every(isAuxiliary)) {
1135
- products.push(
1136
- this.metodProcessProduct(
1137
- component.Products[i],
1138
- index,
1139
- inheritedIndexComponent,
1140
- ),
1141
- );
1142
- index++;
1143
- //}
1156
+ if (component.Products && Array.isArray(component.Products)) {
1157
+ for (var i in component.Products) {
1158
+ if (component.Products[i] && component.Products[i].Datasets) {
1159
+ // CLMS-1544
1160
+ // dont show the product if all of its datasets has the auxiliary service as its ViewService URL
1161
+ //CLMS-1756
1162
+ //don´t show the product if MarkAsDownloadableNoServiceToVisualize is true
1163
+ // const isAuxiliary = (dataset) =>
1164
+ // dataset.MarkAsDownloadableNoServiceToVisualize;
1165
+ // if (!component.Products[i].Datasets.every(isAuxiliary)) {
1166
+ products.push(
1167
+ this.metodProcessProduct(
1168
+ component.Products[i],
1169
+ index,
1170
+ inheritedIndexComponent,
1171
+ ),
1172
+ );
1173
+ index++;
1174
+ //}
1175
+ }
1176
+ }
1144
1177
  }
1145
1178
  let style = this.props.download ? { display: 'none' } : {};
1146
1179
 
@@ -1199,25 +1232,31 @@ class MenuWidget extends React.Component {
1199
1232
  ? product.ProductDescription.substr(0, 300) + '...'
1200
1233
  : product.ProductDescription;
1201
1234
 
1202
- //Add only default datasets
1203
- for (var i in product.Datasets) {
1204
- if (product.Datasets[i].Default_active === true) {
1205
- var idDataset = 'map_dataset_' + inheritedIndexProduct + '_' + index;
1206
- dataset_def.push(idDataset);
1207
- }
1235
+ if (product.Datasets && Array.isArray(product.Datasets)) {
1236
+ for (var i in product.Datasets) {
1237
+ if (
1238
+ product.Datasets[i] &&
1239
+ product.Datasets[i].Default_active === true
1240
+ ) {
1241
+ var idDataset = 'map_dataset_' + inheritedIndexProduct + '_' + index;
1242
+ dataset_def.push(idDataset);
1243
+ }
1208
1244
 
1209
- // CLMS-1545
1210
- //if (!product.Datasets[i].MarkAsDownloadableNoServiceToVisualize) {
1211
- datasets.push(
1212
- this.metodProcessDataset(
1213
- product.Datasets[i],
1214
- index,
1215
- inheritedIndexProduct,
1216
- checkProduct,
1217
- ),
1218
- );
1219
- index++;
1220
- //}
1245
+ // CLMS-1545
1246
+ // if (!product.Datasets[i].MarkAsDownloadableNoServiceToVisualize) {
1247
+ if (product.Datasets[i]) {
1248
+ datasets.push(
1249
+ this.metodProcessDataset(
1250
+ product.Datasets[i],
1251
+ index,
1252
+ inheritedIndexProduct,
1253
+ checkProduct,
1254
+ ),
1255
+ );
1256
+ index++;
1257
+ }
1258
+ // }
1259
+ }
1221
1260
  }
1222
1261
 
1223
1262
  // Empty vector, add the first dataset
@@ -1308,8 +1347,10 @@ class MenuWidget extends React.Component {
1308
1347
  document.querySelectorAll('[parentid="' + productid + '"]'),
1309
1348
  );
1310
1349
  let productCheck = document.querySelector('#' + productid);
1350
+ if (!productCheck) return;
1311
1351
  let trueCheck = datasetChecks.filter((elem) => elem.checked).length;
1312
1352
  let product = productCheck.closest('.map-menu-product-dropdown');
1353
+ if (!product) return;
1313
1354
  let productId = product.getAttribute('productid');
1314
1355
  productCheck.checked = trueCheck > 0;
1315
1356
  // let productCheckLabel = productCheck.labels[0].innerText;
@@ -1339,7 +1380,8 @@ class MenuWidget extends React.Component {
1339
1380
  var index = 0;
1340
1381
  var inheritedIndexDataset = inheritedIndex + '_' + datIndex;
1341
1382
  var checkIndex = 'map_dataset_' + inheritedIndexDataset;
1342
- let checkedLayers = JSON.parse(sessionStorage.getItem('checkedLayers'));
1383
+ let checkedLayers =
1384
+ JSON.parse(sessionStorage.getItem('checkedLayers')) || [];
1343
1385
  var description =
1344
1386
  dataset.DatasetDescription && dataset.DatasetDescription.length >= 300
1345
1387
  ? dataset.DatasetDescription.substr(0, 300) + '...'
@@ -1374,11 +1416,7 @@ class MenuWidget extends React.Component {
1374
1416
  dataset: dataset,
1375
1417
  };
1376
1418
 
1377
- if (sessionStorage.getItem('TMSLayerObj')) {
1378
- sessionStorage.setItem('TMSLayerObj', JSON.stringify(TMSLayerObj));
1379
- } else {
1380
- sessionStorage.setItem('TMSLayerObj', JSON.stringify(TMSLayerObj));
1381
- }
1419
+ sessionStorage.setItem('TMSLayerObj', JSON.stringify(TMSLayerObj));
1382
1420
 
1383
1421
  // add each sublayer to this.layers
1384
1422
  this.processTMSLayer(layer, checkboxId, dataset);
@@ -1446,7 +1484,7 @@ class MenuWidget extends React.Component {
1446
1484
  }
1447
1485
  }
1448
1486
 
1449
- if (!layer_default.length) {
1487
+ if (!layer_default.length && dataset.Layer && dataset.Layer[0]) {
1450
1488
  layer_default.push(
1451
1489
  dataset.Layer[0].LayerId + '_' + inheritedIndexDataset + '_0',
1452
1490
  );
@@ -1635,13 +1673,19 @@ class MenuWidget extends React.Component {
1635
1673
 
1636
1674
  updateCheckDataset(id) {
1637
1675
  let datasetCheck = document.querySelector('#' + id);
1676
+ if (!datasetCheck) return;
1677
+
1638
1678
  let layerChecks = Array.from(
1639
1679
  document.querySelectorAll('[parentid="' + id + '"]'),
1640
1680
  );
1641
1681
 
1642
1682
  let trueChecks = layerChecks.filter((elem) => elem.checked).length;
1643
1683
  datasetCheck.checked = trueChecks > 0;
1644
- this.updateCheckProduct(datasetCheck.getAttribute('parentid'));
1684
+
1685
+ let parentId = datasetCheck.getAttribute('parentid');
1686
+ if (parentId) {
1687
+ this.updateCheckProduct(parentId);
1688
+ }
1645
1689
  }
1646
1690
 
1647
1691
  /**
@@ -1801,10 +1845,12 @@ class MenuWidget extends React.Component {
1801
1845
  let selectedUrl;
1802
1846
  let zoom = this.view.get('zoom');
1803
1847
  if (layer.LayerUrl && Object.keys(layer.LayerUrl).length > 0) {
1804
- zoom < 10
1805
- ? (selectedUrl = layer.LayerUrl['longZoom'])
1806
- : (selectedUrl = layer.LayerUrl['shortZoom']);
1807
- } else selectedUrl = layer.LayerUrl;
1848
+ selectedUrl =
1849
+ zoom < 10 ? layer.LayerUrl['longZoom'] : layer.LayerUrl['shortZoom'];
1850
+ } else {
1851
+ selectedUrl = layer.LayerUrl;
1852
+ }
1853
+
1808
1854
  const CustomTileLayer = BaseTileLayer.createSubclass({
1809
1855
  properties: {
1810
1856
  urlTemplate: null,
@@ -1816,10 +1862,8 @@ class MenuWidget extends React.Component {
1816
1862
 
1817
1863
  // generate the tile url for a given level, row and column
1818
1864
  getTileUrl: function (level, row, col) {
1819
- // si es cero será el maximo. las filas serán el array invertido
1820
- // tengo que extrarer de alguna manera la cantidad de filas y columnas que se muestran.
1821
-
1822
- return /* this.urlTemplate */ selectedUrl
1865
+ if (!selectedUrl) return '';
1866
+ return selectedUrl
1823
1867
  .replace('{z}', level)
1824
1868
  .replace('{x}', col)
1825
1869
  .replace('{y}', row);
@@ -1828,10 +1872,7 @@ class MenuWidget extends React.Component {
1828
1872
  // This method fetches tiles for the specified level and size.
1829
1873
  // Override this method to process the data returned from the server.
1830
1874
  fetchTile: function (level, row, col, options) {
1831
- // call getTileUrl() method to construct the URL to tiles
1832
- // for a given level, row and col provided by the LayerView
1833
-
1834
- // Images pyramid formula
1875
+ if (!selectedUrl) return Promise.resolve(null);
1835
1876
  if (this.tms) {
1836
1877
  var rowmax = 1 << level; // LEVEL 1 * (2 ** 1) = 1 * (2) = 2 ; LEVEL 2 * (2 ** 2) = 1 * (4) = 4 ; LEVEL 3 * (2 ** 3) = 1 * (8) = 8 . . .
1837
1878
  row = zoom < 10 ? rowmax - row - 1 : row; // Invert Y axis
@@ -1897,7 +1938,8 @@ class MenuWidget extends React.Component {
1897
1938
  return;
1898
1939
  let elemContainer = document
1899
1940
  .getElementById(elem.id)
1900
- .closest('.ccl-form-group');
1941
+ ?.closest('.ccl-form-group');
1942
+ if (!elemContainer) return;
1901
1943
  let nextElemSibling = elemContainer.nextElementSibling;
1902
1944
  let previousElemSibling = elemContainer.previousElementSibling;
1903
1945
 
@@ -1907,6 +1949,7 @@ class MenuWidget extends React.Component {
1907
1949
  let productContainer = document.querySelector(
1908
1950
  '[productid="' + productContainerId + '"]',
1909
1951
  );
1952
+ if (!productContainer) return;
1910
1953
 
1911
1954
  let datasetArray = productContainer.querySelectorAll('[datasetid]');
1912
1955
 
@@ -1931,6 +1974,7 @@ class MenuWidget extends React.Component {
1931
1974
 
1932
1975
  for (let k = 0; k < dataSetContainer.length; k++) {
1933
1976
  let elemContainerIdElement = elemContainer.closest('[datasetid]');
1977
+ if (!elemContainerIdElement) continue;
1934
1978
  if (
1935
1979
  dataSetContainer[k].getAttribute('datasetid') !==
1936
1980
  elemContainerIdElement.getAttribute('datasetid')
@@ -1948,16 +1992,16 @@ class MenuWidget extends React.Component {
1948
1992
  for (let g = 1; g < dataSetContents.length; g++) {
1949
1993
  if (dataSetContents[g].checked) {
1950
1994
  currentDataSetLayer = dataSetContents[g];
1951
- currentDataSetLayerSpan = currentDataSetLayer.nextSibling.querySelector(
1995
+ currentDataSetLayerSpan = currentDataSetLayer.nextSibling?.querySelector(
1952
1996
  'span',
1953
1997
  );
1954
1998
  currentElemContainerSpan = elemContainer.querySelector('span');
1955
1999
 
1956
2000
  if (
1957
- (currentDataSetLayerSpan.innerText.includes('Modular') &&
1958
- currentElemContainerSpan.innerText.includes('Modular')) ||
1959
- (currentDataSetLayerSpan.innerText.includes('Dichotomous') &&
1960
- currentElemContainerSpan.innerText.includes('Dichotomous'))
2001
+ (currentDataSetLayerSpan?.innerText.includes('Modular') &&
2002
+ currentElemContainerSpan?.innerText.includes('Modular')) ||
2003
+ (currentDataSetLayerSpan?.innerText.includes('Dichotomous') &&
2004
+ currentElemContainerSpan?.innerText.includes('Dichotomous'))
1961
2005
  ) {
1962
2006
  continue;
1963
2007
  } else {
@@ -1997,10 +2041,10 @@ class MenuWidget extends React.Component {
1997
2041
  return;
1998
2042
  } else {
1999
2043
  if (
2000
- (currentDataSetLayerSpan.innerText.includes('Modular') &&
2001
- currentElemContainerSpan.innerText.includes('Modular')) ||
2002
- (currentDataSetLayerSpan.innerText.includes('Dichotomous') &&
2003
- currentElemContainerSpan.innerText.includes('Dichotomous'))
2044
+ (currentDataSetLayerSpan?.innerText.includes('Modular') &&
2045
+ currentElemContainerSpan?.innerText.includes('Modular')) ||
2046
+ (currentDataSetLayerSpan?.innerText.includes('Dichotomous') &&
2047
+ currentElemContainerSpan?.innerText.includes('Dichotomous'))
2004
2048
  ) {
2005
2049
  this.setState({});
2006
2050
  return;
@@ -2009,7 +2053,9 @@ class MenuWidget extends React.Component {
2009
2053
  currentDataSetLayer.click();
2010
2054
  }
2011
2055
  if (currentDataSetLayer && !currentDataSetLayer.checked) {
2012
- dataSetLayerInput.click();
2056
+ if (dataSetLayerInput) {
2057
+ dataSetLayerInput.click();
2058
+ }
2013
2059
  }
2014
2060
  }
2015
2061
  }
@@ -2029,7 +2075,6 @@ class MenuWidget extends React.Component {
2029
2075
  ? layerTitle
2030
2076
  : layerTitle;
2031
2077
  let scale;
2032
- //let layerTitleToCompare = layerTitle;
2033
2078
  if (this.layers[key].resourceInfo) {
2034
2079
  this.layers[key].resourceInfo.layers.forEach((sublayer) => {
2035
2080
  if (