@eeacms/volto-arcgis-block 0.1.357 → 0.1.358

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,10 +4,16 @@ 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.358](https://github.com/eea/volto-arcgis-block/compare/0.1.357...0.1.358) - 14 May 2025
8
+
9
+ #### :hammer_and_wrench: Others
10
+
11
+ - CLMS-285620 (bug): Fixed the but that made interacting with bookmarks freeze the map up [Unai Bolivar - [`a1c3354`](https://github.com/eea/volto-arcgis-block/commit/a1c3354591a141f5c634d4e1eee6f466017addec)]
7
12
  ### [0.1.357](https://github.com/eea/volto-arcgis-block/compare/0.1.356...0.1.357) - 12 May 2025
8
13
 
9
14
  #### :hammer_and_wrench: Others
10
15
 
16
+ - Merge pull request #946 from eea/develop [Unai Bolivar - [`4220c81`](https://github.com/eea/volto-arcgis-block/commit/4220c81bcd656e5911742b55f4b64c29f586b231)]
11
17
  - Merge pull request #945 from eea/CLMS-285178-ISOLATED-SWIPE-WIDGET-FIX [Unai Bolivar - [`617b4c4`](https://github.com/eea/volto-arcgis-block/commit/617b4c43ad4363267c4df34c72e64314ee42afb4)]
12
18
  - CLMS-285178 (bug): Separated swipe from other tickets and can push now going [Unai Bolivar - [`84efe24`](https://github.com/eea/volto-arcgis-block/commit/84efe24d964b79f54ddf17f69e389a3f57e3f867)]
13
19
  - CLMS-285178 (bug): Separated swipe from other tickets and can push [Unai Bolivar - [`3e94fd6`](https://github.com/eea/volto-arcgis-block/commit/3e94fd6d2f92817d6b0220155a7e8a0ed5d8dfdb)]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eeacms/volto-arcgis-block",
3
- "version": "0.1.357",
3
+ "version": "0.1.358",
4
4
  "description": "volto-arcgis-block: Volto add-on",
5
5
  "main": "src/index.js",
6
6
  "author": "European Environment Agency: CodeSyntax",
@@ -5,7 +5,7 @@ import { loadModules } from 'esri-loader';
5
5
 
6
6
  export const BOOKMARK_SESSION_KEY = 'bookmark_session';
7
7
 
8
- var Bookmarks;
8
+ var Bookmarks, Extent;
9
9
  class BookmarkWidget extends React.Component {
10
10
  /**
11
11
  * Creator of the Basemap widget class
@@ -31,12 +31,18 @@ class BookmarkWidget extends React.Component {
31
31
  this.sessionBookmarkOpacity = [];
32
32
  this.sessionBookmarkVisible = [];
33
33
  this.sessionBookmarkHotspot = [];
34
+ this.arcgisEventHandles = [];
35
+ this.boundLimitMaxLenth = this.limitMaxLenth.bind(this);
36
+ this._isMounted = false;
34
37
  }
35
38
 
36
39
  loader() {
37
- return loadModules(['esri/widgets/Bookmarks']).then(([_Bookmarks]) => {
38
- Bookmarks = _Bookmarks;
39
- });
40
+ return loadModules(['esri/widgets/Bookmarks', 'esri/geometry/Extent']).then(
41
+ ([_Bookmarks, _Extent]) => {
42
+ Bookmarks = _Bookmarks;
43
+ Extent = _Extent;
44
+ },
45
+ );
40
46
  }
41
47
  /**
42
48
  * Method that will be invoked when the
@@ -87,6 +93,7 @@ class BookmarkWidget extends React.Component {
87
93
  }
88
94
 
89
95
  async componentDidMount() {
96
+ this._isMounted = true;
90
97
  await this.loader();
91
98
  if (!this.container.current) return;
92
99
  this.props.view.when(() => {
@@ -148,15 +155,173 @@ class BookmarkWidget extends React.Component {
148
155
  time: false, // don't show the time (h:m:s) next to the date
149
156
  },
150
157
  container: document.querySelector('.bookmark-panel'),
151
- bookmarks: this.sessionBookmarks,
158
+ bookmarks: this.sessionBookmarks.map((bm) => {
159
+ if (bm.extent) {
160
+ const { extent, ...rest } = bm;
161
+ let geometry;
162
+ if (extent && typeof extent === 'object') {
163
+ geometry = extent.type ? extent : new Extent(extent);
164
+ }
165
+ return {
166
+ ...rest,
167
+ viewpoint: {
168
+ targetGeometry: geometry,
169
+ },
170
+ };
171
+ }
172
+ return bm;
173
+ }),
152
174
  });
153
175
  this.sessionBookmarks = [];
154
176
  this.Bookmarks.bookmarks.items.forEach((bookmark) => {
155
177
  this.sessionBookmarks.push(bookmark);
156
178
  });
157
179
  this.Bookmarks.when(() => {
158
- this.Bookmarks.bookmarks.on('change', (e) => {
159
- if (e.added[0]) {
180
+ this.arcgisEventHandles.push(
181
+ this.Bookmarks.bookmarks.on('change', (e) => {
182
+ if (!this._isMounted) return;
183
+ let shouldUpdate = false;
184
+ if (e.added[0]) {
185
+ let check =
186
+ JSON.parse(sessionStorage.getItem('checkedLayers')) || [];
187
+ let visibleLayers =
188
+ JSON.parse(sessionStorage.getItem('visibleLayers')) || [];
189
+ let opacity = [];
190
+ let visible = [];
191
+ check.forEach((layer) => {
192
+ opacity.push(this.layers[layer].opacity);
193
+ if (
194
+ visibleLayers[layer] &&
195
+ visibleLayers[layer][1] === 'eye-slash'
196
+ ) {
197
+ visible.push(false);
198
+ } else {
199
+ visible.push(true);
200
+ }
201
+ });
202
+ this.sessionBookmarks.push(e.added[0]);
203
+ this.sessionBookmarkLayers.push(check);
204
+ this.sessionBookmarkOpacity.push(opacity);
205
+ this.sessionBookmarkVisible.push(visible);
206
+ let hotspotFilters = {
207
+ activeLayers: {},
208
+ filteredLayers: {},
209
+ };
210
+ if (this.props.hotspotData && this.props.hotspotData.activeLayers) {
211
+ Object.keys(this.props.hotspotData.activeLayers).forEach(
212
+ (key) => {
213
+ hotspotFilters.activeLayers[key] = null;
214
+ },
215
+ );
216
+ }
217
+ if (
218
+ this.props.hotspotData &&
219
+ this.props.hotspotData.filteredLayers
220
+ ) {
221
+ Object.keys(this.props.hotspotData.filteredLayers).forEach(
222
+ (key) => {
223
+ hotspotFilters.filteredLayers[
224
+ key
225
+ ] = this.props.hotspotData.filteredLayers[
226
+ key
227
+ ].customLayerParameters['CQL_FILTER'];
228
+ },
229
+ );
230
+ }
231
+ this.sessionBookmarkHotspot.push(hotspotFilters);
232
+ shouldUpdate = true;
233
+ } else if (e.removed[0]) {
234
+ for (let index = 0; index < this.sessionBookmarks.length; index++) {
235
+ if (e.removed[0] === this.sessionBookmarks[index]) {
236
+ this.sessionBookmarks.splice(index, 1);
237
+ this.sessionBookmarkLayers.splice(index, 1);
238
+ this.sessionBookmarkOpacity.splice(index, 1);
239
+ this.sessionBookmarkVisible.splice(index, 1);
240
+ this.sessionBookmarkHotspot.splice(index, 1);
241
+ shouldUpdate = true;
242
+ break;
243
+ }
244
+ }
245
+ } else {
246
+ let newSessionBookmark = [];
247
+ let newSessionBookmarkLayers = [];
248
+ let newSessionBookmarkOpacity = [];
249
+ let newSessionBookmarkVisible = [];
250
+ let newSessionBookmarkHotspot = [];
251
+ for (let i = 0; i < this.Bookmarks.bookmarks.items.length; i++) {
252
+ for (let j = 0; j < this.sessionBookmarks.length; j++) {
253
+ if (
254
+ this.Bookmarks.bookmarks.items[i] === this.sessionBookmarks[j]
255
+ ) {
256
+ newSessionBookmark.push(this.sessionBookmarks[j]);
257
+ newSessionBookmarkLayers.push(this.sessionBookmarkLayers[j]);
258
+ newSessionBookmarkOpacity.push(
259
+ this.sessionBookmarkOpacity[j],
260
+ );
261
+ newSessionBookmarkVisible.push(
262
+ this.sessionBookmarkVisible[j],
263
+ );
264
+ newSessionBookmarkHotspot.push(
265
+ this.sessionBookmarkHotspot[j],
266
+ );
267
+ }
268
+ }
269
+ }
270
+ if (
271
+ newSessionBookmark.length !== this.sessionBookmarks.length ||
272
+ newSessionBookmarkLayers.length !==
273
+ this.sessionBookmarkLayers.length ||
274
+ newSessionBookmarkOpacity.length !==
275
+ this.sessionBookmarkOpacity.length ||
276
+ newSessionBookmarkVisible.length !==
277
+ this.sessionBookmarkVisible.length ||
278
+ newSessionBookmarkHotspot.length !==
279
+ this.sessionBookmarkHotspot.length
280
+ ) {
281
+ this.sessionBookmarks = newSessionBookmark;
282
+ this.sessionBookmarkLayers = newSessionBookmarkLayers;
283
+ this.sessionBookmarkOpacity = newSessionBookmarkOpacity;
284
+ this.sessionBookmarkVisible = newSessionBookmarkVisible;
285
+ this.sessionBookmarkHotspot = newSessionBookmarkHotspot;
286
+ shouldUpdate = true;
287
+ }
288
+ }
289
+ if (shouldUpdate && this.userID != null) {
290
+ localStorage.setItem(
291
+ BOOKMARK_SESSION_KEY + '_' + this.userID,
292
+ JSON.stringify(this.Bookmarks.bookmarks.items),
293
+ );
294
+ localStorage.setItem(
295
+ BOOKMARK_SESSION_KEY + '_' + this.userID + '_layers',
296
+ JSON.stringify(this.sessionBookmarkLayers),
297
+ );
298
+ localStorage.setItem(
299
+ BOOKMARK_SESSION_KEY + '_' + this.userID + '_opacity',
300
+ JSON.stringify(this.sessionBookmarkOpacity),
301
+ );
302
+ localStorage.setItem(
303
+ BOOKMARK_SESSION_KEY + '_' + this.userID + '_visible',
304
+ JSON.stringify(this.sessionBookmarkVisible),
305
+ );
306
+ localStorage.setItem(
307
+ BOOKMARK_SESSION_KEY + '_' + this.userID + '_hotspot',
308
+ JSON.stringify(this.sessionBookmarkHotspot),
309
+ );
310
+ }
311
+ if (shouldUpdate) {
312
+ let bookmarkData = {
313
+ ...(this.props.bookmarkData || {}),
314
+ active: false,
315
+ layers: this.sessionBookmarkLayers,
316
+ opacity: this.sessionBookmarkOpacity,
317
+ visible: this.sessionBookmarkVisible,
318
+ position: null,
319
+ };
320
+ this.props.bookmarkHandler(bookmarkData);
321
+ }
322
+ }),
323
+ this.Bookmarks.on('bookmark-edit', (e) => {
324
+ if (!this._isMounted) return;
160
325
  let check = JSON.parse(sessionStorage.getItem('checkedLayers')) || [];
161
326
  let visibleLayers =
162
327
  JSON.parse(sessionStorage.getItem('visibleLayers')) || [];
@@ -173,20 +338,24 @@ class BookmarkWidget extends React.Component {
173
338
  visible.push(true);
174
339
  }
175
340
  });
176
- this.sessionBookmarks.push(e.added[0]);
177
- this.sessionBookmarkLayers.push(check);
178
- this.sessionBookmarkOpacity.push(opacity);
179
- this.sessionBookmarkVisible.push(visible);
180
341
  let hotspotFilters = {
181
342
  activeLayers: {},
182
343
  filteredLayers: {},
183
344
  };
184
- if (this.props.hotspotData && this.props.hotspotData.activeLayers) {
345
+ if (
346
+ this.props.hotspotData &&
347
+ this.props.hotspotData.activeLayers &&
348
+ Object.keys(this.props.hotspotData.activeLayers).length !== 0
349
+ ) {
185
350
  Object.keys(this.props.hotspotData.activeLayers).forEach((key) => {
186
351
  hotspotFilters.activeLayers[key] = null;
187
352
  });
188
353
  }
189
- if (this.props.hotspotData && this.props.hotspotData.filteredLayers) {
354
+ if (
355
+ this.props.hotspotData &&
356
+ this.props.hotspotData.filteredLayers &&
357
+ Object.keys(this.props.hotspotData.filteredLayers).length !== 0
358
+ ) {
190
359
  Object.keys(this.props.hotspotData.filteredLayers).forEach(
191
360
  (key) => {
192
361
  hotspotFilters.filteredLayers[
@@ -197,231 +366,148 @@ class BookmarkWidget extends React.Component {
197
366
  },
198
367
  );
199
368
  }
200
- this.sessionBookmarkHotspot.push(hotspotFilters);
201
- } else if (e.removed[0]) {
202
369
  for (let index = 0; index < this.sessionBookmarks.length; index++) {
203
- if (e.removed[0] === this.sessionBookmarks[index]) {
204
- this.sessionBookmarks.splice(index, 1);
205
- this.sessionBookmarkLayers.splice(index, 1);
206
- this.sessionBookmarkOpacity.splice(index, 1);
207
- this.sessionBookmarkVisible.splice(index, 1);
208
- this.sessionBookmarkHotspot.splice(index, 1);
370
+ if (e.bookmark === this.sessionBookmarks[index]) {
371
+ this.sessionBookmarks[index] = e.bookmark;
372
+ this.sessionBookmarkLayers[index] = check;
373
+ this.sessionBookmarkOpacity[index] = opacity;
374
+ this.sessionBookmarkVisible[index] = visible;
375
+ this.sessionBookmarkHotspot[index] = hotspotFilters;
209
376
  }
210
377
  }
211
- } else {
212
- let newSessionBookmark = [];
213
- let newSessionBookmarkLayers = [];
214
- let newSessionBookmarkOpacity = [];
215
- let newSessionBookmarkVisible = [];
216
- let newSessionBookmarkHotspot = [];
217
- for (let i = 0; i < this.Bookmarks.bookmarks.items.length; i++) {
218
- for (let j = 0; j < this.sessionBookmarks.length; j++) {
219
- if (
220
- this.Bookmarks.bookmarks.items[i] === this.sessionBookmarks[j]
221
- ) {
222
- newSessionBookmark.push(this.sessionBookmarks[j]);
223
- newSessionBookmarkLayers.push(this.sessionBookmarkLayers[j]);
224
- newSessionBookmarkOpacity.push(this.sessionBookmarkOpacity[j]);
225
- newSessionBookmarkVisible.push(this.sessionBookmarkVisible[j]);
226
- newSessionBookmarkHotspot.push(this.sessionBookmarkHotspot[j]);
227
- }
228
- }
229
- }
230
- this.sessionBookmarks = newSessionBookmark;
231
- this.sessionBookmarkLayers = newSessionBookmarkLayers;
232
- this.sessionBookmarkOpacity = newSessionBookmarkOpacity;
233
- this.sessionBookmarkVisible = newSessionBookmarkVisible;
234
- this.sessionBookmarkHotspot = newSessionBookmarkHotspot;
235
- }
236
- if (this.userID != null) {
237
- localStorage.setItem(
238
- BOOKMARK_SESSION_KEY + '_' + this.userID,
239
- JSON.stringify(this.Bookmarks.bookmarks.items),
240
- );
241
- localStorage.setItem(
242
- BOOKMARK_SESSION_KEY + '_' + this.userID + '_layers',
243
- JSON.stringify(this.sessionBookmarkLayers),
244
- );
245
- localStorage.setItem(
246
- BOOKMARK_SESSION_KEY + '_' + this.userID + '_opacity',
247
- JSON.stringify(this.sessionBookmarkOpacity),
248
- );
249
- localStorage.setItem(
250
- BOOKMARK_SESSION_KEY + '_' + this.userID + '_visible',
251
- JSON.stringify(this.sessionBookmarkVisible),
252
- );
253
- localStorage.setItem(
254
- BOOKMARK_SESSION_KEY + '_' + this.userID + '_hotspot',
255
- JSON.stringify(this.sessionBookmarkHotspot),
256
- );
257
- }
258
-
259
- let bookmarkData = {
260
- ...(this.props.bookmarkData || {}),
261
- active: false,
262
- layers: this.sessionBookmarkLayers,
263
- opacity: this.sessionBookmarkOpacity,
264
- visible: this.sessionBookmarkVisible,
265
- position: null,
266
- };
267
-
268
- this.props.bookmarkHandler(bookmarkData);
269
- });
270
- this.Bookmarks.on('bookmark-edit', (e) => {
271
- let check = JSON.parse(sessionStorage.getItem('checkedLayers')) || [];
272
- let visibleLayers =
273
- JSON.parse(sessionStorage.getItem('visibleLayers')) || [];
274
- let opacity = [];
275
- let visible = [];
276
- check.forEach((layer) => {
277
- opacity.push(this.layers[layer].opacity);
278
- if (visibleLayers[layer] && visibleLayers[layer][1] === 'eye-slash') {
279
- visible.push(false);
280
- } else {
281
- visible.push(true);
282
- }
283
- });
284
- let hotspotFilters = {
285
- activeLayers: {},
286
- filteredLayers: {},
287
- };
288
- if (
289
- this.props.hotspotData &&
290
- this.props.hotspotData.activeLayers &&
291
- Object.keys(this.props.hotspotData.activeLayers).length !== 0
292
- ) {
293
- Object.keys(this.props.hotspotData.activeLayers).forEach((key) => {
294
- hotspotFilters.activeLayers[key] = null;
295
- });
296
- }
297
- if (
298
- this.props.hotspotData &&
299
- this.props.hotspotData.filteredLayers &&
300
- Object.keys(this.props.hotspotData.filteredLayers).length !== 0
301
- ) {
302
- Object.keys(this.props.hotspotData.filteredLayers).forEach((key) => {
303
- hotspotFilters.filteredLayers[
304
- key
305
- ] = this.props.hotspotData.filteredLayers[
306
- key
307
- ].customLayerParameters['CQL_FILTER'];
308
- });
309
- }
310
- for (let index = 0; index < this.sessionBookmarks.length; index++) {
311
- if (e.bookmark === this.sessionBookmarks[index]) {
312
- this.sessionBookmarks[index] = e.bookmark;
313
- this.sessionBookmarkLayers[index] = check;
314
- this.sessionBookmarkOpacity[index] = opacity;
315
- this.sessionBookmarkVisible[index] = visible;
316
- this.sessionBookmarkHotspot[index] = hotspotFilters;
378
+ if (this.userID != null) {
379
+ localStorage.setItem(
380
+ BOOKMARK_SESSION_KEY + '_' + this.userID,
381
+ JSON.stringify(this.Bookmarks.bookmarks.items),
382
+ );
383
+ localStorage.setItem(
384
+ BOOKMARK_SESSION_KEY + '_' + this.userID + '_layers',
385
+ JSON.stringify(this.sessionBookmarkLayers),
386
+ );
387
+ localStorage.setItem(
388
+ BOOKMARK_SESSION_KEY + '_' + this.userID + '_opacity',
389
+ JSON.stringify(this.sessionBookmarkOpacity),
390
+ );
391
+ localStorage.setItem(
392
+ BOOKMARK_SESSION_KEY + '_' + this.userID + '_visible',
393
+ JSON.stringify(this.sessionBookmarkVisible),
394
+ );
395
+ localStorage.setItem(
396
+ BOOKMARK_SESSION_KEY + '_' + this.userID + '_hotspot',
397
+ JSON.stringify(this.sessionBookmarkHotspot),
398
+ );
317
399
  }
318
- }
319
- if (this.userID != null) {
320
- localStorage.setItem(
321
- BOOKMARK_SESSION_KEY + '_' + this.userID,
322
- JSON.stringify(this.Bookmarks.bookmarks.items),
323
- );
324
- localStorage.setItem(
325
- BOOKMARK_SESSION_KEY + '_' + this.userID + '_layers',
326
- JSON.stringify(this.sessionBookmarkLayers),
327
- );
328
- localStorage.setItem(
329
- BOOKMARK_SESSION_KEY + '_' + this.userID + '_opacity',
330
- JSON.stringify(this.sessionBookmarkOpacity),
331
- );
332
- localStorage.setItem(
333
- BOOKMARK_SESSION_KEY + '_' + this.userID + '_visible',
334
- JSON.stringify(this.sessionBookmarkVisible),
335
- );
336
- localStorage.setItem(
337
- BOOKMARK_SESSION_KEY + '_' + this.userID + '_hotspot',
338
- JSON.stringify(this.sessionBookmarkHotspot),
339
- );
340
- }
341
400
 
342
- let bookmarkData = {
343
- ...(this.props.bookmarkData || {}),
344
- active: false,
345
- layers: this.sessionBookmarkLayers,
346
- opacity: this.sessionBookmarkOpacity,
347
- visible: this.sessionBookmarkVisible,
348
- position: null,
349
- };
401
+ let bookmarkData = {
402
+ ...(this.props.bookmarkData || {}),
403
+ active: false,
404
+ layers: this.sessionBookmarkLayers,
405
+ opacity: this.sessionBookmarkOpacity,
406
+ visible: this.sessionBookmarkVisible,
407
+ position: null,
408
+ };
350
409
 
351
- this.props.bookmarkHandler(bookmarkData);
352
- });
353
- this.Bookmarks.on('bookmark-select', (e) => {
354
- let selectLayers = [];
355
- let selectOpacity = [];
356
- let selectVisible = [];
357
- let selectPosition;
358
- for (let index = 0; index < this.Bookmarks.bookmarks.length; index++) {
359
- if (e.bookmark === this.Bookmarks.bookmarks.items[index]) {
360
- selectLayers = this.sessionBookmarkLayers[index];
361
- selectOpacity = this.sessionBookmarkOpacity[index];
362
- selectVisible = this.sessionBookmarkVisible[index];
363
- selectPosition = index;
364
- localStorage.setItem(
365
- 'bookmarkHotspotFilter',
366
- JSON.stringify(this.sessionBookmarkHotspot[index]),
367
- );
410
+ this.props.bookmarkHandler(bookmarkData);
411
+ }),
412
+ this.Bookmarks.on('bookmark-select', (e) => {
413
+ if (!this._isMounted) return;
414
+ let selectLayers = [];
415
+ let selectOpacity = [];
416
+ let selectVisible = [];
417
+ let selectPosition;
418
+ for (
419
+ let index = 0;
420
+ index < this.Bookmarks.bookmarks.length;
421
+ index++
422
+ ) {
423
+ if (e.bookmark === this.Bookmarks.bookmarks.items[index]) {
424
+ selectLayers = this.sessionBookmarkLayers[index];
425
+ selectOpacity = this.sessionBookmarkOpacity[index];
426
+ selectVisible = this.sessionBookmarkVisible[index];
427
+ selectPosition = index;
428
+ localStorage.setItem(
429
+ 'bookmarkHotspotFilter',
430
+ JSON.stringify(this.sessionBookmarkHotspot[index]),
431
+ );
432
+ }
368
433
  }
369
- }
370
- let layerOpacities = {};
371
- const layerKeys = {
372
- lcc_filter: 'all_lcc',
373
- lc_filter: 'all_present',
374
- klc_filter: 'cop_klc',
375
- pa_filter: 'protected_areas',
376
- };
377
- for (let index = 0; index < selectLayers.length; index++) {
378
- if (selectOpacity[index]) {
379
- Object.entries(layerKeys).forEach(([key, val]) => {
380
- if (
381
- this.props.hotspotData?.filteredLayers?.hasOwnProperty(key) &&
382
- this.layers[key] &&
383
- selectLayers[index].includes(val)
384
- ) {
385
- this.layers[key].opacity = selectOpacity[index];
386
- } else {
387
- this.layers[selectLayers[index]].opacity = selectOpacity[index];
388
- layerOpacities[selectLayers[index]] = selectOpacity[index];
434
+ let layerOpacities = {};
435
+ const layerKeys = {
436
+ lcc_filter: 'all_lcc',
437
+ lc_filter: 'all_present',
438
+ klc_filter: 'cop_klc',
439
+ pa_filter: 'protected_areas',
440
+ };
441
+ let i = 0;
442
+ const chunkSize = 10;
443
+ const processChunk = () => {
444
+ let end = Math.min(i + chunkSize, selectLayers.length);
445
+ for (; i < end; i++) {
446
+ const opacityIndex = i;
447
+ if (selectOpacity[opacityIndex]) {
448
+ Object.entries(layerKeys).forEach(([key, val]) => {
449
+ if (
450
+ this.props.hotspotData?.filteredLayers?.hasOwnProperty(
451
+ key,
452
+ ) &&
453
+ this.layers[key] &&
454
+ selectLayers[opacityIndex].includes(val)
455
+ ) {
456
+ this.layers[key].opacity = selectOpacity[opacityIndex];
457
+ } else {
458
+ this.layers[selectLayers[opacityIndex]].opacity =
459
+ selectOpacity[opacityIndex];
460
+ layerOpacities[selectLayers[opacityIndex]] =
461
+ selectOpacity[opacityIndex];
462
+ }
463
+ });
389
464
  }
390
- });
391
- }
392
- if (selectVisible[index] !== null) {
393
- Object.entries(layerKeys).forEach(([key, val]) => {
394
- if (
395
- this.props.hotspotData?.filteredLayers?.hasOwnProperty(key) &&
396
- this.layers[key] &&
397
- selectLayers[index].includes(val)
398
- ) {
399
- this.layers[key].visible = selectVisible[index];
400
- } else {
401
- this.layers[selectLayers[index]].visible = selectVisible[index];
465
+ if (selectVisible[opacityIndex] !== null) {
466
+ Object.entries(layerKeys).forEach(([key, val]) => {
467
+ if (
468
+ this.props.hotspotData?.filteredLayers?.hasOwnProperty(
469
+ key,
470
+ ) &&
471
+ this.layers[key] &&
472
+ selectLayers[opacityIndex].includes(val)
473
+ ) {
474
+ this.layers[key].visible = selectVisible[opacityIndex];
475
+ } else {
476
+ this.layers[selectLayers[opacityIndex]].visible =
477
+ selectVisible[opacityIndex];
478
+ }
479
+ });
402
480
  }
403
- });
404
- }
405
- }
406
- sessionStorage.setItem('checkedLayers', JSON.stringify(selectLayers));
407
- sessionStorage.setItem(
408
- 'layerOpacities',
409
- JSON.stringify(layerOpacities),
410
- );
411
- let bookmarkData = {
412
- ...(this.props.bookmarkData || {}),
413
- active: true,
414
- layers: this.sessionBookmarkLayers,
415
- opacity: this.sessionBookmarkOpacity,
416
- visible: this.sessionBookmarkVisible,
417
- position: selectPosition,
418
- };
481
+ }
482
+ if (i < selectLayers.length) {
483
+ requestAnimationFrame(processChunk);
484
+ } else {
485
+ sessionStorage.setItem(
486
+ 'checkedLayers',
487
+ JSON.stringify(selectLayers),
488
+ );
489
+ sessionStorage.setItem(
490
+ 'layerOpacities',
491
+ JSON.stringify(layerOpacities),
492
+ );
493
+ let bookmarkData = {
494
+ ...(this.props.bookmarkData || {}),
495
+ active: true,
496
+ layers: this.sessionBookmarkLayers,
497
+ opacity: this.sessionBookmarkOpacity,
498
+ visible: this.sessionBookmarkVisible,
499
+ position: selectPosition,
500
+ };
419
501
 
420
- this.props.bookmarkHandler(bookmarkData);
421
- this.map.layers.removeAll();
422
- let firstLayer = Object.values(this.layers)[0];
423
- this.map.add(firstLayer);
424
- });
502
+ this.props.bookmarkHandler(bookmarkData);
503
+ this.map.layers.removeAll();
504
+ let firstLayer = Object.values(this.layers)[0];
505
+ this.map.add(firstLayer);
506
+ }
507
+ };
508
+ processChunk();
509
+ }),
510
+ );
425
511
  });
426
512
  }
427
513
  componentDidUpdate() {
@@ -429,12 +515,32 @@ class BookmarkWidget extends React.Component {
429
515
  this.Bookmarks.when(() => {
430
516
  this.Bookmarks.container.addEventListener(
431
517
  'keydown',
432
- this.limitMaxLenth,
518
+ this.boundLimitMaxLenth,
519
+ );
520
+ this.Bookmarks.container.addEventListener(
521
+ 'paste',
522
+ this.boundLimitMaxLenth,
433
523
  );
434
- this.Bookmarks.container.addEventListener('paste', this.limitMaxLenth);
435
524
  });
436
525
  });
437
526
  }
527
+ componentWillUnmount() {
528
+ this._isMounted = false;
529
+ if (this.arcgisEventHandles) {
530
+ this.arcgisEventHandles.forEach((handle) => handle.remove());
531
+ this.arcgisEventHandles = [];
532
+ }
533
+ if (this.Bookmarks && this.Bookmarks.container) {
534
+ this.Bookmarks.container.removeEventListener(
535
+ 'keydown',
536
+ this.boundLimitMaxLenth,
537
+ );
538
+ this.Bookmarks.container.removeEventListener(
539
+ 'paste',
540
+ this.boundLimitMaxLenth,
541
+ );
542
+ }
543
+ }
438
544
  /**
439
545
  * This method renders the component
440
546
  * @returns jsx
@@ -53,6 +53,8 @@ class HotspotWidget extends React.Component {
53
53
  this.lccYear = null;
54
54
  this.urls = this.props.urls;
55
55
  this.layers = this.props.selectedLayers;
56
+ this.arcgisEventHandles = [];
57
+ this._isMounted = false;
56
58
  }
57
59
 
58
60
  loader() {
@@ -946,6 +948,7 @@ class HotspotWidget extends React.Component {
946
948
  */
947
949
 
948
950
  async componentDidMount() {
951
+ this._isMounted = true;
949
952
  await this.getLayerParameters();
950
953
  await this.loader();
951
954
  if (!this.container.current) return;
@@ -954,8 +957,9 @@ class HotspotWidget extends React.Component {
954
957
  });
955
958
  this.layerModelInit();
956
959
  this.getBBoxData();
960
+ this.arcgisEventHandles = [];
957
961
  this.props.view.when(() => {
958
- this.props.view.map.layers.on('change', () => {
962
+ const handle = this.props.view.map.layers.on('change', () => {
959
963
  let bookmarkHotspotFilter = null;
960
964
  if (localStorage.getItem('bookmarkHotspotFilter')) {
961
965
  bookmarkHotspotFilter = JSON.parse(
@@ -964,12 +968,13 @@ class HotspotWidget extends React.Component {
964
968
  } else {
965
969
  return;
966
970
  }
971
+ let shouldUpdate = false;
967
972
  if (
968
973
  bookmarkHotspotFilter !== null &&
969
974
  Object.keys(bookmarkHotspotFilter?.filteredLayers).length !== 0 &&
975
+ this.props.bookmarkData &&
970
976
  this.props.bookmarkData.active === true
971
977
  ) {
972
- // setTimeout(() => {
973
978
  let activeLayers = [];
974
979
  let filteredLayers = [];
975
980
  Object.keys(bookmarkHotspotFilter.activeLayers).forEach((key) => {
@@ -978,32 +983,51 @@ class HotspotWidget extends React.Component {
978
983
  Object.keys(bookmarkHotspotFilter.filteredLayers).forEach((key) => {
979
984
  filteredLayers[key] = null;
980
985
  });
981
- this.props.hotspotData['activeLayers'] = activeLayers;
982
- this.props.hotspotData['filteredLayers'] = filteredLayers;
986
+ if (this.props.hotspotData) {
987
+ this.props.hotspotData['activeLayers'] = activeLayers;
988
+ this.props.hotspotData['filteredLayers'] = filteredLayers;
989
+ }
983
990
  this.renderApplyFilterButton();
984
991
  localStorage.setItem('bookmarkHotspotFilter', null);
985
- // }, 2000);
992
+ shouldUpdate = true;
986
993
  } else if (
987
994
  bookmarkHotspotFilter !== null &&
988
995
  Object.keys(bookmarkHotspotFilter?.filteredLayers).length === 0 &&
996
+ this.props.bookmarkData &&
989
997
  this.props.bookmarkData.active === true
990
998
  ) {
991
999
  this.lcYear = null;
992
1000
  this.lccYear = null;
993
1001
  this.selectedArea = null;
994
- this.setState({ lcYear: null, lccYear: null, selectedArea: null });
1002
+ if (this._isMounted) {
1003
+ this.setState({ lcYear: null, lccYear: null, selectedArea: null });
1004
+ }
1005
+ shouldUpdate = true;
1006
+ }
1007
+ if (shouldUpdate && this._isMounted) {
1008
+ this.setState({
1009
+ activeLayersArray: Array.from(
1010
+ document.querySelectorAll('.active-layer'),
1011
+ ),
1012
+ });
1013
+ const newHotspotData = this.props.hotspotData;
1014
+ this.props.hotspotDataHandler(newHotspotData);
995
1015
  }
996
- this.setState({
997
- activeLayersArray: Array.from(
998
- document.querySelectorAll('.active-layer'),
999
- ),
1000
- });
1001
- const newHotspotData = this.props.hotspotData;
1002
- this.props.hotspotDataHandler(newHotspotData);
1003
1016
  });
1017
+ this.arcgisEventHandles.push(handle);
1004
1018
  });
1005
1019
  }
1006
1020
 
1021
+ componentWillUnmount() {
1022
+ this._isMounted = false;
1023
+ if (this.arcgisEventHandles) {
1024
+ this.arcgisEventHandles.forEach(
1025
+ (handle) => handle && handle.remove && handle.remove(),
1026
+ );
1027
+ this.arcgisEventHandles = [];
1028
+ }
1029
+ }
1030
+
1007
1031
  componentDidUpdate(prevState, prevProps) {
1008
1032
  if (prevProps.hotspotData !== this.props.hotspotData) {
1009
1033
  this.getKLCNames(this.dataJSONNames, this.state.selectedArea);
@@ -28,6 +28,8 @@ class InfoWidget extends React.Component {
28
28
  'esri-icon-description esri-widget--button esri-widget esri-interactive';
29
29
  this.infoData = {};
30
30
  this.Highcharts = props.highcharts;
31
+ this.arcgisEventHandles = [];
32
+ this._isMounted = false;
31
33
  }
32
34
 
33
35
  async loader() {
@@ -96,13 +98,15 @@ class InfoWidget extends React.Component {
96
98
  /**
97
99
  * This method is executed after the rener method is executed
98
100
  */ async componentDidMount() {
101
+ this._isMounted = true;
99
102
  await this.loader();
100
103
  //this.waitForContainer(this.container.current);
101
104
  if (!this.container.current) return;
102
105
  this.props.view.when(() => {
103
106
  this.props.view.ui.add(this.container.current, 'top-right');
104
107
  });
105
- this.props.view.on('click', (e) => {
108
+ const clickHandle = this.props.view.on('click', (e) => {
109
+ if (!this._isMounted) return;
106
110
  let screenPoint = {
107
111
  x: e.x,
108
112
  y: e.y,
@@ -425,6 +429,17 @@ class InfoWidget extends React.Component {
425
429
  });
426
430
  }
427
431
  });
432
+ this.arcgisEventHandles.push(clickHandle);
433
+ }
434
+
435
+ componentWillUnmount() {
436
+ this._isMounted = false;
437
+ if (this.arcgisEventHandles) {
438
+ this.arcgisEventHandles.forEach(
439
+ (handle) => handle && handle.remove && handle.remove(),
440
+ );
441
+ this.arcgisEventHandles = [];
442
+ }
428
443
  }
429
444
 
430
445
  getLayerTitle(layer) {
@@ -23,6 +23,8 @@ class LegendWidget extends React.Component {
23
23
  this.menuClass =
24
24
  'esri-icon-legend esri-widget--button esri-widget esri-interactive';
25
25
  this.urls = this.props.urls;
26
+ this.arcgisEventHandles = [];
27
+ this._isMounted = false;
26
28
  }
27
29
 
28
30
  hideNutsLegend() {
@@ -219,6 +221,7 @@ class LegendWidget extends React.Component {
219
221
  * This method is executed after the rener method is executed
220
222
  */
221
223
  async componentDidMount() {
224
+ this._isMounted = true;
222
225
  await this.loader();
223
226
  if (!this.container.current) return;
224
227
  this.props.view.when(() => {
@@ -232,14 +235,27 @@ class LegendWidget extends React.Component {
232
235
  container: document.querySelector('.legend-panel'),
233
236
  });
234
237
  this.LegendWidget.when(() => {
235
- this.LegendWidget.activeLayerInfos.on('after-changes', (event) => {
236
- this.setState({ loading: true });
237
- //this.scanImages();
238
- //this.brokenLegendImagePatch();
239
- });
238
+ const handle = this.LegendWidget.activeLayerInfos.on(
239
+ 'after-changes',
240
+ (event) => {
241
+ if (!this._isMounted) return;
242
+ this.setState({ loading: true });
243
+ },
244
+ );
245
+ this.arcgisEventHandles.push(handle);
240
246
  });
241
247
  }
242
248
 
249
+ componentWillUnmount() {
250
+ this._isMounted = false;
251
+ if (this.arcgisEventHandles) {
252
+ this.arcgisEventHandles.forEach(
253
+ (handle) => handle && handle.remove && handle.remove(),
254
+ );
255
+ this.arcgisEventHandles = [];
256
+ }
257
+ }
258
+
243
259
  /**
244
260
  * Method that returns true or false if session storage has any visible active layer
245
261
  */
@@ -293,6 +309,7 @@ class LegendWidget extends React.Component {
293
309
  if (prevState.loading !== this.state.loading) {
294
310
  if (this.state.loading === true) {
295
311
  setTimeout(() => {
312
+ if (!this._isMounted) return;
296
313
  if (this.props.download) {
297
314
  this.hideNutsLegend();
298
315
  }
@@ -12,36 +12,36 @@ class LoadingSpinner extends React.Component {
12
12
  };
13
13
  this.showLoading = this.showLoading.bind(this);
14
14
  this.listenForLayerChanges = this.listenForLayerChanges.bind(this);
15
+ this.arcgisEventHandles = [];
16
+ this._isMounted = false;
15
17
  }
16
18
 
17
19
  listenForLayerChanges() {
18
- this.props.view.map.layers.on('change', (event) => {
19
- if (event.added.length > 0)
20
- if (this.state.loading === false) {
21
- this.setState({ loading: true });
22
- this.showLoading();
23
- }
20
+ const handle1 = this.props.view.map.layers.on('change', (event) => {
21
+ if (!this._isMounted) return;
22
+ if (event.added.length > 0 && this.state.loading === false) {
23
+ this.setState({ loading: true }, this.showLoading);
24
+ }
24
25
  });
25
- this.props.view.on('layerview-create', (event) => {
26
+ const handle2 = this.props.view.on('layerview-create', (event) => {
27
+ if (!this._isMounted) return;
26
28
  if (event.layer.loadStatus === 'loaded') {
27
- this.props.view.watch('updating', (isUpdating) => {
28
- if (!isUpdating) {
29
- if (this.state.loading === true) {
30
- this.setState({ loading: false });
31
- this.showLoading();
32
- }
29
+ const watchHandle = this.props.view.watch('updating', (isUpdating) => {
30
+ if (!this._isMounted) return;
31
+ if (!isUpdating && this.state.loading === true) {
32
+ this.setState({ loading: false }, this.showLoading);
33
33
  }
34
34
  });
35
+ this.arcgisEventHandles.push(watchHandle);
35
36
  }
36
37
  });
37
- this.props.view.on('layerview-create-error', (event) => {
38
- if (event.layer.loadError !== null) {
39
- if (this.state.loading === true) {
40
- this.setState({ loading: false });
41
- this.showLoading();
42
- }
38
+ const handle3 = this.props.view.on('layerview-create-error', (event) => {
39
+ if (!this._isMounted) return;
40
+ if (event.layer.loadError !== null && this.state.loading === true) {
41
+ this.setState({ loading: false }, this.showLoading);
43
42
  }
44
43
  });
44
+ this.arcgisEventHandles.push(handle1, handle2, handle3);
45
45
  }
46
46
 
47
47
  showLoading() {
@@ -51,17 +51,10 @@ class LoadingSpinner extends React.Component {
51
51
  } else {
52
52
  this.container.current.style.display = 'block';
53
53
  }
54
- this.setState({});
55
54
  }
56
55
 
57
- // waitForContainer(mapdiv) {
58
- // while (mapdiv === null) {
59
- // new Promise((resolve) => setTimeout(resolve, 100)); // wait for 100ms
60
- // }
61
- // return mapdiv;
62
- // }
63
-
64
56
  async componentDidMount() {
57
+ this._isMounted = true;
65
58
  //this.waitForContainer(this.props.view);
66
59
  if (!this.container.current) return;
67
60
  this.props.view.when(() => {
@@ -70,6 +63,16 @@ class LoadingSpinner extends React.Component {
70
63
  });
71
64
  }
72
65
 
66
+ componentWillUnmount() {
67
+ this._isMounted = false;
68
+ if (this.arcgisEventHandles) {
69
+ this.arcgisEventHandles.forEach(
70
+ (handle) => handle && handle.remove && handle.remove(),
71
+ );
72
+ this.arcgisEventHandles = [];
73
+ }
74
+ }
75
+
73
76
  render() {
74
77
  return (
75
78
  <div