structra-ui 0.2.52 → 0.2.53

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.
@@ -1285,8 +1285,62 @@ const SUBMENU_OPEN_MS = 200;
1285
1285
  * não fica no DOM do trigger) sem fechar; emparelha com a sobreposição de posição.
1286
1286
  */
1287
1287
  const SUBMENU_CLOSE_MS = 1200;
1288
- /** Abrir/fechar de grupos na sidebar — sobrevive à navegação SPA até ao refresh. */
1288
+ /** Prefixo das chaves em `sessionStorage` (`<prefix>:<menuId>`). */
1289
1289
  const MENU_GROUP_EXPANSION_STORAGE_PREFIX = 'structra.menuGroups';
1290
+ /**
1291
+ * `PerformanceNavigationTiming.type` mantém-se `reload` durante **toda** a vida do documento após F5;
1292
+ * por isso só tratamos o reload **uma vez** por carga — senão cada `loadPersistedGroupExpansion` apagaria o estado na SPA.
1293
+ */
1294
+ let menuGroupExpansionReloadPurgeChecked = false;
1295
+ function isFullPageReloadNavigationType() {
1296
+ try {
1297
+ const entries = performance.getEntriesByType?.('navigation');
1298
+ const nav = entries?.[0];
1299
+ if (nav?.type === 'reload') {
1300
+ return true;
1301
+ }
1302
+ }
1303
+ catch {
1304
+ /* ignore */
1305
+ }
1306
+ try {
1307
+ const legacy = performance.navigation;
1308
+ /** Legacy `PerformanceNavigation.TYPE_RELOAD` === 1 */
1309
+ return legacy?.type === 1;
1310
+ }
1311
+ catch {
1312
+ return false;
1313
+ }
1314
+ }
1315
+ /** Uma vez por documento: em recarga total (F5), remover todas as chaves `structra.menuGroups:*`. */
1316
+ function purgeMenuGroupExpansionStorageAfterReload() {
1317
+ if (menuGroupExpansionReloadPurgeChecked) {
1318
+ return;
1319
+ }
1320
+ menuGroupExpansionReloadPurgeChecked = true;
1321
+ if (typeof sessionStorage === 'undefined') {
1322
+ return;
1323
+ }
1324
+ if (!isFullPageReloadNavigationType()) {
1325
+ return;
1326
+ }
1327
+ try {
1328
+ const prefix = `${MENU_GROUP_EXPANSION_STORAGE_PREFIX}:`;
1329
+ const toRemove = [];
1330
+ for (let i = 0; i < sessionStorage.length; i++) {
1331
+ const k = sessionStorage.key(i);
1332
+ if (k?.startsWith(prefix)) {
1333
+ toRemove.push(k);
1334
+ }
1335
+ }
1336
+ for (const k of toRemove) {
1337
+ sessionStorage.removeItem(k);
1338
+ }
1339
+ }
1340
+ catch {
1341
+ /* quota / modo privado */
1342
+ }
1343
+ }
1290
1344
  class MenuListBodyComponent {
1291
1345
  constructor(cdr, hostRef) {
1292
1346
  /** Igual a `[appTheme]` na lib; omitir = tema global (ex.: propagado por `app-sidebar`). */
@@ -1325,7 +1379,8 @@ class MenuListBodyComponent {
1325
1379
  this.groupDefaultExpansion = 'all';
1326
1380
  /**
1327
1381
  * Quando `true`, grava em `sessionStorage` o estado dos grupos colapsáveis (por `menuId`)
1328
- * para restaurar após troca de rota / remount do componente.
1382
+ * para restaurar após troca de rota / remount na mesma carga da página.
1383
+ * Em **recarga completa** (F5 / refresh), o estado gravado é ignorado e removido — voltam os defaults do modelo.
1329
1384
  */
1330
1385
  this.persistGroupExpansion = true;
1331
1386
  /**
@@ -1528,6 +1583,7 @@ class MenuListBodyComponent {
1528
1583
  if (!this.persistGroupExpansion || typeof sessionStorage === 'undefined') {
1529
1584
  return null;
1530
1585
  }
1586
+ purgeMenuGroupExpansionStorageAfterReload();
1531
1587
  try {
1532
1588
  const raw = sessionStorage.getItem(this.groupExpansionStorageKey());
1533
1589
  if (!raw) {
@@ -10078,8 +10134,8 @@ class MenuListComponent {
10078
10134
  /** Repasse para {@link MenuListBodyComponent.groupDefaultExpansion}. */
10079
10135
  this.groupDefaultExpansion = 'all';
10080
10136
  /**
10081
- * Quando `true` (omissão), abrir/fechar grupos colapsáveis persiste em `sessionStorage`
10082
- * até ao refresh da página útil na navegação SPA da sidebar.
10137
+ * Quando `true` (omissão), o estado aberto/fechado persiste em `sessionStorage` entre rotas
10138
+ * na mesma carga; após **recarga completa** (F5), repõe-se aos defaults do modelo.
10083
10139
  */
10084
10140
  this.persistGroupExpansion = true;
10085
10141
  this.searchable = false;