@eeacms/volto-arcgis-block 0.1.23 → 0.1.27

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,8 +4,60 @@ 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.27](https://github.com/eea/volto-arcgis-block/compare/0.1.26...0.1.27)
8
+
9
+ - Bugs n improvements [`#91`](https://github.com/eea/volto-arcgis-block/pull/91)
10
+ - ESLint fix [`27ee762`](https://github.com/eea/volto-arcgis-block/commit/27ee762c776b8635cb414edf5f20e3e40187801b)
11
+ - Granularity [`9e8d87a`](https://github.com/eea/volto-arcgis-block/commit/9e8d87a9b5baebec5d5300195bd3ba2f9d5e1e2c)
12
+
13
+ #### [0.1.26](https://github.com/eea/volto-arcgis-block/compare/0.1.25...0.1.26)
14
+
15
+ > 17 January 2022
16
+
17
+ - Develop [`#89`](https://github.com/eea/volto-arcgis-block/pull/89)
18
+ - Bug fixing [`#88`](https://github.com/eea/volto-arcgis-block/pull/88)
19
+ - Bugs n improvements [`#87`](https://github.com/eea/volto-arcgis-block/pull/87)
20
+ - Develop [`#86`](https://github.com/eea/volto-arcgis-block/pull/86)
21
+ - Time slider drag/drop [`#85`](https://github.com/eea/volto-arcgis-block/pull/85)
22
+ - Use cases [`#84`](https://github.com/eea/volto-arcgis-block/pull/84)
23
+ - Develop [`#81`](https://github.com/eea/volto-arcgis-block/pull/81)
24
+ - Downloadable dataset [`c48eea9`](https://github.com/eea/volto-arcgis-block/commit/c48eea93b0f71134f9aa8fee1f5d6b4cf7e1368b)
25
+ - add flattenToAppURL to send the correct url to the MapViewerConfig action [`ca5f684`](https://github.com/eea/volto-arcgis-block/commit/ca5f684ae683e0df249d3fab3534f579583f03a8)
26
+ - ESLint fix [`7f43112`](https://github.com/eea/volto-arcgis-block/commit/7f4311224483fb599e7cecfe65096166ed5f2026)
27
+ - Use case highlight [`2279a5a`](https://github.com/eea/volto-arcgis-block/commit/2279a5ad669172545588e9030e3cf49ca4e30dfa)
28
+
29
+ #### [0.1.25](https://github.com/eea/volto-arcgis-block/compare/0.1.24...0.1.25)
30
+
31
+ > 5 January 2022
32
+
33
+ - Develop [`#83`](https://github.com/eea/volto-arcgis-block/pull/83)
34
+ - Bugs n improvements [`#82`](https://github.com/eea/volto-arcgis-block/pull/82)
35
+ - ESLint fix [`c129348`](https://github.com/eea/volto-arcgis-block/commit/c129348ee3886e0419029dd2bfe835c28878444c)
36
+ - Filter by product and dataset [`c89711a`](https://github.com/eea/volto-arcgis-block/commit/c89711acf4f46c8426c7e34add2baf4debe67697)
37
+ - ESLint fix [`406842a`](https://github.com/eea/volto-arcgis-block/commit/406842a54f1964bf2b4b0e709719028a5a47a903)
38
+ - Timeslider bug fixing [`c7a8345`](https://github.com/eea/volto-arcgis-block/commit/c7a834538a54a8c48e2e34259d3d733a1194007a)
39
+
40
+ #### [0.1.24](https://github.com/eea/volto-arcgis-block/compare/0.1.23...0.1.24)
41
+
42
+ > 21 December 2021
43
+
44
+ - Develop [`#77`](https://github.com/eea/volto-arcgis-block/pull/77)
45
+ - Bugs n improvements [`#80`](https://github.com/eea/volto-arcgis-block/pull/80)
46
+ - The area array to a json object and added a unique_id to the cart [`#79`](https://github.com/eea/volto-arcgis-block/pull/79)
47
+ - Remove Global from legend [`#76`](https://github.com/eea/volto-arcgis-block/pull/76)
48
+ - ESLint fix [`974d62b`](https://github.com/eea/volto-arcgis-block/commit/974d62bd5b66025e12fa85dffcd0d1a5ae04cba4)
49
+ - ESLint fix [`5c4b0d7`](https://github.com/eea/volto-arcgis-block/commit/5c4b0d76de50edd85809c35449f2fb364a9e9312)
50
+ - ESLint fix [`d57d144`](https://github.com/eea/volto-arcgis-block/commit/d57d144fd0e3dbbbbc95195f289d50e6c4b03375)
51
+ - ESLint fix [`9eb0a0c`](https://github.com/eea/volto-arcgis-block/commit/9eb0a0c17d018ac1b25bde422ac149b46b146ff4)
52
+ - ESLint fix [`5fd3772`](https://github.com/eea/volto-arcgis-block/commit/5fd3772f197a3a380067962a5638dbf901a4624e)
53
+ - Pixel info [`1ccef39`](https://github.com/eea/volto-arcgis-block/commit/1ccef39a9adcc3ee94655c77a5a166b613600a08)
54
+ - NUTS bug fix [`37fe7f3`](https://github.com/eea/volto-arcgis-block/commit/37fe7f3fad2c005e3b7c234b3b0564d5df92fa8c)
55
+
7
56
  #### [0.1.23](https://github.com/eea/volto-arcgis-block/compare/0.1.22...0.1.23)
8
57
 
58
+ > 17 December 2021
59
+
60
+ - Develop [`#75`](https://github.com/eea/volto-arcgis-block/pull/75)
9
61
  - Use cases region highlight [`#71`](https://github.com/eea/volto-arcgis-block/pull/71)
10
62
  - Bugs n improvements [`#74`](https://github.com/eea/volto-arcgis-block/pull/74)
11
63
  - Add NUTS 2 in the Map viewer [`#72`](https://github.com/eea/volto-arcgis-block/pull/72)
package/Jenkinsfile CHANGED
@@ -4,7 +4,7 @@ pipeline {
4
4
  environment {
5
5
  GIT_NAME = "volto-arcgis-block"
6
6
  NAMESPACE = "@eeacms"
7
- SONARQUBE_TAGS = "volto.eea.europa.eu,clms.land.copernicus.eu"
7
+ SONARQUBE_TAGS = "volto.eea.europa.eu,clms.land.copernicus.eu,water.europa.eu-freshwater"
8
8
  DEPENDENCIES = ""
9
9
  }
10
10
 
@@ -124,7 +124,7 @@ pipeline {
124
124
  node(label: 'docker') {
125
125
  script {
126
126
  try {
127
- sh '''docker pull plone; docker run -d --name="$BUILD_TAG-plone" -e SITE="Plone" -e PROFILES="profile-plone.restapi:blocks" plone fg'''
127
+ sh '''docker pull plone; docker run -d --rm --name="$BUILD_TAG-plone" -e SITE="Plone" -e PROFILES="profile-plone.restapi:blocks" plone fg'''
128
128
  sh '''docker pull plone/volto-addon-ci; docker run -i --name="$BUILD_TAG-cypress" --link $BUILD_TAG-plone:plone -e NAMESPACE="$NAMESPACE" -e GIT_NAME=$GIT_NAME -e GIT_BRANCH="$BRANCH_NAME" -e GIT_CHANGE_ID="$CHANGE_ID" -e DEPENDENCIES="$DEPENDENCIES" -e NODE_ENV=test plone/volto-addon-ci cypress'''
129
129
  } finally {
130
130
  try {
@@ -142,7 +142,8 @@ pipeline {
142
142
  reportName: 'CypressCoverage',
143
143
  reportTitles: 'Integration Tests Code Coverage'])
144
144
  }
145
- archiveArtifacts artifacts: 'cypress-reports/videos/*.mp4', fingerprint: true
145
+ sh '''touch empty_file; for ok_test in $(grep -E 'file=.*failures="0"' $(grep 'testsuites .*failures="0"' $(find cypress-results -name *.xml) empty_file | awk -F: '{print $1}') empty_file | sed 's/.* file="\\(.*\\)" time.*/\\1/' | sed 's#^cypress/integration/##g' | sed 's#^../../../node_modules/@eeacms/##g'); do rm -f cypress-reports/videos/$ok_test.mp4; rm -f cypress-reports/$ok_test.mp4; done'''
146
+ archiveArtifacts artifacts: 'cypress-reports/**/*.mp4', fingerprint: true, allowEmptyArchive: true
146
147
  stash name: "cypress-coverage", includes: "cypress-coverage/**", allowEmpty: true
147
148
  }
148
149
  finally {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eeacms/volto-arcgis-block",
3
- "version": "0.1.23",
3
+ "version": "0.1.27",
4
4
  "description": "volto-arcgis-block: Volto add-on",
5
5
  "main": "src/index.js",
6
6
  "author": "European Environment Agency: CodeSyntax",
@@ -40,7 +40,9 @@
40
40
  "@fortawesome/fontawesome-svg-core": "1.2.35",
41
41
  "@fortawesome/free-solid-svg-icons": "5.15.3",
42
42
  "@fortawesome/react-fontawesome": "0.1.14",
43
- "@eeacms/volto-clms-utils": "0.1.1"
43
+ "@eeacms/volto-clms-utils": "0.1.1",
44
+ "highcharts": "^9.3.2",
45
+ "highcharts-react-official": "^3.1.0"
44
46
  },
45
47
  "devDependencies": {
46
48
  "@cypress/code-coverage": "^3.9.5",
@@ -1,7 +1,4 @@
1
1
  import React, { createRef } from 'react';
2
- //import "@arcgis/core/assets/esri/css/main.css";
3
- //import "./css/ArcgisMap.css";
4
- //import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
5
2
  import { loadModules } from 'esri-loader';
6
3
 
7
4
  var Graphic,
@@ -174,7 +171,10 @@ class AreaWidget extends React.Component {
174
171
  }),
175
172
  symbol: fillSymbol,
176
173
  });
177
- this.props.updateArea({ origin: e.origin, end: { x: e.x, y: e.y } });
174
+ this.props.updateArea({
175
+ origin: { x: origin.longitude, y: origin.latitude },
176
+ end: { x: p.longitude, y: p.latitude },
177
+ });
178
178
  this.props.view.graphics.add(extentGraphic);
179
179
  }
180
180
  });
@@ -202,7 +202,14 @@ class AreaWidget extends React.Component {
202
202
  });
203
203
  this.props.map.add(this.nutsGroupLayer);
204
204
  this.props.view.on('click', (event) => {
205
- if (this.props.mapViewer.activeWidget === this) {
205
+ if (
206
+ (this.props.mapViewer.activeWidget === this || this.props.download) &&
207
+ (this.props.mapViewer.activeWidget
208
+ ? !this.props.mapViewer.activeWidget.container.current.classList.contains(
209
+ 'info-container',
210
+ )
211
+ : true)
212
+ ) {
206
213
  this.props.view.hitTest(event).then((response) => {
207
214
  if (response.results.length > 0) {
208
215
  let graphic = response.results.filter((result) => {
@@ -15,7 +15,7 @@ class BasemapWidget extends React.Component {
15
15
  //not be showing the basemap panel
16
16
  this.state = { showMapMenu: false };
17
17
  this.menuClass =
18
- 'esri-icon-basemap esri-widget--button esri-widget esri-interactive esri-icon-basemap';
18
+ 'esri-icon-basemap esri-widget--button esri-widget esri-interactive';
19
19
  this.loadFirst = true;
20
20
  }
21
21
 
@@ -0,0 +1,469 @@
1
+ import React, { createRef } from 'react';
2
+ import { loadModules } from 'esri-loader';
3
+ import Highcharts from 'highcharts';
4
+ import HighchartsReact from 'highcharts-react-official';
5
+ var GeometryEngine, Graphic;
6
+
7
+ class InfoWidget extends React.Component {
8
+ /**
9
+ * Creator of the InfoWidget widget class
10
+ * @param {*} props
11
+ */
12
+ constructor(props) {
13
+ super(props);
14
+ //We create a reference to a DOM element to be mounted
15
+ this.container = createRef();
16
+ //Initially, we set the state of the component to
17
+ //not be showing the basemap panel
18
+ this.state = { showMapMenu: false, timeLayers: {} };
19
+ this.map = this.props.map;
20
+ this.menuClass =
21
+ 'esri-icon-description esri-widget--button esri-widget esri-interactive';
22
+ }
23
+
24
+ loader() {
25
+ return loadModules(['esri/geometry/geometryEngine', 'esri/Graphic']).then(
26
+ ([_GeometryEngine, _Graphic]) => {
27
+ [GeometryEngine, Graphic] = [_GeometryEngine, _Graphic];
28
+ },
29
+ );
30
+ }
31
+
32
+ /**
33
+ * Method that will be invoked when the
34
+ * button is clicked. It controls the open
35
+ * and close actions of the component
36
+ */
37
+ openMenu() {
38
+ if (this.state.showMapMenu) {
39
+ this.props.mapViewer.setActiveWidget();
40
+ this.container.current.querySelector('.info-panel').style.display =
41
+ 'none';
42
+ this.container.current
43
+ .querySelector('.esri-widget--button')
44
+ .classList.replace('esri-icon-right-arrow', 'esri-icon-description');
45
+ // By invoking the setState, we notify the state we want to reach
46
+ // and ensure that the component is rendered again
47
+ this.setState({ showMapMenu: false, pixelInfo: false, timeLayers: {} });
48
+ this.props.view.popup.autoOpenEnabled = true;
49
+ this.removeMarker();
50
+ } else {
51
+ this.props.mapViewer.setActiveWidget(this);
52
+ this.container.current
53
+ .querySelector('.esri-widget--button')
54
+ .classList.replace('esri-icon-description', 'esri-icon-right-arrow');
55
+ this.container.current.querySelector('.info-panel').style.display =
56
+ 'block';
57
+ // By invoking the setState, we notify the state we want to reach
58
+ // and ensure that the component is rendered again
59
+ this.setState({ showMapMenu: true });
60
+ this.props.mapViewer.view.popup.close();
61
+ this.props.view.popup.autoOpenEnabled = false;
62
+ }
63
+ }
64
+ /**
65
+ * This method is executed after the rener method is executed
66
+ */
67
+ async componentDidMount() {
68
+ await this.loader();
69
+ this.props.view.ui.add(this.container.current, 'top-right');
70
+ this.props.view.on('click', (e) => {
71
+ if (this.props.mapViewer.activeWidget === this) {
72
+ let option = document.querySelector('#info_layer').value;
73
+ let selected = this.props.activeLayers[
74
+ this.props.activeLayers.findIndex((a) => a.name === option)
75
+ ];
76
+ let layer = selected.layer;
77
+ let title = selected.title;
78
+ let name = selected.name;
79
+ this.identify(layer, e).then((response) => {
80
+ let variables = response.variables.options;
81
+ let variable = response.variables.selected;
82
+ if (
83
+ this.state.variables
84
+ ? variables.includes(this.state.variables.selected)
85
+ : false
86
+ ) {
87
+ variable = this.state.variables.selected;
88
+ }
89
+ let data = {
90
+ x: response.timeFields.values
91
+ .map((a) => {
92
+ return a[response.timeFields.start];
93
+ })
94
+ .sort((a, b) => {
95
+ return new Date(a).getTime() - new Date(b).getTime();
96
+ }),
97
+ y: response.data.values.map((a) => {
98
+ return Math.round(a[variable] * 100) / 100;
99
+ }),
100
+ };
101
+ let chartData = this.createChart(title, variable, data);
102
+ this.addMarker(e);
103
+ this.setState({
104
+ pixelInfo: true,
105
+ data: response,
106
+ options: chartData,
107
+ variables: { options: variables, selected: variable },
108
+ timeLayers: { selected: name },
109
+ });
110
+ });
111
+ }
112
+ });
113
+ }
114
+
115
+ addMarker(evt) {
116
+ this.removeMarker();
117
+ let lat = evt.mapPoint.latitude;
118
+ let long = evt.mapPoint.longitude;
119
+ var point = {
120
+ type: 'point',
121
+ longitude: long,
122
+ latitude: lat,
123
+ };
124
+ var markerSymbol = {
125
+ type: 'simple-marker',
126
+ color: [255, 255, 255, 0.75],
127
+ outline: {
128
+ color: 'black',
129
+ width: '2px',
130
+ },
131
+ };
132
+ var pointGraphic = new Graphic({
133
+ geometry: point,
134
+ symbol: markerSymbol,
135
+ attributes: { long, lat, id: 'pixel-info' },
136
+ });
137
+ this.props.view.graphics.add(pointGraphic);
138
+ }
139
+
140
+ removeMarker() {
141
+ if (
142
+ this.props.view.graphics.items.find((a) => {
143
+ return a.attributes ? a.attributes.id === 'pixel-info' : false;
144
+ })
145
+ ) {
146
+ let marker = this.props.view.graphics.items.find((a) => {
147
+ return a.attributes && a.attributes.id === 'pixel-info';
148
+ });
149
+ this.props.view.graphics.remove(marker);
150
+ }
151
+ }
152
+
153
+ identify(layer, evt) {
154
+ let values = { timeFields: {}, data: {}, variables: {} };
155
+ //Complete time data
156
+ values.timeFields['start'] = layer.timeInfo.startField;
157
+ values.timeFields['end'] = layer.timeInfo.endField;
158
+ let timeQuery = layer.createQuery();
159
+ timeQuery.outFields = [layer.timeInfo.startField];
160
+ let fields = layer.fields
161
+ .filter((a) => {
162
+ return (
163
+ a.type !== 'date' &&
164
+ a.type !== 'geometry' &&
165
+ a.type !== 'string' &&
166
+ a.type !== 'oid'
167
+ );
168
+ })
169
+ .map((b) => {
170
+ return b.name;
171
+ });
172
+ let field = layer.displayField in fields ? layer.displayField : fields[0];
173
+ values.variables = { options: fields, selected: field };
174
+ if (layer.timeInfo.fullTimeExtent.endField) {
175
+ timeQuery.outFields.push(layer.timeInfo.endField);
176
+ }
177
+ timeQuery.returnDistinctValues = true;
178
+ timeQuery.returnGeometry = false;
179
+ let p1 = layer.queryFeatures(timeQuery).then((r) => {
180
+ let timevals = [];
181
+ r.features.forEach((e) => timevals.push(e.attributes));
182
+ values.timeFields['values'] = timevals;
183
+ });
184
+
185
+ //Query for data
186
+ let query = layer.createQuery();
187
+ query.geometry = this.props.view.toMap(evt); // the point location of the pointer
188
+ query.distance = 1000;
189
+ query.units = 'meters';
190
+ query.spatialRelationship = 'intersects'; // this is the default
191
+ query.returnGeometry = true;
192
+ query.outFields = [fields.toString()]; // Information to be returned
193
+ values.data['outFields'] = [fields.toString()];
194
+
195
+ let p2 = layer.queryFeatures(query).then((response) => {
196
+ //First of all, we get all the points with its distance to click point
197
+ let points = response.features.map((e) => {
198
+ return {
199
+ latitude: e.geometry.latitude,
200
+ longitude: e.geometry.longitude,
201
+ distance: GeometryEngine.distance(
202
+ this.props.view.toMap(evt),
203
+ e.geometry,
204
+ 'meters',
205
+ ),
206
+ };
207
+ });
208
+ let min_distance = Math.min.apply(
209
+ null,
210
+ points.map((e) => e.distance),
211
+ ); //minimum distance
212
+ let point = points.find((e) => e.distance <= min_distance); //minimum distance point
213
+ //get de info of the minimum distance point at all the times possible
214
+ let info = response.features.filter(
215
+ (e) =>
216
+ e.geometry.latitude === point.latitude &&
217
+ e.geometry.longitude === point.longitude,
218
+ );
219
+ values.data['values'] = info.map((e) => {
220
+ return e.attributes;
221
+ });
222
+ });
223
+
224
+ return Promise.all([p1, p2]).then(() => {
225
+ return values;
226
+ });
227
+ }
228
+
229
+ createChart(title, variable, chartData) {
230
+ let chartOptions = {
231
+ chart: {
232
+ height: 208,
233
+ },
234
+ title: {
235
+ text: title,
236
+ style: {},
237
+ },
238
+ subtitle: {
239
+ text: '',
240
+ style: {
241
+ display: 'none',
242
+ },
243
+ },
244
+ plotOptions: {
245
+ line: {
246
+ pointPlacement: 'between',
247
+ },
248
+ },
249
+ xAxis: {
250
+ title: {
251
+ text: null,
252
+ },
253
+ labels: {
254
+ format: '{value:%d/%m/%Y}',
255
+ },
256
+ type: 'datetime',
257
+ categories: chartData.x,
258
+ tickmarkPlacement: 'between',
259
+ startOnTick: true,
260
+ endOnTick: true,
261
+ },
262
+ legend: {
263
+ enabled: false,
264
+ },
265
+ tooltip: {
266
+ shared: true,
267
+ useHTML: true,
268
+ headerFormat: '{point.x:%d/%m/%Y}<br><b>{point.point.symbolName}</b>',
269
+ },
270
+ series: [
271
+ {
272
+ marker: {
273
+ enabled: false,
274
+ },
275
+ name: variable,
276
+ data: chartData.y,
277
+ shadow: false,
278
+ zIndex: 1,
279
+ color: '#a0b128',
280
+ },
281
+ ],
282
+ exporting: {
283
+ buttons: {
284
+ contextButton: {
285
+ enabled: false,
286
+ },
287
+ },
288
+ },
289
+ credits: {
290
+ enabled: false,
291
+ },
292
+ };
293
+ return chartOptions;
294
+ }
295
+
296
+ getActiveLayers() {
297
+ let layers = {};
298
+ if (!this.state.timeLayers.hasOwnProperty('selected')) {
299
+ layers.selected = this.props.activeLayers
300
+ .map((a) => {
301
+ return a.name;
302
+ })
303
+ .reverse()[0];
304
+ layers.layer = this.props.activeLayers[
305
+ this.props.activeLayers.findIndex((a) => a.name === layers.selected)
306
+ ].layer;
307
+ } else if (
308
+ !this.props.activeLayers
309
+ .map((a) => {
310
+ return a.name;
311
+ })
312
+ .includes(this.state.timeLayers.selected)
313
+ ) {
314
+ layers.selected = this.props.activeLayers
315
+ .map((a) => {
316
+ return a.name;
317
+ })
318
+ .reverse()[0];
319
+ layers.layer = this.props.activeLayers[
320
+ this.props.activeLayers.findIndex((a) => a.name === layers.selected)
321
+ ].layer;
322
+ }
323
+ this.setState({
324
+ timeLayers: layers,
325
+ });
326
+ }
327
+
328
+ selectLayer(option) {
329
+ let selected = this.props.activeLayers[
330
+ this.props.activeLayers.findIndex((a) => a.name === option)
331
+ ];
332
+ let names = this.state.timeLayers.names;
333
+ let name = option;
334
+ let layer = selected.layer;
335
+ this.removeMarker();
336
+ this.setState({
337
+ timeLayers: { names: names, selected: name, layer: layer },
338
+ pixelInfo: false,
339
+ data: {},
340
+ variables: {},
341
+ });
342
+ }
343
+
344
+ selectVariable(option) {
345
+ let variables = this.state.variables.options;
346
+ let variable = option;
347
+ let selected = this.props.activeLayers[
348
+ this.props.activeLayers.findIndex(
349
+ (a) => a.name === this.state.timeLayers.selected,
350
+ )
351
+ ];
352
+ let title = selected.title;
353
+ let data = {
354
+ x: this.state.data.timeFields.values
355
+ .map((a) => {
356
+ return a[this.state.data.timeFields.start];
357
+ })
358
+ .sort((a, b) => {
359
+ return new Date(a).getTime() - new Date(b).getTime();
360
+ }),
361
+ y: this.state.data.data.values.map((a) => {
362
+ return Math.round(a[variable] * 100) / 100;
363
+ }),
364
+ };
365
+ let chartData = this.createChart(title, variable, data);
366
+ this.setState({
367
+ options: chartData,
368
+ variables: { options: variables, selected: variable },
369
+ });
370
+ }
371
+
372
+ /**
373
+ * This method renders the component
374
+ * @returns jsx
375
+ */
376
+ render() {
377
+ let isEmpty = true;
378
+ let pixelInfo = true;
379
+ if (this.state.pixelInfo && this.state.data) {
380
+ isEmpty =
381
+ this.state.data.data.values.map((a) => {
382
+ return a[this.state.variables.selected];
383
+ }).length === 0;
384
+ }
385
+ if (
386
+ (this.props.activeLayers &&
387
+ !this.props.activeLayers
388
+ .map((a) => {
389
+ return a.name;
390
+ })
391
+ .includes(this.state.timeLayers.selected)) ||
392
+ (this.props.activeLayers &&
393
+ document.querySelector('#info_layer').value !==
394
+ this.state.timeLayers.selected)
395
+ ) {
396
+ pixelInfo = false;
397
+ this.removeMarker();
398
+ }
399
+ return (
400
+ <>
401
+ <div ref={this.container} className="info-container">
402
+ <div
403
+ className={this.menuClass}
404
+ id="info_button"
405
+ title="Info"
406
+ onClick={this.openMenu.bind(this)}
407
+ onKeyDown={this.openMenu.bind(this)}
408
+ tabIndex="0"
409
+ role="button"
410
+ ></div>
411
+ <div className="info-panel">
412
+ {this.state.showMapMenu && (
413
+ <label>
414
+ Layer
415
+ <select
416
+ className="esri-select"
417
+ id="info_layer"
418
+ value={this.state.timeLayers.selected}
419
+ onBlur={(e) => e.preventDefault()}
420
+ onChange={(e) => this.selectLayer(e.target.value)}
421
+ >
422
+ {this.props.activeLayers.map((option) => (
423
+ <option key={option.name} value={option.name}>
424
+ {option.title}
425
+ </option>
426
+ ))}
427
+ </select>
428
+ </label>
429
+ )}
430
+ {this.state.pixelInfo && pixelInfo ? (
431
+ <>
432
+ <label>
433
+ Variable
434
+ <select
435
+ className="esri-select"
436
+ id="info_variable"
437
+ value={this.state.variables.selected}
438
+ onBlur={(e) => e.preventDefault()}
439
+ onChange={(e) => this.selectVariable(e.target.value)}
440
+ >
441
+ {this.state.variables.options.map((option) => (
442
+ <option key={option} value={option}>
443
+ {option}
444
+ </option>
445
+ ))}
446
+ </select>
447
+ </label>
448
+ {isEmpty ? (
449
+ <span className="info-panel-empty">No data</span>
450
+ ) : (
451
+ <HighchartsReact
452
+ highcharts={Highcharts}
453
+ options={this.state.options}
454
+ />
455
+ )}
456
+ </>
457
+ ) : (
458
+ <span className="info-panel-empty">
459
+ Click on the map to get pixel info
460
+ </span>
461
+ )}
462
+ </div>
463
+ </div>
464
+ </>
465
+ );
466
+ }
467
+ }
468
+
469
+ export default InfoWidget;
@@ -8,10 +8,12 @@ import PrintWidget from './PrintWidget';
8
8
  import AreaWidget from './AreaWidget';
9
9
  import ScaleWidget from './ScaleWidget';
10
10
  import LegendWidget from './LegendWidget';
11
+ import InfoWidget from './InfoWidget';
11
12
  import MenuWidget from './MenuWidget';
12
13
  import { MapViewerConfig } from '../../actions';
13
14
  import { compose } from 'redux';
14
15
  import { connect } from 'react-redux';
16
+ import { flattenToAppURL } from '@plone/volto/helpers/Url/Url';
15
17
 
16
18
  //import "isomorphic-fetch"; <-- Necessary to use fetch?
17
19
  var Map, MapView, Zoom;
@@ -44,6 +46,10 @@ class MapViewer extends React.Component {
44
46
  this.mapViewer.setState({ area: shared_value });
45
47
  }
46
48
 
49
+ updateActiveLayers(shared_value) {
50
+ this.mapViewer.setState({ activeLayers: shared_value });
51
+ }
52
+
47
53
  loader() {
48
54
  return loadModules([
49
55
  'esri/WebMap',
@@ -87,7 +93,7 @@ class MapViewer extends React.Component {
87
93
  // After launching the MapViewerConfig action
88
94
  // we will have stored the json response here:
89
95
  // this.props.mapviewer_config
90
- this.props.MapViewerConfig(this.props.url);
96
+ this.props.MapViewerConfig(flattenToAppURL(this.props.url));
91
97
 
92
98
  //Once we have created the MapView, we need to ensure that the map div
93
99
  //is refreshed in order to show the map on it. To do so, we need to
@@ -156,6 +162,19 @@ class MapViewer extends React.Component {
156
162
  if (this.view) return <ScaleWidget view={this.view} mapViewer={this} />;
157
163
  }
158
164
 
165
+ renderInfo() {
166
+ if (this.view)
167
+ return (
168
+ <InfoWidget
169
+ view={this.view}
170
+ map={this.map}
171
+ mapViewer={this}
172
+ updateActiveLayers={this.updateActiveLayers}
173
+ activeLayers={this.state.activeLayers}
174
+ />
175
+ );
176
+ }
177
+
159
178
  renderMenu() {
160
179
  if (this.view)
161
180
  return (
@@ -167,6 +186,7 @@ class MapViewer extends React.Component {
167
186
  mapViewer={this}
168
187
  updateArea={this.updateArea}
169
188
  area={this.state.area}
189
+ updateActiveLayers={this.updateActiveLayers}
170
190
  />
171
191
  ); //call conf
172
192
  }
@@ -188,6 +208,7 @@ class MapViewer extends React.Component {
188
208
  {this.renderPrint()}
189
209
  {this.renderArea()}
190
210
  {this.renderScale()}
211
+ {this.renderInfo()}
191
212
  {this.renderMenu()}
192
213
  </div>
193
214
  </div>