@eeacms/volto-arcgis-block 0.1.333 → 0.1.335

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.335](https://github.com/eea/volto-arcgis-block/compare/0.1.334...0.1.335) - 7 February 2025
8
+
9
+ #### :hammer_and_wrench: Others
10
+
11
+ - 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)]
12
+ - commiting latest change [Unai Bolivar - [`6c88ed5`](https://github.com/eea/volto-arcgis-block/commit/6c88ed5897d72ecc2373fca07fcacf08f3934480)]
13
+ - CLMS-282421 (bug): solving for null continue on metodProcessLayer line 1700 [Unai Bolivar - [`fd934f4`](https://github.com/eea/volto-arcgis-block/commit/fd934f4528db043a4c25cc78d1a8c19d510d27c7)]
14
+ ### [0.1.334](https://github.com/eea/volto-arcgis-block/compare/0.1.333...0.1.334) - 31 January 2025
15
+
7
16
  ### [0.1.333](https://github.com/eea/volto-arcgis-block/compare/0.1.332...0.1.333) - 30 January 2025
8
17
 
9
18
  ### [0.1.332](https://github.com/eea/volto-arcgis-block/compare/0.1.331...0.1.332) - 21 January 2025
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eeacms/volto-arcgis-block",
3
- "version": "0.1.333",
3
+ "version": "0.1.335",
4
4
  "description": "volto-arcgis-block: Volto add-on",
5
5
  "main": "src/index.js",
6
6
  "author": "European Environment Agency: CodeSyntax",
@@ -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,11 +986,14 @@ 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() {
981
- let tokenResult = null;
995
+ let tokenResult;
996
+ tokenResult = null;
982
997
  if (this.getCookie('auth_token')) {
983
998
  tokenResult = true;
984
999
  } else {
@@ -996,7 +1011,7 @@ class MenuWidget extends React.Component {
996
1011
  !!(elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length);
997
1012
  let element = document.querySelector('.opacity-panel');
998
1013
  const outsideClickListener = (event) => {
999
- if (!element.contains(event.target) && isVisible(element)) {
1014
+ if (element && !element.contains(event.target) && isVisible(element)) {
1000
1015
  // or use: event.target.closest(selector) === null
1001
1016
  this.closeOpacity();
1002
1017
  removeClickListener();
@@ -1036,35 +1051,38 @@ class MenuWidget extends React.Component {
1036
1051
  let node = document.querySelector(elem + ' input');
1037
1052
  if (node) {
1038
1053
  node.dispatchEvent(event);
1039
- let dropdown = document
1040
- .querySelector(elem + ' input')
1041
- .closest('.map-menu-dropdown');
1042
- dropdown
1043
- .querySelector('.ccl-expandable__button')
1044
- .setAttribute('aria-expanded', 'true');
1045
- let scrollPosition = document
1046
- .querySelector(elem + ' input')
1047
- .closest('.map-menu-product-dropdown').offsetTop;
1048
- if (dataset) {
1049
- dropdown = document
1050
- .querySelector(elem + ' input')
1051
- .closest('.map-menu-product-dropdown');
1052
- dropdown
1053
- .querySelector('.ccl-expandable__button')
1054
- .setAttribute('aria-expanded', 'true');
1055
- let mapMenu = document
1056
- .querySelector(elem + ' input')
1057
- .closest('.map-menu-dataset-dropdown');
1058
- if (mapMenu) {
1059
- // mapMenu is null for Corine and was blocking.
1060
- 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');
1061
1059
  }
1062
1060
  }
1063
- setTimeout(() => {
1064
- document.querySelector(
1065
- 'div#paneles.panels',
1066
- ).scrollTop = scrollPosition;
1067
- }, 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
+ }
1068
1086
  }
1069
1087
  }
1070
1088
  }
@@ -1084,11 +1102,19 @@ class MenuWidget extends React.Component {
1084
1102
  },
1085
1103
  ];
1086
1104
  buttons.forEach((element, index) => {
1087
- element.setAttribute('aria-label', element.getAttribute('title'));
1088
- element.removeAttribute('title');
1089
- Object.keys(attributes[index]).forEach((attr) => {
1090
- element.setAttribute(attr, attributes[index][attr]);
1091
- });
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
+ }
1092
1118
  });
1093
1119
  }
1094
1120
 
@@ -1100,9 +1126,13 @@ class MenuWidget extends React.Component {
1100
1126
  if (!WMSLayer && !WMTSLayer && !FeatureLayer) return;
1101
1127
  var components = [];
1102
1128
  var index = 0;
1103
- for (var i in this.compCfg) {
1104
- components.push(this.metodProcessComponent(this.compCfg[i], index));
1105
- 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
+ }
1106
1136
  }
1107
1137
  return components;
1108
1138
  }
@@ -1123,23 +1153,27 @@ class MenuWidget extends React.Component {
1123
1153
  ? component.ComponentDescription.substr(0, 300) + '...'
1124
1154
  : component.ComponentDescription;
1125
1155
 
1126
- for (var i in component.Products) {
1127
- // CLMS-1544
1128
- // dont show the product if all of its datasets has the auxiliary service as its ViewService URL
1129
- //CLMS-1756
1130
- //don´t show the product if MarkAsDownloadableNoServiceToVisualize is true
1131
- // const isAuxiliary = (dataset) =>
1132
- // dataset.MarkAsDownloadableNoServiceToVisualize;
1133
- // if (!component.Products[i].Datasets.every(isAuxiliary)) {
1134
- products.push(
1135
- this.metodProcessProduct(
1136
- component.Products[i],
1137
- index,
1138
- inheritedIndexComponent,
1139
- ),
1140
- );
1141
- index++;
1142
- //}
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
+ }
1143
1177
  }
1144
1178
  let style = this.props.download ? { display: 'none' } : {};
1145
1179
 
@@ -1198,25 +1232,31 @@ class MenuWidget extends React.Component {
1198
1232
  ? product.ProductDescription.substr(0, 300) + '...'
1199
1233
  : product.ProductDescription;
1200
1234
 
1201
- //Add only default datasets
1202
- for (var i in product.Datasets) {
1203
- if (product.Datasets[i].Default_active === true) {
1204
- var idDataset = 'map_dataset_' + inheritedIndexProduct + '_' + index;
1205
- dataset_def.push(idDataset);
1206
- }
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
+ }
1207
1244
 
1208
- // CLMS-1545
1209
- //if (!product.Datasets[i].MarkAsDownloadableNoServiceToVisualize) {
1210
- datasets.push(
1211
- this.metodProcessDataset(
1212
- product.Datasets[i],
1213
- index,
1214
- inheritedIndexProduct,
1215
- checkProduct,
1216
- ),
1217
- );
1218
- index++;
1219
- //}
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
+ }
1220
1260
  }
1221
1261
 
1222
1262
  // Empty vector, add the first dataset
@@ -1307,8 +1347,10 @@ class MenuWidget extends React.Component {
1307
1347
  document.querySelectorAll('[parentid="' + productid + '"]'),
1308
1348
  );
1309
1349
  let productCheck = document.querySelector('#' + productid);
1350
+ if (!productCheck) return;
1310
1351
  let trueCheck = datasetChecks.filter((elem) => elem.checked).length;
1311
1352
  let product = productCheck.closest('.map-menu-product-dropdown');
1353
+ if (!product) return;
1312
1354
  let productId = product.getAttribute('productid');
1313
1355
  productCheck.checked = trueCheck > 0;
1314
1356
  // let productCheckLabel = productCheck.labels[0].innerText;
@@ -1338,7 +1380,8 @@ class MenuWidget extends React.Component {
1338
1380
  var index = 0;
1339
1381
  var inheritedIndexDataset = inheritedIndex + '_' + datIndex;
1340
1382
  var checkIndex = 'map_dataset_' + inheritedIndexDataset;
1341
- let checkedLayers = JSON.parse(sessionStorage.getItem('checkedLayers'));
1383
+ let checkedLayers =
1384
+ JSON.parse(sessionStorage.getItem('checkedLayers')) || [];
1342
1385
  var description =
1343
1386
  dataset.DatasetDescription && dataset.DatasetDescription.length >= 300
1344
1387
  ? dataset.DatasetDescription.substr(0, 300) + '...'
@@ -1373,11 +1416,7 @@ class MenuWidget extends React.Component {
1373
1416
  dataset: dataset,
1374
1417
  };
1375
1418
 
1376
- if (sessionStorage.getItem('TMSLayerObj')) {
1377
- sessionStorage.setItem('TMSLayerObj', JSON.stringify(TMSLayerObj));
1378
- } else {
1379
- sessionStorage.setItem('TMSLayerObj', JSON.stringify(TMSLayerObj));
1380
- }
1419
+ sessionStorage.setItem('TMSLayerObj', JSON.stringify(TMSLayerObj));
1381
1420
 
1382
1421
  // add each sublayer to this.layers
1383
1422
  this.processTMSLayer(layer, checkboxId, dataset);
@@ -1445,7 +1484,7 @@ class MenuWidget extends React.Component {
1445
1484
  }
1446
1485
  }
1447
1486
 
1448
- if (!layer_default.length) {
1487
+ if (!layer_default.length && dataset.Layer && dataset.Layer[0]) {
1449
1488
  layer_default.push(
1450
1489
  dataset.Layer[0].LayerId + '_' + inheritedIndexDataset + '_0',
1451
1490
  );
@@ -1634,13 +1673,19 @@ class MenuWidget extends React.Component {
1634
1673
 
1635
1674
  updateCheckDataset(id) {
1636
1675
  let datasetCheck = document.querySelector('#' + id);
1676
+ if (!datasetCheck) return;
1677
+
1637
1678
  let layerChecks = Array.from(
1638
1679
  document.querySelectorAll('[parentid="' + id + '"]'),
1639
1680
  );
1640
1681
 
1641
1682
  let trueChecks = layerChecks.filter((elem) => elem.checked).length;
1642
1683
  datasetCheck.checked = trueChecks > 0;
1643
- this.updateCheckProduct(datasetCheck.getAttribute('parentid'));
1684
+
1685
+ let parentId = datasetCheck.getAttribute('parentid');
1686
+ if (parentId) {
1687
+ this.updateCheckProduct(parentId);
1688
+ }
1644
1689
  }
1645
1690
 
1646
1691
  /**
@@ -1800,10 +1845,12 @@ class MenuWidget extends React.Component {
1800
1845
  let selectedUrl;
1801
1846
  let zoom = this.view.get('zoom');
1802
1847
  if (layer.LayerUrl && Object.keys(layer.LayerUrl).length > 0) {
1803
- zoom < 10
1804
- ? (selectedUrl = layer.LayerUrl['longZoom'])
1805
- : (selectedUrl = layer.LayerUrl['shortZoom']);
1806
- } else selectedUrl = layer.LayerUrl;
1848
+ selectedUrl =
1849
+ zoom < 10 ? layer.LayerUrl['longZoom'] : layer.LayerUrl['shortZoom'];
1850
+ } else {
1851
+ selectedUrl = layer.LayerUrl;
1852
+ }
1853
+
1807
1854
  const CustomTileLayer = BaseTileLayer.createSubclass({
1808
1855
  properties: {
1809
1856
  urlTemplate: null,
@@ -1815,10 +1862,8 @@ class MenuWidget extends React.Component {
1815
1862
 
1816
1863
  // generate the tile url for a given level, row and column
1817
1864
  getTileUrl: function (level, row, col) {
1818
- // si es cero será el maximo. las filas serán el array invertido
1819
- // tengo que extrarer de alguna manera la cantidad de filas y columnas que se muestran.
1820
-
1821
- return /* this.urlTemplate */ selectedUrl
1865
+ if (!selectedUrl) return '';
1866
+ return selectedUrl
1822
1867
  .replace('{z}', level)
1823
1868
  .replace('{x}', col)
1824
1869
  .replace('{y}', row);
@@ -1827,10 +1872,7 @@ class MenuWidget extends React.Component {
1827
1872
  // This method fetches tiles for the specified level and size.
1828
1873
  // Override this method to process the data returned from the server.
1829
1874
  fetchTile: function (level, row, col, options) {
1830
- // call getTileUrl() method to construct the URL to tiles
1831
- // for a given level, row and col provided by the LayerView
1832
-
1833
- // Images pyramid formula
1875
+ if (!selectedUrl) return Promise.resolve(null);
1834
1876
  if (this.tms) {
1835
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 . . .
1836
1878
  row = zoom < 10 ? rowmax - row - 1 : row; // Invert Y axis
@@ -1896,7 +1938,8 @@ class MenuWidget extends React.Component {
1896
1938
  return;
1897
1939
  let elemContainer = document
1898
1940
  .getElementById(elem.id)
1899
- .closest('.ccl-form-group');
1941
+ ?.closest('.ccl-form-group');
1942
+ if (!elemContainer) return;
1900
1943
  let nextElemSibling = elemContainer.nextElementSibling;
1901
1944
  let previousElemSibling = elemContainer.previousElementSibling;
1902
1945
 
@@ -1906,6 +1949,7 @@ class MenuWidget extends React.Component {
1906
1949
  let productContainer = document.querySelector(
1907
1950
  '[productid="' + productContainerId + '"]',
1908
1951
  );
1952
+ if (!productContainer) return;
1909
1953
 
1910
1954
  let datasetArray = productContainer.querySelectorAll('[datasetid]');
1911
1955
 
@@ -1930,6 +1974,7 @@ class MenuWidget extends React.Component {
1930
1974
 
1931
1975
  for (let k = 0; k < dataSetContainer.length; k++) {
1932
1976
  let elemContainerIdElement = elemContainer.closest('[datasetid]');
1977
+ if (!elemContainerIdElement) continue;
1933
1978
  if (
1934
1979
  dataSetContainer[k].getAttribute('datasetid') !==
1935
1980
  elemContainerIdElement.getAttribute('datasetid')
@@ -1947,16 +1992,16 @@ class MenuWidget extends React.Component {
1947
1992
  for (let g = 1; g < dataSetContents.length; g++) {
1948
1993
  if (dataSetContents[g].checked) {
1949
1994
  currentDataSetLayer = dataSetContents[g];
1950
- currentDataSetLayerSpan = currentDataSetLayer.nextSibling.querySelector(
1995
+ currentDataSetLayerSpan = currentDataSetLayer.nextSibling?.querySelector(
1951
1996
  'span',
1952
1997
  );
1953
1998
  currentElemContainerSpan = elemContainer.querySelector('span');
1954
1999
 
1955
2000
  if (
1956
- (currentDataSetLayerSpan.innerText.includes('Modular') &&
1957
- currentElemContainerSpan.innerText.includes('Modular')) ||
1958
- (currentDataSetLayerSpan.innerText.includes('Dichotomous') &&
1959
- currentElemContainerSpan.innerText.includes('Dichotomous'))
2001
+ (currentDataSetLayerSpan?.innerText.includes('Modular') &&
2002
+ currentElemContainerSpan?.innerText.includes('Modular')) ||
2003
+ (currentDataSetLayerSpan?.innerText.includes('Dichotomous') &&
2004
+ currentElemContainerSpan?.innerText.includes('Dichotomous'))
1960
2005
  ) {
1961
2006
  continue;
1962
2007
  } else {
@@ -1996,10 +2041,10 @@ class MenuWidget extends React.Component {
1996
2041
  return;
1997
2042
  } else {
1998
2043
  if (
1999
- (currentDataSetLayerSpan.innerText.includes('Modular') &&
2000
- currentElemContainerSpan.innerText.includes('Modular')) ||
2001
- (currentDataSetLayerSpan.innerText.includes('Dichotomous') &&
2002
- currentElemContainerSpan.innerText.includes('Dichotomous'))
2044
+ (currentDataSetLayerSpan?.innerText.includes('Modular') &&
2045
+ currentElemContainerSpan?.innerText.includes('Modular')) ||
2046
+ (currentDataSetLayerSpan?.innerText.includes('Dichotomous') &&
2047
+ currentElemContainerSpan?.innerText.includes('Dichotomous'))
2003
2048
  ) {
2004
2049
  this.setState({});
2005
2050
  return;
@@ -2008,7 +2053,9 @@ class MenuWidget extends React.Component {
2008
2053
  currentDataSetLayer.click();
2009
2054
  }
2010
2055
  if (currentDataSetLayer && !currentDataSetLayer.checked) {
2011
- dataSetLayerInput.click();
2056
+ if (dataSetLayerInput) {
2057
+ dataSetLayerInput.click();
2058
+ }
2012
2059
  }
2013
2060
  }
2014
2061
  }
@@ -2028,7 +2075,6 @@ class MenuWidget extends React.Component {
2028
2075
  ? layerTitle
2029
2076
  : layerTitle;
2030
2077
  let scale;
2031
- //let layerTitleToCompare = layerTitle;
2032
2078
  if (this.layers[key].resourceInfo) {
2033
2079
  this.layers[key].resourceInfo.layers.forEach((sublayer) => {
2034
2080
  if (