@acorex-platform/framework-client 2.0.0-next.26 → 2.0.0-next.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.
Files changed (33) hide show
  1. package/fesm2022/acorex-platform-framework-client-common.mjs +558 -106
  2. package/fesm2022/acorex-platform-framework-client-common.mjs.map +1 -1
  3. package/fesm2022/{acorex-platform-framework-client-layout-entity-acorex-platform-framework-client-layout-entity-BTLgOdQN.mjs → acorex-platform-framework-client-layout-entity-acorex-platform-framework-client-layout-entity-DmkFxSuJ.mjs} +13 -11
  4. package/fesm2022/acorex-platform-framework-client-layout-entity-acorex-platform-framework-client-layout-entity-DmkFxSuJ.mjs.map +1 -0
  5. package/fesm2022/{acorex-platform-framework-client-layout-entity-attachments-page.component-DH2Wq7ux.mjs → acorex-platform-framework-client-layout-entity-attachments-page.component-BV5WLQVo.mjs} +2 -2
  6. package/fesm2022/{acorex-platform-framework-client-layout-entity-attachments-page.component-DH2Wq7ux.mjs.map → acorex-platform-framework-client-layout-entity-attachments-page.component-BV5WLQVo.mjs.map} +1 -1
  7. package/fesm2022/{acorex-platform-framework-client-layout-entity-bulk-entity.command-DMgR7yq0.mjs → acorex-platform-framework-client-layout-entity-bulk-entity.command-O8zdiHRH.mjs} +2 -2
  8. package/fesm2022/{acorex-platform-framework-client-layout-entity-bulk-entity.command-DMgR7yq0.mjs.map → acorex-platform-framework-client-layout-entity-bulk-entity.command-O8zdiHRH.mjs.map} +1 -1
  9. package/fesm2022/{acorex-platform-framework-client-layout-entity-file-list-popup.component-DLt5p2Iy.mjs → acorex-platform-framework-client-layout-entity-file-list-popup.component-B3-0gJTQ.mjs} +2 -2
  10. package/fesm2022/{acorex-platform-framework-client-layout-entity-file-list-popup.component-DLt5p2Iy.mjs.map → acorex-platform-framework-client-layout-entity-file-list-popup.component-B3-0gJTQ.mjs.map} +1 -1
  11. package/fesm2022/{acorex-platform-framework-client-layout-entity-gallery-page.component-C_JIijQZ.mjs → acorex-platform-framework-client-layout-entity-gallery-page.component-CjfLUBPZ.mjs} +2 -2
  12. package/fesm2022/{acorex-platform-framework-client-layout-entity-gallery-page.component-C_JIijQZ.mjs.map → acorex-platform-framework-client-layout-entity-gallery-page.component-CjfLUBPZ.mjs.map} +1 -1
  13. package/fesm2022/acorex-platform-framework-client-layout-entity.mjs +1 -1
  14. package/fesm2022/acorex-platform-framework-client-layout-views.mjs +24 -8
  15. package/fesm2022/acorex-platform-framework-client-layout-views.mjs.map +1 -1
  16. package/fesm2022/{acorex-platform-framework-client-themes-default-error-401.component-1lfBpY_d.mjs → acorex-platform-framework-client-themes-default-error-401.component-DszlyIaw.mjs} +5 -11
  17. package/fesm2022/acorex-platform-framework-client-themes-default-error-401.component-DszlyIaw.mjs.map +1 -0
  18. package/fesm2022/{acorex-platform-framework-client-themes-default-error-404.component-BeWyRCJr.mjs → acorex-platform-framework-client-themes-default-error-404.component-BusKNAit.mjs} +5 -11
  19. package/fesm2022/acorex-platform-framework-client-themes-default-error-404.component-BusKNAit.mjs.map +1 -0
  20. package/fesm2022/{acorex-platform-framework-client-themes-default-error-offline.component-PvveUj5c.mjs → acorex-platform-framework-client-themes-default-error-offline.component-Abf14p44.mjs} +15 -4
  21. package/fesm2022/acorex-platform-framework-client-themes-default-error-offline.component-Abf14p44.mjs.map +1 -0
  22. package/fesm2022/acorex-platform-framework-client-themes-default-error-page-go-home-B9VmB9Vt.mjs +19 -0
  23. package/fesm2022/acorex-platform-framework-client-themes-default-error-page-go-home-B9VmB9Vt.mjs.map +1 -0
  24. package/fesm2022/acorex-platform-framework-client-themes-default.mjs +15 -6
  25. package/fesm2022/acorex-platform-framework-client-themes-default.mjs.map +1 -1
  26. package/fesm2022/acorex-platform-framework-client-themes-shared.mjs +10 -4
  27. package/fesm2022/acorex-platform-framework-client-themes-shared.mjs.map +1 -1
  28. package/package.json +2 -2
  29. package/types/acorex-platform-framework-client-common.d.ts +122 -7
  30. package/fesm2022/acorex-platform-framework-client-layout-entity-acorex-platform-framework-client-layout-entity-BTLgOdQN.mjs.map +0 -1
  31. package/fesm2022/acorex-platform-framework-client-themes-default-error-401.component-1lfBpY_d.mjs.map +0 -1
  32. package/fesm2022/acorex-platform-framework-client-themes-default-error-404.component-BeWyRCJr.mjs.map +0 -1
  33. package/fesm2022/acorex-platform-framework-client-themes-default-error-offline.component-PvveUj5c.mjs.map +0 -1
@@ -34,7 +34,7 @@ import { AXProgressBarModule } from '@acorex/components/progress-bar';
34
34
  import * as i3$1 from '@acorex/core/format';
35
35
  import { AXFormatModule, AXFormatService } from '@acorex/core/format';
36
36
  import { AXNotificationService, AXNotificationModule } from '@acorex/components/notification';
37
- import { filter as filter$1 } from 'rxjs/operators';
37
+ import { filter as filter$1, map as map$1, distinctUntilChanged as distinctUntilChanged$1 } from 'rxjs/operators';
38
38
  import { signalStore, withState, withMethods, patchState, withHooks } from '@ngrx/signals';
39
39
  import { AXPopupService, AXPopupModule } from '@acorex/components/popup';
40
40
  import { AXToastModule, AXToastService } from '@acorex/components/toast';
@@ -3917,6 +3917,10 @@ class AXPTabRouteCacheRegistry {
3917
3917
  this.openKeys = new Set();
3918
3918
  this.enabled = false;
3919
3919
  this.deactivateGuardSuspended = false;
3920
+ /** While true, cached pages stay stored but must not be attached to a navigation. */
3921
+ this.attachSuspended = false;
3922
+ /** Session that owns cached pages. Null means signed out: never keep another user's components. */
3923
+ this.ownerKey = null;
3920
3924
  }
3921
3925
  //#endregion
3922
3926
  //#region ---- Deactivate Guard Suspension ----
@@ -3940,6 +3944,35 @@ class AXPTabRouteCacheRegistry {
3940
3944
  }
3941
3945
  //#endregion
3942
3946
  //#region ---- Mode ----
3947
+ /** True while a signed-in session may keep detached pages. */
3948
+ canCache() {
3949
+ return this.ownerKey !== null;
3950
+ }
3951
+ /** True while a session transition must not reattach a cached page. */
3952
+ isAttachSuspended() {
3953
+ return this.attachSuspended;
3954
+ }
3955
+ /**
3956
+ * Keeps cached pages for a failed switch, but blocks attaching them until the transition settles.
3957
+ */
3958
+ suspendAttach() {
3959
+ this.attachSuspended = true;
3960
+ }
3961
+ /** Allows attach again. Does not destroy the stored pages. */
3962
+ resumeAttach() {
3963
+ this.attachSuspended = false;
3964
+ }
3965
+ /**
3966
+ * Binds cached pages to one session. A sign-out or a different user destroys every cached
3967
+ * component so the next session cannot reattach the previous user's data.
3968
+ */
3969
+ bindOwner(ownerKey) {
3970
+ if (this.ownerKey === ownerKey) {
3971
+ return;
3972
+ }
3973
+ this.ownerKey = ownerKey;
3974
+ this.clear();
3975
+ }
3943
3976
  /** Enables caching (tabular mode). Disabling clears and destroys every cached component. */
3944
3977
  setEnabled(enabled) {
3945
3978
  if (this.enabled === enabled) {
@@ -4007,6 +4040,10 @@ class AXPTabRouteCacheRegistry {
4007
4040
  * destroying the old one would destroy the live component and corrupt the view (NG0922).
4008
4041
  */
4009
4042
  store(key, handle) {
4043
+ if (!this.ownerKey) {
4044
+ this.destroyHandle(handle);
4045
+ return;
4046
+ }
4010
4047
  this.handles.set(key, handle);
4011
4048
  }
4012
4049
  /**
@@ -4016,6 +4053,9 @@ class AXPTabRouteCacheRegistry {
4016
4053
  * `store(snapshot, null)`.
4017
4054
  */
4018
4055
  retrieve(key) {
4056
+ if (this.attachSuspended) {
4057
+ return null;
4058
+ }
4019
4059
  return this.handles.get(key) ?? null;
4020
4060
  }
4021
4061
  /**
@@ -7373,6 +7413,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
7373
7413
  function axpMenuItemNeedsUpdate(item, updates) {
7374
7414
  return Object.keys(updates).some((key) => item[key] !== updates[key]);
7375
7415
  }
7416
+ /** True when the menu command itself navigates. A path on the same item must not navigate again. */
7417
+ function axpMenuCommandIsNavigation(command) {
7418
+ if (!command || typeof command !== 'object') {
7419
+ return false;
7420
+ }
7421
+ if ('type' in command && command.type === 'router') {
7422
+ return true;
7423
+ }
7424
+ return 'name' in command && command.name === 'navigate';
7425
+ }
7376
7426
  /** Immutably patches the first menu item with the given name. */
7377
7427
  function axpUpdateMenuItemByName(items, name, updates) {
7378
7428
  let changed = false;
@@ -7446,18 +7496,22 @@ withMethods((store, router = inject(Router), commandService = inject(AXPCommandS
7446
7496
  });
7447
7497
  },
7448
7498
  executeCommand(item) {
7449
- if (item.path) {
7450
- const path = item.name
7499
+ const path = item.path
7500
+ ? item.name
7451
7501
  ? axpEnsureEntityListInstanceQueryParam(item.path, item.name)
7452
- : item.path;
7502
+ : item.path
7503
+ : undefined;
7504
+ if (path) {
7453
7505
  void commandService.execute('navigate', { path });
7454
7506
  patchState(store, { selectedMenuItem: { item, isFullMatch: true } });
7455
7507
  }
7456
- if (item.command) {
7457
- const command = item.command;
7458
- if (commandService.exists(command?.name)) {
7459
- void commandService.execute(command.name, command.options ?? {});
7460
- }
7508
+ const command = item.command;
7509
+ if (!command || (path && axpMenuCommandIsNavigation(command))) {
7510
+ return;
7511
+ }
7512
+ const executeCommand = command;
7513
+ if (executeCommand.name && commandService.exists(executeCommand.name)) {
7514
+ void commandService.execute(executeCommand.name, executeCommand.options ?? {});
7461
7515
  }
7462
7516
  },
7463
7517
  isItemOpen(item) {
@@ -7622,6 +7676,73 @@ function axpFallbackTabTitle(url) {
7622
7676
  }
7623
7677
  //#endregion
7624
7678
 
7679
+ //#region ---- Constants ----
7680
+ /** Query param that keeps the failed route as the tab identity. */
7681
+ const AXP_IN_TAB_ERROR_FROM_PARAM = 'from';
7682
+ const IN_TAB_ERROR_PATHS = new Set(['/error/401', '/error/404', '/error/offline', '/401', '/404']);
7683
+ //#endregion
7684
+ //#region ---- URL Helpers ----
7685
+ /**
7686
+ * Original page URL carried on an in-shell error route.
7687
+ * Null when the URL is not an error page or `from` is missing.
7688
+ */
7689
+ function axpInTabErrorSourceUrl(url) {
7690
+ const normalized = normalizeRouterUrl(url);
7691
+ const pathOnly = normalized.split('?')[0].split('#')[0];
7692
+ if (!IN_TAB_ERROR_PATHS.has(pathOnly)) {
7693
+ return null;
7694
+ }
7695
+ const params = new URLSearchParams(normalized.split('?')[1] ?? '');
7696
+ const from = params.get(AXP_IN_TAB_ERROR_FROM_PARAM);
7697
+ if (!from?.startsWith('/')) {
7698
+ return null;
7699
+ }
7700
+ const fromPath = from.split('?')[0].split('#')[0];
7701
+ if (IN_TAB_ERROR_PATHS.has(fromPath)) {
7702
+ return null;
7703
+ }
7704
+ return normalizeRouterUrl(from);
7705
+ }
7706
+ /** URL a tab should open again. An in-tab error page retries its `from` route. */
7707
+ function axpInTabErrorRetryUrl(url) {
7708
+ return axpInTabErrorSourceUrl(url) ?? normalizeRouterUrl(url);
7709
+ }
7710
+ /** In-shell error URL whose tab identity is `sourceUrl`, not a single app-wide error route. */
7711
+ function axpInTabErrorLocation(kind, sourceUrl) {
7712
+ const path = inTabErrorPath(kind);
7713
+ const source = axpInTabErrorSourceUrl(sourceUrl) ?? sourceUrl;
7714
+ const params = new URLSearchParams();
7715
+ params.set(AXP_IN_TAB_ERROR_FROM_PARAM, source);
7716
+ return `${path}?${params.toString()}`;
7717
+ }
7718
+ /** UrlTree for guards and resolvers. The shell stays mounted; the tab key stays the source route. */
7719
+ function axpInTabErrorUrlTree(router, kind, sourceUrl) {
7720
+ return router.parseUrl(axpInTabErrorLocation(kind, sourceUrl));
7721
+ }
7722
+ //#endregion
7723
+ //#region ---- Unknown Route Guard ----
7724
+ /**
7725
+ * Sends an unmatched URL to the in-shell 404 without dropping the root layout.
7726
+ * `from` keeps that URL as its own tab.
7727
+ */
7728
+ const axpRedirectUnknownToNotFound = (_route, state) => {
7729
+ const router = inject(Router);
7730
+ return axpInTabErrorUrlTree(router, '404', state.url);
7731
+ };
7732
+ //#endregion
7733
+ //#region ---- Helpers ----
7734
+ function inTabErrorPath(kind) {
7735
+ switch (kind) {
7736
+ case '401':
7737
+ return '/error/401';
7738
+ case '404':
7739
+ return '/error/404';
7740
+ case 'offline':
7741
+ return '/error/offline';
7742
+ }
7743
+ }
7744
+ //#endregion
7745
+
7625
7746
  //#region ---- Types ----
7626
7747
  const AXP_HOME_TAB_KEY = 'axp:home';
7627
7748
  /** Route `data` key for tab-navigation behavior (`data.tab`). */
@@ -7691,7 +7812,17 @@ function axpResolveTabKeyFromSnapshot(leaf) {
7691
7812
  */
7692
7813
  function axpResolveTabKey(router, url) {
7693
7814
  const normalized = normalizeRouterUrl(url ?? router.url);
7815
+ const errorSource = axpInTabErrorSourceUrl(normalized);
7816
+ if (errorSource) {
7817
+ return axpResolveTabKey(router, errorSource);
7818
+ }
7694
7819
  const pathOnly = normalized.split('?')[0].split('#')[0];
7820
+ // Entity lists key off the URL itself. Route-config matching and the live snapshot can
7821
+ // disagree until navigation finishes, and that split was opening a second tab for one click.
7822
+ // `mode` and `list` stay in the key; `view`, `layout`, `filters`, and `_ts` do not.
7823
+ if (axpIsEntityListPath(pathOnly)) {
7824
+ return axpEntityListNavigationTabKey(pathOnly, normalized);
7825
+ }
7695
7826
  const currentPath = normalizeRouterUrl(router.url).split('?')[0].split('#')[0];
7696
7827
  let basePath;
7697
7828
  if (!url || pathOnly === currentPath) {
@@ -7896,6 +8027,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
7896
8027
  //#region ----- Command sub-flow navigation (session) -----
7897
8028
  const SUPPRESS_TAB_RESTORE_KEY = 'axp:command-subflow-suppress-tab-restore';
7898
8029
  const RETURN_URL_KEY = 'axp:command-subflow-return-url';
8030
+ const subFlowEndedListeners = new Set();
8031
+ /** Fires after a command sub-flow releases tab restore. Returns an unsubscribe function. */
8032
+ function axpOnCommandSubFlowNavigationEnded(listener) {
8033
+ subFlowEndedListeners.add(listener);
8034
+ return () => {
8035
+ subFlowEndedListeners.delete(listener);
8036
+ };
8037
+ }
7899
8038
  /** Marks an in-flight command sub-flow (file picker, crop, dialog) so tab restore must not hijack the route. */
7900
8039
  function axpBeginCommandSubFlowNavigation(returnUrl) {
7901
8040
  const trimmed = returnUrl.trim();
@@ -7935,11 +8074,14 @@ function axpEndCommandSubFlowNavigation() {
7935
8074
  catch {
7936
8075
  // sessionStorage may be unavailable
7937
8076
  }
8077
+ for (const listener of subFlowEndedListeners) {
8078
+ listener();
8079
+ }
7938
8080
  }
7939
8081
  //#endregion
7940
8082
 
7941
8083
  //#region ---- Tab Route Policy ----
7942
- const EXCLUDED_PATH_PREFIXES = ['/auth', '/error'];
8084
+ const EXCLUDED_PATH_PREFIXES = ['/auth'];
7943
8085
  const EXCLUDED_PATH_PATTERNS = [
7944
8086
  /^\/assessment\/fill\//i,
7945
8087
  /^\/forms\//i,
@@ -7991,7 +8133,28 @@ class AXPTabNavigationService {
7991
8133
  ...(ngDevMode ? [{ debugName: "tabs" }] : /* istanbul ignore next */ []));
7992
8134
  this.activeTabKey = signal(null, /* @ts-ignore */
7993
8135
  ...(ngDevMode ? [{ debugName: "activeTabKey" }] : /* istanbul ignore next */ []));
7994
- this.suppressNavigationSync = false;
8136
+ /** Nested navigations (menu + route `replaceUrl`) must not clear each other's sync guard. */
8137
+ this.navigationSyncSuppressDepth = 0;
8138
+ this.navigationSettingsChain = Promise.resolve();
8139
+ /** `tenantId:applicationId:userId` while the tab strip belongs to that session. Null after sign-out. */
8140
+ this.tabsOwnerStamp = null;
8141
+ /** False until the first session emission. A later stamp change must not restore saved tabs. */
8142
+ this.sessionTabsBound = false;
8143
+ /** Set when the user actually signs out, so the next sign-in does not reopen that list. */
8144
+ this.closedTabsForSessionChange = false;
8145
+ /** Storage key of the session that owned the strip. Survives sign-out, when the user id is already gone. */
8146
+ this.ownedStorageKey = null;
8147
+ /**
8148
+ * Stamp captured when readiness dropped but the user was still signed in.
8149
+ * A failed tenant/application switch returns to this stamp and must keep the saved list.
8150
+ */
8151
+ this.pendingReadinessGap = null;
8152
+ /** False until the saved list has been read, so an earlier route sync cannot overwrite it. */
8153
+ this.sessionTabsHydrated = false;
8154
+ /** Restore was skipped because a command sub-flow was open. Resumed when that sub-flow ends. */
8155
+ this.restoreDeferred = false;
8156
+ /** Incremented on every session emission. A queued task stops when a newer emission exists. */
8157
+ this.sessionSyncGeneration = 0;
7995
8158
  //#endregion
7996
8159
  //#region ---- Computed ----
7997
8160
  /** Effective mode: mobile always uses simple navigation. */
@@ -8011,6 +8174,10 @@ class AXPTabNavigationService {
8011
8174
  this.bindSettingsChanges();
8012
8175
  this.bindSessionChanges();
8013
8176
  this.bindRouteCacheSync();
8177
+ const stopSubFlowWatch = axpOnCommandSubFlowNavigationEnded(() => {
8178
+ void this.enqueueNavigationSettingsSync(() => this.resumeDeferredTabRestore());
8179
+ });
8180
+ this.destroyRef.onDestroy(stopSubFlowWatch);
8014
8181
  }
8015
8182
  //#endregion
8016
8183
  //#region ---- Public API ----
@@ -8050,10 +8217,9 @@ class AXPTabNavigationService {
8050
8217
  return;
8051
8218
  }
8052
8219
  // Navigate first so scoped tab keys (`data.tab`) resolve from the live route snapshot.
8053
- this.suppressNavigationSync = true;
8054
- try {
8220
+ await this.runWithSuppressedNavigationSync(async () => {
8055
8221
  await axpNavigateAppPath(this.router, normalizedUrl);
8056
- const key = axpResolveTabKey(this.router);
8222
+ const key = axpResolveTabKey(this.router, normalizedUrl);
8057
8223
  const postNavExisting = this.findTabForUrl(normalizedUrl);
8058
8224
  if (postNavExisting) {
8059
8225
  if (postNavExisting.key !== key) {
@@ -8068,10 +8234,7 @@ class AXPTabNavigationService {
8068
8234
  this.insertTab(this.createTabDescriptor(normalizedUrl, title, key));
8069
8235
  this.activeTabKey.set(key);
8070
8236
  this.persistSession();
8071
- }
8072
- finally {
8073
- this.suppressNavigationSync = false;
8074
- }
8237
+ });
8075
8238
  }
8076
8239
  /**
8077
8240
  * Activates a tab and navigates to its URL. The previously active page is detached and cached by
@@ -8086,18 +8249,15 @@ class AXPTabNavigationService {
8086
8249
  if (!tab) {
8087
8250
  return;
8088
8251
  }
8089
- const targetUrl = urlOverride ?? tab.url;
8252
+ const targetUrl = axpInTabErrorRetryUrl(urlOverride ?? tab.url);
8253
+ if (tab.url !== targetUrl) {
8254
+ this.updateTabUrl(key, targetUrl);
8255
+ }
8090
8256
  this.touchTab(key);
8091
8257
  this.activeTabKey.set(key);
8092
8258
  this.persistSession();
8093
8259
  const navigate = async () => {
8094
- this.suppressNavigationSync = true;
8095
- try {
8096
- await this.router.navigateByUrl(targetUrl);
8097
- }
8098
- finally {
8099
- this.suppressNavigationSync = false;
8100
- }
8260
+ await this.runWithSuppressedNavigationSync(() => this.router.navigateByUrl(targetUrl));
8101
8261
  };
8102
8262
  if (suspendDeactivateGuard) {
8103
8263
  await this.routeCacheRegistry.runWithSuspendedDeactivateGuards(navigate);
@@ -8109,6 +8269,24 @@ class AXPTabNavigationService {
8109
8269
  async closeTab(key) {
8110
8270
  await this.closeTabs([key]);
8111
8271
  }
8272
+ /**
8273
+ * Drops the active error tab without opening a neighbor.
8274
+ * Home stays. The caller navigates to the real home page afterwards.
8275
+ */
8276
+ closeActiveErrorTab() {
8277
+ if (this.effectiveMode() !== 'tabular') {
8278
+ return;
8279
+ }
8280
+ const activeKey = this.activeTabKey();
8281
+ const tab = this.tabs().find((item) => item.key === activeKey);
8282
+ if (!tab || tab.key === AXP_HOME_TAB_KEY) {
8283
+ return;
8284
+ }
8285
+ this.tabs.update((items) => items.filter((item) => item.key !== tab.key));
8286
+ this.tabPreviewService.clearPreviews(new Set([tab.key]));
8287
+ this.activeTabKey.set(AXP_HOME_TAB_KEY);
8288
+ this.persistSession();
8289
+ }
8112
8290
  /** Closes every closable tab except the given key (pinned tabs are kept). */
8113
8291
  async closeOtherTabs(keepKey) {
8114
8292
  const keys = this.tabs()
@@ -8290,15 +8468,9 @@ class AXPTabNavigationService {
8290
8468
  targetKey = home.key;
8291
8469
  targetUrl = home.url;
8292
8470
  }
8293
- this.suppressNavigationSync = true;
8294
- try {
8295
- const navigated = await this.router.navigateByUrl(targetUrl);
8296
- if (!navigated) {
8297
- return false;
8298
- }
8299
- }
8300
- finally {
8301
- this.suppressNavigationSync = false;
8471
+ const navigated = await this.runWithSuppressedNavigationSync(() => this.router.navigateByUrl(targetUrl));
8472
+ if (!navigated) {
8473
+ return false;
8302
8474
  }
8303
8475
  this.activeTabKey.set(targetKey);
8304
8476
  this.touchTab(targetKey);
@@ -8328,6 +8500,16 @@ class AXPTabNavigationService {
8328
8500
  }
8329
8501
  //#endregion
8330
8502
  //#region ---- Router Sync ----
8503
+ /** Holds route-sync until every nested navigation in this turn has finished. */
8504
+ async runWithSuppressedNavigationSync(action) {
8505
+ this.navigationSyncSuppressDepth += 1;
8506
+ try {
8507
+ return await action();
8508
+ }
8509
+ finally {
8510
+ this.navigationSyncSuppressDepth = Math.max(0, this.navigationSyncSuppressDepth - 1);
8511
+ }
8512
+ }
8331
8513
  bindRouterEvents() {
8332
8514
  this.router.events
8333
8515
  .pipe(filter$1((event) => event instanceof NavigationEnd), takeUntilDestroyed(this.destroyRef))
@@ -8336,7 +8518,7 @@ class AXPTabNavigationService {
8336
8518
  });
8337
8519
  }
8338
8520
  async handleNavigationEnd(url) {
8339
- if (this.suppressNavigationSync) {
8521
+ if (this.navigationSyncSuppressDepth > 0) {
8340
8522
  return;
8341
8523
  }
8342
8524
  if (this.effectiveMode() === 'simple') {
@@ -8347,67 +8529,288 @@ class AXPTabNavigationService {
8347
8529
  return;
8348
8530
  }
8349
8531
  await this.ensureHomeTab();
8350
- if (this.isHomePageUrl(normalizedUrl)) {
8351
- this.activateHomeTabForUrl(normalizedUrl);
8532
+ const errorSource = axpInTabErrorSourceUrl(normalizedUrl);
8533
+ const storedUrl = errorSource ?? normalizedUrl;
8534
+ if (this.isHomePageUrl(storedUrl)) {
8535
+ this.activateHomeTabForUrl(storedUrl);
8352
8536
  return;
8353
8537
  }
8354
- const key = axpResolveTabKey(this.router, normalizedUrl);
8355
- const existing = this.findTabForUrl(normalizedUrl);
8538
+ const key = axpResolveTabKey(this.router, storedUrl);
8539
+ const existing = this.findTabForUrl(storedUrl);
8356
8540
  if (existing) {
8357
8541
  if (existing.key !== key) {
8358
8542
  this.migrateTabKey(existing.key, key);
8359
8543
  }
8360
- this.updateTabUrl(key, normalizedUrl);
8544
+ this.updateTabUrl(key, storedUrl);
8361
8545
  this.touchTab(key);
8362
8546
  this.activeTabKey.set(key);
8363
8547
  this.persistSession();
8364
8548
  return;
8365
8549
  }
8366
- this.insertTab(this.createTabDescriptor(normalizedUrl, undefined, key));
8550
+ this.insertTab(this.createTabDescriptor(storedUrl, errorSource ? this.resolveTabTitle(errorSource) : undefined, key));
8367
8551
  this.activeTabKey.set(key);
8368
8552
  this.persistSession();
8369
8553
  }
8370
8554
  //#endregion
8371
8555
  //#region ---- Settings ----
8372
8556
  async loadSettings() {
8373
- const [mode, maxTabs] = await Promise.all([
8374
- this.settingsService.get(AXPCommonSettings.NavigationMode),
8375
- this.settingsService.get(AXPCommonSettings.MaxOpenTabs),
8376
- ]);
8377
- this.navigationMode.set(mode === 'tabular' ? 'tabular' : 'simple');
8378
- this.maxOpenTabs.set(this.normalizeMaxTabs(maxTabs));
8379
- await this.restoreSessionIfNeeded();
8557
+ await this.enqueueNavigationSettingsSync(async () => {
8558
+ const maxTabs = await this.settingsService.get(AXPCommonSettings.MaxOpenTabs);
8559
+ this.maxOpenTabs.set(this.normalizeMaxTabs(maxTabs));
8560
+ await this.applyEffectiveNavigationMode();
8561
+ });
8380
8562
  }
8381
8563
  bindSettingsChanges() {
8564
+ this.settingsService.onLoaded.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => {
8565
+ void this.enqueueNavigationSettingsSync(() => this.applyEffectiveNavigationMode());
8566
+ });
8382
8567
  this.settingsService.onChanged.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((event) => {
8383
- if (event.keys.includes(AXPCommonSettings.NavigationMode)) {
8384
- const raw = event.values[AXPCommonSettings.NavigationMode];
8385
- const newMode = raw === 'tabular' ? 'tabular' : 'simple';
8386
- if (newMode !== this.navigationMode()) {
8387
- this.navigationMode.set(newMode);
8388
- if (this.effectiveMode() === 'simple') {
8389
- this.clearSession();
8390
- }
8391
- else {
8392
- void this.ensureHomeTab().then(() => this.syncCurrentRouteAsTab());
8393
- }
8394
- }
8395
- }
8396
- if (event.keys.includes(AXPCommonSettings.MaxOpenTabs)) {
8397
- this.maxOpenTabs.set(this.normalizeMaxTabs(event.values[AXPCommonSettings.MaxOpenTabs]));
8398
- this.enforceMaxTabs();
8399
- this.persistSession();
8568
+ const modeChanged = event.keys.includes(AXPCommonSettings.NavigationMode);
8569
+ const maxChanged = event.keys.includes(AXPCommonSettings.MaxOpenTabs);
8570
+ if (!modeChanged && !maxChanged) {
8571
+ return;
8400
8572
  }
8573
+ void this.enqueueNavigationSettingsSync(async () => {
8574
+ if (modeChanged) {
8575
+ await this.applyEffectiveNavigationMode();
8576
+ }
8577
+ if (maxChanged) {
8578
+ const maxTabs = await this.settingsService.get(AXPCommonSettings.MaxOpenTabs);
8579
+ this.maxOpenTabs.set(this.normalizeMaxTabs(maxTabs));
8580
+ this.enforceMaxTabs();
8581
+ this.persistSession();
8582
+ }
8583
+ });
8401
8584
  });
8402
8585
  }
8403
8586
  bindSessionChanges() {
8404
- this.sessionService.user$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => {
8405
- if (axpIsCommandSubFlowNavigationSuspended()) {
8406
- return;
8587
+ combineLatest([
8588
+ this.sessionService.user$.pipe(map$1((user) => user?.id ?? null)),
8589
+ this.sessionService.tenant$.pipe(map$1((tenant) => tenant?.id ?? null)),
8590
+ this.sessionService.application$.pipe(map$1((application) => application?.id ?? null)),
8591
+ this.sessionService.isReadyForAppScopedApi$,
8592
+ ])
8593
+ .pipe(distinctUntilChanged$1((previous, next) => previous[0] === next[0] &&
8594
+ previous[1] === next[1] &&
8595
+ previous[2] === next[2] &&
8596
+ previous[3] === next[3]), takeUntilDestroyed(this.destroyRef))
8597
+ .subscribe(() => {
8598
+ const context = this.captureSessionSyncContext();
8599
+ if (this.tabsOwnerStamp != null && (context.sessionEnded || context.stamp !== this.tabsOwnerStamp)) {
8600
+ this.routeCacheRegistry.suspendAttach();
8407
8601
  }
8408
- void this.restoreSessionIfNeeded();
8602
+ void this.enqueueNavigationSettingsSync(() => this.syncTabsToSession(context));
8409
8603
  });
8410
8604
  }
8605
+ /** Reads the session once, so a later user cannot replace this event's storage key. */
8606
+ captureSessionSyncContext() {
8607
+ return {
8608
+ generation: ++this.sessionSyncGeneration,
8609
+ stamp: this.sessionStamp(),
8610
+ sessionEnded: !this.sessionService.user?.id || !this.sessionService.hasSessionCredentials(),
8611
+ storageKey: this.sessionStorageKey(),
8612
+ url: normalizeRouterUrl(this.router.url),
8613
+ };
8614
+ }
8615
+ isCurrentSessionSync(context) {
8616
+ return context.generation === this.sessionSyncGeneration;
8617
+ }
8618
+ /**
8619
+ * Closes every tab when the signed-in user, tenant, or application actually changes, including sign-out.
8620
+ * The saved list is deleted only for that real change, so a failed switch can restore it.
8621
+ * The context is the session at enqueue time. A newer emission stops this task, including after an await.
8622
+ */
8623
+ async syncTabsToSession(context) {
8624
+ // Sign-out still deletes its own captured list when a later sign-in made this event stale.
8625
+ if (context.sessionEnded) {
8626
+ this.applyCapturedSignOut(context);
8627
+ return;
8628
+ }
8629
+ if (!this.isCurrentSessionSync(context)) {
8630
+ return;
8631
+ }
8632
+ if (!this.sessionTabsBound) {
8633
+ this.sessionTabsBound = true;
8634
+ this.tabsOwnerStamp = context.stamp;
8635
+ this.ownedStorageKey = context.storageKey;
8636
+ if (!context.stamp) {
8637
+ return;
8638
+ }
8639
+ this.routeCacheRegistry.bindOwner(context.stamp);
8640
+ await this.applyEffectiveNavigationMode();
8641
+ if (!this.isCurrentSessionSync(context)) {
8642
+ return;
8643
+ }
8644
+ await this.restoreSessionIfNeeded(context);
8645
+ return;
8646
+ }
8647
+ if (context.stamp === this.tabsOwnerStamp &&
8648
+ this.pendingReadinessGap == null &&
8649
+ !this.closedTabsForSessionChange) {
8650
+ this.routeCacheRegistry.resumeAttach();
8651
+ return;
8652
+ }
8653
+ if (context.stamp == null) {
8654
+ if (this.tabsOwnerStamp != null) {
8655
+ this.pendingReadinessGap = this.tabsOwnerStamp;
8656
+ }
8657
+ return;
8658
+ }
8659
+ const gap = this.pendingReadinessGap;
8660
+ this.pendingReadinessGap = null;
8661
+ if (gap != null && gap === context.stamp && !this.closedTabsForSessionChange) {
8662
+ this.tabsOwnerStamp = context.stamp;
8663
+ this.routeCacheRegistry.resumeAttach();
8664
+ return;
8665
+ }
8666
+ const previous = gap ?? this.tabsOwnerStamp;
8667
+ const identityChanged = previous != null && previous !== context.stamp;
8668
+ if (identityChanged || this.closedTabsForSessionChange) {
8669
+ this.closedTabsForSessionChange = false;
8670
+ this.restoreDeferred = false;
8671
+ this.forgetPersistedTabs(this.ownedStorageKey);
8672
+ this.tabsOwnerStamp = context.stamp;
8673
+ this.ownedStorageKey = context.storageKey;
8674
+ this.sessionTabsHydrated = false;
8675
+ this.discardRuntimeTabs();
8676
+ this.routeCacheRegistry.bindOwner(context.stamp);
8677
+ this.routeCacheRegistry.resumeAttach();
8678
+ await this.applyEffectiveNavigationMode();
8679
+ if (!this.isCurrentSessionSync(context)) {
8680
+ return;
8681
+ }
8682
+ this.sessionTabsHydrated = true;
8683
+ await this.syncSettledDestination(context);
8684
+ return;
8685
+ }
8686
+ if (this.tabsOwnerStamp == null && context.stamp != null) {
8687
+ this.tabsOwnerStamp = context.stamp;
8688
+ this.ownedStorageKey = context.storageKey;
8689
+ this.routeCacheRegistry.bindOwner(context.stamp);
8690
+ this.routeCacheRegistry.resumeAttach();
8691
+ await this.applyEffectiveNavigationMode();
8692
+ if (!this.isCurrentSessionSync(context)) {
8693
+ return;
8694
+ }
8695
+ await this.restoreSessionIfNeeded(context);
8696
+ }
8697
+ }
8698
+ /**
8699
+ * Sign-out cleanup uses the captured storage key and still runs when a newer sign-in
8700
+ * has already superseded this event. It does not read the live session.
8701
+ */
8702
+ applyCapturedSignOut(context) {
8703
+ this.pendingReadinessGap = null;
8704
+ this.restoreDeferred = false;
8705
+ this.forgetPersistedTabs(context.storageKey ?? this.ownedStorageKey);
8706
+ this.tabsOwnerStamp = null;
8707
+ this.discardRuntimeTabs();
8708
+ this.routeCacheRegistry.resumeAttach();
8709
+ this.closedTabsForSessionChange = true;
8710
+ this.sessionTabsHydrated = false;
8711
+ }
8712
+ /**
8713
+ * Opens Home for the settled session. The current route is added only after the router
8714
+ * has left the URL captured with the event, so the previous context is not reopened.
8715
+ * Home is created even when that URL is unchanged, including when it is already Home.
8716
+ */
8717
+ async syncSettledDestination(context) {
8718
+ if (!this.isCurrentSessionSync(context) || this.effectiveMode() !== 'tabular') {
8719
+ return;
8720
+ }
8721
+ await this.ensureHomeTab();
8722
+ if (!this.isCurrentSessionSync(context)) {
8723
+ return;
8724
+ }
8725
+ const destination = normalizeRouterUrl(this.router.url);
8726
+ const routeBelongsToSettledSession = !!destination && destination !== context.url && axpIsTabEligibleUrl(destination);
8727
+ if (routeBelongsToSettledSession || (!!destination && this.isHomePageUrl(destination))) {
8728
+ await this.syncCurrentRouteAsTab();
8729
+ return;
8730
+ }
8731
+ if (this.tabs().some((tab) => tab.key === AXP_HOME_TAB_KEY)) {
8732
+ this.activeTabKey.set(AXP_HOME_TAB_KEY);
8733
+ }
8734
+ this.persistSession();
8735
+ }
8736
+ /** Continues a restore that was skipped while a command sub-flow held the router. */
8737
+ async resumeDeferredTabRestore() {
8738
+ if (!this.restoreDeferred || axpIsCommandSubFlowNavigationSuspended()) {
8739
+ return;
8740
+ }
8741
+ const context = {
8742
+ generation: this.sessionSyncGeneration,
8743
+ stamp: this.tabsOwnerStamp,
8744
+ sessionEnded: false,
8745
+ storageKey: this.ownedStorageKey,
8746
+ url: normalizeRouterUrl(this.router.url),
8747
+ };
8748
+ this.restoreDeferred = false;
8749
+ if (!context.stamp) {
8750
+ return;
8751
+ }
8752
+ await this.restoreSessionIfNeeded(context);
8753
+ }
8754
+ /** Identity of the session that may own open tabs. Null when the app session is not ready. */
8755
+ sessionStamp() {
8756
+ if (!this.sessionService.isReadyForAppScopedApi) {
8757
+ return null;
8758
+ }
8759
+ const userId = this.sessionService.user?.id;
8760
+ const tenantId = this.sessionService.tenant?.id;
8761
+ const applicationId = this.sessionService.application?.id;
8762
+ if (!userId || !tenantId || !applicationId) {
8763
+ return null;
8764
+ }
8765
+ return `${tenantId}:${applicationId}:${userId}`;
8766
+ }
8767
+ /** Deletes one captured tab list. A newer user's key is left untouched. */
8768
+ forgetPersistedTabs(storageKey) {
8769
+ if (!storageKey) {
8770
+ return;
8771
+ }
8772
+ sessionStorage.removeItem(storageKey);
8773
+ if (this.ownedStorageKey === storageKey) {
8774
+ this.ownedStorageKey = null;
8775
+ }
8776
+ }
8777
+ /** Closes every tab and destroys cached page components. */
8778
+ discardRuntimeTabs() {
8779
+ this.tabs.set([]);
8780
+ this.activeTabKey.set(null);
8781
+ this.tabPreviewService.clearAll();
8782
+ this.routeCacheRegistry.bindOwner(this.tabsOwnerStamp);
8783
+ }
8784
+ /**
8785
+ * Reads the effective NavigationMode (User, then Tenant, then Platform, then the definition default).
8786
+ * Scope reloads update the settings cache without `onChanged`, so callers must use this instead of
8787
+ * treating a partial event value as "switch to simple".
8788
+ */
8789
+ async applyEffectiveNavigationMode() {
8790
+ if (!this.sessionService.isReadyForAppScopedApi) {
8791
+ return;
8792
+ }
8793
+ const mode = await this.settingsService.get(AXPCommonSettings.NavigationMode);
8794
+ const next = mode === 'tabular' ? 'tabular' : 'simple';
8795
+ const previous = this.navigationMode();
8796
+ if (next === previous) {
8797
+ return;
8798
+ }
8799
+ this.navigationMode.set(next);
8800
+ if (previous === 'tabular' && next === 'simple') {
8801
+ this.clearSession();
8802
+ return;
8803
+ }
8804
+ if (next === 'tabular' && this.effectiveMode() === 'tabular' && this.sessionTabsHydrated) {
8805
+ await this.ensureHomeTab();
8806
+ await this.syncCurrentRouteAsTab();
8807
+ }
8808
+ }
8809
+ enqueueNavigationSettingsSync(task) {
8810
+ const run = this.navigationSettingsChain.then(task, task);
8811
+ this.navigationSettingsChain = run.then(() => undefined, () => undefined);
8812
+ return run;
8813
+ }
8411
8814
  //#endregion
8412
8815
  //#region ---- Tab Management ----
8413
8816
  async ensureHomeTab() {
@@ -8449,7 +8852,7 @@ class AXPTabNavigationService {
8449
8852
  }
8450
8853
  this.tabs.update((items) => {
8451
8854
  const withoutDuplicate = items.filter((item) => {
8452
- if (item.key === tab.key) {
8855
+ if (item.key === tab.key || this.isSameEntityListTab(item, tab)) {
8453
8856
  return false;
8454
8857
  }
8455
8858
  return axpResolveTabKey(this.router, item.url) !== tab.key;
@@ -8509,14 +8912,29 @@ class AXPTabNavigationService {
8509
8912
  lastActivatedAt: now,
8510
8913
  };
8511
8914
  }
8512
- /** Finds a tab by scoped key or legacy full-path key for the same URL. */
8915
+ /** Finds a tab by scoped key, or by entity-list identity when an older key drifted. */
8513
8916
  findTabForUrl(url) {
8514
8917
  if (this.isHomePageUrl(url)) {
8515
8918
  return this.tabs().find((tab) => tab.key === AXP_HOME_TAB_KEY);
8516
8919
  }
8517
8920
  const resolvedKey = axpResolveTabKey(this.router, url);
8518
- return this.tabs().find((tab) => tab.key !== AXP_HOME_TAB_KEY &&
8921
+ const byKey = this.tabs().find((tab) => tab.key !== AXP_HOME_TAB_KEY &&
8519
8922
  (tab.key === resolvedKey || axpResolveTabKey(this.router, tab.url) === resolvedKey));
8923
+ if (byKey) {
8924
+ return byKey;
8925
+ }
8926
+ if (!axpIsEntityListPath(url)) {
8927
+ return undefined;
8928
+ }
8929
+ const identity = axpBuildTabKey(normalizeRouterUrl(url));
8930
+ return this.tabs().find((tab) => tab.key !== AXP_HOME_TAB_KEY && axpIsEntityListPath(tab.url) && axpBuildTabKey(tab.url) === identity);
8931
+ }
8932
+ /** Same list menu (`mode`, `list`, …). Page-state query params do not make a new tab. */
8933
+ isSameEntityListTab(left, right) {
8934
+ if (!axpIsEntityListPath(left.url) || !axpIsEntityListPath(right.url)) {
8935
+ return false;
8936
+ }
8937
+ return axpBuildTabKey(left.url) === axpBuildTabKey(right.url);
8520
8938
  }
8521
8939
  /** True when the URL is the configured application home page (e.g. dashboard). */
8522
8940
  isHomePageUrl(url) {
@@ -8661,8 +9079,12 @@ class AXPTabNavigationService {
8661
9079
  return `${SESSION_STORAGE_PREFIX}(${userId})`;
8662
9080
  }
8663
9081
  persistSession() {
8664
- const key = this.sessionStorageKey();
8665
- if (!key || this.effectiveMode() === 'simple') {
9082
+ const key = this.ownedStorageKey;
9083
+ if (!key ||
9084
+ key !== this.sessionStorageKey() ||
9085
+ this.tabsOwnerStamp !== this.sessionStamp() ||
9086
+ !this.sessionTabsHydrated ||
9087
+ this.effectiveMode() === 'simple') {
8666
9088
  return;
8667
9089
  }
8668
9090
  const payload = {
@@ -8679,31 +9101,54 @@ class AXPTabNavigationService {
8679
9101
  this.tabs.set([]);
8680
9102
  this.activeTabKey.set(null);
8681
9103
  this.tabPreviewService.clearAll();
9104
+ this.routeCacheRegistry.clear();
8682
9105
  }
8683
- async restoreSessionIfNeeded() {
9106
+ async restoreSessionIfNeeded(context) {
9107
+ if (!this.isCurrentSessionSync(context)) {
9108
+ return;
9109
+ }
8684
9110
  if (this.effectiveMode() === 'simple') {
9111
+ this.sessionTabsHydrated = true;
8685
9112
  return;
8686
9113
  }
8687
9114
  if (axpIsCommandSubFlowNavigationSuspended()) {
9115
+ this.restoreDeferred = true;
8688
9116
  return;
8689
9117
  }
8690
- const storageKey = this.sessionStorageKey();
9118
+ const storageKey = context.storageKey;
8691
9119
  if (!storageKey) {
8692
- await this.ensureHomeTab();
8693
- await this.syncCurrentRouteAsTab();
9120
+ this.tabs.set([]);
9121
+ this.activeTabKey.set(null);
9122
+ this.tabPreviewService.clearAll();
9123
+ this.sessionTabsHydrated = true;
8694
9124
  return;
8695
9125
  }
8696
9126
  const raw = sessionStorage.getItem(storageKey);
8697
9127
  if (!raw) {
9128
+ this.tabs.set([]);
9129
+ this.activeTabKey.set(null);
9130
+ this.sessionTabsHydrated = true;
8698
9131
  await this.ensureHomeTab();
9132
+ if (!this.isCurrentSessionSync(context)) {
9133
+ return;
9134
+ }
8699
9135
  await this.syncCurrentRouteAsTab();
8700
9136
  return;
8701
9137
  }
8702
9138
  try {
8703
9139
  const parsed = JSON.parse(raw);
8704
- const restoredTabs = this.removeDuplicateHomeUrlTabs(this.normalizeRestoredTabKeys(defaultTo(parsed.tabs, []).filter((tab) => tab?.key && tab?.url)));
9140
+ const restoredTabs = this.removeDuplicateHomeUrlTabs(this.normalizeRestoredTabKeys(defaultTo(parsed.tabs, [])
9141
+ .filter((tab) => tab?.key && tab?.url)
9142
+ .map((tab) => ({ ...tab, url: axpInTabErrorRetryUrl(tab.url) }))));
9143
+ if (!this.isCurrentSessionSync(context)) {
9144
+ return;
9145
+ }
9146
+ this.sessionTabsHydrated = true;
8705
9147
  this.tabs.set(this.ensureHomeTabFirst(restoredTabs));
8706
9148
  await this.ensureHomeTab();
9149
+ if (!this.isCurrentSessionSync(context)) {
9150
+ return;
9151
+ }
8707
9152
  const activeKey = parsed.activeTabKey ?? this.tabs()[this.tabs().length - 1]?.key ?? AXP_HOME_TAB_KEY;
8708
9153
  this.activeTabKey.set(activeKey);
8709
9154
  const activeTab = this.tabs().find((tab) => tab.key === activeKey);
@@ -8711,17 +9156,18 @@ class AXPTabNavigationService {
8711
9156
  if (activeTab &&
8712
9157
  currentUrl !== normalizeRouterUrl(activeTab.url) &&
8713
9158
  axpIsTabEligibleUrl(currentUrl)) {
8714
- this.suppressNavigationSync = true;
8715
- try {
8716
- await this.router.navigateByUrl(activeTab.url);
8717
- }
8718
- finally {
8719
- this.suppressNavigationSync = false;
8720
- }
9159
+ await this.runWithSuppressedNavigationSync(() => this.router.navigateByUrl(activeTab.url));
8721
9160
  }
8722
9161
  }
8723
9162
  catch {
9163
+ if (!this.isCurrentSessionSync(context)) {
9164
+ return;
9165
+ }
9166
+ this.sessionTabsHydrated = true;
8724
9167
  await this.ensureHomeTab();
9168
+ if (!this.isCurrentSessionSync(context)) {
9169
+ return;
9170
+ }
8725
9171
  await this.syncCurrentRouteAsTab();
8726
9172
  }
8727
9173
  }
@@ -9621,6 +10067,23 @@ class AXPNotFoundError extends Error {
9621
10067
  }
9622
10068
  }
9623
10069
 
10070
+ /**
10071
+ * Placeholder for a wildcard route whose guard always redirects into the shell.
10072
+ * The component is not shown.
10073
+ */
10074
+ class AXPUnreachableRouteComponent {
10075
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPUnreachableRouteComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
10076
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.8", type: AXPUnreachableRouteComponent, isStandalone: true, selector: "axp-unreachable-route", ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
10077
+ }
10078
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPUnreachableRouteComponent, decorators: [{
10079
+ type: Component,
10080
+ args: [{
10081
+ selector: 'axp-unreachable-route',
10082
+ template: '',
10083
+ changeDetection: ChangeDetectionStrategy.OnPush,
10084
+ }]
10085
+ }] });
10086
+
9624
10087
  /** Canonical route path for the platform 404 page. */
9625
10088
  const AXP_NOT_FOUND_ROUTE = '/error/404';
9626
10089
  /**
@@ -9629,7 +10092,8 @@ const AXP_NOT_FOUND_ROUTE = '/error/404';
9629
10092
  */
9630
10093
  const AXP_NOT_FOUND_CATCH_ALL_ROUTE = {
9631
10094
  path: '**',
9632
- redirectTo: AXP_NOT_FOUND_ROUTE,
10095
+ canActivate: [axpRedirectUnknownToNotFound],
10096
+ component: AXPUnreachableRouteComponent,
9633
10097
  };
9634
10098
  /**
9635
10099
  * Registers the platform catch-all 404 route.
@@ -9653,8 +10117,8 @@ function axpIsEntityRecordNotFound(data) {
9653
10117
  /**
9654
10118
  * Creates an Angular redirect command to the platform 404 page.
9655
10119
  */
9656
- function axpRedirectToNotFound(router = inject(Router)) {
9657
- return new RedirectCommand(router.parseUrl(AXP_NOT_FOUND_ROUTE));
10120
+ function axpRedirectToNotFound(router = inject(Router), sourceUrl) {
10121
+ return new RedirectCommand(axpInTabErrorUrlTree(router, '404', sourceUrl ?? router.url));
9658
10122
  }
9659
10123
 
9660
10124
  /** Canonical route path for the platform 401 page. */
@@ -9662,8 +10126,8 @@ const AXP_UNAUTHORIZED_ROUTE = '/error/401';
9662
10126
  /**
9663
10127
  * Creates an Angular redirect command to the platform 401 page.
9664
10128
  */
9665
- function axpRedirectToUnauthorized(router = inject(Router)) {
9666
- return new RedirectCommand(router.parseUrl(AXP_UNAUTHORIZED_ROUTE));
10129
+ function axpRedirectToUnauthorized(router = inject(Router), sourceUrl) {
10130
+ return new RedirectCommand(axpInTabErrorUrlTree(router, '401', sourceUrl ?? router.url));
9667
10131
  }
9668
10132
 
9669
10133
  //#endregion
@@ -10431,15 +10895,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
10431
10895
  const AXP_ENTITY_VIEW_ACCESS = new InjectionToken('AXP_ENTITY_VIEW_ACCESS');
10432
10896
 
10433
10897
  const APP_CHOOSER_ROUTE = '/auth/account/app-chooser';
10434
- /** In-app navigations (e.g. Open Details) stay put instead of redirecting to 401. */
10435
- function axpShouldStayOnCurrentPage(router, targetUrl) {
10436
- const currentPath = router.url.split('#')[0]?.split('?')[0] ?? '';
10437
- const targetPath = targetUrl.split('#')[0]?.split('?')[0] ?? '';
10438
- if (!currentPath || currentPath === '/' || currentPath === targetPath) {
10439
- return false;
10440
- }
10441
- return !currentPath.startsWith('/auth') && !currentPath.startsWith('/error');
10442
- }
10443
10898
  /**
10444
10899
 
10445
10900
  * Blocks navigation when the target route is not accessible for the current user.
@@ -10467,10 +10922,7 @@ const AXPMenuRouteGuard = (route, state) => {
10467
10922
  if (isAllowed instanceof UrlTree) {
10468
10923
  return isAllowed;
10469
10924
  }
10470
- if (axpShouldStayOnCurrentPage(router, state.url)) {
10471
- return false;
10472
- }
10473
- return router.parseUrl(AXP_UNAUTHORIZED_ROUTE);
10925
+ return axpInTabErrorUrlTree(router, '401', state.url);
10474
10926
  }));
10475
10927
  };
10476
10928
 
@@ -14446,5 +14898,5 @@ const axpPageGetContextQueryDefinition = defineQuery({
14446
14898
  * Generated bundle index. Do not edit.
14447
14899
  */
14448
14900
 
14449
- export { ALL_DEFAULT_OPERATORS, AXPAcorexFileTypeBridgeProvider, AXPAcorexFileTypeModule, AXPAppVersionService, AXPBackgroundOperationCompletionService, AXPBackgroundOperationEntityStoreService, AXPBackgroundOperationHandler, AXPBackgroundOperationNotificationService, AXPBackgroundOperationProvider, AXPBackgroundOperationRootConfig, AXPBackgroundOperationService, AXPBackgroundOperationSlotComponent, AXPBrowserTitleService, AXPCleanNestedFilters, AXPClipBoardService, AXPCommonModule, AXPCommonSettings, AXPCustomOperatorService, AXPCustomOperatorServiceImpl, AXPDataProvider, AXPDefaultMultiLanguageConfigService, AXPEntityDetailsNavTrailService, AXPErrorHandlerRegistryService, AXPExportService, AXPFileActionsService, AXPFileChooserSettings, AXPFileStorageEvaluatorScopeProvider, AXPFileStorageService, AXPFileTypeProviderService, AXPFilterDefaultOperatorService, AXPFilterOperatorMiddlewareService, AXPFilterOperatorMiddlewareServiceImpl, AXPFooterTextSlotComponent, AXPGlobalErrorHandler, AXPHomePageModule, AXPHomePageService, AXPIndexedDbSettingValueProvider, AXPIntegrationDomainProviderContext, AXPIntegrationDomainRegistryFacade, AXPIntegrationDomainRegistryService, AXPIntegrationOAuthService, AXPIntegrationProviderContext, AXPIntegrationProviderRegistryService, AXPIntegrationRuntimeService, AXPKeyboardShortcutsHelpComponent, AXPKeyboardShortcutsHelpService, AXPLocalEntityEngine, AXPLocalEntityIndexedDb, AXPLocalEntityOfflineRuntime, AXPLocalEntityOutboxService, AXPLocalEntityRealtimeBridge, AXPLockService, AXPLogoImageSrcResolverService, AXPMenuKeyboardShortcutService, AXPMenuMiddlewareRegistry, AXPMenuProviderService, AXPMenuRouteAccessService, AXPMenuRouteGuard, AXPMenuSearchDefinitionProvider, AXPMenuSearchProvider, AXPMenuService, AXPMenuVisibilityService, AXPNavBarSlotComponent, AXPNavigateCommand, AXPNetworkConnectivityService, AXPNotFoundCatchAllRoute, AXPNotFoundError, AXPOutputContractTranscriptSegmentService, AXPPageGetContextQuery, AXPPageRunActionCommand, AXPPlatformBrandingService, AXPPlatformDefaultConfigs, AXPPlatformSettingsLoadState, AXPPlatformSettingsOfflineBootstrapService, AXPQueryEvaluatorScopeProvider, AXPQueryParamsEvaluatorScopeProvider, AXPRegionalCalendarService, AXPSearchCommandProvider, AXPSearchDefinitionActionBuilder, AXPSearchDefinitionBuilder, AXPSearchDefinitionProviderContext, AXPSearchDefinitionProviderService, AXPSearchService, AXPSettingDefaultValuesAggregatorService, AXPSettingDefinitionGroupBuilder, AXPSettingDefinitionProviderContext, AXPSettingDefinitionProviderService, AXPSettingDefinitionSectionBuilder, AXPSettingsBulkSyncService, AXPSettingsEvaluatorScopeProvider, AXPSettingsIndexedDb, AXPSettingsService, AXPStateMessageComponent, AXPStatusDefinitionProviderService, AXPStickyDirective, AXPTabNavigationService, AXPTabPreviewService, AXPTabRouteCacheRegistry, AXPTokenDefinitionService, AXPTokenEvaluatorScopeProvider, AXPTranslateFormatter, AXPUnsavedChangesConfirmService, AXPUnsavedChangesPopstateService, AXPUserNotificationService, AXPUserStatusFeatureService, AXPVersioningService, AXP_AGENT_OUTPUT_CONTRACT_DEFAULT_STRUCTURED_RETRIES, AXP_APP_VERSION_PROVIDER, AXP_BACKGROUND_OPERATION_ENTITY_STORAGE, AXP_BACKGROUND_OPERATION_HANDLERS, AXP_BACKGROUND_OPERATION_PROVIDERS, AXP_BREADCRUMB_COLLAPSE_HEAD_COUNT, AXP_BREADCRUMB_COLLAPSE_TAIL_COUNT, AXP_DOCUMENT_FILE_TYPE_PURPOSES, AXP_ENTITY_LIST_DISPLAY_MODE_DEFAULT, AXP_ENTITY_VIEW_ACCESS, AXP_EXPERIENCE_SETTINGS_GROUP, AXP_EXPERIENCE_SETTINGS_SECTIONS, AXP_FILE_ACTION_PROVIDER, AXP_FILE_TYPE_INFO_PROVIDER, AXP_FILTER_DEFAULT_OPERATORS_WIDGET_NAME, AXP_FILTER_DEFAULT_OPERATOR_WIDGETS, AXP_HOME_PAGES, AXP_HOME_PAGE_DEFAULT_KEY, AXP_HOME_TAB_KEY, AXP_INTEGRATION_CONNECTION_ESTABLISHED, AXP_INTEGRATION_CONNECTION_LIFECYCLE, AXP_INTEGRATION_DOMAIN_PROVIDER, AXP_INTEGRATION_OAUTH_SERVICE, AXP_INTEGRATION_PROVIDER, AXP_INTEGRATION_RUNTIME_PROVIDER, AXP_INTEGRATION_SECRET_STORE, AXP_IN_APP_NOTIFICATION_SERVICE, AXP_LOCALE_MANAGEMENT_PORT, AXP_LOCAL_ENTITY_BROADCAST_CHANNEL, AXP_LOCAL_ENTITY_DEFAULT_MAX_ITEMS, AXP_LOCAL_ENTITY_OUTBOX_LOCK, AXP_MENU_MIDDLEWARE, AXP_MENU_PROVIDER, AXP_NOT_FOUND_CATCH_ALL_ROUTE, AXP_NOT_FOUND_ROUTE, AXP_OUTPUT_CONTRACT_TRANSCRIPT_SEGMENT_PROVIDER, AXP_PLATFORM_BRANDING_SETTING_KEYS, AXP_PLATFORM_CONFIG_TOKEN, AXP_PROTECTED_ROUTE_GUARDS, AXP_ROOT_CONFIG_TOKEN, AXP_RUNTIME_QUERY_CACHE_DEFAULTS, AXP_SEARCH_DEFINITION_LAZY_RESOLVER, AXP_SEARCH_DEFINITION_PROVIDER, AXP_SEARCH_PROVIDER, AXP_SETTINGS_CACHE_SYNC, AXP_SETTINGS_SYNC_DEBOUNCE_MS, AXP_SETTINGS_SYNC_KEYS, AXP_SETTINGS_SYNC_RETRY_BACKOFF_MS, AXP_SETTINGS_SYNC_TTL_MS, AXP_SETTING_DEFAULT_VALUES_PROVIDERS, AXP_SETTING_DEFINITION_PROVIDER, AXP_SETTING_SCOPE_DESCENDANTS, AXP_SETTING_VALUE_PROVIDER, AXP_STATUS_PROVIDERS, AXP_TAB_BREADCRUMB_JOIN_SEPARATOR, AXP_TAB_ROUTE_DATA_KEY, AXP_TOKEN_DEFINITION_PROVIDER, AXP_UNAUTHORIZED_ROUTE, AXP_USER_NOTIFICATION_SERVICE, AXP_USER_STATUS_ENABLED_DEFAULT, AXVChangeType, AX_FILE_TYPE_METADATA_SUPPORT_BY_FILE_VIEWER, BETWEEN_OPER, BOOLEAN_OPERATORS, CONTAINS_OPER, DATE_OPERATORS, DEFAULT_DATE_FILTER_PRESETS, DEFAULT_MULTILANGUAGE_FIELD_NAMES, ENDS_WITH_OPER, ENTITY_LIST_DEFAULT_INSTANCE_ID, ENTITY_LIST_INSTANCE_QUERY_PARAM, ENVIRONMENT, EQ_OPER, FILE_VIEWER_PREVIEW_EXTENSIONS, GTE_OPER, GT_OPER, IN_OPER, IS_EMPTY_OPER, IS_NOT_EMPTY_OPER, LTE_OPER, LT_OPER, MULTILANGUAGE_CAPABLE_WIDGET_TYPES, NOT_CONTAINS_OPER, NOT_EQ_OPER, NUMBER_OPERATORS, SETTINGS_TRACE_NS, SETTINGS_TRACE_TITLE, STARTS_WITH_OPER, STRING_OPERATORS, UploadFromComputerActionProvider, applyDateFilterPreset, axpBackgroundOperationCapabilities, axpBackgroundOperationDisplayTime, axpBackgroundOperationDurationMs, axpBackgroundOperationEntityName, axpBackgroundOperationEstimateEndDate, axpBackgroundOperationFailurePolicy, axpBackgroundOperationFromEntityModel, axpBackgroundOperationRemainingMs, axpBackgroundOperationStatusTextParams, axpBackgroundOperationToEntityModel, axpBeginCommandSubFlowNavigation, axpBuildBackgroundOperation, axpBuildTabKey, axpClearEntityDetailsNavTrail, axpCloneBreadcrumbItems, axpCoerceBackgroundOperationDate, axpComposeEntityDetailsNavTrail, axpCreateBackgroundOperationId, axpEndCommandSubFlowNavigation, axpEnsureEntityListInstanceQueryParam, axpEntityKeyFromDetailsPath, axpEntityListNavigationTabKey, axpFallbackTabTitle, axpFindMenuItemByRoute, axpFormatBackgroundOperationDurationMs, axpGetBreadcrumbNavigatePath, axpGetEntityDetailsNavTrail, axpGetEntityListInstanceIdFromParamMap, axpGetEntityListInstanceIdFromPath, axpGetEntityListInstanceIdFromQueryString, axpGetEntityListReturnUrl, axpGetLeafRouteSnapshot, axpHasTabScope, axpInterpolateNavigatePath, axpIsActiveBackgroundOperationStatus, axpIsBackgroundOperationI18nText, axpIsCommandSubFlowNavigationSuspended, axpIsCompletedBackgroundOperationStatus, axpIsCompletedPanelBackgroundOperation, axpIsEntityDetailsPath, axpIsEntityDetailsViewRoute, axpIsEntityListPath, axpIsEntityListRoute, axpIsEntityRecordNotFound, axpIsInProgressPanelBackgroundOperation, axpIsLikelyNetworkFailure, axpIsSameEntityDetailsRecord, axpIsTabEligibleUrl, axpIsTrayVisibleBackgroundOperation, axpJoinTabTitleSegments, axpLocalEntityCanServeListLocally, axpLocalEntityHotListRequest, axpLocalEntityIndexedDb, axpLocalEntityRecordId, axpLocalEntitySortAt, axpLocalEntitySupportsOfflineWrite, axpLocalEntityToPayload, axpMenuItemListInstanceId, axpMenuPathsMatch, axpNavigateAppPath, axpNavigateCommandDefinition, axpNormalizeEntityListInstanceId, axpPageGetContextQueryDefinition, axpPageRunActionCommandDefinition, axpParseAppPath, axpParseEntityDetailsRoute, axpParseEntityListRoute, axpPathFromSnapshot, axpPeekCommandSubFlowReturnUrl, axpPlatformSettingsAvailableGuard, axpPrepareOriginNavTrail, axpRedirectToNotFound, axpRedirectToUnauthorized, axpReplaceEntityListRouteQueryParams, axpResolveNavigatePath, axpResolveTabKey, axpResolveTabKeyFromRouteConfig, axpResolveTabKeyFromSnapshot, axpResolveTabTitleParts, axpSaveEntityDetailsNavTrail, axpSaveEntityListReturnUrl, axpSetEntityDetailsPageQuery, axpSettingsIndexedDb, axpSnapshotDeclaresTabScope, axpSplitCollapsedBreadcrumbs, axpStampEntityListMenuInstancePaths, axpStripHomeBreadcrumb, axpStripTrailingCommandlessCrumbs, axpTabScopePathFromSnapshot, axpTrimNavTrailBeforeTarget, backgroundOperationEntityFactory, buildFileStorageDownloadUrl, buildLocalEntityMetaId, buildLocalEntityStorageId, buildScopedSettingsSnapshotId, chooseSystemFiles, coerceAXPSettingRawValue, coerceAXPSettingRawValueByKind, configPlatform, createBackgroundOperationStore, createDefaultSettingValueProviders, createEmptyScopedSettingsSnapshot, createEntityCommandOptions, createEntityRowExpressionScope, createEntitySearchCommand, createFileTypeOpenContext, createIndexedDbSettingValueProviders, createMenuContext, createMenuMiddleware, createUnsavedChangesCanDeactivateGuard, downloadGraphicFromElement, evaluateEntityDisplayTemplate, extractFileExtension, extractHttpRequestErrorInfo, extractRequestErrorInfo, findFilterDefaultOperatorWidget, findManualPresetIdByOperation, formatEntityRowDisplayTitle, formatRequestError, hasFileTypeOpenHandler, hydrateSettingsValuesFromIndexedDb, inferSettingCoercionKind, isFileNameShownInViewer, isFileTypeShownInViewer, isFileViewerPreviewExtension, isOneWaySettingsIndexedDbCache, isPendingCascadeFilter, isSettingKeyCacheable, isSettingVisibleOnScope, isStoredImageFileId, normalizeAvailableLanguageCodes, normalizeDocumentFileTypePurposes, normalizeDocumentToFileListItem, normalizeOverridableAt, normalizePositiveNumberOption, normalizeRouterUrl, normalizeStoredImageRef, openSystemFileDialog, peelSettingValueKey, platformErrorI18nKey, primaryLanguageSubtag, printGraphicFromElement, projectSettingsValuesForIndexedDb, provideAXPUserNotificationService, provideDynamicHomePage, provideLocalEntityOfflineRuntime, provideMenuMiddleware, purgeLegacyTenantScopedSettingsSnapshots, readFilterDefaultOperatorMap, resolveDateFilterPresets, resolveEffectiveAvailableLanguageCodes, resolveEntityCreateListBehavior, resolveEntityDetailsRouteAccess, resolveEntityModifyPopupTitle, resolveEntityRowDisplayText, resolveEntityRowDisplayTitle, resolveEntityRowDisplayTitleFromColumnContext, resolveEntitySearchTitleFallback, resolveExplorerFileDisplayName, resolveFileTypeDisplay, resolveFileViewerType, resolveGraphicElementSize, resolveGraphicPrintContent, resolveQueryMatchingDisplayText, resolveSearchDisplayTemplate, resolveSearchableText, resolveStoredFilterDefaultOperator, resolveStoredImageDisplayUrl, searchInRecordValues, searchInSearchableValue, serializeSvgElement, shouldApplyDefaultMultiLanguageToEntityProperty, shouldApplyDefaultMultiLanguageToWidgetNode, shouldApplyDefaultMultiLanguageToWidgetProperty, shouldPersistSettingsInIndexedDb, stripAccidentalNestedSettingParents, throwIfCommandFailed, toAXPRequestError, toExecuteCommandFailureResult, traceSettingsAppStartupLoadComplete, traceSettingsAppStartupLoadStarted, traceSettingsClientTool, traceSettingsFlush, traceSettingsLocalPersist, traceSettingsPageLoadComplete, traceSettingsPageLoadStarted, traceSettingsPageRouteLoad, traceSettingsRetryScheduled, traceSettingsRevalidateFailed, traceSettingsServerApiCall, traceSettingsServiceLoadComplete, traceSettingsServiceLoadFailed, traceSettingsServiceLoadStarted, traceSettingsServiceReload, traceSettingsSyncFailed, triggerBrowserDownload, tryOpenFileByCatalogType, withDefaultMultiLanguageOnWidgetNodeTree, withDefaultMultiLanguageOnWidgetProperty, withFilterDefaultOperator, writeFilterDefaultOperatorOverride };
14901
+ export { ALL_DEFAULT_OPERATORS, AXPAcorexFileTypeBridgeProvider, AXPAcorexFileTypeModule, AXPAppVersionService, AXPBackgroundOperationCompletionService, AXPBackgroundOperationEntityStoreService, AXPBackgroundOperationHandler, AXPBackgroundOperationNotificationService, AXPBackgroundOperationProvider, AXPBackgroundOperationRootConfig, AXPBackgroundOperationService, AXPBackgroundOperationSlotComponent, AXPBrowserTitleService, AXPCleanNestedFilters, AXPClipBoardService, AXPCommonModule, AXPCommonSettings, AXPCustomOperatorService, AXPCustomOperatorServiceImpl, AXPDataProvider, AXPDefaultMultiLanguageConfigService, AXPEntityDetailsNavTrailService, AXPErrorHandlerRegistryService, AXPExportService, AXPFileActionsService, AXPFileChooserSettings, AXPFileStorageEvaluatorScopeProvider, AXPFileStorageService, AXPFileTypeProviderService, AXPFilterDefaultOperatorService, AXPFilterOperatorMiddlewareService, AXPFilterOperatorMiddlewareServiceImpl, AXPFooterTextSlotComponent, AXPGlobalErrorHandler, AXPHomePageModule, AXPHomePageService, AXPIndexedDbSettingValueProvider, AXPIntegrationDomainProviderContext, AXPIntegrationDomainRegistryFacade, AXPIntegrationDomainRegistryService, AXPIntegrationOAuthService, AXPIntegrationProviderContext, AXPIntegrationProviderRegistryService, AXPIntegrationRuntimeService, AXPKeyboardShortcutsHelpComponent, AXPKeyboardShortcutsHelpService, AXPLocalEntityEngine, AXPLocalEntityIndexedDb, AXPLocalEntityOfflineRuntime, AXPLocalEntityOutboxService, AXPLocalEntityRealtimeBridge, AXPLockService, AXPLogoImageSrcResolverService, AXPMenuKeyboardShortcutService, AXPMenuMiddlewareRegistry, AXPMenuProviderService, AXPMenuRouteAccessService, AXPMenuRouteGuard, AXPMenuSearchDefinitionProvider, AXPMenuSearchProvider, AXPMenuService, AXPMenuVisibilityService, AXPNavBarSlotComponent, AXPNavigateCommand, AXPNetworkConnectivityService, AXPNotFoundCatchAllRoute, AXPNotFoundError, AXPOutputContractTranscriptSegmentService, AXPPageGetContextQuery, AXPPageRunActionCommand, AXPPlatformBrandingService, AXPPlatformDefaultConfigs, AXPPlatformSettingsLoadState, AXPPlatformSettingsOfflineBootstrapService, AXPQueryEvaluatorScopeProvider, AXPQueryParamsEvaluatorScopeProvider, AXPRegionalCalendarService, AXPSearchCommandProvider, AXPSearchDefinitionActionBuilder, AXPSearchDefinitionBuilder, AXPSearchDefinitionProviderContext, AXPSearchDefinitionProviderService, AXPSearchService, AXPSettingDefaultValuesAggregatorService, AXPSettingDefinitionGroupBuilder, AXPSettingDefinitionProviderContext, AXPSettingDefinitionProviderService, AXPSettingDefinitionSectionBuilder, AXPSettingsBulkSyncService, AXPSettingsEvaluatorScopeProvider, AXPSettingsIndexedDb, AXPSettingsService, AXPStateMessageComponent, AXPStatusDefinitionProviderService, AXPStickyDirective, AXPTabNavigationService, AXPTabPreviewService, AXPTabRouteCacheRegistry, AXPTokenDefinitionService, AXPTokenEvaluatorScopeProvider, AXPTranslateFormatter, AXPUnreachableRouteComponent, AXPUnsavedChangesConfirmService, AXPUnsavedChangesPopstateService, AXPUserNotificationService, AXPUserStatusFeatureService, AXPVersioningService, AXP_AGENT_OUTPUT_CONTRACT_DEFAULT_STRUCTURED_RETRIES, AXP_APP_VERSION_PROVIDER, AXP_BACKGROUND_OPERATION_ENTITY_STORAGE, AXP_BACKGROUND_OPERATION_HANDLERS, AXP_BACKGROUND_OPERATION_PROVIDERS, AXP_BREADCRUMB_COLLAPSE_HEAD_COUNT, AXP_BREADCRUMB_COLLAPSE_TAIL_COUNT, AXP_DOCUMENT_FILE_TYPE_PURPOSES, AXP_ENTITY_LIST_DISPLAY_MODE_DEFAULT, AXP_ENTITY_VIEW_ACCESS, AXP_EXPERIENCE_SETTINGS_GROUP, AXP_EXPERIENCE_SETTINGS_SECTIONS, AXP_FILE_ACTION_PROVIDER, AXP_FILE_TYPE_INFO_PROVIDER, AXP_FILTER_DEFAULT_OPERATORS_WIDGET_NAME, AXP_FILTER_DEFAULT_OPERATOR_WIDGETS, AXP_HOME_PAGES, AXP_HOME_PAGE_DEFAULT_KEY, AXP_HOME_TAB_KEY, AXP_INTEGRATION_CONNECTION_ESTABLISHED, AXP_INTEGRATION_CONNECTION_LIFECYCLE, AXP_INTEGRATION_DOMAIN_PROVIDER, AXP_INTEGRATION_OAUTH_SERVICE, AXP_INTEGRATION_PROVIDER, AXP_INTEGRATION_RUNTIME_PROVIDER, AXP_INTEGRATION_SECRET_STORE, AXP_IN_APP_NOTIFICATION_SERVICE, AXP_IN_TAB_ERROR_FROM_PARAM, AXP_LOCALE_MANAGEMENT_PORT, AXP_LOCAL_ENTITY_BROADCAST_CHANNEL, AXP_LOCAL_ENTITY_DEFAULT_MAX_ITEMS, AXP_LOCAL_ENTITY_OUTBOX_LOCK, AXP_MENU_MIDDLEWARE, AXP_MENU_PROVIDER, AXP_NOT_FOUND_CATCH_ALL_ROUTE, AXP_NOT_FOUND_ROUTE, AXP_OUTPUT_CONTRACT_TRANSCRIPT_SEGMENT_PROVIDER, AXP_PLATFORM_BRANDING_SETTING_KEYS, AXP_PLATFORM_CONFIG_TOKEN, AXP_PROTECTED_ROUTE_GUARDS, AXP_ROOT_CONFIG_TOKEN, AXP_RUNTIME_QUERY_CACHE_DEFAULTS, AXP_SEARCH_DEFINITION_LAZY_RESOLVER, AXP_SEARCH_DEFINITION_PROVIDER, AXP_SEARCH_PROVIDER, AXP_SETTINGS_CACHE_SYNC, AXP_SETTINGS_SYNC_DEBOUNCE_MS, AXP_SETTINGS_SYNC_KEYS, AXP_SETTINGS_SYNC_RETRY_BACKOFF_MS, AXP_SETTINGS_SYNC_TTL_MS, AXP_SETTING_DEFAULT_VALUES_PROVIDERS, AXP_SETTING_DEFINITION_PROVIDER, AXP_SETTING_SCOPE_DESCENDANTS, AXP_SETTING_VALUE_PROVIDER, AXP_STATUS_PROVIDERS, AXP_TAB_BREADCRUMB_JOIN_SEPARATOR, AXP_TAB_ROUTE_DATA_KEY, AXP_TOKEN_DEFINITION_PROVIDER, AXP_UNAUTHORIZED_ROUTE, AXP_USER_NOTIFICATION_SERVICE, AXP_USER_STATUS_ENABLED_DEFAULT, AXVChangeType, AX_FILE_TYPE_METADATA_SUPPORT_BY_FILE_VIEWER, BETWEEN_OPER, BOOLEAN_OPERATORS, CONTAINS_OPER, DATE_OPERATORS, DEFAULT_DATE_FILTER_PRESETS, DEFAULT_MULTILANGUAGE_FIELD_NAMES, ENDS_WITH_OPER, ENTITY_LIST_DEFAULT_INSTANCE_ID, ENTITY_LIST_INSTANCE_QUERY_PARAM, ENVIRONMENT, EQ_OPER, FILE_VIEWER_PREVIEW_EXTENSIONS, GTE_OPER, GT_OPER, IN_OPER, IS_EMPTY_OPER, IS_NOT_EMPTY_OPER, LTE_OPER, LT_OPER, MULTILANGUAGE_CAPABLE_WIDGET_TYPES, NOT_CONTAINS_OPER, NOT_EQ_OPER, NUMBER_OPERATORS, SETTINGS_TRACE_NS, SETTINGS_TRACE_TITLE, STARTS_WITH_OPER, STRING_OPERATORS, UploadFromComputerActionProvider, applyDateFilterPreset, axpBackgroundOperationCapabilities, axpBackgroundOperationDisplayTime, axpBackgroundOperationDurationMs, axpBackgroundOperationEntityName, axpBackgroundOperationEstimateEndDate, axpBackgroundOperationFailurePolicy, axpBackgroundOperationFromEntityModel, axpBackgroundOperationRemainingMs, axpBackgroundOperationStatusTextParams, axpBackgroundOperationToEntityModel, axpBeginCommandSubFlowNavigation, axpBuildBackgroundOperation, axpBuildTabKey, axpClearEntityDetailsNavTrail, axpCloneBreadcrumbItems, axpCoerceBackgroundOperationDate, axpComposeEntityDetailsNavTrail, axpCreateBackgroundOperationId, axpEndCommandSubFlowNavigation, axpEnsureEntityListInstanceQueryParam, axpEntityKeyFromDetailsPath, axpEntityListNavigationTabKey, axpFallbackTabTitle, axpFindMenuItemByRoute, axpFormatBackgroundOperationDurationMs, axpGetBreadcrumbNavigatePath, axpGetEntityDetailsNavTrail, axpGetEntityListInstanceIdFromParamMap, axpGetEntityListInstanceIdFromPath, axpGetEntityListInstanceIdFromQueryString, axpGetEntityListReturnUrl, axpGetLeafRouteSnapshot, axpHasTabScope, axpInTabErrorLocation, axpInTabErrorRetryUrl, axpInTabErrorSourceUrl, axpInTabErrorUrlTree, axpInterpolateNavigatePath, axpIsActiveBackgroundOperationStatus, axpIsBackgroundOperationI18nText, axpIsCommandSubFlowNavigationSuspended, axpIsCompletedBackgroundOperationStatus, axpIsCompletedPanelBackgroundOperation, axpIsEntityDetailsPath, axpIsEntityDetailsViewRoute, axpIsEntityListPath, axpIsEntityListRoute, axpIsEntityRecordNotFound, axpIsInProgressPanelBackgroundOperation, axpIsLikelyNetworkFailure, axpIsSameEntityDetailsRecord, axpIsTabEligibleUrl, axpIsTrayVisibleBackgroundOperation, axpJoinTabTitleSegments, axpLocalEntityCanServeListLocally, axpLocalEntityHotListRequest, axpLocalEntityIndexedDb, axpLocalEntityRecordId, axpLocalEntitySortAt, axpLocalEntitySupportsOfflineWrite, axpLocalEntityToPayload, axpMenuItemListInstanceId, axpMenuPathsMatch, axpNavigateAppPath, axpNavigateCommandDefinition, axpNormalizeEntityListInstanceId, axpOnCommandSubFlowNavigationEnded, axpPageGetContextQueryDefinition, axpPageRunActionCommandDefinition, axpParseAppPath, axpParseEntityDetailsRoute, axpParseEntityListRoute, axpPathFromSnapshot, axpPeekCommandSubFlowReturnUrl, axpPlatformSettingsAvailableGuard, axpPrepareOriginNavTrail, axpRedirectToNotFound, axpRedirectToUnauthorized, axpRedirectUnknownToNotFound, axpReplaceEntityListRouteQueryParams, axpResolveNavigatePath, axpResolveTabKey, axpResolveTabKeyFromRouteConfig, axpResolveTabKeyFromSnapshot, axpResolveTabTitleParts, axpSaveEntityDetailsNavTrail, axpSaveEntityListReturnUrl, axpSetEntityDetailsPageQuery, axpSettingsIndexedDb, axpSnapshotDeclaresTabScope, axpSplitCollapsedBreadcrumbs, axpStampEntityListMenuInstancePaths, axpStripHomeBreadcrumb, axpStripTrailingCommandlessCrumbs, axpTabScopePathFromSnapshot, axpTrimNavTrailBeforeTarget, backgroundOperationEntityFactory, buildFileStorageDownloadUrl, buildLocalEntityMetaId, buildLocalEntityStorageId, buildScopedSettingsSnapshotId, chooseSystemFiles, coerceAXPSettingRawValue, coerceAXPSettingRawValueByKind, configPlatform, createBackgroundOperationStore, createDefaultSettingValueProviders, createEmptyScopedSettingsSnapshot, createEntityCommandOptions, createEntityRowExpressionScope, createEntitySearchCommand, createFileTypeOpenContext, createIndexedDbSettingValueProviders, createMenuContext, createMenuMiddleware, createUnsavedChangesCanDeactivateGuard, downloadGraphicFromElement, evaluateEntityDisplayTemplate, extractFileExtension, extractHttpRequestErrorInfo, extractRequestErrorInfo, findFilterDefaultOperatorWidget, findManualPresetIdByOperation, formatEntityRowDisplayTitle, formatRequestError, hasFileTypeOpenHandler, hydrateSettingsValuesFromIndexedDb, inferSettingCoercionKind, isFileNameShownInViewer, isFileTypeShownInViewer, isFileViewerPreviewExtension, isOneWaySettingsIndexedDbCache, isPendingCascadeFilter, isSettingKeyCacheable, isSettingVisibleOnScope, isStoredImageFileId, normalizeAvailableLanguageCodes, normalizeDocumentFileTypePurposes, normalizeDocumentToFileListItem, normalizeOverridableAt, normalizePositiveNumberOption, normalizeRouterUrl, normalizeStoredImageRef, openSystemFileDialog, peelSettingValueKey, platformErrorI18nKey, primaryLanguageSubtag, printGraphicFromElement, projectSettingsValuesForIndexedDb, provideAXPUserNotificationService, provideDynamicHomePage, provideLocalEntityOfflineRuntime, provideMenuMiddleware, purgeLegacyTenantScopedSettingsSnapshots, readFilterDefaultOperatorMap, resolveDateFilterPresets, resolveEffectiveAvailableLanguageCodes, resolveEntityCreateListBehavior, resolveEntityDetailsRouteAccess, resolveEntityModifyPopupTitle, resolveEntityRowDisplayText, resolveEntityRowDisplayTitle, resolveEntityRowDisplayTitleFromColumnContext, resolveEntitySearchTitleFallback, resolveExplorerFileDisplayName, resolveFileTypeDisplay, resolveFileViewerType, resolveGraphicElementSize, resolveGraphicPrintContent, resolveQueryMatchingDisplayText, resolveSearchDisplayTemplate, resolveSearchableText, resolveStoredFilterDefaultOperator, resolveStoredImageDisplayUrl, searchInRecordValues, searchInSearchableValue, serializeSvgElement, shouldApplyDefaultMultiLanguageToEntityProperty, shouldApplyDefaultMultiLanguageToWidgetNode, shouldApplyDefaultMultiLanguageToWidgetProperty, shouldPersistSettingsInIndexedDb, stripAccidentalNestedSettingParents, throwIfCommandFailed, toAXPRequestError, toExecuteCommandFailureResult, traceSettingsAppStartupLoadComplete, traceSettingsAppStartupLoadStarted, traceSettingsClientTool, traceSettingsFlush, traceSettingsLocalPersist, traceSettingsPageLoadComplete, traceSettingsPageLoadStarted, traceSettingsPageRouteLoad, traceSettingsRetryScheduled, traceSettingsRevalidateFailed, traceSettingsServerApiCall, traceSettingsServiceLoadComplete, traceSettingsServiceLoadFailed, traceSettingsServiceLoadStarted, traceSettingsServiceReload, traceSettingsSyncFailed, triggerBrowserDownload, tryOpenFileByCatalogType, withDefaultMultiLanguageOnWidgetNodeTree, withDefaultMultiLanguageOnWidgetProperty, withFilterDefaultOperator, writeFilterDefaultOperatorOverride };
14450
14902
  //# sourceMappingURL=acorex-platform-framework-client-common.mjs.map