@acorex-platform/framework-client 2.0.0-next.2 → 2.0.0-next.21

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 (61) hide show
  1. package/fesm2022/{acorex-platform-framework-client-common-common-settings.provider-ChU2tvyt.mjs → acorex-platform-framework-client-common-common-settings.provider-Cyr1DaiD.mjs} +19 -2
  2. package/fesm2022/{acorex-platform-framework-client-common-common-settings.provider-ChU2tvyt.mjs.map → acorex-platform-framework-client-common-common-settings.provider-Cyr1DaiD.mjs.map} +1 -1
  3. package/fesm2022/acorex-platform-framework-client-common.mjs +416 -191
  4. package/fesm2022/acorex-platform-framework-client-common.mjs.map +1 -1
  5. package/fesm2022/acorex-platform-framework-client-core.mjs +7 -2
  6. package/fesm2022/acorex-platform-framework-client-core.mjs.map +1 -1
  7. package/fesm2022/acorex-platform-framework-client-layout-builder.mjs +20 -0
  8. package/fesm2022/acorex-platform-framework-client-layout-builder.mjs.map +1 -1
  9. package/fesm2022/acorex-platform-framework-client-layout-components.mjs +520 -142
  10. package/fesm2022/acorex-platform-framework-client-layout-components.mjs.map +1 -1
  11. package/fesm2022/{acorex-platform-framework-client-layout-entity-acorex-platform-framework-client-layout-entity-CA19c8sx.mjs → acorex-platform-framework-client-layout-entity-acorex-platform-framework-client-layout-entity-B3NLw_X8.mjs} +801 -207
  12. package/fesm2022/acorex-platform-framework-client-layout-entity-acorex-platform-framework-client-layout-entity-B3NLw_X8.mjs.map +1 -0
  13. package/fesm2022/{acorex-platform-framework-client-layout-entity-attachments-page.component-Dxp4kGsa.mjs → acorex-platform-framework-client-layout-entity-attachments-page.component-CCOi5IsF.mjs} +2 -2
  14. package/fesm2022/{acorex-platform-framework-client-layout-entity-attachments-page.component-Dxp4kGsa.mjs.map → acorex-platform-framework-client-layout-entity-attachments-page.component-CCOi5IsF.mjs.map} +1 -1
  15. package/fesm2022/{acorex-platform-framework-client-layout-entity-bulk-entity.command-fnICGK0s.mjs → acorex-platform-framework-client-layout-entity-bulk-entity.command-D8g9PkkI.mjs} +2 -2
  16. package/fesm2022/{acorex-platform-framework-client-layout-entity-bulk-entity.command-fnICGK0s.mjs.map → acorex-platform-framework-client-layout-entity-bulk-entity.command-D8g9PkkI.mjs.map} +1 -1
  17. package/fesm2022/{acorex-platform-framework-client-layout-entity-file-list-popup.component-BxTbTlUr.mjs → acorex-platform-framework-client-layout-entity-file-list-popup.component-B2aSSN0A.mjs} +4 -4
  18. package/fesm2022/{acorex-platform-framework-client-layout-entity-file-list-popup.component-BxTbTlUr.mjs.map → acorex-platform-framework-client-layout-entity-file-list-popup.component-B2aSSN0A.mjs.map} +1 -1
  19. package/fesm2022/{acorex-platform-framework-client-layout-entity-gallery-page.component-D0WZheYu.mjs → acorex-platform-framework-client-layout-entity-gallery-page.component-D6r3VvFN.mjs} +2 -2
  20. package/fesm2022/{acorex-platform-framework-client-layout-entity-gallery-page.component-D0WZheYu.mjs.map → acorex-platform-framework-client-layout-entity-gallery-page.component-D6r3VvFN.mjs.map} +1 -1
  21. package/fesm2022/acorex-platform-framework-client-layout-entity.mjs +1 -1
  22. package/fesm2022/acorex-platform-framework-client-layout-views.mjs +71 -10
  23. package/fesm2022/acorex-platform-framework-client-layout-views.mjs.map +1 -1
  24. package/fesm2022/acorex-platform-framework-client-layout-widget-core.mjs +285 -184
  25. package/fesm2022/acorex-platform-framework-client-layout-widget-core.mjs.map +1 -1
  26. package/fesm2022/{acorex-platform-framework-client-layout-widgets-acorex-platform-framework-client-layout-widgets-1UJh0Qj4.mjs → acorex-platform-framework-client-layout-widgets-acorex-platform-framework-client-layout-widgets-ByihbDgl.mjs} +228 -113
  27. package/fesm2022/acorex-platform-framework-client-layout-widgets-acorex-platform-framework-client-layout-widgets-ByihbDgl.mjs.map +1 -0
  28. package/fesm2022/{acorex-platform-framework-client-layout-widgets-repeater-widget-column.component-SHCgo4UC.mjs → acorex-platform-framework-client-layout-widgets-repeater-widget-column.component-BFB3Jo5r.mjs} +3 -3
  29. package/fesm2022/{acorex-platform-framework-client-layout-widgets-repeater-widget-column.component-SHCgo4UC.mjs.map → acorex-platform-framework-client-layout-widgets-repeater-widget-column.component-BFB3Jo5r.mjs.map} +1 -1
  30. package/fesm2022/{acorex-platform-framework-client-layout-widgets-text-block-widget-designer.component-BYsrp8LT.mjs → acorex-platform-framework-client-layout-widgets-text-block-widget-designer.component-HBONm-TI.mjs} +2 -2
  31. package/fesm2022/{acorex-platform-framework-client-layout-widgets-text-block-widget-designer.component-BYsrp8LT.mjs.map → acorex-platform-framework-client-layout-widgets-text-block-widget-designer.component-HBONm-TI.mjs.map} +1 -1
  32. package/fesm2022/acorex-platform-framework-client-layout-widgets.mjs +1 -1
  33. package/fesm2022/acorex-platform-framework-client-realtime.mjs +49 -7
  34. package/fesm2022/acorex-platform-framework-client-realtime.mjs.map +1 -1
  35. package/fesm2022/{acorex-platform-framework-client-themes-default-entity-master-create-view.component-DwCoz2Du.mjs → acorex-platform-framework-client-themes-default-entity-master-create-view.component-DPU6jTDk.mjs} +8 -2
  36. package/fesm2022/acorex-platform-framework-client-themes-default-entity-master-create-view.component-DPU6jTDk.mjs.map +1 -0
  37. package/fesm2022/{acorex-platform-framework-client-themes-default-entity-master-modify-view.component-BCyFK60f.mjs → acorex-platform-framework-client-themes-default-entity-master-modify-view.component-CLdQJ8e8.mjs} +8 -2
  38. package/fesm2022/acorex-platform-framework-client-themes-default-entity-master-modify-view.component-CLdQJ8e8.mjs.map +1 -0
  39. package/fesm2022/acorex-platform-framework-client-themes-default.mjs +124 -43
  40. package/fesm2022/acorex-platform-framework-client-themes-default.mjs.map +1 -1
  41. package/fesm2022/acorex-platform-framework-client-themes-shared.mjs +1 -1
  42. package/fesm2022/acorex-platform-framework-client-themes-shared.mjs.map +1 -1
  43. package/i18n/en-AU/general.json +16 -4
  44. package/i18n/en-AU/layout.json +2 -1
  45. package/i18n/en-US/general.json +16 -4
  46. package/i18n/en-US/layout.json +2 -1
  47. package/i18n/fa-IR/general.json +16 -4
  48. package/i18n/fa-IR/layout.json +2 -1
  49. package/package.json +6 -6
  50. package/types/acorex-platform-framework-client-common.d.ts +67 -7
  51. package/types/acorex-platform-framework-client-layout-components.d.ts +47 -6
  52. package/types/acorex-platform-framework-client-layout-entity.d.ts +117 -34
  53. package/types/acorex-platform-framework-client-layout-views.d.ts +15 -0
  54. package/types/acorex-platform-framework-client-layout-widget-core.d.ts +64 -14
  55. package/types/acorex-platform-framework-client-layout-widgets.d.ts +30 -1
  56. package/types/acorex-platform-framework-client-realtime.d.ts +5 -0
  57. package/types/acorex-platform-framework-client-themes-default.d.ts +12 -0
  58. package/fesm2022/acorex-platform-framework-client-layout-entity-acorex-platform-framework-client-layout-entity-CA19c8sx.mjs.map +0 -1
  59. package/fesm2022/acorex-platform-framework-client-layout-widgets-acorex-platform-framework-client-layout-widgets-1UJh0Qj4.mjs.map +0 -1
  60. package/fesm2022/acorex-platform-framework-client-themes-default-entity-master-create-view.component-DwCoz2Du.mjs.map +0 -1
  61. package/fesm2022/acorex-platform-framework-client-themes-default-entity-master-modify-view.component-BCyFK60f.mjs.map +0 -1
@@ -413,6 +413,11 @@ var AXPCommonSettings;
413
413
  * IndexedDB platform-settings cache. When false, bootstrap redirects to /auth/unavailable.
414
414
  */
415
415
  AXPCommonSettings["AllowWorkingOffline"] = "Common:Setting:Offline.AllowWorkingOffline";
416
+ /**
417
+ * Platform (P): when false, hide user availability (account menu, avatar dot, user card).
418
+ * Products without a status surface turn this off.
419
+ */
420
+ AXPCommonSettings["UserStatusEnabled"] = "Common:Setting:Presence.UserStatusEnabled";
416
421
  AXPCommonSettings["ShowRowIndexColumn"] = "Common:Setting:Entity.ShowRowIndexColumn";
417
422
  /** When true, the entity master-list table derives header bands from entity sections (property groups). */
418
423
  AXPCommonSettings["EntityMultiLevelHeaders"] = "Common:Setting:Entity.MultiLevelHeaders";
@@ -445,6 +450,8 @@ const AXP_RUNTIME_QUERY_CACHE_DEFAULTS = {
445
450
  };
446
451
  /** Default entity list presentation when the user has not chosen a layout. */
447
452
  const AXP_ENTITY_LIST_DISPLAY_MODE_DEFAULT = 'table';
453
+ /** User status stays visible until a platform setting turns it off. */
454
+ const AXP_USER_STATUS_ENABLED_DEFAULT = true;
448
455
 
449
456
  class AXPSettingDefinitionProviderContext {
450
457
  constructor() {
@@ -584,24 +591,64 @@ const AXP_SETTING_DEFINITION_PROVIDER = new InjectionToken('AXP_SETTING_DEFINITI
584
591
  class AXPSettingDefinitionProviderService {
585
592
  constructor() {
586
593
  this.providers = inject(AXP_SETTING_DEFINITION_PROVIDER, { optional: true });
594
+ this.sessionService = inject(AXPSessionService);
587
595
  this.cache = null;
596
+ /**
597
+ * Tenant, application, and enabled edition features.
598
+ * Providers such as Telegram gate sections on `isModuleEnabled` at build time,
599
+ * so a catalog built before login must be rebuilt once features arrive.
600
+ */
601
+ this.cacheAvailabilityKey = null;
588
602
  this.loadPromise = null;
589
603
  }
604
+ /** Same identity permissions use when deciding the definition cache is still valid. */
605
+ getAvailabilityKey() {
606
+ return this.buildAvailabilityKey();
607
+ }
608
+ buildAvailabilityKey() {
609
+ const enabled = this.sessionService.features
610
+ .filter((feature) => feature.value === true && !!feature.name)
611
+ .map((feature) => feature.name)
612
+ .sort();
613
+ const applicationId = this.sessionService.application?.id ?? '';
614
+ const tenantId = this.sessionService.tenant?.id ?? '';
615
+ return `${tenantId}|${applicationId}|${enabled.join(',')}`;
616
+ }
590
617
  async load() {
591
- if (this.cache) {
592
- return;
593
- }
594
- if (!this.loadPromise) {
595
- this.loadPromise = this.loadDefinitions().finally(() => {
596
- this.loadPromise = null;
618
+ while (true) {
619
+ const availabilityKey = this.buildAvailabilityKey();
620
+ if (this.cache && this.cacheAvailabilityKey === availabilityKey) {
621
+ return;
622
+ }
623
+ if (this.loadPromise) {
624
+ await this.loadPromise;
625
+ continue;
626
+ }
627
+ const keyAtStart = availabilityKey;
628
+ this.cache = null;
629
+ this.cacheAvailabilityKey = null;
630
+ let resolveLoad;
631
+ this.loadPromise = new Promise((resolve) => {
632
+ resolveLoad = resolve;
597
633
  });
634
+ try {
635
+ await this.loadDefinitions();
636
+ if (this.buildAvailabilityKey() === keyAtStart) {
637
+ this.cacheAvailabilityKey = keyAtStart;
638
+ }
639
+ else {
640
+ // Features changed while providers ran. Drop the catalog and rebuild.
641
+ this.cache = null;
642
+ this.cacheAvailabilityKey = null;
643
+ }
644
+ }
645
+ finally {
646
+ this.loadPromise = null;
647
+ resolveLoad();
648
+ }
598
649
  }
599
- await this.loadPromise;
600
650
  }
601
651
  async loadDefinitions() {
602
- if (this.cache) {
603
- return;
604
- }
605
652
  const context = new AXPSettingDefinitionProviderContext();
606
653
  // Load providers from DI tokens — isolate failures so one provider cannot block bootstrap.
607
654
  const providerList = this.normalizeProviders(this.providers);
@@ -629,6 +676,12 @@ class AXPSettingDefinitionProviderService {
629
676
  }
630
677
  async reload() {
631
678
  this.cache = null;
679
+ this.cacheAvailabilityKey = null;
680
+ if (this.loadPromise) {
681
+ await this.loadPromise;
682
+ this.cache = null;
683
+ this.cacheAvailabilityKey = null;
684
+ }
632
685
  await this.load();
633
686
  }
634
687
  async getListAsync(scope) {
@@ -2977,6 +3030,52 @@ function withDefaultMultiLanguageOnWidgetProperty(prop, applyDefault) {
2977
3030
  }
2978
3031
  //#endregion
2979
3032
 
3033
+ //#region ----- User status feature -----
3034
+ /**
3035
+ * Platform switch for showing user availability.
3036
+ * Stays on until {@link AXPCommonSettings.UserStatusEnabled} is false.
3037
+ */
3038
+ class AXPUserStatusFeatureService {
3039
+ //#endregion
3040
+ //#region ----- Lifecycle -----
3041
+ constructor() {
3042
+ //#region ----- Services & Dependencies -----
3043
+ this.settingsService = inject(AXPSettingsService);
3044
+ //#endregion
3045
+ //#region ----- State Signals -----
3046
+ this.enabledSignal = signal(AXP_USER_STATUS_ENABLED_DEFAULT, /* @ts-ignore */
3047
+ ...(ngDevMode ? [{ debugName: "enabledSignal" }] : /* istanbul ignore next */ []));
3048
+ /** Live platform flag. True until settings say otherwise. */
3049
+ this.enabled = this.enabledSignal.asReadonly();
3050
+ this.settingsService.onLoaded.subscribe(() => {
3051
+ void this.refresh();
3052
+ });
3053
+ this.settingsService.onChanged.subscribe((event) => {
3054
+ if (!event.keys.includes(AXPCommonSettings.UserStatusEnabled)) {
3055
+ return;
3056
+ }
3057
+ void this.refresh();
3058
+ });
3059
+ }
3060
+ //#endregion
3061
+ //#region ----- Public API -----
3062
+ async isEnabled() {
3063
+ return this.refresh();
3064
+ }
3065
+ async refresh() {
3066
+ const value = await this.settingsService.get(AXPCommonSettings.UserStatusEnabled);
3067
+ const enabled = value !== false;
3068
+ this.enabledSignal.set(enabled);
3069
+ return enabled;
3070
+ }
3071
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPUserStatusFeatureService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
3072
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPUserStatusFeatureService, providedIn: 'root' }); }
3073
+ }
3074
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPUserStatusFeatureService, decorators: [{
3075
+ type: Injectable,
3076
+ args: [{ providedIn: 'root' }]
3077
+ }], ctorParameters: () => [] });
3078
+
2980
3079
  //#region ----- Platform settings load state -----
2981
3080
  /**
2982
3081
  * Tracks fatal failure / offline-continue of the public platform (P) settings bootstrap.
@@ -3442,6 +3541,213 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
3442
3541
  }]
3443
3542
  }], ctorParameters: () => [] });
3444
3543
 
3544
+ //#endregion
3545
+ //#region ---- App Path Navigation ----
3546
+ /**
3547
+ * Splits an absolute app path (`/app/m/module/e/Entity/id/view`) into router command segments.
3548
+ * Prefer this over `navigate([fullPath])` or ambiguous single-segment navigation so browser history stays correct.
3549
+ */
3550
+ function axpParseAppPath(path) {
3551
+ const trimmed = path.trim();
3552
+ const withoutLeadingSlash = trimmed.startsWith('/') ? trimmed.slice(1) : trimmed;
3553
+ const [pathAndFragment, queryString] = withoutLeadingSlash.split('?');
3554
+ const [pathPart, fragment] = pathAndFragment.split('#');
3555
+ const segments = pathPart.split('/').filter(Boolean);
3556
+ const queryParams = queryString
3557
+ ? queryString.split('&').reduce((params, pair) => {
3558
+ const [key, value = ''] = pair.split('=');
3559
+ if (key) {
3560
+ params[decodeURIComponent(key)] = decodeURIComponent(value);
3561
+ }
3562
+ return params;
3563
+ }, {})
3564
+ : undefined;
3565
+ return {
3566
+ segments,
3567
+ queryParams,
3568
+ fragment: fragment || undefined,
3569
+ };
3570
+ }
3571
+ /** Navigates using explicit path segments (same pattern as entity preload filters). */
3572
+ function axpNavigateAppPath(router, path, extras) {
3573
+ const { segments, queryParams, fragment } = axpParseAppPath(path);
3574
+ return router.navigate(segments, {
3575
+ ...extras,
3576
+ queryParams,
3577
+ fragment,
3578
+ });
3579
+ }
3580
+ /** True when a URL path is an entity master list route (`.../e/{Entity}/list`). */
3581
+ function axpIsEntityListPath(url) {
3582
+ const path = url.split('?')[0].split('#')[0];
3583
+ return /\/e\/[^/]+\/list$/.test(path);
3584
+ }
3585
+ /** True when the current browser URL is an entity master list route (`.../e/{Entity}/list`). */
3586
+ function axpIsEntityListRoute(router) {
3587
+ return axpIsEntityListPath(router.url);
3588
+ }
3589
+ /** True when a URL path is an entity details view route (`.../e/{Entity}/{id}/view`). */
3590
+ function axpIsEntityDetailsPath(url) {
3591
+ const path = url.split('?')[0].split('#')[0];
3592
+ return /\/e\/[^/]+\/[^/]+\/view$/.test(path);
3593
+ }
3594
+ /**
3595
+ * Entity key (`module.entity`) for `/{app}/m/{module}/e/{entity}/{id}/view`.
3596
+ * Query and hash are ignored. Returns null for every other path.
3597
+ */
3598
+ function axpEntityKeyFromDetailsPath(url) {
3599
+ const path = url.split('?')[0]?.split('#')[0] ?? '';
3600
+ const match = /\/m\/([^/]+)\/e\/([^/]+)\/[^/]+\/view$/.exec(path);
3601
+ const moduleName = match?.[1];
3602
+ const entityName = match?.[2];
3603
+ if (!moduleName || !entityName) {
3604
+ return null;
3605
+ }
3606
+ return `${moduleName}.${entityName}`;
3607
+ }
3608
+ /** True when the current browser URL is an entity details view route (`.../e/{Entity}/{id}/view`). */
3609
+ function axpIsEntityDetailsViewRoute(router) {
3610
+ return axpIsEntityDetailsPath(router.url);
3611
+ }
3612
+ /**
3613
+ * Merges query params on the current entity list route without pushing history.
3614
+ * Uses absolute path segments so a stale `relativeTo` cannot rewrite the active URL after navigating away.
3615
+ */
3616
+ function axpReplaceEntityListRouteQueryParams(router, queryParams) {
3617
+ const url = router.url;
3618
+ if (!axpIsEntityListPath(url)) {
3619
+ return;
3620
+ }
3621
+ const parsed = router.parseUrl(url);
3622
+ const pathOnly = url.split('?')[0].split('#')[0];
3623
+ const { segments } = axpParseAppPath(pathOnly);
3624
+ const mergedQueryParams = { ...parsed.queryParams, ...queryParams };
3625
+ void router.navigate(segments, {
3626
+ queryParams: mergedQueryParams,
3627
+ replaceUrl: true,
3628
+ });
3629
+ }
3630
+ //#endregion
3631
+
3632
+ //#region ----- Constants -----
3633
+ /** Query param that distinguishes two menus pointing at the same entity list. */
3634
+ const ENTITY_LIST_INSTANCE_QUERY_PARAM = 'list';
3635
+ /** Used when the list is opened without a menu (command, deep link). */
3636
+ const ENTITY_LIST_DEFAULT_INSTANCE_ID = 'default';
3637
+ //#endregion
3638
+ //#region ----- Instance id -----
3639
+ function axpNormalizeEntityListInstanceId(value) {
3640
+ if (typeof value !== 'string') {
3641
+ return ENTITY_LIST_DEFAULT_INSTANCE_ID;
3642
+ }
3643
+ const trimmed = value.trim();
3644
+ return trimmed.length > 0 ? trimmed : ENTITY_LIST_DEFAULT_INSTANCE_ID;
3645
+ }
3646
+ function axpGetEntityListInstanceIdFromQueryString(queryString) {
3647
+ const params = new URLSearchParams(queryString.startsWith('?') ? queryString.slice(1) : queryString);
3648
+ return axpNormalizeEntityListInstanceId(params.get(ENTITY_LIST_INSTANCE_QUERY_PARAM));
3649
+ }
3650
+ function axpGetEntityListInstanceIdFromParamMap(queryParamMap) {
3651
+ return axpNormalizeEntityListInstanceId(queryParamMap.get(ENTITY_LIST_INSTANCE_QUERY_PARAM));
3652
+ }
3653
+ function axpGetEntityListInstanceIdFromPath(path) {
3654
+ const queryString = path.split('#')[0].split('?')[1] ?? '';
3655
+ return axpGetEntityListInstanceIdFromQueryString(queryString);
3656
+ }
3657
+ //#endregion
3658
+ //#region ----- Menu / URL stamping -----
3659
+ /**
3660
+ * Appends `list={instanceId}` to an entity-list path when missing.
3661
+ * Named menu entries get a stable identity so Angular reuses the list route
3662
+ * while filter persistence can still isolate each menu.
3663
+ */
3664
+ function axpEnsureEntityListInstanceQueryParam(path, instanceId) {
3665
+ if (!path || !instanceId || !axpIsEntityListPath(path)) {
3666
+ return path;
3667
+ }
3668
+ const normalized = axpNormalizeEntityListInstanceId(instanceId);
3669
+ if (normalized === ENTITY_LIST_DEFAULT_INSTANCE_ID) {
3670
+ return path;
3671
+ }
3672
+ const { segments, queryParams, fragment } = axpParseAppPath(path);
3673
+ if (queryParams?.[ENTITY_LIST_INSTANCE_QUERY_PARAM]) {
3674
+ return path;
3675
+ }
3676
+ const nextQuery = new URLSearchParams({
3677
+ ...(queryParams ?? {}),
3678
+ [ENTITY_LIST_INSTANCE_QUERY_PARAM]: normalized,
3679
+ });
3680
+ const base = `/${segments.join('/')}`;
3681
+ const withQuery = `${base}?${nextQuery.toString()}`;
3682
+ return fragment ? `${withQuery}#${fragment}` : withQuery;
3683
+ }
3684
+ /**
3685
+ * Query keys the list page rewrites while the user stays on the same menu
3686
+ * (`view`, `filters`, layout, refresh). They must not open another tab.
3687
+ */
3688
+ const ENTITY_LIST_PAGE_STATE_QUERY_KEYS = new Set(['view', 'layout', 'filters', '_ts']);
3689
+ function pushEntityListNavigationPair(pairs, key, raw) {
3690
+ if (!key || ENTITY_LIST_PAGE_STATE_QUERY_KEYS.has(key)) {
3691
+ return;
3692
+ }
3693
+ const value = Array.isArray(raw) ? raw[0] : raw;
3694
+ if (typeof value !== 'string') {
3695
+ return;
3696
+ }
3697
+ if (key === ENTITY_LIST_INSTANCE_QUERY_PARAM) {
3698
+ const normalized = axpNormalizeEntityListInstanceId(value);
3699
+ if (normalized === ENTITY_LIST_DEFAULT_INSTANCE_ID) {
3700
+ return;
3701
+ }
3702
+ pairs.push([key, normalized]);
3703
+ return;
3704
+ }
3705
+ pairs.push([key, value]);
3706
+ }
3707
+ function readEntityListNavigationPairs(query) {
3708
+ const pairs = [];
3709
+ if (!query) {
3710
+ return pairs;
3711
+ }
3712
+ if (typeof query === 'string') {
3713
+ const queryString = query.includes('?')
3714
+ ? (query.split('#')[0].split('?')[1] ?? '')
3715
+ : query.replace(/^\?/, '');
3716
+ const params = new URLSearchParams(queryString);
3717
+ params.forEach((value, key) => pushEntityListNavigationPair(pairs, key, value));
3718
+ return pairs;
3719
+ }
3720
+ if (typeof URLSearchParams !== 'undefined' && query instanceof URLSearchParams) {
3721
+ query.forEach((value, key) => pushEntityListNavigationPair(pairs, key, value));
3722
+ return pairs;
3723
+ }
3724
+ for (const [key, value] of Object.entries(query)) {
3725
+ pushEntityListNavigationPair(pairs, key, value);
3726
+ }
3727
+ return pairs;
3728
+ }
3729
+ /**
3730
+ * Tab and route-cache identity for an entity list.
3731
+ * Navigation query params (`mode=cm`, `mode=pm`, non-default `list`, …) keep each menu distinct,
3732
+ * the same way simple navigation does. Page-state params stay on the URL and do not split the tab.
3733
+ */
3734
+ function axpEntityListNavigationTabKey(path, query) {
3735
+ const base = path.split('?')[0].split('#')[0].replace(/\/+$/, '') || '/';
3736
+ if (!axpIsEntityListPath(base)) {
3737
+ return base;
3738
+ }
3739
+ const pairs = readEntityListNavigationPairs(query);
3740
+ if (!pairs.length) {
3741
+ return base;
3742
+ }
3743
+ pairs.sort((left, right) => left[0].localeCompare(right[0]) || left[1].localeCompare(right[1]));
3744
+ const queryString = pairs
3745
+ .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
3746
+ .join('&');
3747
+ return `${base}?${queryString}`;
3748
+ }
3749
+ //#endregion
3750
+
3445
3751
  //#endregion
3446
3752
  /**
3447
3753
  * Holds detached Angular route component instances keyed by tab key so tabular navigation can
@@ -3502,7 +3808,11 @@ class AXPTabRouteCacheRegistry {
3502
3808
  */
3503
3809
  syncOpenKeys(scopedKeys, activeTabUrls = []) {
3504
3810
  const scopedSet = new Set(scopedKeys);
3505
- const activePathSet = new Set(activeTabUrls.map((url) => url.split('?')[0].split('#')[0].replace(/\/+$/, '') || '/'));
3811
+ const activePathSet = new Set(activeTabUrls.flatMap((url) => {
3812
+ const pathOnly = url.split('?')[0].split('#')[0].replace(/\/+$/, '') || '/';
3813
+ const withNavigation = axpEntityListNavigationTabKey(pathOnly, url);
3814
+ return withNavigation === pathOnly ? [pathOnly] : [pathOnly, withNavigation];
3815
+ }));
3506
3816
  for (const cacheKey of [...this.handles.keys()]) {
3507
3817
  const normalizedCacheKey = cacheKey.replace(/\/+$/, '') || '/';
3508
3818
  const keepsScopedKey = scopedSet.has(normalizedCacheKey);
@@ -3832,6 +4142,7 @@ const AXP_EXPERIENCE_SETTINGS_SECTIONS = {
3832
4142
  Performance: 'performance',
3833
4143
  Entity: 'entity',
3834
4144
  Offline: 'offline',
4145
+ Presence: 'presence',
3835
4146
  FileChooser: 'file-chooser',
3836
4147
  };
3837
4148
  //#endregion
@@ -5329,7 +5640,7 @@ class AXPBackgroundOperationSlotComponent {
5329
5640
  this.popover()?.close();
5330
5641
  }
5331
5642
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPBackgroundOperationSlotComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
5332
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPBackgroundOperationSlotComponent, isStandalone: true, selector: "axp-background-operation-slot", viewQueries: [{ propertyName: "popover", first: true, predicate: AXPopoverComponent, descendants: true, isSignal: true }], ngImport: i0, template: "@if (showSlot()) {\n <!-- ----- Footer tray trigger ----- -->\n <button type=\"button\" class=\"operation-slot__trigger\" #operationTrigger (click)=\"onTriggerClick(panel)\">\n @if (badgeDisplay()) {\n <!-- ----- Count badge ----- -->\n <ax-badge class=\"operation-slot__badge\" [class.--xs]=\"badgeDisplay().length > 2\" color=\"danger\" [text]=\"badgeDisplay()\"></ax-badge>\n }\n @if (slotShowsFailureOnly()) {\n <!-- ----- Failed tasks ----- -->\n <ax-icon class=\"operation-slot__icon\">\n <i class=\"fa-light fa-circle-exclamation\"></i>\n </ax-icon>\n }\n <!--->\n <!-- ----- In-progress spinner (no icon for completed) ----- -->\n @else if (!slotShowsRetainedOnly()) {\n <ax-icon class=\"operation-slot__icon\">\n <i class=\"fa-light fa-spinner fa-spin\"></i>\n </ax-icon>\n }\n <span class=\"operation-slot__text\">\n {{ slotLabelKey() | translate | async }}\n </span>\n </button>\n\n <ax-popover\n [target]=\"operationTrigger\"\n [openOn]=\"'toggle'\"\n [closeOn]=\"'clickOut'\"\n [adaptivityEnabled]=\"true\"\n (onOpened)=\"onPopoverOpened(panel)\"\n >\n <axp-background-operation-panel\n #panel\n (onClosePopover)=\"closePopover()\"\n ></axp-background-operation-panel>\n </ax-popover>\n}\n", styles: ["@layer properties;axp-background-operation-slot{display:inline-flex}.operation-slot__trigger{display:inline-flex;cursor:pointer;align-items:center;gap:calc(var(--spacing, .25rem) * 1.5);border-radius:var(--radius-md, .375rem);border-style:var(--tw-border-style);border-width:0px;background-color:transparent;padding-inline:calc(var(--spacing, .25rem) * 2);padding-block:var(--spacing, .25rem);color:var(--color-text-default);--ax-sys-size: ax-sm;--ax-sys-size-base: calc(var(--ax-sys-size-md) - var(--ax-sys-size-step));--spacing: calc(var(--ax-sys-spacing-base) - .25 * var(--ax-sys-padding-step));--ax-sys-border-radius: var(--ax-sys-border-radius-base);--text-xs: calc(var(--ax-sys-text-xs-base) * 11 / 12);--text-sm: calc(var(--ax-sys-text-sm-base) * 6 / 7);--text-base: calc(var(--ax-sys-body-font-size) * .875);--text-lg: calc(var(--ax-sys-text-lg-base) * 8 / 9);--text-xl: calc(var(--ax-sys-text-xl-base) * .9);--leading-3: calc(var(--ax-sys-leading-3-base) * 7 / 6);--leading-4: var(--ax-sys-leading-4-base);--leading-5: calc(var(--ax-sys-leading-5-base) * .9);--leading-6: calc(var(--ax-sys-leading-6-base) * 11 / 12)}@media(hover:hover){.operation-slot__trigger:hover{background-color:rgba(var(--ax-sys-color-light-surface))}}.operation-slot__icon{font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)))}.operation-slot__text{font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500)}.operation-slot__badge{flex-shrink:0}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid;--tw-font-weight: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "component", type: i4$1.AXBadgeComponent, selector: "ax-badge", inputs: ["color", "look", "text"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: AXPopoverModule }, { kind: "component", type: i3$2.AXPopoverComponent, selector: "ax-popover", inputs: ["width", "disablePanelClass", "visualContextScope", "disabled", "offsetX", "offsetY", "target", "placement", "content", "openOn", "closeOn", "hasBackdrop", "openAfter", "closeAfter", "closeOnScroll", "closeOnNavigation", "backdropClass", "panelClass", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "component", type: AXPBackgroundOperationPanelComponent, selector: "axp-background-operation-panel", outputs: ["onActiveCountChange", "onClosePopover"] }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
5643
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPBackgroundOperationSlotComponent, isStandalone: true, selector: "axp-background-operation-slot", viewQueries: [{ propertyName: "popover", first: true, predicate: AXPopoverComponent, descendants: true, isSignal: true }], ngImport: i0, template: "@if (showSlot()) {\n <!-- ----- Footer tray trigger ----- -->\n <button type=\"button\" class=\"operation-slot__trigger\" #operationTrigger (click)=\"onTriggerClick(panel)\">\n @if (badgeDisplay()) {\n <!-- ----- Count badge ----- -->\n <ax-badge class=\"operation-slot__badge\" [class.--xs]=\"badgeDisplay().length > 2\" color=\"danger\" [text]=\"badgeDisplay()\"></ax-badge>\n }\n @if (slotShowsFailureOnly()) {\n <!-- ----- Failed tasks ----- -->\n <ax-icon class=\"operation-slot__icon\">\n <i class=\"fa-light fa-circle-exclamation\"></i>\n </ax-icon>\n }\n <!--->\n <!-- ----- In-progress spinner (no icon for completed) ----- -->\n @else if (!slotShowsRetainedOnly()) {\n <ax-icon class=\"operation-slot__icon\">\n <i class=\"fa-light fa-spinner fa-spin\"></i>\n </ax-icon>\n }\n <span class=\"operation-slot__text\">\n {{ slotLabelKey() | translate | async }}\n </span>\n </button>\n\n <ax-popover\n [target]=\"operationTrigger\"\n [openOn]=\"'toggle'\"\n [closeOn]=\"'clickOut'\"\n [adaptivityEnabled]=\"true\"\n (onOpened)=\"onPopoverOpened(panel)\"\n >\n <axp-background-operation-panel\n #panel\n (onClosePopover)=\"closePopover()\"\n ></axp-background-operation-panel>\n </ax-popover>\n}\n", styles: ["@layer properties;axp-background-operation-slot{display:inline-flex}.operation-slot__trigger{display:inline-flex;cursor:pointer;align-items:center;gap:calc(var(--spacing, .25rem) * 1.5);border-radius:var(--radius-md, .375rem);border-style:var(--tw-border-style);border-width:0px;background-color:transparent;padding-inline:calc(var(--spacing, .25rem) * 2);padding-block:var(--spacing, .25rem);color:var(--color-text-default);--ax-sys-size: ax-sm;--ax-sys-size-base: calc(var(--ax-sys-size-md) - var(--ax-sys-size-step));--spacing: calc(var(--ax-sys-spacing-base) - .25 * var(--ax-sys-padding-step));--ax-sys-border-radius: var(--ax-sys-border-radius-base);--text-xs: calc(var(--ax-sys-text-xs-base) * 11 / 12);--text-sm: calc(var(--ax-sys-text-sm-base) * 6 / 7);--text-base: calc(var(--ax-sys-body-font-size) * .875);--text-lg: calc(var(--ax-sys-text-lg-base) * 8 / 9);--text-xl: calc(var(--ax-sys-text-xl-base) * .9);--leading-3: calc(var(--ax-sys-leading-3-base) * 7 / 6);--leading-4: var(--ax-sys-leading-4-base);--leading-5: calc(var(--ax-sys-leading-5-base) * .9);--leading-6: calc(var(--ax-sys-leading-6-base) * 11 / 12)}@media(hover:hover){.operation-slot__trigger:hover{background-color:rgba(var(--ax-sys-color-light-surface))}}.operation-slot__icon{font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)))}.operation-slot__text{font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500)}.operation-slot__badge{flex-shrink:0}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid;--tw-font-weight: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "component", type: i4$1.AXBadgeComponent, selector: "ax-badge", inputs: ["color", "look", "text"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: AXPopoverModule }, { kind: "component", type: i3$2.AXPopoverComponent, selector: "ax-popover", inputs: ["width", "disablePanelClass", "visualContextScope", "disabled", "offsetX", "offsetY", "target", "placement", "content", "openOn", "closeOn", "hasBackdrop", "restoreFocusOnClose", "openAfter", "closeAfter", "closeOnScroll", "closeOnNavigation", "backdropClass", "panelClass", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "component", type: AXPBackgroundOperationPanelComponent, selector: "axp-background-operation-panel", outputs: ["onActiveCountChange", "onClosePopover"] }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
5333
5644
  }
5334
5645
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPBackgroundOperationSlotComponent, decorators: [{
5335
5646
  type: Component,
@@ -5600,148 +5911,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
5600
5911
  args: [{ providedIn: 'root' }]
5601
5912
  }] });
5602
5913
 
5603
- //#endregion
5604
- //#region ---- App Path Navigation ----
5605
- /**
5606
- * Splits an absolute app path (`/app/m/module/e/Entity/id/view`) into router command segments.
5607
- * Prefer this over `navigate([fullPath])` or ambiguous single-segment navigation so browser history stays correct.
5608
- */
5609
- function axpParseAppPath(path) {
5610
- const trimmed = path.trim();
5611
- const withoutLeadingSlash = trimmed.startsWith('/') ? trimmed.slice(1) : trimmed;
5612
- const [pathAndFragment, queryString] = withoutLeadingSlash.split('?');
5613
- const [pathPart, fragment] = pathAndFragment.split('#');
5614
- const segments = pathPart.split('/').filter(Boolean);
5615
- const queryParams = queryString
5616
- ? queryString.split('&').reduce((params, pair) => {
5617
- const [key, value = ''] = pair.split('=');
5618
- if (key) {
5619
- params[decodeURIComponent(key)] = decodeURIComponent(value);
5620
- }
5621
- return params;
5622
- }, {})
5623
- : undefined;
5624
- return {
5625
- segments,
5626
- queryParams,
5627
- fragment: fragment || undefined,
5628
- };
5629
- }
5630
- /** Navigates using explicit path segments (same pattern as entity preload filters). */
5631
- function axpNavigateAppPath(router, path, extras) {
5632
- const { segments, queryParams, fragment } = axpParseAppPath(path);
5633
- return router.navigate(segments, {
5634
- ...extras,
5635
- queryParams,
5636
- fragment,
5637
- });
5638
- }
5639
- /** True when a URL path is an entity master list route (`.../e/{Entity}/list`). */
5640
- function axpIsEntityListPath(url) {
5641
- const path = url.split('?')[0].split('#')[0];
5642
- return /\/e\/[^/]+\/list$/.test(path);
5643
- }
5644
- /** True when the current browser URL is an entity master list route (`.../e/{Entity}/list`). */
5645
- function axpIsEntityListRoute(router) {
5646
- return axpIsEntityListPath(router.url);
5647
- }
5648
- /** True when a URL path is an entity details view route (`.../e/{Entity}/{id}/view`). */
5649
- function axpIsEntityDetailsPath(url) {
5650
- const path = url.split('?')[0].split('#')[0];
5651
- return /\/e\/[^/]+\/[^/]+\/view$/.test(path);
5652
- }
5653
- /**
5654
- * Entity key (`module.entity`) for `/{app}/m/{module}/e/{entity}/{id}/view`.
5655
- * Query and hash are ignored. Returns null for every other path.
5656
- */
5657
- function axpEntityKeyFromDetailsPath(url) {
5658
- const path = url.split('?')[0]?.split('#')[0] ?? '';
5659
- const match = /\/m\/([^/]+)\/e\/([^/]+)\/[^/]+\/view$/.exec(path);
5660
- const moduleName = match?.[1];
5661
- const entityName = match?.[2];
5662
- if (!moduleName || !entityName) {
5663
- return null;
5664
- }
5665
- return `${moduleName}.${entityName}`;
5666
- }
5667
- /** True when the current browser URL is an entity details view route (`.../e/{Entity}/{id}/view`). */
5668
- function axpIsEntityDetailsViewRoute(router) {
5669
- return axpIsEntityDetailsPath(router.url);
5670
- }
5671
- /**
5672
- * Merges query params on the current entity list route without pushing history.
5673
- * Uses absolute path segments so a stale `relativeTo` cannot rewrite the active URL after navigating away.
5674
- */
5675
- function axpReplaceEntityListRouteQueryParams(router, queryParams) {
5676
- const url = router.url;
5677
- if (!axpIsEntityListPath(url)) {
5678
- return;
5679
- }
5680
- const parsed = router.parseUrl(url);
5681
- const pathOnly = url.split('?')[0].split('#')[0];
5682
- const { segments } = axpParseAppPath(pathOnly);
5683
- const mergedQueryParams = { ...parsed.queryParams, ...queryParams };
5684
- void router.navigate(segments, {
5685
- queryParams: mergedQueryParams,
5686
- replaceUrl: true,
5687
- });
5688
- }
5689
- //#endregion
5690
-
5691
- //#region ----- Constants -----
5692
- /** Query param that distinguishes two menus pointing at the same entity list. */
5693
- const ENTITY_LIST_INSTANCE_QUERY_PARAM = 'list';
5694
- /** Used when the list is opened without a menu (command, deep link). */
5695
- const ENTITY_LIST_DEFAULT_INSTANCE_ID = 'default';
5696
- //#endregion
5697
- //#region ----- Instance id -----
5698
- function axpNormalizeEntityListInstanceId(value) {
5699
- if (typeof value !== 'string') {
5700
- return ENTITY_LIST_DEFAULT_INSTANCE_ID;
5701
- }
5702
- const trimmed = value.trim();
5703
- return trimmed.length > 0 ? trimmed : ENTITY_LIST_DEFAULT_INSTANCE_ID;
5704
- }
5705
- function axpGetEntityListInstanceIdFromQueryString(queryString) {
5706
- const params = new URLSearchParams(queryString.startsWith('?') ? queryString.slice(1) : queryString);
5707
- return axpNormalizeEntityListInstanceId(params.get(ENTITY_LIST_INSTANCE_QUERY_PARAM));
5708
- }
5709
- function axpGetEntityListInstanceIdFromParamMap(queryParamMap) {
5710
- return axpNormalizeEntityListInstanceId(queryParamMap.get(ENTITY_LIST_INSTANCE_QUERY_PARAM));
5711
- }
5712
- function axpGetEntityListInstanceIdFromPath(path) {
5713
- const queryString = path.split('#')[0].split('?')[1] ?? '';
5714
- return axpGetEntityListInstanceIdFromQueryString(queryString);
5715
- }
5716
- //#endregion
5717
- //#region ----- Menu / URL stamping -----
5718
- /**
5719
- * Appends `list={instanceId}` to an entity-list path when missing.
5720
- * Named menu entries get a stable identity so Angular reuses the list route
5721
- * while filter persistence can still isolate each menu.
5722
- */
5723
- function axpEnsureEntityListInstanceQueryParam(path, instanceId) {
5724
- if (!path || !instanceId || !axpIsEntityListPath(path)) {
5725
- return path;
5726
- }
5727
- const normalized = axpNormalizeEntityListInstanceId(instanceId);
5728
- if (normalized === ENTITY_LIST_DEFAULT_INSTANCE_ID) {
5729
- return path;
5730
- }
5731
- const { segments, queryParams, fragment } = axpParseAppPath(path);
5732
- if (queryParams?.[ENTITY_LIST_INSTANCE_QUERY_PARAM]) {
5733
- return path;
5734
- }
5735
- const nextQuery = new URLSearchParams({
5736
- ...(queryParams ?? {}),
5737
- [ENTITY_LIST_INSTANCE_QUERY_PARAM]: normalized,
5738
- });
5739
- const base = `/${segments.join('/')}`;
5740
- const withQuery = `${base}?${nextQuery.toString()}`;
5741
- return fragment ? `${withQuery}#${fragment}` : withQuery;
5742
- }
5743
- //#endregion
5744
-
5745
5914
  //#region ----- Menu instance identity -----
5746
5915
  /** Prefers the stamped `list` query param, then the menu item name. */
5747
5916
  function axpMenuItemListInstanceId(item) {
@@ -7248,13 +7417,14 @@ withMethods((store, router = inject(Router), commandService = inject(AXPCommandS
7248
7417
  const IGNORED_QUERY_KEYS = new Set(['_ts']);
7249
7418
  /**
7250
7419
  * Builds a stable tab key from a router URL.
7251
- * Path segments define identity; query params are excluded so the same entity record
7252
- * or list reuses one tab even when filters or refresh tokens change.
7420
+ * Path segments define the page. Entity-list navigation query params (`mode`, `list`, …)
7421
+ * stay in the key so two menus of the same entity stay distinct, matching simple navigation.
7422
+ * Page-state params (`view`, `filters`, `_ts`) stay on the URL and do not open another tab.
7253
7423
  */
7254
7424
  function axpBuildTabKey(url) {
7255
7425
  const normalized = normalizeRouterUrl(url);
7256
7426
  const pathOnly = normalized.split('?')[0].split('#')[0];
7257
- return pathOnly;
7427
+ return axpEntityListNavigationTabKey(pathOnly, normalized);
7258
7428
  }
7259
7429
  /** Normalizes a router URL for storage and navigation. */
7260
7430
  function normalizeRouterUrl(url) {
@@ -7306,9 +7476,20 @@ const AXP_TAB_ROUTE_DATA_KEY = 'tab';
7306
7476
  //#endregion
7307
7477
 
7308
7478
  //#region ---- Route Data ----
7309
- /** True when the route declares itself as a scoped tab root (`data.tab = true`). */
7479
+ /**
7480
+ * True when this route node itself sets `data.tab = true`.
7481
+ * Pass the route's own config data. Activated snapshots merge parent `data`, so `snapshot.data`
7482
+ * is not a declaration — a child would look like its own tab root.
7483
+ */
7310
7484
  function axpHasTabScope(data) {
7311
- return data?.[AXP_TAB_ROUTE_DATA_KEY] === true;
7485
+ if (!data) {
7486
+ return false;
7487
+ }
7488
+ return data[AXP_TAB_ROUTE_DATA_KEY] === true;
7489
+ }
7490
+ /** True when this snapshot's route config declares `data.tab`, ignoring data inherited from parents. */
7491
+ function axpSnapshotDeclaresTabScope(snapshot) {
7492
+ return axpHasTabScope(snapshot.routeConfig?.data);
7312
7493
  }
7313
7494
  //#endregion
7314
7495
  //#region ---- Snapshot Resolution ----
@@ -7328,19 +7509,27 @@ function axpGetLeafRouteSnapshot(root) {
7328
7509
  return route;
7329
7510
  }
7330
7511
  /**
7331
- * Resolves the tab dedupe key from an activated route tree.
7332
- * Uses the nearest ancestor with `data.tab = true`; otherwise the leaf path.
7512
+ * Path identity from an activated route tree, without query params.
7513
+ * Uses the nearest ancestor whose own route config sets `data.tab = true`; otherwise the leaf path.
7514
+ * Child navigations under that boundary (settings groups, profile sections) stay on the same tab.
7333
7515
  */
7334
- function axpResolveTabKeyFromSnapshot(leaf) {
7516
+ function axpTabScopePathFromSnapshot(leaf) {
7335
7517
  const chain = leaf.pathFromRoot;
7336
7518
  for (let index = chain.length - 1; index >= 0; index--) {
7337
7519
  const snapshot = chain[index];
7338
- if (axpHasTabScope(snapshot.data)) {
7520
+ if (axpSnapshotDeclaresTabScope(snapshot)) {
7339
7521
  return axpPathFromSnapshot(snapshot);
7340
7522
  }
7341
7523
  }
7342
7524
  return axpPathFromSnapshot(leaf);
7343
7525
  }
7526
+ /**
7527
+ * Resolves the tab dedupe key from an activated route tree.
7528
+ * Entity list routes also include navigation query params (`mode`, `list`, …), same as simple navigation.
7529
+ */
7530
+ function axpResolveTabKeyFromSnapshot(leaf) {
7531
+ return axpEntityListNavigationTabKey(axpTabScopePathFromSnapshot(leaf), leaf.queryParams);
7532
+ }
7344
7533
  //#endregion
7345
7534
  //#region ---- Router / URL Resolution ----
7346
7535
  /**
@@ -7351,15 +7540,17 @@ function axpResolveTabKey(router, url) {
7351
7540
  const normalized = normalizeRouterUrl(url ?? router.url);
7352
7541
  const pathOnly = normalized.split('?')[0].split('#')[0];
7353
7542
  const currentPath = normalizeRouterUrl(router.url).split('?')[0].split('#')[0];
7543
+ let basePath;
7354
7544
  if (!url || pathOnly === currentPath) {
7355
7545
  const leaf = axpGetLeafRouteSnapshot(router.routerState.snapshot.root);
7356
- return axpResolveTabKeyFromSnapshot(leaf);
7546
+ basePath = axpTabScopePathFromSnapshot(leaf);
7357
7547
  }
7358
- const fromConfig = axpResolveTabKeyFromRouteConfig(router.config, pathOnly);
7359
- if (fromConfig) {
7360
- return fromConfig;
7548
+ else {
7549
+ basePath =
7550
+ axpResolveTabKeyFromRouteConfig(router.config, pathOnly) ??
7551
+ (pathOnly.startsWith('/') ? pathOnly : `/${pathOnly}`);
7361
7552
  }
7362
- return pathOnly.startsWith('/') ? pathOnly : `/${pathOnly}`;
7553
+ return axpEntityListNavigationTabKey(basePath, normalized);
7363
7554
  }
7364
7555
  /**
7365
7556
  * Matches a URL path against registered routes and resolves the tab key from `data.tab`.
@@ -7367,19 +7558,19 @@ function axpResolveTabKey(router, url) {
7367
7558
  function axpResolveTabKeyFromRouteConfig(routes, pathOnly) {
7368
7559
  const normalized = pathOnly.startsWith('/') ? pathOnly.replace(/\/+$/, '') || '/' : `/${pathOnly}`.replace(/\/+$/, '') || '/';
7369
7560
  const segments = normalized === '/' ? [] : normalized.split('/').filter(Boolean);
7370
- const chain = matchRouteConfigChain(routes, segments, 0, {}, []);
7561
+ const chain = matchRouteConfigChain(routes, segments, 0, []);
7371
7562
  if (!chain?.length) {
7372
7563
  return null;
7373
7564
  }
7374
7565
  for (let index = chain.length - 1; index >= 0; index--) {
7375
7566
  const level = chain[index];
7376
- if (axpHasTabScope(level.mergedData)) {
7567
+ if (axpHasTabScope(level.ownData)) {
7377
7568
  return level.path;
7378
7569
  }
7379
7570
  }
7380
7571
  return chain[chain.length - 1]?.path ?? null;
7381
7572
  }
7382
- function matchRouteConfigChain(routes, segments, startIndex, inheritedData, chain) {
7573
+ function matchRouteConfigChain(routes, segments, startIndex, chain) {
7383
7574
  let bestMatch = null;
7384
7575
  for (const route of routes) {
7385
7576
  if (route.redirectTo) {
@@ -7391,12 +7582,12 @@ function matchRouteConfigChain(routes, segments, startIndex, inheritedData, chai
7391
7582
  }
7392
7583
  const pathSegments = [...segments.slice(0, startIndex), ...segments.slice(startIndex, startIndex + segmentMatch.consumed)];
7393
7584
  const path = pathSegments.length ? `/${pathSegments.join('/')}` : '/';
7394
- const mergedData = { ...inheritedData, ...(route.data ?? {}) };
7395
- const level = { mergedData, path };
7585
+ const ownData = { ...(route.data ?? {}) };
7586
+ const level = { ownData, path };
7396
7587
  const nextChain = [...chain, level];
7397
7588
  const nextIndex = startIndex + segmentMatch.consumed;
7398
7589
  if (route.children?.length) {
7399
- const childMatch = matchRouteConfigChain(route.children, segments, nextIndex, mergedData, nextChain);
7590
+ const childMatch = matchRouteConfigChain(route.children, segments, nextIndex, nextChain);
7400
7591
  if (childMatch && (!bestMatch || childMatch.length > bestMatch.length)) {
7401
7592
  bestMatch = childMatch;
7402
7593
  }
@@ -9426,7 +9617,7 @@ function isStoredImageFileId(value) {
9426
9617
  */
9427
9618
  function buildFileStorageDownloadUrl(baseUrl, fileId) {
9428
9619
  const base = baseUrl.replace(/\/$/, '');
9429
- return `${base}/v1/file-storage/download/${encodeURIComponent(fileId)}`;
9620
+ return `${base}/v1/file-storage/download/${encodeURIComponent(fileId)}?v=raw`;
9430
9621
  }
9431
9622
  /**
9432
9623
  * Resolves a stored image ref to a browser-displayable URL.
@@ -11175,7 +11366,7 @@ class AXPCommonModule {
11175
11366
  provide: AXP_SETTING_DEFINITION_PROVIDER,
11176
11367
  useFactory: async () => {
11177
11368
  const injector = inject(Injector);
11178
- const provider = (await import('./acorex-platform-framework-client-common-common-settings.provider-ChU2tvyt.mjs')).AXPCommonSettingProvider;
11369
+ const provider = (await import('./acorex-platform-framework-client-common-common-settings.provider-Cyr1DaiD.mjs')).AXPCommonSettingProvider;
11179
11370
  return new provider(injector);
11180
11371
  },
11181
11372
  multi: true,
@@ -11298,7 +11489,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
11298
11489
  provide: AXP_SETTING_DEFINITION_PROVIDER,
11299
11490
  useFactory: async () => {
11300
11491
  const injector = inject(Injector);
11301
- const provider = (await import('./acorex-platform-framework-client-common-common-settings.provider-ChU2tvyt.mjs')).AXPCommonSettingProvider;
11492
+ const provider = (await import('./acorex-platform-framework-client-common-common-settings.provider-Cyr1DaiD.mjs')).AXPCommonSettingProvider;
11302
11493
  return new provider(injector);
11303
11494
  },
11304
11495
  multi: true,
@@ -11343,20 +11534,38 @@ const AXP_ROOT_CONFIG_TOKEN = new InjectionToken('AXP_ROOT_CONFIG_TOKEN');
11343
11534
 
11344
11535
  /**
11345
11536
  * Opens the native file picker and always settles — including when the user cancels.
11346
- * `AXFileService.choose()` can hang on cancel because no `change` event fires.
11537
+ * `AXFileService.choose()` only listens for `change`, so dismissing the dialog leaves that promise pending.
11347
11538
  */
11348
11539
  function chooseSystemFiles(options = {}) {
11349
- const document = inject(DOCUMENT);
11540
+ return openSystemFileDialog(inject(DOCUMENT), options);
11541
+ }
11542
+ /**
11543
+ * Same picker as {@link chooseSystemFiles}, with the document passed in so callers can `await` before opening it.
11544
+ */
11545
+ function openSystemFileDialog(doc, options = {}) {
11546
+ const view = doc.defaultView;
11547
+ if (!view) {
11548
+ return Promise.resolve([]);
11549
+ }
11350
11550
  const accept = options.accept ?? '';
11351
11551
  const multiple = options.multiple ?? false;
11352
11552
  return new Promise((resolve) => {
11353
- const input = document.createElement('input');
11553
+ const input = doc.createElement('input');
11354
11554
  input.type = 'file';
11355
11555
  input.accept = accept;
11356
11556
  input.multiple = multiple;
11357
11557
  input.style.display = 'none';
11358
- document.body.appendChild(input);
11558
+ doc.body.appendChild(input);
11359
11559
  let settled = false;
11560
+ let dialogOpened = false;
11561
+ let watchFocus = false;
11562
+ const cleanup = () => {
11563
+ input.removeEventListener('change', onChange);
11564
+ input.removeEventListener('cancel', onCancel);
11565
+ view.removeEventListener('blur', onBlur);
11566
+ view.removeEventListener('focus', onFocus);
11567
+ input.remove();
11568
+ };
11360
11569
  const settle = (files) => {
11361
11570
  if (settled) {
11362
11571
  return;
@@ -11365,21 +11574,37 @@ function chooseSystemFiles(options = {}) {
11365
11574
  cleanup();
11366
11575
  resolve(files);
11367
11576
  };
11368
- const cleanup = () => {
11369
- input.removeEventListener('change', onChange);
11370
- window.removeEventListener('focus', onWindowFocus);
11371
- input.remove();
11372
- };
11373
11577
  const onChange = () => {
11374
11578
  settle(Array.from(input.files ?? []));
11375
11579
  };
11376
- const onWindowFocus = () => {
11377
- // Allow `change` to fire first when the user confirms a selection.
11378
- window.setTimeout(() => settle([]), 300);
11580
+ const onCancel = () => {
11581
+ settle([]);
11582
+ };
11583
+ const onBlur = () => {
11584
+ if (watchFocus) {
11585
+ dialogOpened = true;
11586
+ }
11587
+ };
11588
+ const onFocus = () => {
11589
+ if (!watchFocus || !dialogOpened) {
11590
+ return;
11591
+ }
11592
+ // `change` fires before this timeout when the user confirms a file.
11593
+ view.setTimeout(() => {
11594
+ if (!settled) {
11595
+ settle(Array.from(input.files ?? []));
11596
+ }
11597
+ }, 300);
11379
11598
  };
11380
11599
  input.addEventListener('change', onChange);
11381
- window.addEventListener('focus', onWindowFocus, { once: true });
11600
+ input.addEventListener('cancel', onCancel);
11601
+ view.addEventListener('blur', onBlur);
11602
+ view.addEventListener('focus', onFocus);
11382
11603
  input.click();
11604
+ // Ignore blur/focus caused by opening the dialog itself. Cancel still settles via the `cancel` event.
11605
+ view.setTimeout(() => {
11606
+ watchFocus = true;
11607
+ }, 0);
11383
11608
  });
11384
11609
  }
11385
11610
  //#endregion
@@ -14054,5 +14279,5 @@ const axpPageGetContextQueryDefinition = defineQuery({
14054
14279
  * Generated bundle index. Do not edit.
14055
14280
  */
14056
14281
 
14057
- 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, 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, 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_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, 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, 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, axpSplitCollapsedBreadcrumbs, axpStampEntityListMenuInstancePaths, axpStripHomeBreadcrumb, axpStripTrailingCommandlessCrumbs, 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, findManualPresetIdByOperation, formatEntityRowDisplayTitle, formatRequestError, hasFileTypeOpenHandler, hydrateSettingsValuesFromIndexedDb, inferSettingCoercionKind, isFileNameShownInViewer, isFileTypeShownInViewer, isFileViewerPreviewExtension, isOneWaySettingsIndexedDbCache, isPendingCascadeFilter, isSettingKeyCacheable, isSettingVisibleOnScope, isStoredImageFileId, normalizeAvailableLanguageCodes, normalizeDocumentFileTypePurposes, normalizeDocumentToFileListItem, normalizeOverridableAt, normalizePositiveNumberOption, normalizeRouterUrl, normalizeStoredImageRef, peelSettingValueKey, platformErrorI18nKey, primaryLanguageSubtag, printGraphicFromElement, projectSettingsValuesForIndexedDb, provideAXPUserNotificationService, provideDynamicHomePage, provideLocalEntityOfflineRuntime, provideMenuMiddleware, purgeLegacyTenantScopedSettingsSnapshots, resolveDateFilterPresets, resolveEffectiveAvailableLanguageCodes, resolveEntityCreateListBehavior, resolveEntityDetailsRouteAccess, resolveEntityModifyPopupTitle, resolveEntityRowDisplayText, resolveEntityRowDisplayTitle, resolveEntityRowDisplayTitleFromColumnContext, resolveEntitySearchTitleFallback, resolveExplorerFileDisplayName, resolveFileTypeDisplay, resolveFileViewerType, resolveGraphicElementSize, resolveGraphicPrintContent, resolveQueryMatchingDisplayText, resolveSearchDisplayTemplate, resolveSearchableText, 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 };
14282
+ 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, 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_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, 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, resolveDateFilterPresets, resolveEffectiveAvailableLanguageCodes, resolveEntityCreateListBehavior, resolveEntityDetailsRouteAccess, resolveEntityModifyPopupTitle, resolveEntityRowDisplayText, resolveEntityRowDisplayTitle, resolveEntityRowDisplayTitleFromColumnContext, resolveEntitySearchTitleFallback, resolveExplorerFileDisplayName, resolveFileTypeDisplay, resolveFileViewerType, resolveGraphicElementSize, resolveGraphicPrintContent, resolveQueryMatchingDisplayText, resolveSearchDisplayTemplate, resolveSearchableText, 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 };
14058
14283
  //# sourceMappingURL=acorex-platform-framework-client-common.mjs.map