@eeacms/volto-arcgis-block 0.1.379 → 0.1.381
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,20 @@ 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.381](https://github.com/eea/volto-arcgis-block/compare/0.1.380...0.1.381) - 20 August 2025
|
|
8
|
+
|
|
9
|
+
#### :hammer_and_wrench: Others
|
|
10
|
+
|
|
11
|
+
- (feat): extent from CDSE is applied and map escapes CDSE resolution warning. This push is clean and contains no console.log statements [Unai Bolivar - [`e909e39`](https://github.com/eea/volto-arcgis-block/commit/e909e390baa803b3785a4ab6f3ce5ff693bdaafb)]
|
|
12
|
+
- (feat): changing values from CDSE service bbox parser to web mercator [Unai Bolivar - [`0973a7d`](https://github.com/eea/volto-arcgis-block/commit/0973a7de01f78c34b02577c8eadd4560046ae3fb)]
|
|
13
|
+
- (feat): Getting the extents from layers fetched via CDSE OGC API to match the data viewer map status center extent [Unai Bolivar - [`e592a4e`](https://github.com/eea/volto-arcgis-block/commit/e592a4e7e7f488f1011dfb522ea063c2a20b4834)]
|
|
14
|
+
### [0.1.380](https://github.com/eea/volto-arcgis-block/compare/0.1.379...0.1.380) - 20 August 2025
|
|
15
|
+
|
|
7
16
|
### [0.1.379](https://github.com/eea/volto-arcgis-block/compare/0.1.378...0.1.379) - 11 August 2025
|
|
8
17
|
|
|
9
18
|
#### :hammer_and_wrench: Others
|
|
10
19
|
|
|
20
|
+
- Merge pull request #999 from eea/develop [Unai Bolivar - [`f5b976f`](https://github.com/eea/volto-arcgis-block/commit/f5b976fdc7e5568973e7db87c29c05f8fe2abcbd)]
|
|
11
21
|
- Merge pull request #998 from eea/CLMS-LOCAL-STORAGE-ISSUES-REFACTOR-CLEAN [Unai Bolivar - [`3b84fbd`](https://github.com/eea/volto-arcgis-block/commit/3b84fbd1cc3706976cc746a95c6885da7a746e22)]
|
|
12
22
|
- (lint): cleared console statements [Unai Bolivar - [`f6d649d`](https://github.com/eea/volto-arcgis-block/commit/f6d649d51d9254a250e49ca31b83bc4cc8c6b30a)]
|
|
13
23
|
- (bug): implemented safe store and recall for all user data in mapviewer fix [Unai Bolivar - [`a0491a7`](https://github.com/eea/volto-arcgis-block/commit/a0491a7bbeffdcd527eabc91b716757d680ea5d3)]
|
package/package.json
CHANGED
|
@@ -97,15 +97,6 @@ const MapViewerStateMonitor = ({ children, onUserStateChange }) => {
|
|
|
97
97
|
prevCartStateRef.current.isLoggedIn !== currentUserState.isLoggedIn;
|
|
98
98
|
|
|
99
99
|
if (hasUserIdChanged || hasLoggedInChanged) {
|
|
100
|
-
/* eslint-disable no-console */
|
|
101
|
-
console.log('[MapViewerStateMonitor] User state change detected:', {
|
|
102
|
-
previous: prevCartStateRef.current,
|
|
103
|
-
current: currentUserState,
|
|
104
|
-
userIdChanged: hasUserIdChanged,
|
|
105
|
-
loggedInChanged: hasLoggedInChanged,
|
|
106
|
-
});
|
|
107
|
-
/* eslint-enable no-console */
|
|
108
|
-
|
|
109
100
|
// Notify parent component of state change
|
|
110
101
|
if (onUserStateChange) {
|
|
111
102
|
onUserStateChange(currentUserState, prevCartStateRef.current);
|
|
@@ -137,17 +128,6 @@ const UserStorageManager = ({ children, onStorageManaged }) => {
|
|
|
137
128
|
const populateSessionFromUserData = (userKey) => {
|
|
138
129
|
const userData = localStorage.getItem(userKey);
|
|
139
130
|
if (userData) {
|
|
140
|
-
/* eslint-disable no-console */
|
|
141
|
-
console.log(
|
|
142
|
-
`[UserStorageManager:${instanceId.current}] Restoring from localStorage:`,
|
|
143
|
-
{
|
|
144
|
-
key: userKey,
|
|
145
|
-
dataPreview:
|
|
146
|
-
userData.substring(0, 100) + (userData.length > 100 ? '...' : ''),
|
|
147
|
-
dataLength: userData.length,
|
|
148
|
-
},
|
|
149
|
-
);
|
|
150
|
-
/* eslint-enable no-console */
|
|
151
131
|
const parsed = JSON.parse(userData);
|
|
152
132
|
const userIdFromKey = (key) => key.replace(/^user_/, '');
|
|
153
133
|
const hydratedFor = sessionStorage.getItem('mv_hydrated_for');
|
|
@@ -195,12 +175,6 @@ const UserStorageManager = ({ children, onStorageManaged }) => {
|
|
|
195
175
|
|
|
196
176
|
return true; // Indicate successful restoration
|
|
197
177
|
} else {
|
|
198
|
-
/* eslint-disable no-console */
|
|
199
|
-
console.log(
|
|
200
|
-
`[UserStorageManager:${instanceId.current}] No data found for key:`,
|
|
201
|
-
userKey,
|
|
202
|
-
);
|
|
203
|
-
/* eslint-enable no-console */
|
|
204
178
|
return false;
|
|
205
179
|
}
|
|
206
180
|
};
|
|
@@ -225,15 +199,6 @@ const UserStorageManager = ({ children, onStorageManaged }) => {
|
|
|
225
199
|
// Initialization effect - handles user state readiness
|
|
226
200
|
useEffect(() => {
|
|
227
201
|
if (userID !== undefined && isLoggedIn !== undefined) {
|
|
228
|
-
/* eslint-disable no-console */
|
|
229
|
-
console.log(
|
|
230
|
-
`[UserStorageManager:${instanceId.current}] User state initialized:`,
|
|
231
|
-
{
|
|
232
|
-
userID,
|
|
233
|
-
isLoggedIn,
|
|
234
|
-
},
|
|
235
|
-
);
|
|
236
|
-
/* eslint-enable no-console */
|
|
237
202
|
setIsInitialized(true);
|
|
238
203
|
}
|
|
239
204
|
}, [userID, isLoggedIn]);
|
|
@@ -246,35 +211,12 @@ const UserStorageManager = ({ children, onStorageManaged }) => {
|
|
|
246
211
|
|
|
247
212
|
const lockKey = `storage_lock_${userID || 'anonymous'}`;
|
|
248
213
|
|
|
249
|
-
/* eslint-disable no-console */
|
|
250
|
-
console.log(
|
|
251
|
-
`[UserStorageManager:${instanceId.current}] Component mounting with state:`,
|
|
252
|
-
{
|
|
253
|
-
isLoggedIn,
|
|
254
|
-
userID,
|
|
255
|
-
storageManaged,
|
|
256
|
-
isInitialized,
|
|
257
|
-
},
|
|
258
|
-
);
|
|
259
|
-
/* eslint-enable no-console */
|
|
260
|
-
|
|
261
214
|
// Acquire lock to prevent concurrent operations
|
|
262
215
|
if (!acquireStorageLock(lockKey)) {
|
|
263
|
-
/* eslint-disable no-console */
|
|
264
|
-
console.log(
|
|
265
|
-
`[UserStorageManager:${instanceId.current}] Another instance is managing storage for this user`,
|
|
266
|
-
);
|
|
267
|
-
/* eslint-enable no-console */
|
|
268
216
|
return;
|
|
269
217
|
}
|
|
270
218
|
try {
|
|
271
219
|
if (isLoggedIn === true) {
|
|
272
|
-
/* eslint-disable no-console */
|
|
273
|
-
console.log(
|
|
274
|
-
`[UserStorageManager:${instanceId.current}] Detected signed-in user, processing storage...`,
|
|
275
|
-
);
|
|
276
|
-
/* eslint-enable no-console */
|
|
277
|
-
|
|
278
220
|
if (
|
|
279
221
|
userID &&
|
|
280
222
|
userID !== null &&
|
|
@@ -285,26 +227,8 @@ const UserStorageManager = ({ children, onStorageManaged }) => {
|
|
|
285
227
|
const userData = localStorage.getItem(userKey);
|
|
286
228
|
const anonymousData = localStorage.getItem('user_anonymous');
|
|
287
229
|
|
|
288
|
-
/* eslint-disable no-console */
|
|
289
|
-
console.log(
|
|
290
|
-
`[UserStorageManager:${instanceId.current}] Storage analysis:`,
|
|
291
|
-
{
|
|
292
|
-
userKey,
|
|
293
|
-
hasUserData: !!userData,
|
|
294
|
-
hasAnonymousData: !!anonymousData,
|
|
295
|
-
sessionEmpty: sessionStorage.length === 0,
|
|
296
|
-
sessionLength: sessionStorage.length,
|
|
297
|
-
},
|
|
298
|
-
);
|
|
299
|
-
/* eslint-enable no-console */
|
|
300
|
-
|
|
301
230
|
// Migration and restoration logic for signed-in users
|
|
302
231
|
if (!userData && anonymousData) {
|
|
303
|
-
/* eslint-disable no-console */
|
|
304
|
-
console.log(
|
|
305
|
-
`[UserStorageManager:${instanceId.current}] Migrating anonymous data to signed-in user`,
|
|
306
|
-
);
|
|
307
|
-
/* eslint-enable no-console */
|
|
308
232
|
// Move anonymous data to the signed-in user's localStorage key
|
|
309
233
|
localStorage.setItem(userKey, anonymousData);
|
|
310
234
|
// Delete the anonymous key from localStorage
|
|
@@ -312,49 +236,18 @@ const UserStorageManager = ({ children, onStorageManaged }) => {
|
|
|
312
236
|
// Populate sessionStorage with the migrated data from localStorage
|
|
313
237
|
populateSessionFromUserData(userKey);
|
|
314
238
|
} else if (userData) {
|
|
315
|
-
/* eslint-disable no-console */
|
|
316
|
-
console.log(
|
|
317
|
-
`[UserStorageManager:${instanceId.current}] Found existing user data - restoring to session storage`,
|
|
318
|
-
);
|
|
319
|
-
/* eslint-enable no-console */
|
|
320
239
|
// User has existing saved data - restore it to sessionStorage
|
|
321
240
|
populateSessionFromUserData(userKey);
|
|
322
241
|
} else {
|
|
323
|
-
/* eslint-disable no-console */
|
|
324
|
-
console.log(
|
|
325
|
-
`[UserStorageManager:${instanceId.current}] No saved user data found - preserving current session state`,
|
|
326
|
-
);
|
|
327
|
-
/* eslint-enable no-console */
|
|
328
242
|
}
|
|
329
243
|
setStorageManaged(true);
|
|
330
244
|
} else {
|
|
331
|
-
/* eslint-disable no-console */
|
|
332
|
-
console.log(
|
|
333
|
-
`[UserStorageManager:${instanceId.current}] valid userID unavailable: userID is ${userID}`,
|
|
334
|
-
);
|
|
335
|
-
/* eslint-enable no-console */
|
|
336
245
|
}
|
|
337
246
|
} else if (isLoggedIn === false) {
|
|
338
|
-
/* eslint-disable no-console */
|
|
339
|
-
console.log(
|
|
340
|
-
`[UserStorageManager:${instanceId.current}] Detected anonymous user, processing storage...`,
|
|
341
|
-
);
|
|
342
|
-
/* eslint-enable no-console */
|
|
343
247
|
// Handle anonymous user session - restore anonymous data if it exists
|
|
344
248
|
const anonymousKey = 'user_anonymous';
|
|
345
249
|
const anonymousData = localStorage.getItem(anonymousKey);
|
|
346
250
|
if (anonymousData) {
|
|
347
|
-
/* eslint-disable no-console */
|
|
348
|
-
console.log(
|
|
349
|
-
`[UserStorageManager:${instanceId.current}] Restoring anonymous data to session storage:`,
|
|
350
|
-
{
|
|
351
|
-
dataPreview:
|
|
352
|
-
anonymousData.substring(0, 100) +
|
|
353
|
-
(anonymousData.length > 100 ? '...' : ''),
|
|
354
|
-
dataLength: anonymousData.length,
|
|
355
|
-
},
|
|
356
|
-
);
|
|
357
|
-
/* eslint-enable no-console */
|
|
358
251
|
sessionStorage.clear();
|
|
359
252
|
const parsed = JSON.parse(anonymousData);
|
|
360
253
|
Object.keys(parsed).forEach((k) =>
|
|
@@ -366,25 +259,10 @@ const UserStorageManager = ({ children, onStorageManaged }) => {
|
|
|
366
259
|
),
|
|
367
260
|
);
|
|
368
261
|
hasRestoredData.current = true;
|
|
369
|
-
/* eslint-disable no-console */
|
|
370
|
-
console.log(
|
|
371
|
-
`[UserStorageManager:${instanceId.current}] Anonymous data restored to sessionStorage`,
|
|
372
|
-
);
|
|
373
|
-
/* eslint-enable no-console */
|
|
374
262
|
} else {
|
|
375
|
-
/* eslint-disable no-console */
|
|
376
|
-
console.log(
|
|
377
|
-
`[UserStorageManager:${instanceId.current}] No anonymous data found to restore`,
|
|
378
|
-
);
|
|
379
|
-
/* eslint-enable no-console */
|
|
380
263
|
}
|
|
381
264
|
setStorageManaged(true);
|
|
382
265
|
} else {
|
|
383
|
-
/* eslint-disable no-console */
|
|
384
|
-
console.log(
|
|
385
|
-
`[UserStorageManager:${instanceId.current}] User state does not match any processing condition - skipping storage logic`,
|
|
386
|
-
);
|
|
387
|
-
/* eslint-enable no-console */
|
|
388
266
|
}
|
|
389
267
|
|
|
390
268
|
if (onStorageManaged) {
|
|
@@ -403,31 +281,13 @@ const UserStorageManager = ({ children, onStorageManaged }) => {
|
|
|
403
281
|
|
|
404
282
|
// Data-reactive effect - ensures sessionStorage mirrors localStorage whenever userData changes
|
|
405
283
|
// useEffect(() => {
|
|
406
|
-
//
|
|
407
|
-
// console.log(
|
|
408
|
-
// `[UserStorageManager:${instanceId.current}] Data-reactive effect triggered:`,
|
|
409
|
-
// {
|
|
410
|
-
// storageManaged,
|
|
411
|
-
// userKey: userKey,
|
|
412
|
-
// hasUserData: !!userData,
|
|
413
|
-
// userDataLength: userData ? userData.length : 0,
|
|
414
|
-
// },
|
|
415
|
-
// );
|
|
416
|
-
// /* eslint-enable no-console */
|
|
284
|
+
//
|
|
417
285
|
|
|
418
286
|
// if (storageManaged && userKey && userData) {
|
|
419
|
-
//
|
|
420
|
-
// console.log(
|
|
421
|
-
// `[UserStorageManager:${instanceId.current}] Re-syncing session storage with localStorage changes`,
|
|
422
|
-
// );
|
|
423
|
-
// /* eslint-enable no-console */
|
|
287
|
+
//
|
|
424
288
|
// populateSessionFromUserData(userKey);
|
|
425
289
|
// } else {
|
|
426
|
-
//
|
|
427
|
-
// console.log(
|
|
428
|
-
// `[UserStorageManager:${instanceId.current}] Skipping data sync - conditions not met`,
|
|
429
|
-
// );
|
|
430
|
-
// /* eslint-enable no-console */
|
|
290
|
+
//
|
|
431
291
|
// }
|
|
432
292
|
// }, [userData, userKey, storageManaged]);
|
|
433
293
|
|
|
@@ -504,14 +364,6 @@ class MapViewer extends React.Component {
|
|
|
504
364
|
|
|
505
365
|
// Method to handle user state changes from the monitoring wrapper
|
|
506
366
|
handleUserStateChange(newUserState, previousUserState) {
|
|
507
|
-
/* eslint-disable no-console */
|
|
508
|
-
console.log('[MapViewer] Handling user state change:', {
|
|
509
|
-
newUserState,
|
|
510
|
-
previousUserState,
|
|
511
|
-
currentState: this.state.currentUserState,
|
|
512
|
-
});
|
|
513
|
-
/* eslint-enable no-console */
|
|
514
|
-
|
|
515
367
|
// Update current user state in component state
|
|
516
368
|
this.setState({ currentUserState: newUserState });
|
|
517
369
|
|
|
@@ -522,27 +374,9 @@ class MapViewer extends React.Component {
|
|
|
522
374
|
// Enhanced method to save session data to localStorage with instance tracking
|
|
523
375
|
saveSessionToLocalStorage = () => {
|
|
524
376
|
const { user_id, isLoggedIn } = this.context;
|
|
525
|
-
const instanceId = this.instanceId || 'unknown';
|
|
526
|
-
|
|
527
|
-
/* eslint-disable no-console */
|
|
528
|
-
console.log(`[MapViewer:${instanceId}] Saving session data:`, {
|
|
529
|
-
hasUserContext:
|
|
530
|
-
user_id !== undefined && user_id !== null && user_id !== '',
|
|
531
|
-
isLoggedIn,
|
|
532
|
-
userId:
|
|
533
|
-
user_id !== undefined && user_id !== null && user_id !== ''
|
|
534
|
-
? user_id
|
|
535
|
-
: 'anonymous',
|
|
536
|
-
sessionStorageLength: sessionStorage.length,
|
|
537
|
-
});
|
|
538
|
-
/* eslint-enable no-console */
|
|
377
|
+
//const instanceId = this.instanceId || 'unknown';
|
|
539
378
|
|
|
540
379
|
if (sessionStorage.length === 0) {
|
|
541
|
-
/* eslint-disable no-console */
|
|
542
|
-
console.log(
|
|
543
|
-
`[MapViewer:${instanceId}] Skipping data save - session storage is empty`,
|
|
544
|
-
);
|
|
545
|
-
/* eslint-enable no-console */
|
|
546
380
|
return;
|
|
547
381
|
}
|
|
548
382
|
|
|
@@ -555,19 +389,7 @@ class MapViewer extends React.Component {
|
|
|
555
389
|
|
|
556
390
|
try {
|
|
557
391
|
localStorage.setItem(key, JSON.stringify(data));
|
|
558
|
-
|
|
559
|
-
console.log(
|
|
560
|
-
`[MapViewer:${instanceId}] Successfully saved data to localStorage key: ${key}`,
|
|
561
|
-
);
|
|
562
|
-
/* eslint-enable no-console */
|
|
563
|
-
} catch (error) {
|
|
564
|
-
/* eslint-disable no-console */
|
|
565
|
-
console.error(
|
|
566
|
-
`[MapViewer:${instanceId}] Error saving to localStorage key ${key}:`,
|
|
567
|
-
error,
|
|
568
|
-
);
|
|
569
|
-
/* eslint-enable no-console */
|
|
570
|
-
}
|
|
392
|
+
} catch (error) {}
|
|
571
393
|
};
|
|
572
394
|
|
|
573
395
|
// Save session data to appropriate localStorage key based on user state (always overwrite user key)
|
|
@@ -577,13 +399,6 @@ class MapViewer extends React.Component {
|
|
|
577
399
|
user_id !== null &&
|
|
578
400
|
user_id !== ''
|
|
579
401
|
) {
|
|
580
|
-
if (localStorage.getItem(`user_${user_id}`)) {
|
|
581
|
-
/* eslint-disable no-console */
|
|
582
|
-
console.log(
|
|
583
|
-
`[MapViewer:${instanceId}] User session data already exists in localStorage`,
|
|
584
|
-
);
|
|
585
|
-
/* eslint-enable no-console */
|
|
586
|
-
}
|
|
587
402
|
saveToLocal(`user_${user_id}`);
|
|
588
403
|
} else if (!isLoggedIn) {
|
|
589
404
|
saveToLocal('user_anonymous');
|
|
@@ -593,24 +408,12 @@ class MapViewer extends React.Component {
|
|
|
593
408
|
|
|
594
409
|
// Handle page unload events (navigation, refresh, close)
|
|
595
410
|
handlePageUnload = (event) => {
|
|
596
|
-
/* eslint-disable no-console */
|
|
597
|
-
console.log(
|
|
598
|
-
`[MapViewer:${this.instanceId}] Page unload detected, saving session data`,
|
|
599
|
-
);
|
|
600
|
-
/* eslint-enable no-console */
|
|
601
|
-
|
|
602
411
|
this.saveSessionToLocalStorage();
|
|
603
412
|
};
|
|
604
413
|
|
|
605
414
|
// Handle visibility changes (tab switches, window minimizing)
|
|
606
415
|
handleVisibilityChange = () => {
|
|
607
416
|
if (document.visibilityState === 'hidden') {
|
|
608
|
-
/* eslint-disable no-console */
|
|
609
|
-
console.log(
|
|
610
|
-
`[MapViewer:${this.instanceId}] Page hidden, saving session data`,
|
|
611
|
-
);
|
|
612
|
-
/* eslint-enable no-console */
|
|
613
|
-
|
|
614
417
|
this.saveSessionToLocalStorage();
|
|
615
418
|
}
|
|
616
419
|
};
|
|
@@ -623,15 +426,6 @@ class MapViewer extends React.Component {
|
|
|
623
426
|
isLoggedIn: prevIsLoggedIn,
|
|
624
427
|
} = previousUserState;
|
|
625
428
|
|
|
626
|
-
/* eslint-disable no-console */
|
|
627
|
-
console.log('[MapViewer] Processing session state update:', {
|
|
628
|
-
userIdChanged: prevUserId !== newUserId,
|
|
629
|
-
loginStateChanged: prevIsLoggedIn !== newIsLoggedIn,
|
|
630
|
-
loginTransition: `${prevIsLoggedIn} -> ${newIsLoggedIn}`,
|
|
631
|
-
userIdTransition: `${prevUserId} -> ${newUserId}`,
|
|
632
|
-
});
|
|
633
|
-
/* eslint-enable no-console */
|
|
634
|
-
|
|
635
429
|
// Handle login/logout transitions
|
|
636
430
|
if (prevIsLoggedIn !== newIsLoggedIn) {
|
|
637
431
|
if (newIsLoggedIn && !prevIsLoggedIn) {
|
|
@@ -651,18 +445,11 @@ class MapViewer extends React.Component {
|
|
|
651
445
|
|
|
652
446
|
// Handle user login - restore saved session or preserve current session
|
|
653
447
|
handleUserLogin(userId) {
|
|
654
|
-
/* eslint-disable no-console */
|
|
655
|
-
console.log('[MapViewer] User logged in:', userId);
|
|
656
|
-
/* eslint-enable no-console */
|
|
657
|
-
|
|
658
448
|
// Check if user has saved data
|
|
659
449
|
const userKey = `user_${userId}`;
|
|
660
450
|
const userData = localStorage.getItem(userKey);
|
|
661
451
|
|
|
662
452
|
if (userData) {
|
|
663
|
-
/* eslint-disable no-console */
|
|
664
|
-
console.log('[MapViewer] Restoring saved user session data');
|
|
665
|
-
/* eslint-enable no-console */
|
|
666
453
|
// Restore user's saved session
|
|
667
454
|
try {
|
|
668
455
|
const parsed = JSON.parse(userData);
|
|
@@ -674,27 +461,14 @@ class MapViewer extends React.Component {
|
|
|
674
461
|
: parsed[k],
|
|
675
462
|
),
|
|
676
463
|
);
|
|
677
|
-
} catch (error) {
|
|
678
|
-
/* eslint-disable no-console */
|
|
679
|
-
console.error('[MapViewer] Error restoring user session:', error);
|
|
680
|
-
/* eslint-enable no-console */
|
|
681
|
-
}
|
|
464
|
+
} catch (error) {}
|
|
682
465
|
} else {
|
|
683
|
-
/* eslint-disable no-console */
|
|
684
|
-
console.log(
|
|
685
|
-
'[MapViewer] No saved session found - preserving current session',
|
|
686
|
-
);
|
|
687
|
-
/* eslint-enable no-console */
|
|
688
466
|
// No saved data - preserve current session state
|
|
689
467
|
}
|
|
690
468
|
}
|
|
691
469
|
|
|
692
470
|
// Handle user logout - save current session to anonymous storage
|
|
693
471
|
handleUserLogout(prevUserId) {
|
|
694
|
-
/* eslint-disable no-console */
|
|
695
|
-
console.log('[MapViewer] User logged out:', prevUserId);
|
|
696
|
-
/* eslint-enable no-console */
|
|
697
|
-
|
|
698
472
|
// Save current session to anonymous storage
|
|
699
473
|
const sessionContents = {};
|
|
700
474
|
for (let i = 0; i < sessionStorage.length; i++) {
|
|
@@ -710,42 +484,16 @@ class MapViewer extends React.Component {
|
|
|
710
484
|
`user_${prevUserId}`,
|
|
711
485
|
JSON.stringify(sessionContents),
|
|
712
486
|
);
|
|
713
|
-
|
|
714
|
-
console.log(
|
|
715
|
-
'[MapViewer] Saved session to previous user key before logout',
|
|
716
|
-
);
|
|
717
|
-
/* eslint-enable no-console */
|
|
718
|
-
} catch (error) {
|
|
719
|
-
/* eslint-disable no-console */
|
|
720
|
-
console.error(
|
|
721
|
-
'[MapViewer] Error saving previous user session on logout:',
|
|
722
|
-
error,
|
|
723
|
-
);
|
|
724
|
-
/* eslint-enable no-console */
|
|
725
|
-
}
|
|
487
|
+
} catch (error) {}
|
|
726
488
|
}
|
|
727
489
|
try {
|
|
728
490
|
localStorage.setItem('user_anonymous', JSON.stringify(sessionContents));
|
|
729
|
-
|
|
730
|
-
console.log('[MapViewer] Saved session to anonymous storage');
|
|
731
|
-
/* eslint-enable no-console */
|
|
732
|
-
} catch (error) {
|
|
733
|
-
/* eslint-disable no-console */
|
|
734
|
-
console.error('[MapViewer] Error saving anonymous session:', error);
|
|
735
|
-
/* eslint-enable no-console */
|
|
736
|
-
}
|
|
491
|
+
} catch (error) {}
|
|
737
492
|
}
|
|
738
493
|
}
|
|
739
494
|
|
|
740
495
|
// Handle user account switching
|
|
741
496
|
handleUserSwitch(prevUserId, newUserId) {
|
|
742
|
-
/* eslint-disable no-console */
|
|
743
|
-
console.log('[MapViewer] User switched accounts:', {
|
|
744
|
-
prevUserId,
|
|
745
|
-
newUserId,
|
|
746
|
-
});
|
|
747
|
-
/* eslint-enable no-console */
|
|
748
|
-
|
|
749
497
|
// Save current session to previous user's storage
|
|
750
498
|
if (prevUserId) {
|
|
751
499
|
const sessionContents = {};
|
|
@@ -760,20 +508,7 @@ class MapViewer extends React.Component {
|
|
|
760
508
|
`user_${prevUserId}`,
|
|
761
509
|
JSON.stringify(sessionContents),
|
|
762
510
|
);
|
|
763
|
-
|
|
764
|
-
console.log(
|
|
765
|
-
'[MapViewer] Saved session for previous user:',
|
|
766
|
-
prevUserId,
|
|
767
|
-
);
|
|
768
|
-
/* eslint-enable no-console */
|
|
769
|
-
} catch (error) {
|
|
770
|
-
/* eslint-disable no-console */
|
|
771
|
-
console.error(
|
|
772
|
-
'[MapViewer] Error saving previous user session:',
|
|
773
|
-
error,
|
|
774
|
-
);
|
|
775
|
-
/* eslint-enable no-console */
|
|
776
|
-
}
|
|
511
|
+
} catch (error) {}
|
|
777
512
|
}
|
|
778
513
|
}
|
|
779
514
|
|
|
@@ -950,26 +685,8 @@ class MapViewer extends React.Component {
|
|
|
950
685
|
logo: false,
|
|
951
686
|
});
|
|
952
687
|
|
|
953
|
-
/* eslint-disable no-console */
|
|
954
|
-
console.log(
|
|
955
|
-
`[MapViewer:${this.instanceId}] Attempting to recover map state from sessionStorage`,
|
|
956
|
-
);
|
|
957
|
-
/* eslint-enable no-console */
|
|
958
|
-
|
|
959
688
|
mapStatus = this.recoverState();
|
|
960
689
|
|
|
961
|
-
/* eslint-disable no-console */
|
|
962
|
-
console.log(`[MapViewer:${this.instanceId}] Recovered mapStatus:`, {
|
|
963
|
-
isNull: mapStatus === null,
|
|
964
|
-
isUndefined: mapStatus === undefined,
|
|
965
|
-
type: typeof mapStatus,
|
|
966
|
-
hasZoom: mapStatus && mapStatus.zoom !== undefined,
|
|
967
|
-
hasCenter: mapStatus && mapStatus.center !== undefined,
|
|
968
|
-
entryCount: mapStatus ? Object.entries(mapStatus).length : 0,
|
|
969
|
-
mapStatus: mapStatus,
|
|
970
|
-
});
|
|
971
|
-
/* eslint-enable no-console */
|
|
972
|
-
|
|
973
690
|
// Improved condition check to prevent false positives that overwrite restored data
|
|
974
691
|
if (
|
|
975
692
|
mapStatus === null ||
|
|
@@ -979,12 +696,6 @@ class MapViewer extends React.Component {
|
|
|
979
696
|
mapStatus.center === undefined) ||
|
|
980
697
|
(typeof mapStatus === 'object' && Object.entries(mapStatus).length === 0)
|
|
981
698
|
) {
|
|
982
|
-
/* eslint-disable no-console */
|
|
983
|
-
console.log(
|
|
984
|
-
`[MapViewer:${this.instanceId}] No valid map state found - initializing with default configuration`,
|
|
985
|
-
);
|
|
986
|
-
/* eslint-enable no-console */
|
|
987
|
-
|
|
988
699
|
mapStatus = {};
|
|
989
700
|
mapStatus.zoom = this.mapCfg.zoom;
|
|
990
701
|
mapStatus.center = this.mapCfg.center;
|
|
@@ -993,11 +704,6 @@ class MapViewer extends React.Component {
|
|
|
993
704
|
this.setZoomState(this.mapCfg.zoom);
|
|
994
705
|
this.activeLayersHandler(this.mapCfg.activeLayers);
|
|
995
706
|
} else {
|
|
996
|
-
/* eslint-disable no-console */
|
|
997
|
-
console.log(
|
|
998
|
-
`[MapViewer:${this.instanceId}] Using restored map state from sessionStorage`,
|
|
999
|
-
);
|
|
1000
|
-
/* eslint-enable no-console */
|
|
1001
707
|
}
|
|
1002
708
|
|
|
1003
709
|
this.view = new MapView({
|
|
@@ -1057,11 +763,6 @@ class MapViewer extends React.Component {
|
|
|
1057
763
|
this.props.MapViewerConfig(flattenToAppURL(this.props.url));
|
|
1058
764
|
|
|
1059
765
|
// Add event listeners for page unload events to ensure data is saved
|
|
1060
|
-
/* eslint-disable no-console */
|
|
1061
|
-
console.log(
|
|
1062
|
-
`[MapViewer:${this.instanceId}] Adding page unload event listeners`,
|
|
1063
|
-
);
|
|
1064
|
-
/* eslint-enable no-console */
|
|
1065
766
|
|
|
1066
767
|
// beforeunload - most reliable for catching navigation away from page
|
|
1067
768
|
window.addEventListener('beforeunload', this.handlePageUnload);
|
|
@@ -1100,16 +801,6 @@ class MapViewer extends React.Component {
|
|
|
1100
801
|
prevUserState.user_id !== currentUserId ||
|
|
1101
802
|
prevUserState.isLoggedIn !== currentIsLoggedIn
|
|
1102
803
|
) {
|
|
1103
|
-
/* eslint-disable no-console */
|
|
1104
|
-
console.log(
|
|
1105
|
-
'[MapViewer] User state change detected in componentDidUpdate:',
|
|
1106
|
-
{
|
|
1107
|
-
previous: prevUserState,
|
|
1108
|
-
current: { user_id: currentUserId, isLoggedIn: currentIsLoggedIn },
|
|
1109
|
-
},
|
|
1110
|
-
);
|
|
1111
|
-
/* eslint-enable no-console */
|
|
1112
|
-
|
|
1113
804
|
// Update component state to reflect new user state
|
|
1114
805
|
const newUserState = {
|
|
1115
806
|
user_id: currentUserId,
|
|
@@ -1123,11 +814,6 @@ class MapViewer extends React.Component {
|
|
|
1123
814
|
}
|
|
1124
815
|
|
|
1125
816
|
componentWillUnmount() {
|
|
1126
|
-
// Remove event listeners to prevent memory leaks
|
|
1127
|
-
/* eslint-disable no-console */
|
|
1128
|
-
console.log(`[MapViewer:${this.instanceId}] Removing event listeners`);
|
|
1129
|
-
/* eslint-enable no-console */
|
|
1130
|
-
|
|
1131
817
|
window.removeEventListener('beforeunload', this.handlePageUnload);
|
|
1132
818
|
window.removeEventListener('pagehide', this.handlePageUnload);
|
|
1133
819
|
document.removeEventListener(
|
|
@@ -1138,12 +824,6 @@ class MapViewer extends React.Component {
|
|
|
1138
824
|
// Save data using the extracted method
|
|
1139
825
|
this.saveSessionToLocalStorage();
|
|
1140
826
|
|
|
1141
|
-
/* eslint-disable no-console */
|
|
1142
|
-
console.log(
|
|
1143
|
-
`[MapViewer:${this.instanceId}] Clearing session storage and cleaning up view`,
|
|
1144
|
-
);
|
|
1145
|
-
/* eslint-enable no-console */
|
|
1146
|
-
|
|
1147
827
|
if (this.view) {
|
|
1148
828
|
this.view.container = null;
|
|
1149
829
|
this.view.destroy();
|
|
@@ -634,7 +634,6 @@ class MenuWidget extends React.Component {
|
|
|
634
634
|
let promise = fetch(dataset.ViewService, { mode: 'no-cors' })
|
|
635
635
|
.then((response) => {
|
|
636
636
|
if (!response.ok) {
|
|
637
|
-
//console.error(`HTTP error, status = ${response.status}`);
|
|
638
637
|
return null;
|
|
639
638
|
}
|
|
640
639
|
return response.json();
|
|
@@ -645,9 +644,7 @@ class MenuWidget extends React.Component {
|
|
|
645
644
|
dataset.Layer = data.Layers;
|
|
646
645
|
}
|
|
647
646
|
})
|
|
648
|
-
.catch((error) => {
|
|
649
|
-
//console.error(error);
|
|
650
|
-
});
|
|
647
|
+
.catch((error) => {});
|
|
651
648
|
promises.push(promise);
|
|
652
649
|
}
|
|
653
650
|
});
|
|
@@ -1093,7 +1090,6 @@ class MenuWidget extends React.Component {
|
|
|
1093
1090
|
let button = familyDropdown.querySelector(
|
|
1094
1091
|
'.ccl-expandable__button',
|
|
1095
1092
|
);
|
|
1096
|
-
scrollPosition = familyDropdown.offsetTop;
|
|
1097
1093
|
if (button) {
|
|
1098
1094
|
button.setAttribute('aria-expanded', 'true');
|
|
1099
1095
|
}
|
|
@@ -1107,6 +1103,9 @@ class MenuWidget extends React.Component {
|
|
|
1107
1103
|
button.setAttribute('aria-expanded', 'true');
|
|
1108
1104
|
}
|
|
1109
1105
|
}
|
|
1106
|
+
if (familyDropdown) {
|
|
1107
|
+
scrollPosition = familyDropdown.offsetTop;
|
|
1108
|
+
}
|
|
1110
1109
|
let mapMenu = node.closest('.map-menu-dataset-dropdown');
|
|
1111
1110
|
if (mapMenu) {
|
|
1112
1111
|
scrollPosition = mapMenu.offsetTop;
|
|
@@ -2928,6 +2927,43 @@ class MenuWidget extends React.Component {
|
|
|
2928
2927
|
this.map.reorder(nuts, this.map.layers.items.length + 1);
|
|
2929
2928
|
}
|
|
2930
2929
|
if (!userService) this.checkForHotspots(elem, productContainerId);
|
|
2930
|
+
// Auto-fit extent once for OGC WMS layers on manual toggle
|
|
2931
|
+
try {
|
|
2932
|
+
const layer = this.layers[elem.id];
|
|
2933
|
+
const viewService = layer?.ViewService || '';
|
|
2934
|
+
if (
|
|
2935
|
+
viewService &&
|
|
2936
|
+
viewService.toLowerCase().includes('wms') &&
|
|
2937
|
+
viewService.toLowerCase().includes('/ogc/') &&
|
|
2938
|
+
!layer._ogcExtentApplied &&
|
|
2939
|
+
!this.extentInitiated
|
|
2940
|
+
) {
|
|
2941
|
+
let url;
|
|
2942
|
+
const serviceLayer = this.state.wmsUserServiceLayers.find(
|
|
2943
|
+
(l) => l.LayerId === elem.id,
|
|
2944
|
+
);
|
|
2945
|
+
if (!serviceLayer) {
|
|
2946
|
+
this.findCheckedDataset(elem);
|
|
2947
|
+
url = this.url;
|
|
2948
|
+
} else {
|
|
2949
|
+
url = serviceLayer.ViewService;
|
|
2950
|
+
}
|
|
2951
|
+
if (url) {
|
|
2952
|
+
await this.getCapabilities(url, 'wms');
|
|
2953
|
+
const BBoxes = this.parseBBOXCDSE(this.xml);
|
|
2954
|
+
if (BBoxes && BBoxes['dataset']) {
|
|
2955
|
+
const myExtent = new Extent({
|
|
2956
|
+
xmin: BBoxes['dataset'].xmin,
|
|
2957
|
+
ymin: BBoxes['dataset'].ymin,
|
|
2958
|
+
xmax: BBoxes['dataset'].xmax,
|
|
2959
|
+
ymax: BBoxes['dataset'].ymax,
|
|
2960
|
+
});
|
|
2961
|
+
this.view.goTo(myExtent);
|
|
2962
|
+
layer._ogcExtentApplied = true;
|
|
2963
|
+
}
|
|
2964
|
+
}
|
|
2965
|
+
}
|
|
2966
|
+
} catch (e) {}
|
|
2931
2967
|
} else {
|
|
2932
2968
|
sessionStorage.removeItem('downloadButtonClicked');
|
|
2933
2969
|
sessionStorage.removeItem('timeSliderTag');
|
|
@@ -3382,6 +3418,73 @@ class MenuWidget extends React.Component {
|
|
|
3382
3418
|
return BBoxes;
|
|
3383
3419
|
}
|
|
3384
3420
|
|
|
3421
|
+
parseBBOXCDSE(xml) {
|
|
3422
|
+
if (!xml || typeof xml.getElementsByTagName !== 'function') return {};
|
|
3423
|
+
const all = Array.from(xml.getElementsByTagName('*'));
|
|
3424
|
+
const isLayer = (n) => n && (n.localName || '').toLowerCase() === 'layer';
|
|
3425
|
+
const layers = all.filter(isLayer);
|
|
3426
|
+
if (!layers.length) return {};
|
|
3427
|
+
const hasChildLayer = (el) => {
|
|
3428
|
+
const cs = el ? el.children : null;
|
|
3429
|
+
if (!cs) return false;
|
|
3430
|
+
for (let i = 0; i < cs.length; i++) if (isLayer(cs[i])) return true;
|
|
3431
|
+
return false;
|
|
3432
|
+
};
|
|
3433
|
+
const findDesc = (el, nameLower) => {
|
|
3434
|
+
if (!el) return null;
|
|
3435
|
+
const it = el.getElementsByTagName('*');
|
|
3436
|
+
for (let i = 0; i < it.length; i++) {
|
|
3437
|
+
const n = it[i];
|
|
3438
|
+
if ((n.localName || '').toLowerCase() === nameLower) return n;
|
|
3439
|
+
}
|
|
3440
|
+
return null;
|
|
3441
|
+
};
|
|
3442
|
+
const leaves = layers.filter((n) => !hasChildLayer(n));
|
|
3443
|
+
if (!leaves.length) return {};
|
|
3444
|
+
const boxes = {};
|
|
3445
|
+
const xs = [];
|
|
3446
|
+
const ys = [];
|
|
3447
|
+
for (let i = 0; i < leaves.length; i++) {
|
|
3448
|
+
const leaf = leaves[i];
|
|
3449
|
+
const nameEl = findDesc(leaf, 'name');
|
|
3450
|
+
const name =
|
|
3451
|
+
nameEl && nameEl.textContent ? nameEl.textContent.trim() : '';
|
|
3452
|
+
if (!name) continue;
|
|
3453
|
+
let bb = findDesc(leaf, 'boundingbox');
|
|
3454
|
+
if (!bb) {
|
|
3455
|
+
let p = leaf.parentElement;
|
|
3456
|
+
while (p) {
|
|
3457
|
+
if (isLayer(p)) {
|
|
3458
|
+
const cand = findDesc(p, 'boundingbox');
|
|
3459
|
+
if (cand) {
|
|
3460
|
+
bb = cand;
|
|
3461
|
+
break;
|
|
3462
|
+
}
|
|
3463
|
+
}
|
|
3464
|
+
p = p.parentElement;
|
|
3465
|
+
}
|
|
3466
|
+
}
|
|
3467
|
+
if (!bb) continue;
|
|
3468
|
+
const w = parseFloat(bb.getAttribute('minx') || '');
|
|
3469
|
+
const s = parseFloat(bb.getAttribute('miny') || '');
|
|
3470
|
+
const e = parseFloat(bb.getAttribute('maxx') || '');
|
|
3471
|
+
const n = parseFloat(bb.getAttribute('maxy') || '');
|
|
3472
|
+
if (!isFinite(w) || !isFinite(s) || !isFinite(e) || !isFinite(n))
|
|
3473
|
+
continue;
|
|
3474
|
+
boxes[name] = { xmin: w, ymin: s, xmax: e, ymax: n };
|
|
3475
|
+
xs.push(w, e);
|
|
3476
|
+
ys.push(s, n);
|
|
3477
|
+
}
|
|
3478
|
+
if (!Object.keys(boxes).length) return {};
|
|
3479
|
+
boxes.dataset = {
|
|
3480
|
+
xmin: Math.min.apply(Math, xs),
|
|
3481
|
+
ymin: Math.min.apply(Math, ys),
|
|
3482
|
+
xmax: Math.max.apply(Math, xs),
|
|
3483
|
+
ymax: Math.max.apply(Math, ys),
|
|
3484
|
+
};
|
|
3485
|
+
return boxes;
|
|
3486
|
+
}
|
|
3487
|
+
|
|
3385
3488
|
parseBBOXWMS(xml) {
|
|
3386
3489
|
const layerParentNode = xml.querySelectorAll('Layer');
|
|
3387
3490
|
let layersChildren = Array.from(layerParentNode).filter(
|
|
@@ -3600,18 +3703,20 @@ class MenuWidget extends React.Component {
|
|
|
3600
3703
|
const serviceLayer = this.state.wmsUserServiceLayers.find(
|
|
3601
3704
|
(layer) => layer.LayerId === elem.id,
|
|
3602
3705
|
);
|
|
3603
|
-
|
|
3604
3706
|
if (!serviceLayer) {
|
|
3605
3707
|
this.findCheckedDataset(elem);
|
|
3606
3708
|
} else {
|
|
3607
3709
|
this.url = serviceLayer.ViewService;
|
|
3608
3710
|
}
|
|
3711
|
+
let isCDSE = this.url?.toLowerCase().includes('/ogc/') ? true : false;
|
|
3609
3712
|
let BBoxes = {};
|
|
3610
3713
|
if (this.url?.toLowerCase().endsWith('mapserver')) {
|
|
3611
3714
|
BBoxes = await this.parseBBOXMAPSERVER(this.layers[elem.id]);
|
|
3612
3715
|
} else if (this.url?.toLowerCase().includes('wms') || serviceLayer) {
|
|
3613
3716
|
await this.getCapabilities(this.url, 'wms');
|
|
3614
|
-
BBoxes =
|
|
3717
|
+
BBoxes = isCDSE
|
|
3718
|
+
? this.parseBBOXCDSE(this.xml)
|
|
3719
|
+
: this.parseBBOXWMS(this.xml);
|
|
3615
3720
|
} else if (this.url?.toLowerCase().includes('wmts')) {
|
|
3616
3721
|
await this.getCapabilities(this.url, 'wmts');
|
|
3617
3722
|
BBoxes = this.parseBBOXWMTS(this.xml);
|
|
@@ -3634,6 +3739,32 @@ class MenuWidget extends React.Component {
|
|
|
3634
3739
|
// spatialReference: 4326 // by default wkid 4326
|
|
3635
3740
|
});
|
|
3636
3741
|
}
|
|
3742
|
+
if (isCDSE) {
|
|
3743
|
+
const maxMppAllowed = 23628.54;
|
|
3744
|
+
const vw = this.view && this.view.width ? this.view.width : 0;
|
|
3745
|
+
const vh = this.view && this.view.height ? this.view.height : 0;
|
|
3746
|
+
let extentWM = myExtent;
|
|
3747
|
+
try {
|
|
3748
|
+
if (
|
|
3749
|
+
!(
|
|
3750
|
+
myExtent.spatialReference && myExtent.spatialReference.wkid === 3857
|
|
3751
|
+
)
|
|
3752
|
+
) {
|
|
3753
|
+
extentWM = WebMercatorUtils.geographicToWebMercator(myExtent);
|
|
3754
|
+
}
|
|
3755
|
+
} catch (e) {}
|
|
3756
|
+
if (vw > 0 && vh > 0) {
|
|
3757
|
+
const mppX = (extentWM.xmax - extentWM.xmin) / vw;
|
|
3758
|
+
const mppY = (extentWM.ymax - extentWM.ymin) / vh;
|
|
3759
|
+
const mpp = Math.max(mppX, mppY);
|
|
3760
|
+
if (mpp > maxMppAllowed) {
|
|
3761
|
+
const cx = (myExtent.xmin + myExtent.xmax) / 2;
|
|
3762
|
+
const cy = (myExtent.ymin + myExtent.ymax) / 2;
|
|
3763
|
+
this.view.goTo({ center: [cx, cy], zoom: 3 });
|
|
3764
|
+
return;
|
|
3765
|
+
}
|
|
3766
|
+
}
|
|
3767
|
+
}
|
|
3637
3768
|
this.view.goTo(myExtent); //
|
|
3638
3769
|
}
|
|
3639
3770
|
|
|
@@ -3692,7 +3823,10 @@ class MenuWidget extends React.Component {
|
|
|
3692
3823
|
BBoxes = await this.parseBBOXMAPSERVER(this.layers[elem.id]);
|
|
3693
3824
|
} else if (this.url?.toLowerCase().includes('wms') || serviceLayer) {
|
|
3694
3825
|
await this.getCapabilities(this.url, 'wms');
|
|
3695
|
-
|
|
3826
|
+
if (this.url?.toLowerCase().includes('/ogc/')) {
|
|
3827
|
+
} else {
|
|
3828
|
+
BBoxes = this.parseBBOXWMS(this.xml);
|
|
3829
|
+
}
|
|
3696
3830
|
} else if (this.url?.toLowerCase().includes('wmts')) {
|
|
3697
3831
|
await this.getCapabilities(this.url, 'wmts');
|
|
3698
3832
|
BBoxes = this.parseBBOXWMTS(this.xml);
|