@acorex-platform/framework-client 0.0.38 → 0.0.48

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 (111) hide show
  1. package/fesm2022/acorex-platform-framework-client-auth.mjs +212 -44
  2. package/fesm2022/acorex-platform-framework-client-auth.mjs.map +1 -1
  3. package/fesm2022/{acorex-platform-framework-client-common-common-settings.provider-CzBr0cRi.mjs → acorex-platform-framework-client-common-common-settings.provider-ChU2tvyt.mjs} +31 -1
  4. package/fesm2022/acorex-platform-framework-client-common-common-settings.provider-ChU2tvyt.mjs.map +1 -0
  5. package/fesm2022/acorex-platform-framework-client-common.mjs +1172 -193
  6. package/fesm2022/acorex-platform-framework-client-common.mjs.map +1 -1
  7. package/fesm2022/acorex-platform-framework-client-core.mjs +233 -132
  8. package/fesm2022/acorex-platform-framework-client-core.mjs.map +1 -1
  9. package/fesm2022/acorex-platform-framework-client-layout-builder.mjs +295 -59
  10. package/fesm2022/acorex-platform-framework-client-layout-builder.mjs.map +1 -1
  11. package/fesm2022/{acorex-platform-framework-client-layout-components-binding-expression-editor-popup.component-Bp2cNCPO.mjs → acorex-platform-framework-client-layout-components-binding-expression-editor-popup.component-BqPaHKPM.mjs} +10 -6
  12. package/fesm2022/acorex-platform-framework-client-layout-components-binding-expression-editor-popup.component-BqPaHKPM.mjs.map +1 -0
  13. package/fesm2022/acorex-platform-framework-client-layout-components-property-viewer-inline-code-editor.component-CcpUTEVQ.mjs +66 -0
  14. package/fesm2022/acorex-platform-framework-client-layout-components-property-viewer-inline-code-editor.component-CcpUTEVQ.mjs.map +1 -0
  15. package/fesm2022/acorex-platform-framework-client-layout-components-resource-appointment-board.component-DCkpgsFH.mjs +195 -0
  16. package/fesm2022/acorex-platform-framework-client-layout-components-resource-appointment-board.component-DCkpgsFH.mjs.map +1 -0
  17. package/fesm2022/acorex-platform-framework-client-layout-components.mjs +4015 -1014
  18. package/fesm2022/acorex-platform-framework-client-layout-components.mjs.map +1 -1
  19. package/fesm2022/acorex-platform-framework-client-layout-designer.mjs +1179 -304
  20. package/fesm2022/acorex-platform-framework-client-layout-designer.mjs.map +1 -1
  21. package/fesm2022/{acorex-platform-framework-client-layout-entity-acorex-platform-framework-client-layout-entity-CvaOWbJx.mjs → acorex-platform-framework-client-layout-entity-acorex-platform-framework-client-layout-entity-UkQsf84C.mjs} +1701 -300
  22. package/fesm2022/acorex-platform-framework-client-layout-entity-acorex-platform-framework-client-layout-entity-UkQsf84C.mjs.map +1 -0
  23. package/fesm2022/{acorex-platform-framework-client-layout-entity-attachments-page.component-Ds63Rt2n.mjs → acorex-platform-framework-client-layout-entity-attachments-page.component-DmmiDLZw.mjs} +2 -2
  24. package/fesm2022/{acorex-platform-framework-client-layout-entity-attachments-page.component-Ds63Rt2n.mjs.map → acorex-platform-framework-client-layout-entity-attachments-page.component-DmmiDLZw.mjs.map} +1 -1
  25. package/fesm2022/{acorex-platform-framework-client-layout-entity-bulk-entity.command-C0pohwdo.mjs → acorex-platform-framework-client-layout-entity-bulk-entity.command-BOFTb66c.mjs} +2 -2
  26. package/fesm2022/{acorex-platform-framework-client-layout-entity-bulk-entity.command-C0pohwdo.mjs.map → acorex-platform-framework-client-layout-entity-bulk-entity.command-BOFTb66c.mjs.map} +1 -1
  27. package/fesm2022/{acorex-platform-framework-client-layout-entity-gallery-page.component-o2HuZrDN.mjs → acorex-platform-framework-client-layout-entity-gallery-page.component-Bg-cMOlQ.mjs} +2 -2
  28. package/fesm2022/{acorex-platform-framework-client-layout-entity-gallery-page.component-o2HuZrDN.mjs.map → acorex-platform-framework-client-layout-entity-gallery-page.component-Bg-cMOlQ.mjs.map} +1 -1
  29. package/fesm2022/acorex-platform-framework-client-layout-entity.mjs +2 -2
  30. package/fesm2022/acorex-platform-framework-client-layout-views.mjs +47 -8
  31. package/fesm2022/acorex-platform-framework-client-layout-views.mjs.map +1 -1
  32. package/fesm2022/acorex-platform-framework-client-layout-widget-core.mjs +3854 -3292
  33. package/fesm2022/acorex-platform-framework-client-layout-widget-core.mjs.map +1 -1
  34. package/fesm2022/acorex-platform-framework-client-layout-widgets-acorex-platform-framework-client-layout-widgets-DJNSBNVe.mjs +33319 -0
  35. package/fesm2022/acorex-platform-framework-client-layout-widgets-acorex-platform-framework-client-layout-widgets-DJNSBNVe.mjs.map +1 -0
  36. package/fesm2022/{acorex-platform-framework-client-layout-widgets-button-widget-designer.component-BDOdcoyN.mjs → acorex-platform-framework-client-layout-widgets-button-widget-designer.component-BkrPu1wO.mjs} +8 -5
  37. package/fesm2022/acorex-platform-framework-client-layout-widgets-button-widget-designer.component-BkrPu1wO.mjs.map +1 -0
  38. package/fesm2022/acorex-platform-framework-client-layout-widgets-code-editor-value.util-Cb7R1qLO.mjs +45 -0
  39. package/fesm2022/acorex-platform-framework-client-layout-widgets-code-editor-value.util-Cb7R1qLO.mjs.map +1 -0
  40. package/fesm2022/acorex-platform-framework-client-layout-widgets-code-editor-widget-column.component-BL621E1r.mjs +68 -0
  41. package/fesm2022/acorex-platform-framework-client-layout-widgets-code-editor-widget-column.component-BL621E1r.mjs.map +1 -0
  42. package/fesm2022/acorex-platform-framework-client-layout-widgets-code-editor-widget-edit.component-CVsPKhNl.mjs +88 -0
  43. package/fesm2022/acorex-platform-framework-client-layout-widgets-code-editor-widget-edit.component-CVsPKhNl.mjs.map +1 -0
  44. package/fesm2022/acorex-platform-framework-client-layout-widgets-code-editor-widget-view.component-BEq4O4al.mjs +71 -0
  45. package/fesm2022/acorex-platform-framework-client-layout-widgets-code-editor-widget-view.component-BEq4O4al.mjs.map +1 -0
  46. package/fesm2022/acorex-platform-framework-client-layout-widgets-condition-builder-edit-popup.component-WpiEHusZ.mjs +81 -0
  47. package/fesm2022/acorex-platform-framework-client-layout-widgets-condition-builder-edit-popup.component-WpiEHusZ.mjs.map +1 -0
  48. package/fesm2022/{acorex-platform-framework-client-layout-widgets-page-widget-designer.component-WzIiwnGC.mjs → acorex-platform-framework-client-layout-widgets-page-widget-designer.component-Cadl6guA.mjs} +41 -23
  49. package/fesm2022/acorex-platform-framework-client-layout-widgets-page-widget-designer.component-Cadl6guA.mjs.map +1 -0
  50. package/fesm2022/{acorex-platform-framework-client-layout-widgets-repeater-widget-column.component-4mX8aYzA.mjs → acorex-platform-framework-client-layout-widgets-repeater-widget-column.component-CKtGsWPI.mjs} +3 -3
  51. package/fesm2022/{acorex-platform-framework-client-layout-widgets-repeater-widget-column.component-4mX8aYzA.mjs.map → acorex-platform-framework-client-layout-widgets-repeater-widget-column.component-CKtGsWPI.mjs.map} +1 -1
  52. package/fesm2022/acorex-platform-framework-client-layout-widgets-scheduler-picker-widget-column.component-Clb27Loe.mjs +71 -0
  53. package/fesm2022/acorex-platform-framework-client-layout-widgets-scheduler-picker-widget-column.component-Clb27Loe.mjs.map +1 -0
  54. package/fesm2022/acorex-platform-framework-client-layout-widgets-scheduler-picker-widget-edit.component-l7q8A-D3.mjs +111 -0
  55. package/fesm2022/acorex-platform-framework-client-layout-widgets-scheduler-picker-widget-edit.component-l7q8A-D3.mjs.map +1 -0
  56. package/fesm2022/acorex-platform-framework-client-layout-widgets-scheduler-picker-widget-view.component-Cc1AH09b.mjs +77 -0
  57. package/fesm2022/acorex-platform-framework-client-layout-widgets-scheduler-picker-widget-view.component-Cc1AH09b.mjs.map +1 -0
  58. package/fesm2022/{acorex-platform-framework-client-layout-widgets-tabular-data-edit-popup.component-TWxthl21.mjs → acorex-platform-framework-client-layout-widgets-tabular-data-edit-popup.component-BCLxS3rS.mjs} +3 -3
  59. package/fesm2022/{acorex-platform-framework-client-layout-widgets-tabular-data-edit-popup.component-TWxthl21.mjs.map → acorex-platform-framework-client-layout-widgets-tabular-data-edit-popup.component-BCLxS3rS.mjs.map} +1 -1
  60. package/fesm2022/{acorex-platform-framework-client-layout-widgets-text-block-widget-designer.component-D6HFPmGC.mjs → acorex-platform-framework-client-layout-widgets-text-block-widget-designer.component-DYxgwR2E.mjs} +21 -8
  61. package/fesm2022/acorex-platform-framework-client-layout-widgets-text-block-widget-designer.component-DYxgwR2E.mjs.map +1 -0
  62. package/fesm2022/acorex-platform-framework-client-layout-widgets-trigger-expression-editor-popup.component-C2PGoC7r.mjs +124 -0
  63. package/fesm2022/acorex-platform-framework-client-layout-widgets-trigger-expression-editor-popup.component-C2PGoC7r.mjs.map +1 -0
  64. package/fesm2022/acorex-platform-framework-client-layout-widgets-triggers-widget-editor.component-DDDoPoQa.mjs +345 -0
  65. package/fesm2022/acorex-platform-framework-client-layout-widgets-triggers-widget-editor.component-DDDoPoQa.mjs.map +1 -0
  66. package/fesm2022/acorex-platform-framework-client-layout-widgets.mjs +1 -31985
  67. package/fesm2022/acorex-platform-framework-client-layout-widgets.mjs.map +1 -1
  68. package/fesm2022/acorex-platform-framework-client-realtime.mjs +2 -1
  69. package/fesm2022/acorex-platform-framework-client-realtime.mjs.map +1 -1
  70. package/fesm2022/acorex-platform-framework-client-runtime.mjs +2 -2
  71. package/fesm2022/acorex-platform-framework-client-runtime.mjs.map +1 -1
  72. package/fesm2022/{acorex-platform-framework-client-themes-default-entity-master-create-view.component-CT7WWWG0.mjs → acorex-platform-framework-client-themes-default-entity-master-create-view.component-DlS4v_zb.mjs} +3 -3
  73. package/fesm2022/acorex-platform-framework-client-themes-default-entity-master-create-view.component-DlS4v_zb.mjs.map +1 -0
  74. package/fesm2022/acorex-platform-framework-client-themes-default-entity-master-modify-view.component-DBmdBKBL.mjs +122 -0
  75. package/fesm2022/acorex-platform-framework-client-themes-default-entity-master-modify-view.component-DBmdBKBL.mjs.map +1 -0
  76. package/fesm2022/{acorex-platform-framework-client-themes-default-entity-master-single-view.component-DBUwSzvg.mjs → acorex-platform-framework-client-themes-default-entity-master-single-view.component-CkpRT1a9.mjs} +3 -3
  77. package/fesm2022/acorex-platform-framework-client-themes-default-entity-master-single-view.component-CkpRT1a9.mjs.map +1 -0
  78. package/fesm2022/acorex-platform-framework-client-themes-default.mjs +424 -103
  79. package/fesm2022/acorex-platform-framework-client-themes-default.mjs.map +1 -1
  80. package/fesm2022/{acorex-platform-framework-client-themes-shared-settings.provider-CpsAIsxj.mjs → acorex-platform-framework-client-themes-shared-settings.provider-DIkjSTU7.mjs} +102 -1
  81. package/fesm2022/acorex-platform-framework-client-themes-shared-settings.provider-DIkjSTU7.mjs.map +1 -0
  82. package/fesm2022/acorex-platform-framework-client-themes-shared.mjs +174 -22
  83. package/fesm2022/acorex-platform-framework-client-themes-shared.mjs.map +1 -1
  84. package/package.json +2 -2
  85. package/realtime/README.md +1 -1
  86. package/types/acorex-platform-framework-client-auth.d.ts +18 -1
  87. package/types/acorex-platform-framework-client-common.d.ts +243 -9
  88. package/types/acorex-platform-framework-client-core.d.ts +152 -119
  89. package/types/acorex-platform-framework-client-layout-builder.d.ts +29 -0
  90. package/types/acorex-platform-framework-client-layout-components.d.ts +717 -147
  91. package/types/acorex-platform-framework-client-layout-designer.d.ts +192 -14
  92. package/types/acorex-platform-framework-client-layout-entity.d.ts +167 -92
  93. package/types/acorex-platform-framework-client-layout-views.d.ts +23 -1
  94. package/types/acorex-platform-framework-client-layout-widget-core.d.ts +148 -40
  95. package/types/acorex-platform-framework-client-layout-widgets.d.ts +261 -119
  96. package/types/acorex-platform-framework-client-realtime.d.ts +16 -3
  97. package/types/acorex-platform-framework-client-themes-default.d.ts +62 -11
  98. package/types/acorex-platform-framework-client-themes-shared.d.ts +25 -2
  99. package/fesm2022/acorex-platform-framework-client-common-common-settings.provider-CzBr0cRi.mjs.map +0 -1
  100. package/fesm2022/acorex-platform-framework-client-layout-components-binding-expression-editor-popup.component-Bp2cNCPO.mjs.map +0 -1
  101. package/fesm2022/acorex-platform-framework-client-layout-components-file-provider-picker.popup.component-BtLEUWAA.mjs +0 -77
  102. package/fesm2022/acorex-platform-framework-client-layout-components-file-provider-picker.popup.component-BtLEUWAA.mjs.map +0 -1
  103. package/fesm2022/acorex-platform-framework-client-layout-entity-acorex-platform-framework-client-layout-entity-CvaOWbJx.mjs.map +0 -1
  104. package/fesm2022/acorex-platform-framework-client-layout-widgets-button-widget-designer.component-BDOdcoyN.mjs.map +0 -1
  105. package/fesm2022/acorex-platform-framework-client-layout-widgets-page-widget-designer.component-WzIiwnGC.mjs.map +0 -1
  106. package/fesm2022/acorex-platform-framework-client-layout-widgets-text-block-widget-designer.component-D6HFPmGC.mjs.map +0 -1
  107. package/fesm2022/acorex-platform-framework-client-themes-default-entity-master-create-view.component-CT7WWWG0.mjs.map +0 -1
  108. package/fesm2022/acorex-platform-framework-client-themes-default-entity-master-modify-view.component-DienTcPE.mjs +0 -122
  109. package/fesm2022/acorex-platform-framework-client-themes-default-entity-master-modify-view.component-DienTcPE.mjs.map +0 -1
  110. package/fesm2022/acorex-platform-framework-client-themes-default-entity-master-single-view.component-DBUwSzvg.mjs.map +0 -1
  111. package/fesm2022/acorex-platform-framework-client-themes-shared-settings.provider-CpsAIsxj.mjs.map +0 -1
@@ -1,16 +1,16 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { InjectionToken, inject, Injectable, Injector, signal, ApplicationRef, DestroyRef, makeEnvironmentProviders, NgModule, computed, input, ChangeDetectionStrategy, ViewEncapsulation, Component, output, effect, viewChild, afterNextRender, untracked, ErrorHandler, EventEmitter, Input, Output, Directive, Inject, runInInjectionContext, model, linkedSignal } from '@angular/core';
3
- import * as i4$2 from '@angular/router';
3
+ import * as i5 from '@angular/router';
4
4
  import { Router, NavigationEnd, NavigationStart, ROUTES, RedirectCommand, UrlTree, RouterModule } from '@angular/router';
5
5
  import { AXPSessionService, AXPSessionStatus, AXPUnauthenticatedError, AXPAuthGuard, commandMessageTextForError } from '@acorex-platform/framework-client/auth';
6
6
  export { commandMessageTextForError } from '@acorex-platform/framework-client/auth';
7
7
  import { combineLatest, map, distinctUntilChanged, Subject, ReplaySubject, firstValueFrom, filter, take, timer, timeout, switchMap, from, of } from 'rxjs';
8
- import { unwrapValueProperty, isLocaleStringMap, coerceUnknownToDate, coerceUnknownToFiniteNumber, coerceUnknownToBoolean, coerceUnknownToTrimmedString, AXPPlatformScope, runtimeQueryPayloadData, runtimeCommandPayloadData, AXPRegionalSetting, AXPWidgetsCatalog, axpResolveUserNotificationDelivery, resolveMultiLanguageString, coerceUnknownToMultiLanguageString, AXPKeyboardShortcutPriority, AXP_PLATFORM_ERROR_CODES, AXPRequestError, mapUnknownToAXPErrorBody, AXPSystemActionType, runtimeQueryCollectionData, createRandomUuid } from '@acorex-platform/framework-shared/core';
9
- import * as i3$2 from '@acorex-platform/framework-client/core';
10
- import { AXPDebugService, AXPBroadcastEventService, AXP_SETTINGS_DEFINITION_DIALOG_OPENER, objectKeyValueTransforms, AXPDataGenerator, AXPKeyboardShortcutRegistry, normalizeKeyboardShortcuts, AXPDeviceService, chordToKbdItemKeys, hasForegroundOverlayLayer, AXPExpressionEvaluatorService, AXPContextEvalFactory, AXPModuleManifestModule, AXPComponentSlotModule, AXP_EXPRESSION_EVALUATOR_SCOPE_PROVIDER, AXP_LOGO_IMAGE_SRC_RESOLVER, AXPHookService } from '@acorex-platform/framework-client/core';
8
+ import { unwrapValueProperty, isLocaleStringMap, coerceUnknownToDate, coerceUnknownToFiniteNumber, coerceUnknownToBoolean, coerceUnknownToTrimmedString, AXPPlatformScope, runtimeQueryPayloadData, runtimeCommandPayloadData, AXPRegionalSetting, AXPWidgetsCatalog, axpResolveUserNotificationDelivery, resolveMultiLanguageString, coerceUnknownToMultiLanguageString, AXPKeyboardShortcutPriority, AXP_PLATFORM_ERROR_CODES, AXPRequestError, mapUnknownToAXPErrorBody, AXPSystemActionType, runtimeQueryCollectionData, createRandomUuid, runtimeCommandFailure, runtimeCommandSuccessObject, runtimeQuerySuccessObject } from '@acorex-platform/framework-shared/core';
9
+ import * as i4$2 from '@acorex-platform/framework-client/core';
10
+ import { AXPDebugService, AXPBroadcastEventService, AXP_SETTINGS_DEFINITION_DIALOG_OPENER, objectKeyValueTransforms, AXPDataGenerator, AXPKeyboardShortcutRegistry, normalizeKeyboardShortcuts, AXPDeviceService, provideAppStartUpTask, AXP_APP_STARTUP_PRIORITY, chordToKbdItemKeys, hasForegroundOverlayLayer, AXPExpressionEvaluatorService, AXPContextEvalFactory, AXPModuleManifestModule, AXPComponentSlotModule, AXP_EXPRESSION_EVALUATOR_SCOPE_PROVIDER, AXP_LOGO_IMAGE_SRC_RESOLVER, AXPHookService, AXPPageContextRegistry } from '@acorex-platform/framework-client/core';
11
11
  export { AXPDebugService } from '@acorex-platform/framework-client/core';
12
- import { merge, sortBy, isString, toString, isPlainObject, defaultTo, isEmpty, cloneDeep, get, isNumber, isNil, isObject, omit, uniq } from 'lodash-es';
13
- import { AXPQueryService, AXPCommandService, provideCommandSetups } from '@acorex-platform/framework-client/runtime';
12
+ import { merge, sortBy, isString, toString, isPlainObject, mergeWith, defaultTo, isEmpty, isEqual, cloneDeep, get, isNumber, isNil, isObject, omit, uniq } from 'lodash-es';
13
+ import { AXPQueryService, AXPCommandService, provideCommandSetups, provideQuerySetups } from '@acorex-platform/framework-client/runtime';
14
14
  import Dexie from 'dexie';
15
15
  import { AXDialogService } from '@acorex/components/dialog';
16
16
  import * as i6 from '@acorex/core/translation';
@@ -23,15 +23,15 @@ import * as i4$1 from '@acorex/components/badge';
23
23
  import { AXBadgeModule } from '@acorex/components/badge';
24
24
  import * as i2 from '@acorex/components/decorators';
25
25
  import { AXDecoratorModule } from '@acorex/components/decorators';
26
- import * as i3$1 from '@acorex/components/popover';
26
+ import * as i3$2 from '@acorex/components/popover';
27
27
  import { AXPopoverComponent, AXPopoverModule } from '@acorex/components/popover';
28
28
  import * as i1 from '@acorex/components/button';
29
29
  import { AXButtonModule } from '@acorex/components/button';
30
- import * as i2$2 from '@acorex/components/tabs';
30
+ import * as i2$1 from '@acorex/components/tabs';
31
31
  import { AXTabsModule } from '@acorex/components/tabs';
32
32
  import * as i3 from '@acorex/components/progress-bar';
33
33
  import { AXProgressBarModule } from '@acorex/components/progress-bar';
34
- import * as i2$1 from '@acorex/core/format';
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
37
  import { filter as filter$1 } from 'rxjs/operators';
@@ -51,13 +51,13 @@ import * as i6$1 from '@acorex/components/color-box';
51
51
  import { AXColorBoxModule } from '@acorex/components/color-box';
52
52
  import * as i3$3 from '@acorex/components/label';
53
53
  import { AXLabelModule } from '@acorex/components/label';
54
- import * as i2$3 from '@acorex/components/number-box';
54
+ import * as i2$2 from '@acorex/components/number-box';
55
55
  import { AXNumberBoxModule } from '@acorex/components/number-box';
56
56
  import { AXBasePageComponent } from '@acorex/components/page';
57
57
  import { AXTextBoxModule } from '@acorex/components/text-box';
58
58
  import * as i1$2 from '@angular/forms';
59
59
  import { FormsModule } from '@angular/forms';
60
- import { defineCommand, AXP_COMMAND_DEFINITION_CATEGORY_PLATFORM } from '@acorex-platform/framework-shared/runtime';
60
+ import { defineCommand, AXP_COMMAND_DEFINITION_CATEGORY_PLATFORM, defineQuery, AXP_QUERY_DEFINITION_CATEGORY_PLATFORM } from '@acorex-platform/framework-shared/runtime';
61
61
 
62
62
  //#region ---- Output kind & segment ----
63
63
  /** Default structured retry count when `structuredRetries` is omitted on structured kinds. */
@@ -414,6 +414,8 @@ var AXPCommonSettings;
414
414
  */
415
415
  AXPCommonSettings["AllowWorkingOffline"] = "Common:Setting:Offline.AllowWorkingOffline";
416
416
  AXPCommonSettings["ShowRowIndexColumn"] = "Common:Setting:Entity.ShowRowIndexColumn";
417
+ /** When true, the entity master-list table derives header bands from entity sections (property groups). */
418
+ AXPCommonSettings["EntityMultiLevelHeaders"] = "Common:Setting:Entity.MultiLevelHeaders";
417
419
  AXPCommonSettings["EntityListPersistenceMode"] = "Common:Setting:Entity.ListPersistenceMode";
418
420
  /** User default for entity master-list presentation (`table` | `card` | `row`). */
419
421
  AXPCommonSettings["EntityListDisplayMode"] = "Common:Setting:Entity.ListDisplayMode";
@@ -430,6 +432,11 @@ var AXPCommonSettings;
430
432
  const AXPFileChooserSettings = {
431
433
  CompressImages: 'Common:Setting:FileChooser.CompressImages',
432
434
  PromptZipOnMultiple: 'Common:Setting:FileChooser.PromptZipOnMultiple',
435
+ /**
436
+ * When false (default), profile photos and file prompts use the device picker.
437
+ * When true, users choose a source (device, Drive, Gravatar, …).
438
+ */
439
+ EnableSourcePicker: 'Common:Setting:FileChooser.EnableSourcePicker',
433
440
  };
434
441
  /** Defaults used before platform settings finish loading and by the setting definitions. */
435
442
  const AXP_RUNTIME_QUERY_CACHE_DEFAULTS = {
@@ -1351,6 +1358,18 @@ function hydrateSettingsValuesFromIndexedDb(values, policy) {
1351
1358
  }
1352
1359
  //#endregion
1353
1360
 
1361
+ /**
1362
+ * lodash `merge` keeps destination array items when the source array is shorter or empty.
1363
+ * Settings patches replace whole keys (e.g. cleared list filters `[]`) and must overwrite arrays.
1364
+ */
1365
+ function mergeSettingsPatch(...sources) {
1366
+ return mergeWith({}, ...sources.filter((source) => !!source), (objValue, srcValue) => {
1367
+ if (Array.isArray(srcValue)) {
1368
+ return srcValue;
1369
+ }
1370
+ return undefined;
1371
+ });
1372
+ }
1354
1373
  //#region ---- Scoped settings provider (User bidirectional; Platform one-way cache) ----
1355
1374
  class AXPIndexedDbSettingValueProvider {
1356
1375
  constructor(_scope, injector) {
@@ -1653,8 +1672,8 @@ class AXPIndexedDbSettingValueProvider {
1653
1672
  if (!this.snapshot) {
1654
1673
  return;
1655
1674
  }
1656
- this.snapshot.values = merge({}, this.snapshot.values, patch);
1657
- this.snapshot.dirty = merge({}, this.snapshot.dirty, patch);
1675
+ this.snapshot.values = mergeSettingsPatch(this.snapshot.values, patch);
1676
+ this.snapshot.dirty = mergeSettingsPatch(this.snapshot.dirty, patch);
1658
1677
  this.snapshot.syncStatus = isEmpty(this.snapshot.dirty) ? 'idle' : 'pending_retry';
1659
1678
  }
1660
1679
  /** Updates cached values without queuing a server Patch (platform one-way cache). */
@@ -1662,7 +1681,7 @@ class AXPIndexedDbSettingValueProvider {
1662
1681
  if (!this.snapshot) {
1663
1682
  return;
1664
1683
  }
1665
- this.snapshot.values = merge({}, this.snapshot.values, patch);
1684
+ this.snapshot.values = mergeSettingsPatch(this.snapshot.values, patch);
1666
1685
  }
1667
1686
  clearLocalDirty(snapshot) {
1668
1687
  snapshot.dirty = {};
@@ -1759,20 +1778,16 @@ class AXPIndexedDbSettingValueProvider {
1759
1778
  return;
1760
1779
  }
1761
1780
  try {
1762
- let since = this.resolveFetchSince(snapshot);
1781
+ const since = this.resolveFetchSince(snapshot);
1763
1782
  traceSettingsServerApiCall('GET', this._scope, {
1764
1783
  snapshotId: this.snapshotId,
1765
1784
  since,
1766
1785
  reason: this.requireServerSync ? 'require-server-revalidate' : 'background-revalidate',
1767
1786
  });
1768
- let result = await this.bulkSync.fetch(this._scope, since);
1769
- if (generation !== this.syncGeneration || this.snapshot !== snapshot) {
1770
- return;
1771
- }
1772
- if (!result.changed && isEmpty(result.values) && since) {
1773
- since = null;
1774
- result = await this.bulkSync.fetch(this._scope, null);
1775
- }
1787
+ // `{ changed: false, values: {} }` is the normal not-modified response.
1788
+ // Do not fall back to a full fetch — that reapplies every key as a change
1789
+ // and remounts locale/theme/lookup widgets on tab focus.
1790
+ const result = await this.bulkSync.fetch(this._scope, since);
1776
1791
  if (generation !== this.syncGeneration || this.snapshot !== snapshot) {
1777
1792
  return;
1778
1793
  }
@@ -1784,12 +1799,15 @@ class AXPIndexedDbSettingValueProvider {
1784
1799
  if (key in snapshot.dirty) {
1785
1800
  continue;
1786
1801
  }
1802
+ if (isEqual(snapshot.values[key], value)) {
1803
+ continue;
1804
+ }
1787
1805
  servicePatch[key] = value;
1788
1806
  }
1789
1807
  // Full server payloads replace local values (dirty wins for bidirectional User scope).
1790
1808
  snapshot.values = stripAccidentalNestedSettingParents(this.requireServerSync
1791
- ? merge({}, result.values, isOneWaySettingsIndexedDbCache(this._scope) ? {} : snapshot.dirty)
1792
- : merge({}, result.values, snapshot.dirty));
1809
+ ? mergeSettingsPatch(result.values, isOneWaySettingsIndexedDbCache(this._scope) ? {} : snapshot.dirty)
1810
+ : mergeSettingsPatch(result.values, snapshot.dirty));
1793
1811
  if (result.updatedAt) {
1794
1812
  snapshot.serverUpdatedAt = result.updatedAt;
1795
1813
  }
@@ -5067,7 +5085,7 @@ class AXPBackgroundOperationItemComponent {
5067
5085
  return value === 'cancel' || value === 'pause' || value === 'resume' || value === 'retry' || value === 'dismiss';
5068
5086
  }
5069
5087
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPBackgroundOperationItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
5070
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPBackgroundOperationItemComponent, isStandalone: true, selector: "axp-background-operation-item", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null }, tabKey: { classPropertyName: "tabKey", publicName: "tabKey", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { actionCompleted: "actionCompleted", itemClicked: "itemClicked" }, ngImport: i0, template: "<article class=\"operation-item\" [class]=\"statusClass()\">\n <ax-icon class=\"operation-item__status-icon\" [class]=\"statusClass()\">\n <i [class]=\"statusIcon()\"></i>\n </ax-icon>\n\n <div class=\"operation-item__content\">\n <div class=\"operation-item__headline\">\n <h3 class=\"operation-item__title\">{{ data().title }}</h3>\n </div>\n\n @if (isCompletedTab()) {\n @if (showCompletedSummaryLine()) {\n <!-- ----- Status merged with finished time and duration ----- -->\n <p class=\"operation-item__status-text\">\n @if (statusTextKey(); as key) {\n <span>{{ key | translate: { params: statusTextParams() } | async }}</span>\n } @else if (plainStatusText()) {\n <span>{{ plainStatusText() }}</span>\n }\n @if (timingDatetime(); as finishedAt) {\n @if (statusTextKey() || plainStatusText()) {\n <span class=\"operation-item__status-separator\" aria-hidden=\"true\"> \u00B7 </span>\n }\n <!--->\n <!-- ----- Locale-aware finished datetime via format pipe ----- -->\n @if ((finishedAt | format: 'datetime' : 'short' | async); as datetime) {\n <span>{{\n '@general:background-operation.timing.finished-at'\n | translate: { params: { datetime } }\n | async\n }}</span>\n }\n <!--->\n <!-- ----- Compact duration when available ----- -->\n @if (timingDuration(); as duration) {\n <span class=\"operation-item__status-separator\" aria-hidden=\"true\"> \u00B7 </span>\n <span>{{\n '@general:background-operation.timing.duration'\n | translate: { params: { duration } }\n | async\n }}</span>\n }\n }\n </p>\n }\n } @else {\n @if (statusTextKey(); as key) {\n <p class=\"operation-item__status-text\">\n {{ key | translate: { params: statusTextParams() } | async }}\n </p>\n } @else if (plainStatusText()) {\n <p class=\"operation-item__status-text\">\n {{ plainStatusText() }}\n </p>\n }\n }\n\n @if (showStepLine()) {\n <span class=\"operation-item__step\">\n {{ '@general:background-operation.step' | translate | async }}\n {{ data().currentStep }}\n </span>\n }\n\n @if (timingDatetime(); as startedAt) {\n <!--->\n <!-- ----- Started time and estimate for in-progress tasks ----- -->\n @if (isInProgressTab()) {\n <div class=\"operation-item__timing\">\n <!-- ----- Locale-aware started datetime via format pipe ----- -->\n @if ((startedAt | format: 'datetime' : 'short' | async); as datetime) {\n <span>\n {{\n '@general:background-operation.timing.started-at'\n | translate: { params: { datetime } }\n | async\n }}\n </span>\n }\n <!--->\n <!-- ----- ETA when the task type supports estimates ----- -->\n @if (showEstimateLine()) {\n <span>\n {{\n '@general:background-operation.timing.estimate'\n | translate: { params: { estimate: timingDuration()! } }\n | async\n }}\n </span>\n }\n </div>\n }\n }\n\n @if (showCompletedActionRow()) {\n <div class=\"ax-xs operation-item__footer-actions\">\n @if (cta(); as primaryCta) {\n <!-- ----- Handler-defined CTA on completed tab ----- -->\n <ax-button\n class=\"operation-item__action-btn\"\n look=\"solid\"\n [color]=\"primaryCta.color ?? 'primary'\"\n [text]=\"ctaDisplayText()\"\n [disabled]=\"isCtaDisabled(primaryCta)\"\n (onClick)=\"onCtaClick(primaryCta)\"\n >\n @if (primaryCta.icon) {\n <ax-prefix>\n <ax-icon><i [class]=\"primaryCta.icon\"></i></ax-icon>\n </ax-prefix>\n }\n </ax-button>\n }\n @if (showDismissButton()) {\n <!-- ----- Close / dismiss completed rows ----- -->\n <ax-button\n class=\"operation-item__action-btn\"\n look=\"solid\"\n color=\"default\"\n [text]=\"(actionLabelKey('dismiss') | translate | async) ?? ''\"\n [disabled]=\"isActionDisabled('dismiss') || isActionLoading('dismiss')\"\n (onClick)=\"onAction('dismiss')\"\n ></ax-button>\n }\n </div>\n }\n\n @if (showProgressBar()) {\n <div class=\"operation-item__progress-row\">\n @if (showProgressPercent()) {\n <span class=\"operation-item__progress-label\">\n {{\n '@general:background-operation.progress-percent'\n | translate: { params: { percent: progressValue() } }\n | async\n }}\n </span>\n }\n <ax-progress-bar\n class=\"operation-item__progress\"\n [progress]=\"progressValue()\"\n [mode]=\"progressMode()\"\n [color]=\"progressColor()\"\n [style.height.px]=\"4\"\n ></ax-progress-bar>\n </div>\n }\n\n @if (showError()) {\n @if (errorMessageKey(); as errorKey) {\n <p class=\"operation-item__error\" role=\"alert\">\n {{ errorKey | translate | async }}\n </p>\n } @else if (plainErrorMessage()) {\n <p class=\"operation-item__error\" role=\"alert\">\n {{ plainErrorMessage() }}\n </p>\n }\n }\n </div>\n\n @if (showDate() || showActionColumn()) {\n <div class=\"operation-item__aside\">\n @if (showDate()) {\n <span class=\"operation-item__time\">{{ displayTime() | format: 'timeleft' | async }}</span>\n }\n @if (showActionColumn()) {\n <div class=\"operation-item__actions\" (click)=\"$event.stopPropagation()\">\n @if (isInProgressTab()) {\n @if (showCancelButton()) {\n <!-- ----- Cancel for in-progress cancellable tasks ----- -->\n <ax-button\n class=\"ax-xs operation-item__action-btn\"\n look=\"outline\"\n color=\"danger\"\n [text]=\"(actionLabelKey('cancel') | translate | async) ?? ''\"\n [disabled]=\"isActionDisabled('cancel') || isActionLoading('cancel')\"\n (onClick)=\"onAction('cancel')\"\n ></ax-button>\n }\n @if (showPauseButton()) {\n <!-- ----- Pause when supported and no cancel is shown ----- -->\n <ax-button\n class=\"ax-xs operation-item__action-btn\"\n look=\"outline\"\n color=\"default\"\n [text]=\"(actionLabelKey('pause') | translate | async) ?? ''\"\n [disabled]=\"isActionDisabled('pause') || isActionLoading('pause')\"\n (onClick)=\"onAction('pause')\"\n ></ax-button>\n }\n @if (showResumeButton()) {\n <!-- ----- Resume for paused tasks ----- -->\n <ax-button\n class=\"ax-xs operation-item__action-btn\"\n look=\"outline\"\n color=\"primary\"\n [text]=\"(actionLabelKey('resume') | translate | async) ?? ''\"\n [disabled]=\"isActionDisabled('resume') || isActionLoading('resume')\"\n (onClick)=\"onAction('resume')\"\n ></ax-button>\n }\n }\n </div>\n }\n </div>\n }\n</article>\n", styles: ["@layer properties;axp-background-operation-item{display:block;border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:rgb(var(--ax-sys-color-border-lightest-surface))}axp-background-operation-item:last-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0px}.operation-item{position:relative;display:flex;align-items:flex-start;gap:calc(var(--spacing, .25rem) * 3);padding-inline:calc(var(--spacing, .25rem) * 4);padding-block:calc(var(--spacing, .25rem) * 3);transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease, var(--default-transition-timing-function, cubic-bezier(.4, 0, .2, 1)));transition-duration:var(--tw-duration, var(--default-transition-duration, .15s));--tw-duration: .15s;transition-duration:.15s}.operation-item.--failed{background:rgb(var(--ax-sys-color-danger-lightest-surface) / .35)}.operation-item__status-icon{margin-top:calc(var(--spacing, .25rem) * .5);display:flex;width:calc(var(--spacing, .25rem) * 12);height:calc(var(--spacing, .25rem) * 12);flex-shrink:0;align-items:center;justify-content:center;border-radius:calc(infinity * 1px);border-style:var(--tw-border-style);border-width:1px;font-size:var(--text-base, 1rem);line-height:var(--tw-leading, var(--text-base--line-height, 1.5 ));--tw-leading: 1;line-height:1;color:rgb(var(--ax-sys-color-on-surface-variant));border-color:rgb(var(--ax-sys-color-border-light-surface));background:rgb(var(--ax-sys-color-lightest-surface))}.operation-item__status-icon.--running{color:rgb(var(--ax-sys-color-primary-500));border-color:rgb(var(--ax-sys-color-border-primary-light-surface));background:rgb(var(--ax-sys-color-primary-lightest-surface))}.operation-item__status-icon.--paused{color:rgb(var(--ax-sys-color-warning-500));border-color:rgb(var(--ax-sys-color-border-warning-light-surface));background:rgb(var(--ax-sys-color-warning-lightest-surface))}.operation-item__status-icon.--completed{color:rgb(var(--ax-sys-color-success-500));border-color:rgb(var(--ax-sys-color-border-success-light-surface));background:rgb(var(--ax-sys-color-success-lightest-surface))}.operation-item__status-icon.--failed{color:rgb(var(--ax-sys-color-danger-500));border-color:rgb(var(--ax-sys-color-border-danger-light-surface));background:rgb(var(--ax-sys-color-danger-lightest-surface))}.operation-item__content{display:flex;min-width:0px;flex:1;flex-direction:column;gap:var(--spacing, .25rem);text-align:start}.operation-item__headline{min-width:0px}.operation-item__title{margin:0;min-width:0px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));--tw-leading: var(--leading-snug, 1.375);line-height:var(--leading-snug, 1.375);--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);color:rgb(var(--ax-sys-color-on-surface))}.operation-item__aside{position:relative;flex-shrink:0;align-self:stretch;min-width:3.5rem}.operation-item__time{position:relative;z-index:1;padding-top:calc(var(--spacing, .25rem) * .5);text-align:end;font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));white-space:nowrap;color:rgb(var(--ax-sys-color-on-surface-variant))}.operation-item__status-text{margin:0;overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;text-align:start;font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));--tw-leading: var(--leading-relaxed, 1.625);line-height:var(--leading-relaxed, 1.625);color:rgb(var(--ax-sys-color-on-surface-variant))}.operation-item__step{display:inline-block;font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));color:rgb(var(--ax-sys-color-on-surface-variant))}.operation-item__timing{display:flex;flex-wrap:wrap;column-gap:calc(var(--spacing, .25rem) * 2);row-gap:calc(var(--spacing, .25rem) * .5);font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));color:rgb(var(--ax-sys-color-on-surface-variant))}.operation-item__progress-row{margin-top:var(--spacing, .25rem);display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 2)}.operation-item__progress-label{flex-shrink:0;font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);--tw-numeric-spacing: tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,);color:rgb(var(--ax-sys-color-on-surface-variant))}.operation-item__progress{min-width:0px;flex:1}.operation-item__error{margin:0;border-radius:var(--radius-md, .375rem);padding-inline:calc(var(--spacing, .25rem) * 2);padding-block:var(--spacing, .25rem);font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));--tw-leading: var(--leading-relaxed, 1.625);line-height:var(--leading-relaxed, 1.625);background:rgb(var(--ax-sys-color-danger-lighter-surface));color:rgb(var(--ax-sys-color-on-danger-lighter-surface))}.operation-item__status-separator{white-space:pre}.operation-item__footer-actions{margin-top:var(--spacing, .25rem);display:flex;flex-wrap:wrap;align-items:center;gap:calc(var(--spacing, .25rem) * 2)}.operation-item__actions{position:absolute;top:50%;right:0;display:flex;--tw-translate-y: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y);flex-direction:column;align-items:flex-end;gap:var(--spacing, .25rem)}.operation-item__action-btn{white-space:nowrap}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-duration{syntax: \"*\"; inherits: false;}@property --tw-leading{syntax: \"*\"; inherits: false;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-ordinal{syntax: \"*\"; inherits: false;}@property --tw-slashed-zero{syntax: \"*\"; inherits: false;}@property --tw-numeric-figure{syntax: \"*\"; inherits: false;}@property --tw-numeric-spacing{syntax: \"*\"; inherits: false;}@property --tw-numeric-fraction{syntax: \"*\"; inherits: false;}@property --tw-translate-x{syntax: \"*\"; inherits: false; initial-value: 0;}@property --tw-translate-y{syntax: \"*\"; inherits: false; initial-value: 0;}@property --tw-translate-z{syntax: \"*\"; inherits: false; initial-value: 0;}@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-duration: initial;--tw-leading: initial;--tw-font-weight: initial;--tw-ordinal: initial;--tw-slashed-zero: initial;--tw-numeric-figure: initial;--tw-numeric-spacing: initial;--tw-numeric-fraction: initial;--tw-translate-x: 0;--tw-translate-y: 0;--tw-translate-z: 0}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i2.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXProgressBarModule }, { kind: "component", type: i3.AXProgressBarComponent, selector: "ax-progress-bar", inputs: ["color", "mode", "progress", "height"], outputs: ["ValueChange", "sizeChange"] }, { kind: "ngmodule", type: AXFormatModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }, { kind: "pipe", type: i2$1.AXFormatPipe, name: "format" }, { kind: "pipe", type: i6.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
5088
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPBackgroundOperationItemComponent, isStandalone: true, selector: "axp-background-operation-item", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null }, tabKey: { classPropertyName: "tabKey", publicName: "tabKey", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { actionCompleted: "actionCompleted", itemClicked: "itemClicked" }, ngImport: i0, template: "<article class=\"operation-item\" [class]=\"statusClass()\">\n <ax-icon class=\"operation-item__status-icon\" [class]=\"statusClass()\">\n <i [class]=\"statusIcon()\"></i>\n </ax-icon>\n\n <div class=\"operation-item__content\">\n <div class=\"operation-item__headline\">\n <h3 class=\"operation-item__title\">{{ data().title }}</h3>\n </div>\n\n @if (isCompletedTab()) {\n @if (showCompletedSummaryLine()) {\n <!-- ----- Status merged with finished time and duration ----- -->\n <p class=\"operation-item__status-text\">\n @if (statusTextKey(); as key) {\n <span>{{ key | translate: { params: statusTextParams() } | async }}</span>\n } @else if (plainStatusText()) {\n <span>{{ plainStatusText() }}</span>\n }\n @if (timingDatetime(); as finishedAt) {\n @if (statusTextKey() || plainStatusText()) {\n <span class=\"operation-item__status-separator\" aria-hidden=\"true\"> \u00B7 </span>\n }\n <!--->\n <!-- ----- Locale-aware finished datetime via format pipe ----- -->\n @if ((finishedAt | format: 'datetime' : 'short' | async); as datetime) {\n <span>{{\n '@general:background-operation.timing.finished-at'\n | translate: { params: { datetime } }\n | async\n }}</span>\n }\n <!--->\n <!-- ----- Compact duration when available ----- -->\n @if (timingDuration(); as duration) {\n <span class=\"operation-item__status-separator\" aria-hidden=\"true\"> \u00B7 </span>\n <span>{{\n '@general:background-operation.timing.duration'\n | translate: { params: { duration } }\n | async\n }}</span>\n }\n }\n </p>\n }\n } @else {\n @if (statusTextKey(); as key) {\n <p class=\"operation-item__status-text\">\n {{ key | translate: { params: statusTextParams() } | async }}\n </p>\n } @else if (plainStatusText()) {\n <p class=\"operation-item__status-text\">\n {{ plainStatusText() }}\n </p>\n }\n }\n\n @if (showStepLine()) {\n <span class=\"operation-item__step\">\n {{ '@general:background-operation.step' | translate | async }}\n {{ data().currentStep }}\n </span>\n }\n\n @if (timingDatetime(); as startedAt) {\n <!--->\n <!-- ----- Started time and estimate for in-progress tasks ----- -->\n @if (isInProgressTab()) {\n <div class=\"operation-item__timing\">\n <!-- ----- Locale-aware started datetime via format pipe ----- -->\n @if ((startedAt | format: 'datetime' : 'short' | async); as datetime) {\n <span>\n {{\n '@general:background-operation.timing.started-at'\n | translate: { params: { datetime } }\n | async\n }}\n </span>\n }\n <!--->\n <!-- ----- ETA when the task type supports estimates ----- -->\n @if (showEstimateLine()) {\n <span>\n {{\n '@general:background-operation.timing.estimate'\n | translate: { params: { estimate: timingDuration()! } }\n | async\n }}\n </span>\n }\n </div>\n }\n }\n\n @if (showCompletedActionRow()) {\n <div class=\"ax-xs operation-item__footer-actions\">\n @if (cta(); as primaryCta) {\n <!-- ----- Handler-defined CTA on completed tab ----- -->\n <ax-button\n class=\"operation-item__action-btn\"\n look=\"solid\"\n [color]=\"primaryCta.color ?? 'primary'\"\n [text]=\"ctaDisplayText()\"\n [disabled]=\"isCtaDisabled(primaryCta)\"\n (onClick)=\"onCtaClick(primaryCta)\"\n >\n @if (primaryCta.icon) {\n <ax-prefix>\n <ax-icon><i [class]=\"primaryCta.icon\"></i></ax-icon>\n </ax-prefix>\n }\n </ax-button>\n }\n @if (showDismissButton()) {\n <!-- ----- Close / dismiss completed rows ----- -->\n <ax-button\n class=\"operation-item__action-btn\"\n look=\"solid\"\n color=\"default\"\n [text]=\"(actionLabelKey('dismiss') | translate | async) ?? ''\"\n [disabled]=\"isActionDisabled('dismiss') || isActionLoading('dismiss')\"\n (onClick)=\"onAction('dismiss')\"\n ></ax-button>\n }\n </div>\n }\n\n @if (showProgressBar()) {\n <div class=\"operation-item__progress-row\">\n @if (showProgressPercent()) {\n <span class=\"operation-item__progress-label\">\n {{\n '@general:background-operation.progress-percent'\n | translate: { params: { percent: progressValue() } }\n | async\n }}\n </span>\n }\n <ax-progress-bar\n class=\"operation-item__progress\"\n [progress]=\"progressValue()\"\n [mode]=\"progressMode()\"\n [color]=\"progressColor()\"\n [style.height.px]=\"4\"\n ></ax-progress-bar>\n </div>\n }\n\n @if (showError()) {\n @if (errorMessageKey(); as errorKey) {\n <p class=\"operation-item__error\" role=\"alert\">\n {{ errorKey | translate | async }}\n </p>\n } @else if (plainErrorMessage()) {\n <p class=\"operation-item__error\" role=\"alert\">\n {{ plainErrorMessage() }}\n </p>\n }\n }\n </div>\n\n @if (showDate() || showActionColumn()) {\n <div class=\"operation-item__aside\">\n @if (showDate()) {\n <span class=\"operation-item__time\">{{ displayTime() | format: 'timeleft' | async }}</span>\n }\n @if (showActionColumn()) {\n <div class=\"operation-item__actions\" (click)=\"$event.stopPropagation()\">\n @if (isInProgressTab()) {\n @if (showCancelButton()) {\n <!-- ----- Cancel for in-progress cancellable tasks ----- -->\n <ax-button\n class=\"ax-xs operation-item__action-btn\"\n look=\"outline\"\n color=\"danger\"\n [text]=\"(actionLabelKey('cancel') | translate | async) ?? ''\"\n [disabled]=\"isActionDisabled('cancel') || isActionLoading('cancel')\"\n (onClick)=\"onAction('cancel')\"\n ></ax-button>\n }\n @if (showPauseButton()) {\n <!-- ----- Pause when supported and no cancel is shown ----- -->\n <ax-button\n class=\"ax-xs operation-item__action-btn\"\n look=\"outline\"\n color=\"default\"\n [text]=\"(actionLabelKey('pause') | translate | async) ?? ''\"\n [disabled]=\"isActionDisabled('pause') || isActionLoading('pause')\"\n (onClick)=\"onAction('pause')\"\n ></ax-button>\n }\n @if (showResumeButton()) {\n <!-- ----- Resume for paused tasks ----- -->\n <ax-button\n class=\"ax-xs operation-item__action-btn\"\n look=\"outline\"\n color=\"primary\"\n [text]=\"(actionLabelKey('resume') | translate | async) ?? ''\"\n [disabled]=\"isActionDisabled('resume') || isActionLoading('resume')\"\n (onClick)=\"onAction('resume')\"\n ></ax-button>\n }\n }\n </div>\n }\n </div>\n }\n</article>\n", styles: ["@layer properties;axp-background-operation-item{display:block;border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:rgb(var(--ax-sys-color-border-lightest-surface))}axp-background-operation-item:last-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0px}.operation-item{position:relative;display:flex;align-items:flex-start;gap:calc(var(--spacing, .25rem) * 3);padding-inline:calc(var(--spacing, .25rem) * 4);padding-block:calc(var(--spacing, .25rem) * 3);transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease, var(--default-transition-timing-function, cubic-bezier(.4, 0, .2, 1)));transition-duration:var(--tw-duration, var(--default-transition-duration, .15s));--tw-duration: .15s;transition-duration:.15s}.operation-item.--failed{background:rgb(var(--ax-sys-color-danger-lightest-surface) / .35)}.operation-item__status-icon{margin-top:calc(var(--spacing, .25rem) * .5);display:flex;width:calc(var(--spacing, .25rem) * 12);height:calc(var(--spacing, .25rem) * 12);flex-shrink:0;align-items:center;justify-content:center;border-radius:calc(infinity * 1px);border-style:var(--tw-border-style);border-width:1px;font-size:var(--text-base, 1rem);line-height:var(--tw-leading, var(--text-base--line-height, 1.5 ));--tw-leading: 1;line-height:1;color:rgb(var(--ax-sys-color-on-surface-variant));border-color:rgb(var(--ax-sys-color-border-light-surface));background:rgb(var(--ax-sys-color-lightest-surface))}.operation-item__status-icon.--running{color:rgb(var(--ax-sys-color-primary-500));border-color:rgb(var(--ax-sys-color-border-primary-light-surface));background:rgb(var(--ax-sys-color-primary-lightest-surface))}.operation-item__status-icon.--paused{color:rgb(var(--ax-sys-color-warning-500));border-color:rgb(var(--ax-sys-color-border-warning-light-surface));background:rgb(var(--ax-sys-color-warning-lightest-surface))}.operation-item__status-icon.--completed{color:rgb(var(--ax-sys-color-success-500));border-color:rgb(var(--ax-sys-color-border-success-light-surface));background:rgb(var(--ax-sys-color-success-lightest-surface))}.operation-item__status-icon.--failed{color:rgb(var(--ax-sys-color-danger-500));border-color:rgb(var(--ax-sys-color-border-danger-light-surface));background:rgb(var(--ax-sys-color-danger-lightest-surface))}.operation-item__content{display:flex;min-width:0px;flex:1;flex-direction:column;gap:var(--spacing, .25rem);text-align:start}.operation-item__headline{min-width:0px}.operation-item__title{margin:0;min-width:0px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));--tw-leading: var(--leading-snug, 1.375);line-height:var(--leading-snug, 1.375);--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);color:rgb(var(--ax-sys-color-on-surface))}.operation-item__aside{position:relative;flex-shrink:0;align-self:stretch;min-width:3.5rem}.operation-item__time{position:relative;z-index:1;padding-top:calc(var(--spacing, .25rem) * .5);text-align:end;font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));white-space:nowrap;color:rgb(var(--ax-sys-color-on-surface-variant))}.operation-item__status-text{margin:0;overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;text-align:start;font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));--tw-leading: var(--leading-relaxed, 1.625);line-height:var(--leading-relaxed, 1.625);color:rgb(var(--ax-sys-color-on-surface-variant))}.operation-item__step{display:inline-block;font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));color:rgb(var(--ax-sys-color-on-surface-variant))}.operation-item__timing{display:flex;flex-wrap:wrap;column-gap:calc(var(--spacing, .25rem) * 2);row-gap:calc(var(--spacing, .25rem) * .5);font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));color:rgb(var(--ax-sys-color-on-surface-variant))}.operation-item__progress-row{margin-top:var(--spacing, .25rem);display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 2)}.operation-item__progress-label{flex-shrink:0;font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);--tw-numeric-spacing: tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,);color:rgb(var(--ax-sys-color-on-surface-variant))}.operation-item__progress{min-width:0px;flex:1}.operation-item__error{margin:0;border-radius:var(--radius-md, .375rem);padding-inline:calc(var(--spacing, .25rem) * 2);padding-block:var(--spacing, .25rem);font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));--tw-leading: var(--leading-relaxed, 1.625);line-height:var(--leading-relaxed, 1.625);background:rgb(var(--ax-sys-color-danger-lighter-surface));color:rgb(var(--ax-sys-color-on-danger-lighter-surface))}.operation-item__status-separator{white-space:pre}.operation-item__footer-actions{margin-top:var(--spacing, .25rem);display:flex;flex-wrap:wrap;align-items:center;gap:calc(var(--spacing, .25rem) * 2)}.operation-item__actions{position:absolute;top:50%;right:0;display:flex;--tw-translate-y: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y);flex-direction:column;align-items:flex-end;gap:var(--spacing, .25rem)}.operation-item__action-btn{white-space:nowrap}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-duration{syntax: \"*\"; inherits: false;}@property --tw-leading{syntax: \"*\"; inherits: false;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-ordinal{syntax: \"*\"; inherits: false;}@property --tw-slashed-zero{syntax: \"*\"; inherits: false;}@property --tw-numeric-figure{syntax: \"*\"; inherits: false;}@property --tw-numeric-spacing{syntax: \"*\"; inherits: false;}@property --tw-numeric-fraction{syntax: \"*\"; inherits: false;}@property --tw-translate-x{syntax: \"*\"; inherits: false; initial-value: 0;}@property --tw-translate-y{syntax: \"*\"; inherits: false; initial-value: 0;}@property --tw-translate-z{syntax: \"*\"; inherits: false; initial-value: 0;}@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-duration: initial;--tw-leading: initial;--tw-font-weight: initial;--tw-ordinal: initial;--tw-slashed-zero: initial;--tw-numeric-figure: initial;--tw-numeric-spacing: initial;--tw-numeric-fraction: initial;--tw-translate-x: 0;--tw-translate-y: 0;--tw-translate-z: 0}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i2.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXProgressBarModule }, { kind: "component", type: i3.AXProgressBarComponent, selector: "ax-progress-bar", inputs: ["color", "mode", "progress", "height"], outputs: ["ValueChange", "sizeChange"] }, { kind: "ngmodule", type: AXFormatModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }, { kind: "pipe", type: i3$1.AXFormatPipe, name: "format" }, { kind: "pipe", type: i6.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
5071
5089
  }
5072
5090
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPBackgroundOperationItemComponent, decorators: [{
5073
5091
  type: Component,
@@ -5234,7 +5252,7 @@ class AXPBackgroundOperationPanelComponent {
5234
5252
  }
5235
5253
  }
5236
5254
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPBackgroundOperationPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
5237
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPBackgroundOperationPanelComponent, isStandalone: true, selector: "axp-background-operation-panel", outputs: { onActiveCountChange: "onActiveCountChange", onClosePopover: "onClosePopover" }, viewQueries: [{ propertyName: "tabsHost", first: true, predicate: ["tabsHost"], descendants: true, isSignal: true }], ngImport: i0, template: "<header class=\"operation-panel__header\">\n <h2 class=\"operation-panel__title\">\n {{ '@general:background-operation.panel.title' | translate | async }}\n </h2>\n @if (showCancelAllButton()) {\n <!-- ----- Cancel all cancellable in-progress tasks ----- -->\n <ax-button\n class=\"ax-xs operation-panel__header-action\"\n look=\"blank\"\n color=\"danger\"\n [text]=\"('@general:background-operation.actions.cancel-all' | translate | async) ?? ''\"\n [disabled]=\"bulkActionPending() || operationService.loading()\"\n (onClick)=\"onCancelAll()\"\n ></ax-button>\n }\n @if (showDismissAllButton()) {\n <!-- ----- Dismiss all dismissible completed tasks ----- -->\n <ax-button\n class=\"ax-xs operation-panel__header-action\"\n look=\"blank\"\n color=\"default\"\n [text]=\"('@general:background-operation.actions.dismiss-all' | translate | async) ?? ''\"\n [disabled]=\"bulkActionPending() || operationService.loading()\"\n (onClick)=\"onDismissAll()\"\n ></ax-button>\n }\n <ax-button class=\"ax-xs operation-panel__header-action\" look=\"blank\" [iconOnly]=\"true\" (onClick)=\"onClosePopover.emit()\">\n <ax-icon><i class=\"fa-light fa-xmark \" aria-hidden=\"true\"></i></ax-icon>\n </ax-button>\n</header>\n\n<ax-tabs\n #tabsHost\n [content]=\"tabContent\"\n [look]=\"'with-line'\"\n location=\"bottom\"\n (onActiveTabChanged)=\"handleTabChange($event)\"\n>\n @for (tab of tabItems(); track tab.key) {\n <ax-tab-item [text]=\"(tab.labelKey | translate | async) ?? ''\" [active]=\"activeTab() === tab.key\">\n <ax-suffix>\n @if (tab.count > 0) {\n <ax-badge [color]=\"activeTab() === tab.key ? 'primary' : 'ghost'\" [text]=\"tab.count.toString()\"></ax-badge>\n }\n </ax-suffix>\n <ax-content>\n <div class=\"operation-panel__list\">\n @if (getOperations(tab.key).length === 0) {\n @if (emptyStateForTab(tab.key); as emptyState) {\n <axp-state-message [icon]=\"emptyState.icon\" [title]=\"emptyState.titleKey\" [description]=\"emptyState.descriptionKey\" />\n }\n } @else {\n @for (operation of getOperations(tab.key); track operation.id) {\n <axp-background-operation-item [data]=\"operation\" [tabKey]=\"tab.key\" (actionCompleted)=\"onItemActionCompleted()\" (itemClicked)=\"onClosePopover.emit()\"></axp-background-operation-item>\n }\n }\n </div>\n </ax-content>\n </ax-tab-item>\n }\n</ax-tabs>\n\n<ng-template [axTabContent] #tabContent=\"axTabContent\"></ng-template>\n", styles: ["@layer properties;axp-background-operation-panel{display:block;min-height:calc(var(--spacing, .25rem) * 80);width:100%;border-radius:var(--radius-md, .375rem);border-style:var(--tw-border-style);border-width:2px;border-color:rgba(var(--ax-sys-color-primary-500));background-color:rgba(var(--ax-sys-color-lightest-surface))}@media(width>=48rem){axp-background-operation-panel{width:32rem}}axp-background-operation-panel ax-tabs{padding-inline:calc(var(--spacing, .25rem) * 2)}axp-background-operation-panel .operation-panel__header{display:flex;align-items:center;justify-content:space-between;border-bottom-style:var(--tw-border-style);border-bottom-width:1px;background-color:var(--color-primary);color:var(--color-on-primary);border-color:var(--color-border-primary);padding-inline:calc(var(--spacing, .25rem) * 4);padding-block:calc(var(--spacing, .25rem) * 3)}axp-background-operation-panel .operation-panel__title{margin:0;min-width:0px;flex:1;font-size:var(--text-base, 1rem);line-height:var(--tw-leading, var(--text-base--line-height, 1.5 ));--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600)}axp-background-operation-panel .operation-panel__header-action{flex-shrink:0}axp-background-operation-panel .operation-panel__header-action .ax-blank-interactive{color:var(--color-white, #fff)!important}axp-background-operation-panel .operation-panel__header-action .ax-blank-interactive:hover{color:rgba(var(--ax-sys-color-primary-500))!important}axp-background-operation-panel .operation-panel__list{display:flex;max-height:50vh;flex-direction:column;overflow-y:auto}@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: AXTranslationModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXTabsModule }, { kind: "component", type: i2$2.AXTabsComponent, selector: "ax-tabs", inputs: ["look", "location", "reorderable", "reorderDelay", "fitParent", "minWidth", "content"], outputs: ["onActiveTabChanged", "onTabsReordered"] }, { kind: "component", type: i2$2.AXTabItemComponent, selector: "ax-tab-item", inputs: ["disabled", "text", "key", "headerTemplate", "active"], outputs: ["disabledChange", "onClick", "onBlur", "onFocus", "activeChange"] }, { kind: "directive", type: i2$2.AXTabContentDirective, selector: "[axTabContent]", inputs: ["axTabContent"], exportAs: ["axTabContent"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i2.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "component", type: i4$1.AXBadgeComponent, selector: "ax-badge", inputs: ["color", "look", "text"] }, { kind: "component", type: AXPStateMessageComponent, selector: "axp-state-message", inputs: ["mode", "icon", "title", "description", "titleParams", "descriptionParams", "look"] }, { kind: "component", type: AXPBackgroundOperationItemComponent, selector: "axp-background-operation-item", inputs: ["data", "tabKey"], outputs: ["actionCompleted", "itemClicked"] }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
5255
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPBackgroundOperationPanelComponent, isStandalone: true, selector: "axp-background-operation-panel", outputs: { onActiveCountChange: "onActiveCountChange", onClosePopover: "onClosePopover" }, viewQueries: [{ propertyName: "tabsHost", first: true, predicate: ["tabsHost"], descendants: true, isSignal: true }], ngImport: i0, template: "<header class=\"operation-panel__header\">\n <h2 class=\"operation-panel__title\">\n {{ '@general:background-operation.panel.title' | translate | async }}\n </h2>\n @if (showCancelAllButton()) {\n <!-- ----- Cancel all cancellable in-progress tasks ----- -->\n <ax-button\n class=\"ax-xs operation-panel__header-action\"\n look=\"blank\"\n color=\"danger\"\n [text]=\"('@general:background-operation.actions.cancel-all' | translate | async) ?? ''\"\n [disabled]=\"bulkActionPending() || operationService.loading()\"\n (onClick)=\"onCancelAll()\"\n ></ax-button>\n }\n @if (showDismissAllButton()) {\n <!-- ----- Dismiss all dismissible completed tasks ----- -->\n <ax-button\n class=\"ax-xs operation-panel__header-action\"\n look=\"blank\"\n color=\"default\"\n [text]=\"('@general:background-operation.actions.dismiss-all' | translate | async) ?? ''\"\n [disabled]=\"bulkActionPending() || operationService.loading()\"\n (onClick)=\"onDismissAll()\"\n ></ax-button>\n }\n <ax-button class=\"ax-xs operation-panel__header-action\" look=\"blank\" [iconOnly]=\"true\" (onClick)=\"onClosePopover.emit()\">\n <ax-icon><i class=\"fa-light fa-xmark \" aria-hidden=\"true\"></i></ax-icon>\n </ax-button>\n</header>\n\n<ax-tabs\n #tabsHost\n [content]=\"tabContent\"\n [look]=\"'with-line'\"\n location=\"bottom\"\n (onActiveTabChanged)=\"handleTabChange($event)\"\n>\n @for (tab of tabItems(); track tab.key) {\n <ax-tab-item [text]=\"(tab.labelKey | translate | async) ?? ''\" [active]=\"activeTab() === tab.key\">\n <ax-suffix>\n @if (tab.count > 0) {\n <ax-badge [color]=\"activeTab() === tab.key ? 'primary' : 'ghost'\" [text]=\"tab.count.toString()\"></ax-badge>\n }\n </ax-suffix>\n <ax-content>\n <div class=\"operation-panel__list\">\n @if (getOperations(tab.key).length === 0) {\n @if (emptyStateForTab(tab.key); as emptyState) {\n <axp-state-message [icon]=\"emptyState.icon\" [title]=\"emptyState.titleKey\" [description]=\"emptyState.descriptionKey\" />\n }\n } @else {\n @for (operation of getOperations(tab.key); track operation.id) {\n <axp-background-operation-item [data]=\"operation\" [tabKey]=\"tab.key\" (actionCompleted)=\"onItemActionCompleted()\" (itemClicked)=\"onClosePopover.emit()\"></axp-background-operation-item>\n }\n }\n </div>\n </ax-content>\n </ax-tab-item>\n }\n</ax-tabs>\n\n<ng-template [axTabContent] #tabContent=\"axTabContent\"></ng-template>\n", styles: ["@layer properties;axp-background-operation-panel{display:block;min-height:calc(var(--spacing, .25rem) * 80);width:100%;border-radius:var(--radius-md, .375rem);border-style:var(--tw-border-style);border-width:2px;border-color:rgba(var(--ax-sys-color-primary-500));background-color:rgba(var(--ax-sys-color-lightest-surface))}@media(width>=48rem){axp-background-operation-panel{width:32rem}}axp-background-operation-panel ax-tabs{padding-inline:calc(var(--spacing, .25rem) * 2)}axp-background-operation-panel .operation-panel__header{display:flex;align-items:center;justify-content:space-between;border-bottom-style:var(--tw-border-style);border-bottom-width:1px;background-color:var(--color-primary);color:var(--color-on-primary);border-color:var(--color-border-primary);padding-inline:calc(var(--spacing, .25rem) * 4);padding-block:calc(var(--spacing, .25rem) * 3)}axp-background-operation-panel .operation-panel__title{margin:0;min-width:0px;flex:1;font-size:var(--text-base, 1rem);line-height:var(--tw-leading, var(--text-base--line-height, 1.5 ));--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600)}axp-background-operation-panel .operation-panel__header-action{flex-shrink:0}axp-background-operation-panel .operation-panel__header-action .ax-blank-interactive{color:var(--color-white, #fff)!important}axp-background-operation-panel .operation-panel__header-action .ax-blank-interactive:hover{color:rgba(var(--ax-sys-color-primary-500))!important}axp-background-operation-panel .operation-panel__list{display:flex;max-height:50vh;flex-direction:column;overflow-y:auto}@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: AXTranslationModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXTabsModule }, { kind: "component", type: i2$1.AXTabsComponent, selector: "ax-tabs", inputs: ["look", "location", "reorderable", "reorderDelay", "renderMode", "stacked", "fitParent", "minWidth", "content"], outputs: ["onActiveTabChanged", "onTabsReordered"] }, { kind: "component", type: i2$1.AXTabItemComponent, selector: "ax-tab-item", inputs: ["disabled", "text", "key", "headerTemplate", "active"], outputs: ["disabledChange", "onClick", "onBlur", "onFocus", "activeChange"] }, { kind: "directive", type: i2$1.AXTabContentDirective, selector: "[axTabContent]", inputs: ["axTabContent"], exportAs: ["axTabContent"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i2.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "component", type: i4$1.AXBadgeComponent, selector: "ax-badge", inputs: ["color", "look", "text"] }, { kind: "component", type: AXPStateMessageComponent, selector: "axp-state-message", inputs: ["mode", "icon", "title", "description", "titleParams", "descriptionParams", "look"] }, { kind: "component", type: AXPBackgroundOperationItemComponent, selector: "axp-background-operation-item", inputs: ["data", "tabKey"], outputs: ["actionCompleted", "itemClicked"] }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
5238
5256
  }
5239
5257
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPBackgroundOperationPanelComponent, decorators: [{
5240
5258
  type: Component,
@@ -5311,7 +5329,7 @@ class AXPBackgroundOperationSlotComponent {
5311
5329
  this.popover()?.close();
5312
5330
  }
5313
5331
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPBackgroundOperationSlotComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
5314
- 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$1.AXPopoverComponent, selector: "ax-popover", inputs: ["width", "disablePanelClass", "visualContextScope", "disabled", "offsetX", "offsetY", "target", "placement", "content", "openOn", "closeOn", "hasBackdrop", "openAfter", "closeAfter", "closeOnScroll", "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 }); }
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 }); }
5315
5333
  }
5316
5334
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPBackgroundOperationSlotComponent, decorators: [{
5317
5335
  type: Component,
@@ -5656,13 +5674,99 @@ function axpReplaceEntityListRouteQueryParams(router, queryParams) {
5656
5674
  }
5657
5675
  //#endregion
5658
5676
 
5677
+ //#region ----- Constants -----
5678
+ /** Query param that distinguishes two menus pointing at the same entity list. */
5679
+ const ENTITY_LIST_INSTANCE_QUERY_PARAM = 'list';
5680
+ /** Used when the list is opened without a menu (command, deep link). */
5681
+ const ENTITY_LIST_DEFAULT_INSTANCE_ID = 'default';
5682
+ //#endregion
5683
+ //#region ----- Instance id -----
5684
+ function axpNormalizeEntityListInstanceId(value) {
5685
+ if (typeof value !== 'string') {
5686
+ return ENTITY_LIST_DEFAULT_INSTANCE_ID;
5687
+ }
5688
+ const trimmed = value.trim();
5689
+ return trimmed.length > 0 ? trimmed : ENTITY_LIST_DEFAULT_INSTANCE_ID;
5690
+ }
5691
+ function axpGetEntityListInstanceIdFromQueryString(queryString) {
5692
+ const params = new URLSearchParams(queryString.startsWith('?') ? queryString.slice(1) : queryString);
5693
+ return axpNormalizeEntityListInstanceId(params.get(ENTITY_LIST_INSTANCE_QUERY_PARAM));
5694
+ }
5695
+ function axpGetEntityListInstanceIdFromParamMap(queryParamMap) {
5696
+ return axpNormalizeEntityListInstanceId(queryParamMap.get(ENTITY_LIST_INSTANCE_QUERY_PARAM));
5697
+ }
5698
+ function axpGetEntityListInstanceIdFromPath(path) {
5699
+ const queryString = path.split('#')[0].split('?')[1] ?? '';
5700
+ return axpGetEntityListInstanceIdFromQueryString(queryString);
5701
+ }
5702
+ //#endregion
5703
+ //#region ----- Menu / URL stamping -----
5704
+ /**
5705
+ * Appends `list={instanceId}` to an entity-list path when missing.
5706
+ * Named menu entries get a stable identity so Angular reuses the list route
5707
+ * while filter persistence can still isolate each menu.
5708
+ */
5709
+ function axpEnsureEntityListInstanceQueryParam(path, instanceId) {
5710
+ if (!path || !instanceId || !axpIsEntityListPath(path)) {
5711
+ return path;
5712
+ }
5713
+ const normalized = axpNormalizeEntityListInstanceId(instanceId);
5714
+ if (normalized === ENTITY_LIST_DEFAULT_INSTANCE_ID) {
5715
+ return path;
5716
+ }
5717
+ const { segments, queryParams, fragment } = axpParseAppPath(path);
5718
+ if (queryParams?.[ENTITY_LIST_INSTANCE_QUERY_PARAM]) {
5719
+ return path;
5720
+ }
5721
+ const nextQuery = new URLSearchParams({
5722
+ ...(queryParams ?? {}),
5723
+ [ENTITY_LIST_INSTANCE_QUERY_PARAM]: normalized,
5724
+ });
5725
+ const base = `/${segments.join('/')}`;
5726
+ const withQuery = `${base}?${nextQuery.toString()}`;
5727
+ return fragment ? `${withQuery}#${fragment}` : withQuery;
5728
+ }
5729
+ //#endregion
5730
+
5731
+ //#region ----- Menu instance identity -----
5732
+ /** Prefers the stamped `list` query param, then the menu item name. */
5733
+ function axpMenuItemListInstanceId(item) {
5734
+ if (item.path) {
5735
+ const fromPath = axpGetEntityListInstanceIdFromPath(item.path);
5736
+ if (fromPath !== ENTITY_LIST_DEFAULT_INSTANCE_ID) {
5737
+ return fromPath;
5738
+ }
5739
+ }
5740
+ return axpNormalizeEntityListInstanceId(item.name);
5741
+ }
5742
+ /** Stamps `?list={menu.name}` onto entity-list menu paths so each menu is a distinct list instance. */
5743
+ function axpStampEntityListMenuInstancePaths(items) {
5744
+ const walk = (list) => {
5745
+ let listChanged = false;
5746
+ const next = list.map((item) => {
5747
+ const children = item.children?.length ? walk(item.children) : item.children;
5748
+ const path = item.path && item.name ? axpEnsureEntityListInstanceQueryParam(item.path, item.name) : item.path;
5749
+ if (path === item.path && children === item.children) {
5750
+ return item;
5751
+ }
5752
+ listChanged = true;
5753
+ return { ...item, path, children };
5754
+ });
5755
+ return listChanged ? next : list;
5756
+ };
5757
+ return walk(items);
5758
+ }
5759
+ //#endregion
5760
+
5659
5761
  const DEFAULT_TRAILING_SEGMENTS = ['list', 'view', 'edit', 'create'];
5660
5762
  /**
5661
5763
  * Query params that represent page UI state (not navigation identity).
5662
5764
  * Ignored when deciding whether a menu item matches the current route, so items stay
5663
5765
  * highlighted while the page mutates view/layout (e.g. task board, entity list view).
5766
+ * `list` is the menu-instance id: it must not block detail highlighting, but
5767
+ * {@link axpFindMenuItemByRoute} still prefers the menu whose name matches it.
5664
5768
  */
5665
- const MENU_UI_QUERY_KEYS = new Set(['view', 'layout']);
5769
+ const MENU_UI_QUERY_KEYS = new Set(['view', 'layout', 'list']);
5666
5770
  //#region ---- Entity Route Helpers ----
5667
5771
  /**
5668
5772
  * Parses `/{app}/m/{module}/e/{entity}/...` routes into a stable entity key.
@@ -5809,7 +5913,7 @@ function axpMenuPathsMatch(itemPath, currentPath, trailingSegmentsToIgnore = DEF
5809
5913
  const isPartialMatch = effectiveMenuLength < pathLength;
5810
5914
  const isExactMatch = effectiveMenuLength === pathLength;
5811
5915
  // Only non-UI query params on the menu path must match the current URL.
5812
- // UI-only params (`view`, `layout`) are ignored so pages can mutate them freely.
5916
+ // UI-only params (`view`, `layout`, `list`) are ignored so pages can mutate them freely.
5813
5917
  // Extra current-URL params (filters, etc.) do not break the match.
5814
5918
  const itemNavigationParams = axpMenuDeclaredNavigationParams(itemQueryString);
5815
5919
  const declaredPairs = [];
@@ -5833,6 +5937,10 @@ function axpFindMenuItemByRoute(items, currentPath, trailingSegmentsToIgnore = D
5833
5937
  let bestMatch = null;
5834
5938
  let bestEffectiveLength = -1;
5835
5939
  let bestQuerySpecificity = -1;
5940
+ let bestInstanceMatch = false;
5941
+ const currentQueryString = currentPath.split('#')[0].split('?')[1] ?? '';
5942
+ const currentInstanceId = axpGetEntityListInstanceIdFromQueryString(currentQueryString);
5943
+ const hasListInstance = currentInstanceId !== ENTITY_LIST_DEFAULT_INSTANCE_ID;
5836
5944
  const visit = (menuItems, ancestors) => {
5837
5945
  for (const item of menuItems) {
5838
5946
  if (item.children?.length) {
@@ -5858,10 +5966,17 @@ function axpFindMenuItemByRoute(items, currentPath, trailingSegmentsToIgnore = D
5858
5966
  effectiveMenuLength = menuEntity.entityEndIndex;
5859
5967
  }
5860
5968
  const querySpecificity = axpMenuQueryParamSpecificity(item.path, currentPath);
5861
- if (effectiveMenuLength > bestEffectiveLength ||
5862
- (effectiveMenuLength === bestEffectiveLength && querySpecificity > bestQuerySpecificity)) {
5969
+ const instanceMatch = hasListInstance && axpMenuItemListInstanceId(item) === currentInstanceId;
5970
+ const isBetter = effectiveMenuLength > bestEffectiveLength ||
5971
+ (effectiveMenuLength === bestEffectiveLength && querySpecificity > bestQuerySpecificity) ||
5972
+ (effectiveMenuLength === bestEffectiveLength &&
5973
+ querySpecificity === bestQuerySpecificity &&
5974
+ instanceMatch &&
5975
+ !bestInstanceMatch);
5976
+ if (isBetter) {
5863
5977
  bestEffectiveLength = effectiveMenuLength;
5864
5978
  bestQuerySpecificity = querySpecificity;
5979
+ bestInstanceMatch = instanceMatch;
5865
5980
  bestMatch = { item, ancestors, isPartialMatch: matchResult.isPartial };
5866
5981
  }
5867
5982
  }
@@ -6965,7 +7080,7 @@ withState((router = inject(Router)) => {
6965
7080
  withMethods((store, router = inject(Router), commandService = inject(AXPCommandService)) => {
6966
7081
  return {
6967
7082
  setMenuItems(items) {
6968
- patchState(store, { items: items });
7083
+ patchState(store, { items: axpStampEntityListMenuInstancePaths(items) });
6969
7084
  },
6970
7085
  /**
6971
7086
  * Patches a single menu item by `name` without rebuilding the full menu tree.
@@ -6975,7 +7090,10 @@ withMethods((store, router = inject(Router), commandService = inject(AXPCommandS
6975
7090
  if (!name) {
6976
7091
  return false;
6977
7092
  }
6978
- const { items, changed } = axpUpdateMenuItemByName(store.items(), name, updates);
7093
+ const stampedUpdates = typeof updates.path === 'string'
7094
+ ? { ...updates, path: axpEnsureEntityListInstanceQueryParam(updates.path, name) }
7095
+ : updates;
7096
+ const { items, changed } = axpUpdateMenuItemByName(store.items(), name, stampedUpdates);
6979
7097
  if (!changed) {
6980
7098
  return false;
6981
7099
  }
@@ -6993,7 +7111,10 @@ withMethods((store, router = inject(Router), commandService = inject(AXPCommandS
6993
7111
  },
6994
7112
  executeCommand(item) {
6995
7113
  if (item.path) {
6996
- void commandService.execute('navigate', { path: item.path });
7114
+ const path = item.name
7115
+ ? axpEnsureEntityListInstanceQueryParam(item.path, item.name)
7116
+ : item.path;
7117
+ void commandService.execute('navigate', { path });
6997
7118
  patchState(store, { selectedMenuItem: { item, isFullMatch: true } });
6998
7119
  }
6999
7120
  if (item.command) {
@@ -7026,8 +7147,9 @@ withMethods((store, router = inject(Router), commandService = inject(AXPCommandS
7026
7147
  let sessionStatusSubscription;
7027
7148
  let reloadGeneration = 0;
7028
7149
  const applyMenuItems = (items) => {
7029
- patchState(store, { items });
7030
- menuKeyboardShortcuts.sync(items);
7150
+ const stampedItems = axpStampEntityListMenuInstancePaths(items);
7151
+ patchState(store, { items: stampedItems });
7152
+ menuKeyboardShortcuts.sync(stampedItems);
7031
7153
  store.selectMenuItemByRoute(router.url);
7032
7154
  };
7033
7155
  const rebuildMenu = async (generation) => {
@@ -7413,6 +7535,51 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
7413
7535
  }]
7414
7536
  }] });
7415
7537
 
7538
+ //#region ----- Command sub-flow navigation (session) -----
7539
+ const SUPPRESS_TAB_RESTORE_KEY = 'axp:command-subflow-suppress-tab-restore';
7540
+ const RETURN_URL_KEY = 'axp:command-subflow-return-url';
7541
+ /** Marks an in-flight command sub-flow (file picker, crop, dialog) so tab restore must not hijack the route. */
7542
+ function axpBeginCommandSubFlowNavigation(returnUrl) {
7543
+ const trimmed = returnUrl.trim();
7544
+ if (!trimmed.length) {
7545
+ return;
7546
+ }
7547
+ try {
7548
+ sessionStorage.setItem(SUPPRESS_TAB_RESTORE_KEY, '1');
7549
+ sessionStorage.setItem(RETURN_URL_KEY, trimmed);
7550
+ }
7551
+ catch {
7552
+ // sessionStorage may be unavailable
7553
+ }
7554
+ }
7555
+ function axpIsCommandSubFlowNavigationSuspended() {
7556
+ try {
7557
+ return sessionStorage.getItem(SUPPRESS_TAB_RESTORE_KEY) === '1';
7558
+ }
7559
+ catch {
7560
+ return false;
7561
+ }
7562
+ }
7563
+ function axpPeekCommandSubFlowReturnUrl() {
7564
+ try {
7565
+ const stored = sessionStorage.getItem(RETURN_URL_KEY);
7566
+ return stored?.trim().length ? stored : null;
7567
+ }
7568
+ catch {
7569
+ return null;
7570
+ }
7571
+ }
7572
+ function axpEndCommandSubFlowNavigation() {
7573
+ try {
7574
+ sessionStorage.removeItem(SUPPRESS_TAB_RESTORE_KEY);
7575
+ sessionStorage.removeItem(RETURN_URL_KEY);
7576
+ }
7577
+ catch {
7578
+ // sessionStorage may be unavailable
7579
+ }
7580
+ }
7581
+ //#endregion
7582
+
7416
7583
  //#region ---- Tab Route Policy ----
7417
7584
  const EXCLUDED_PATH_PREFIXES = ['/auth', '/error'];
7418
7585
  const EXCLUDED_PATH_PATTERNS = [
@@ -7877,6 +8044,9 @@ class AXPTabNavigationService {
7877
8044
  }
7878
8045
  bindSessionChanges() {
7879
8046
  this.sessionService.user$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => {
8047
+ if (axpIsCommandSubFlowNavigationSuspended()) {
8048
+ return;
8049
+ }
7880
8050
  void this.restoreSessionIfNeeded();
7881
8051
  });
7882
8052
  }
@@ -8156,6 +8326,9 @@ class AXPTabNavigationService {
8156
8326
  if (this.effectiveMode() === 'simple') {
8157
8327
  return;
8158
8328
  }
8329
+ if (axpIsCommandSubFlowNavigationSuspended()) {
8330
+ return;
8331
+ }
8159
8332
  const storageKey = this.sessionStorageKey();
8160
8333
  if (!storageKey) {
8161
8334
  await this.ensureHomeTab();
@@ -8176,7 +8349,10 @@ class AXPTabNavigationService {
8176
8349
  const activeKey = parsed.activeTabKey ?? this.tabs()[this.tabs().length - 1]?.key ?? AXP_HOME_TAB_KEY;
8177
8350
  this.activeTabKey.set(activeKey);
8178
8351
  const activeTab = this.tabs().find((tab) => tab.key === activeKey);
8179
- if (activeTab && normalizeRouterUrl(this.router.url) !== normalizeRouterUrl(activeTab.url)) {
8352
+ const currentUrl = normalizeRouterUrl(this.router.url);
8353
+ if (activeTab &&
8354
+ currentUrl !== normalizeRouterUrl(activeTab.url) &&
8355
+ axpIsTabEligibleUrl(currentUrl)) {
8180
8356
  this.suppressNavigationSync = true;
8181
8357
  try {
8182
8358
  await this.router.navigateByUrl(activeTab.url);
@@ -8340,141 +8516,503 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
8340
8516
  }]
8341
8517
  }], ctorParameters: () => [] });
8342
8518
 
8343
- class AXPDataProvider {
8519
+ //#region ----- Imports -----
8520
+ //#endregion
8521
+ //#region ----- Constants -----
8522
+ const AXP_LOCAL_ENTITY_DEFAULT_MAX_ITEMS = 100;
8523
+ const AXP_LOCAL_ENTITY_BROADCAST_CHANNEL = 'axp-local-entity';
8524
+ const AXP_LOCAL_ENTITY_OUTBOX_LOCK = 'axp-local-entity-outbox';
8525
+ //#endregion
8526
+ //#region ----- Dexie DB -----
8527
+ class AXPLocalEntityIndexedDb extends Dexie {
8528
+ constructor() {
8529
+ super('ACoreXLocalEntity');
8530
+ this.version(1).stores({
8531
+ items: 'storageId, entityKey, userKey, [entityKey+userKey], sortAt',
8532
+ meta: 'id, entityKey, userKey, [entityKey+userKey]',
8533
+ });
8534
+ this.version(2).stores({
8535
+ items: 'storageId, entityKey, userKey, [entityKey+userKey], sortAt',
8536
+ meta: 'id, entityKey, userKey, [entityKey+userKey]',
8537
+ outbox: 'id, entityKey, userKey, [entityKey+userKey], queuedAt',
8538
+ });
8539
+ }
8344
8540
  }
8345
-
8346
- class AXPCustomOperatorService {
8541
+ const axpLocalEntityIndexedDb = new AXPLocalEntityIndexedDb();
8542
+ function buildLocalEntityStorageId(entityKey, userKey, id) {
8543
+ return `${entityKey}|${userKey}|${id}`;
8347
8544
  }
8348
- class AXPCustomOperatorServiceImpl extends AXPCustomOperatorService {
8349
- getCustomOperators() {
8350
- return {};
8351
- }
8352
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPCustomOperatorServiceImpl, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
8353
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPCustomOperatorServiceImpl }); }
8545
+ function buildLocalEntityMetaId(entityKey, userKey) {
8546
+ return `${entityKey}|${userKey}`;
8354
8547
  }
8355
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPCustomOperatorServiceImpl, decorators: [{
8356
- type: Injectable
8357
- }] });
8548
+ //#endregion
8358
8549
 
8359
- class AXPFilterOperatorMiddlewareService {
8360
- }
8361
- class AXPFilterOperatorMiddlewareServiceImpl extends AXPFilterOperatorMiddlewareService {
8362
- constructor() {
8363
- super(...arguments);
8364
- this.customOperatorService = inject(AXPCustomOperatorService);
8365
- this.operators = {
8366
- ...this.getDefaultOperators(),
8367
- ...this.customOperatorService.getCustomOperators(),
8368
- };
8369
- }
8370
- transformFilters(filters) {
8371
- return filters.map((filter) => this.transformFilter(filter));
8550
+ //#region ----- Network failure detection -----
8551
+ /**
8552
+ * True when a failed HTTP/runtime call is likely a connectivity problem
8553
+ * (queue for outbox) rather than a business error (revert local).
8554
+ */
8555
+ function axpIsLikelyNetworkFailure(error) {
8556
+ if (typeof navigator !== 'undefined' && navigator.onLine === false) {
8557
+ return true;
8372
8558
  }
8373
- transformFilter(filter) {
8374
- const { operator, value, filters, field } = filter;
8375
- // Find the operator (either default or custom)
8376
- const filterOperator = this.operators[operator?.type ?? ''] || null;
8377
- // Start by transforming the filter itself
8378
- const transformedFilter = {
8379
- ...filter, // Keep the original filter structure
8380
- operator: filterOperator ? filterOperator : operator, // Add operator name
8381
- };
8382
- // If the filter contains nested filters, recursively transform them
8383
- if (filters && filters.length > 0) {
8384
- transformedFilter.filters = this.transformFilters(filters); // Recursively transform nested filters
8385
- }
8386
- return transformedFilter;
8559
+ if (error instanceof TypeError) {
8560
+ return true;
8387
8561
  }
8388
- getOperator(key) {
8389
- return this.operators[key];
8562
+ const status = readErrorStatus(error);
8563
+ if (status === 0 || status === 502 || status === 503 || status === 504) {
8564
+ return true;
8390
8565
  }
8391
- // Helper function to return the default operators
8392
- getDefaultOperators() {
8393
- return ALL_DEFAULT_OPERATORS.reduce((acc, operator) => {
8394
- acc[operator.name] = {
8395
- type: operator.name,
8396
- };
8397
- return acc;
8398
- }, {});
8566
+ const message = error instanceof Error ? error.message : String(error ?? '');
8567
+ return /failed to fetch|networkerror|err_internet|err_network|offline|timeout|econnrefused|enetunreach/i.test(message);
8568
+ }
8569
+ function readErrorStatus(error) {
8570
+ if (error == null || typeof error !== 'object') {
8571
+ return null;
8399
8572
  }
8400
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPFilterOperatorMiddlewareServiceImpl, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
8401
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPFilterOperatorMiddlewareServiceImpl }); }
8573
+ const row = error;
8574
+ const status = row.status ?? row.statusCode;
8575
+ return typeof status === 'number' && Number.isFinite(status) ? status : null;
8402
8576
  }
8403
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPFilterOperatorMiddlewareServiceImpl, decorators: [{
8404
- type: Injectable
8405
- }] });
8577
+ //#endregion
8406
8578
 
8407
- class AXPErrorHandlerRegistryService {
8408
- constructor(injector) {
8409
- this.injector = injector;
8410
- this.errorHandlers = [];
8411
- }
8412
- register(...plugins) {
8413
- plugins.forEach(t => {
8414
- const childInjector = Injector.create({ providers: [{ provide: t, useClass: t, deps: [] }], parent: this.injector });
8415
- const handler = childInjector.get(t);
8416
- if (handler) {
8417
- this.errorHandlers.push(handler);
8418
- }
8579
+ //#region ----- Imports -----
8580
+ //#endregion
8581
+ //#region ----- Outbox -----
8582
+ /**
8583
+ * Durable mutation queue for {@link AXPLocalEntityEngine} offline-write entities.
8584
+ * Features register a flush handler per entityKey; replay is HTTP, not socket.
8585
+ */
8586
+ class AXPLocalEntityOutboxService {
8587
+ constructor() {
8588
+ this.sessionService = inject(AXPSessionService);
8589
+ this.destroyRef = inject(DestroyRef);
8590
+ this.originId = typeof crypto !== 'undefined' && 'randomUUID' in crypto
8591
+ ? crypto.randomUUID()
8592
+ : `outbox-${Date.now()}-${Math.random().toString(36).slice(2)}`;
8593
+ this.handlers = new Map();
8594
+ this.userKeySignal = signal(null, /* @ts-ignore */
8595
+ ...(ngDevMode ? [{ debugName: "userKeySignal" }] : /* istanbul ignore next */ []));
8596
+ this.pendingOps = signal([], /* @ts-ignore */
8597
+ ...(ngDevMode ? [{ debugName: "pendingOps" }] : /* istanbul ignore next */ []));
8598
+ this.flushInFlight = null;
8599
+ this.broadcast = null;
8600
+ this.pendingCount = computed(() => this.pendingOps().length, /* @ts-ignore */
8601
+ ...(ngDevMode ? [{ debugName: "pendingCount" }] : /* istanbul ignore next */ []));
8602
+ this.bindBroadcastChannel();
8603
+ this.bindSessionContext();
8604
+ this.destroyRef.onDestroy(() => {
8605
+ this.broadcast?.close();
8606
+ this.broadcast = null;
8419
8607
  });
8420
8608
  }
8421
- get handlers() {
8422
- return this.errorHandlers;
8423
- }
8424
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPErrorHandlerRegistryService, deps: [{ token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable }); }
8425
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPErrorHandlerRegistryService, providedIn: 'root' }); }
8426
- }
8427
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPErrorHandlerRegistryService, decorators: [{
8428
- type: Injectable,
8429
- args: [{
8430
- providedIn: 'root'
8431
- }]
8432
- }], ctorParameters: () => [{ type: i0.Injector }] });
8433
-
8434
- //#region ---- Payload readers ----
8435
- function readBodyRecord(body) {
8436
- if (body == null || typeof body !== 'object' || Array.isArray(body)) {
8437
- return null;
8609
+ register(entityKey, handler) {
8610
+ this.handlers.set(entityKey, handler);
8438
8611
  }
8439
- return body;
8440
- }
8441
- function readPayload(body) {
8442
- const record = readBodyRecord(body);
8443
- if (!record) {
8444
- return null;
8612
+ unregister(entityKey) {
8613
+ this.handlers.delete(entityKey);
8445
8614
  }
8446
- const nestedError = readBodyRecord(record['error']);
8447
- if (nestedError && (nestedError['code'] != null || nestedError['message'] != null)) {
8448
- return {
8449
- ...record,
8450
- ...nestedError,
8451
- };
8615
+ pendingFor(entityKey) {
8616
+ return this.pendingOps().filter((op) => op.entityKey === entityKey);
8452
8617
  }
8453
- const nestedMessage = readBodyRecord(record['message']);
8454
- if (nestedMessage && (nestedMessage['code'] != null || nestedMessage['message'] != null)) {
8455
- return {
8456
- ...record,
8457
- ...nestedMessage,
8618
+ async enqueue(input) {
8619
+ const userKey = this.resolveUserKey();
8620
+ const entityKey = input.entityKey?.trim();
8621
+ const action = input.action?.trim();
8622
+ if (!userKey || !entityKey || !action) {
8623
+ return;
8624
+ }
8625
+ const recordIds = [...new Set((input.recordIds ?? []).map((id) => id?.trim()).filter(Boolean))];
8626
+ const existing = await this.loadUserOps(userKey);
8627
+ const duplicate = existing.find((op) => op.entityKey === entityKey &&
8628
+ op.action === action &&
8629
+ sameIdSet(op.recordIds, recordIds) &&
8630
+ stablePayload(op.payload) === stablePayload(input.payload));
8631
+ if (duplicate) {
8632
+ return;
8633
+ }
8634
+ const op = {
8635
+ id: createOutboxId(),
8636
+ entityKey,
8637
+ userKey,
8638
+ action,
8639
+ recordIds,
8640
+ payload: input.payload,
8641
+ queuedAt: new Date().toISOString(),
8642
+ attempts: 0,
8643
+ lastError: null,
8458
8644
  };
8645
+ await axpLocalEntityIndexedDb.outbox.put(op);
8646
+ await this.refreshPending();
8647
+ this.publish();
8459
8648
  }
8460
- return record;
8461
- }
8462
- function readStringParam(value) {
8463
- return typeof value === 'string' && value.trim() ? value : undefined;
8464
- }
8465
- function flattenDetailsParams(details) {
8466
- const record = readBodyRecord(details);
8467
- if (!record) {
8468
- return {};
8469
- }
8470
- const params = {};
8471
- for (const key of ['jobId', 'status', 'scheduleId', 'field', 'name', 'entityName']) {
8472
- const value = readStringParam(record[key]);
8473
- if (value) {
8474
- params[key] = value;
8649
+ async flushAll() {
8650
+ if (this.flushInFlight) {
8651
+ return this.flushInFlight;
8475
8652
  }
8653
+ this.flushInFlight = this.withFlushLock(() => this.flushUnlocked()).finally(() => {
8654
+ this.flushInFlight = null;
8655
+ });
8656
+ return this.flushInFlight;
8476
8657
  }
8477
- return params;
8658
+ async clearCurrentUser() {
8659
+ const userKey = this.resolveUserKey();
8660
+ if (!userKey) {
8661
+ this.pendingOps.set([]);
8662
+ return;
8663
+ }
8664
+ const keys = await axpLocalEntityIndexedDb.outbox.where('userKey').equals(userKey).primaryKeys();
8665
+ if (keys.length > 0) {
8666
+ await axpLocalEntityIndexedDb.outbox.bulkDelete(keys);
8667
+ }
8668
+ this.pendingOps.set([]);
8669
+ this.publish();
8670
+ }
8671
+ //#region ----- Private -----
8672
+ async flushUnlocked() {
8673
+ const userKey = this.resolveUserKey();
8674
+ if (!userKey) {
8675
+ return;
8676
+ }
8677
+ const ops = (await this.loadUserOps(userKey)).sort((left, right) => left.queuedAt.localeCompare(right.queuedAt));
8678
+ for (const op of ops) {
8679
+ const handler = this.handlers.get(op.entityKey);
8680
+ if (!handler) {
8681
+ continue;
8682
+ }
8683
+ try {
8684
+ await handler.flush(op);
8685
+ await axpLocalEntityIndexedDb.outbox.delete(op.id);
8686
+ }
8687
+ catch (error) {
8688
+ if (axpIsLikelyNetworkFailure(error)) {
8689
+ await axpLocalEntityIndexedDb.outbox.put({
8690
+ ...op,
8691
+ attempts: op.attempts + 1,
8692
+ lastError: error instanceof Error ? error.message : String(error ?? 'network'),
8693
+ });
8694
+ break;
8695
+ }
8696
+ await axpLocalEntityIndexedDb.outbox.delete(op.id);
8697
+ await this.refreshPending();
8698
+ try {
8699
+ await handler.revert?.(op);
8700
+ }
8701
+ catch {
8702
+ // The failed op is already dropped so it cannot loop forever.
8703
+ }
8704
+ }
8705
+ }
8706
+ await this.refreshPending();
8707
+ this.publish();
8708
+ }
8709
+ async withFlushLock(run) {
8710
+ const locks = typeof navigator !== 'undefined' ? navigator.locks : undefined;
8711
+ if (!locks?.request) {
8712
+ return run();
8713
+ }
8714
+ await locks.request(AXP_LOCAL_ENTITY_OUTBOX_LOCK, () => run());
8715
+ }
8716
+ resolveUserKey() {
8717
+ const tenantId = this.sessionService.tenant?.id?.trim();
8718
+ const userId = this.sessionService.user?.id?.trim();
8719
+ if (!tenantId || !userId) {
8720
+ return null;
8721
+ }
8722
+ return `${tenantId}:${userId}`;
8723
+ }
8724
+ async loadUserOps(userKey) {
8725
+ return axpLocalEntityIndexedDb.outbox.where('userKey').equals(userKey).toArray();
8726
+ }
8727
+ async refreshPending() {
8728
+ const userKey = this.resolveUserKey();
8729
+ if (!userKey) {
8730
+ this.pendingOps.set([]);
8731
+ return;
8732
+ }
8733
+ const ops = await this.loadUserOps(userKey);
8734
+ ops.sort((left, right) => left.queuedAt.localeCompare(right.queuedAt));
8735
+ this.pendingOps.set(ops);
8736
+ }
8737
+ bindSessionContext() {
8738
+ combineLatest([this.sessionService.user$, this.sessionService.tenant$])
8739
+ .pipe(map(([user, tenant]) => (user?.id && tenant?.id ? `${tenant.id}:${user.id}` : null)), distinctUntilChanged(), takeUntilDestroyed(this.destroyRef))
8740
+ .subscribe((userKey) => {
8741
+ this.userKeySignal.set(userKey);
8742
+ void this.refreshPending();
8743
+ });
8744
+ }
8745
+ bindBroadcastChannel() {
8746
+ if (typeof BroadcastChannel === 'undefined') {
8747
+ return;
8748
+ }
8749
+ this.broadcast = new BroadcastChannel(AXP_LOCAL_ENTITY_BROADCAST_CHANNEL);
8750
+ this.broadcast.onmessage = (event) => {
8751
+ const message = event.data;
8752
+ if (!message || message.type !== 'outbox-changed' || message.originId === this.originId) {
8753
+ return;
8754
+ }
8755
+ if (message.userKey !== this.resolveUserKey()) {
8756
+ return;
8757
+ }
8758
+ void this.refreshPending();
8759
+ };
8760
+ }
8761
+ publish() {
8762
+ const userKey = this.resolveUserKey();
8763
+ if (!userKey) {
8764
+ return;
8765
+ }
8766
+ try {
8767
+ this.broadcast?.postMessage({
8768
+ type: 'outbox-changed',
8769
+ userKey,
8770
+ originId: this.originId,
8771
+ });
8772
+ }
8773
+ catch {
8774
+ // BroadcastChannel can fail in restricted contexts; local tab still works.
8775
+ }
8776
+ }
8777
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPLocalEntityOutboxService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
8778
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPLocalEntityOutboxService, providedIn: 'root' }); }
8779
+ }
8780
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPLocalEntityOutboxService, decorators: [{
8781
+ type: Injectable,
8782
+ args: [{ providedIn: 'root' }]
8783
+ }], ctorParameters: () => [] });
8784
+ //#endregion
8785
+ //#region ----- Helpers -----
8786
+ function createOutboxId() {
8787
+ if (typeof crypto !== 'undefined' && 'randomUUID' in crypto) {
8788
+ return crypto.randomUUID();
8789
+ }
8790
+ return `outbox-${Date.now()}-${Math.random().toString(36).slice(2)}`;
8791
+ }
8792
+ function sameIdSet(left, right) {
8793
+ if (left.length !== right.length) {
8794
+ return false;
8795
+ }
8796
+ const expected = [...left].sort();
8797
+ const actual = [...right].sort();
8798
+ return expected.every((id, index) => id === actual[index]);
8799
+ }
8800
+ function stablePayload(payload) {
8801
+ if (!payload) {
8802
+ return '';
8803
+ }
8804
+ try {
8805
+ return JSON.stringify(payload);
8806
+ }
8807
+ catch {
8808
+ return '';
8809
+ }
8810
+ }
8811
+
8812
+ //#region ----- Imports -----
8813
+ //#endregion
8814
+ //#region ----- Offline runtime -----
8815
+ /**
8816
+ * Flushes the local-entity outbox when the device comes back online.
8817
+ * Features still own HTTP replay handlers; this only drives reconnect.
8818
+ */
8819
+ class AXPLocalEntityOfflineRuntime {
8820
+ constructor() {
8821
+ this.connectivity = inject(AXPNetworkConnectivityService);
8822
+ this.outbox = inject(AXPLocalEntityOutboxService);
8823
+ this.destroyRef = inject(DestroyRef);
8824
+ this.started = false;
8825
+ this.wasOnline = true;
8826
+ }
8827
+ start() {
8828
+ if (this.started) {
8829
+ return;
8830
+ }
8831
+ this.started = true;
8832
+ this.wasOnline = this.connectivity.online;
8833
+ const onOnline = () => this.handleConnectivity(true);
8834
+ const onOffline = () => this.handleConnectivity(false);
8835
+ if (typeof window !== 'undefined') {
8836
+ window.addEventListener('online', onOnline);
8837
+ window.addEventListener('offline', onOffline);
8838
+ this.destroyRef.onDestroy(() => {
8839
+ window.removeEventListener('online', onOnline);
8840
+ window.removeEventListener('offline', onOffline);
8841
+ });
8842
+ }
8843
+ if (this.connectivity.online && this.outbox.pendingCount() > 0) {
8844
+ void this.outbox.flushAll();
8845
+ }
8846
+ }
8847
+ handleConnectivity(online) {
8848
+ if (online && !this.wasOnline) {
8849
+ void this.outbox.flushAll();
8850
+ }
8851
+ this.wasOnline = online;
8852
+ }
8853
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPLocalEntityOfflineRuntime, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
8854
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPLocalEntityOfflineRuntime, providedIn: 'root' }); }
8855
+ }
8856
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPLocalEntityOfflineRuntime, decorators: [{
8857
+ type: Injectable,
8858
+ args: [{ providedIn: 'root' }]
8859
+ }] });
8860
+
8861
+ //#region ----- Imports -----
8862
+ //#endregion
8863
+ //#region ----- Providers -----
8864
+ /** Registers outbox flush-on-reconnect after realtime handlers exist. */
8865
+ function provideLocalEntityOfflineRuntime() {
8866
+ return [
8867
+ provideAppStartUpTask(() => {
8868
+ const runtime = inject(AXPLocalEntityOfflineRuntime);
8869
+ return {
8870
+ name: 'local-entity-offline-runtime',
8871
+ priority: AXP_APP_STARTUP_PRIORITY.realtimeSubscriptions,
8872
+ run: async () => {
8873
+ runtime.start();
8874
+ },
8875
+ };
8876
+ }),
8877
+ ];
8878
+ }
8879
+ //#endregion
8880
+
8881
+ class AXPDataProvider {
8882
+ }
8883
+
8884
+ class AXPCustomOperatorService {
8885
+ }
8886
+ class AXPCustomOperatorServiceImpl extends AXPCustomOperatorService {
8887
+ getCustomOperators() {
8888
+ return {};
8889
+ }
8890
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPCustomOperatorServiceImpl, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
8891
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPCustomOperatorServiceImpl }); }
8892
+ }
8893
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPCustomOperatorServiceImpl, decorators: [{
8894
+ type: Injectable
8895
+ }] });
8896
+
8897
+ class AXPFilterOperatorMiddlewareService {
8898
+ }
8899
+ class AXPFilterOperatorMiddlewareServiceImpl extends AXPFilterOperatorMiddlewareService {
8900
+ constructor() {
8901
+ super(...arguments);
8902
+ this.customOperatorService = inject(AXPCustomOperatorService);
8903
+ this.operators = {
8904
+ ...this.getDefaultOperators(),
8905
+ ...this.customOperatorService.getCustomOperators(),
8906
+ };
8907
+ }
8908
+ transformFilters(filters) {
8909
+ return filters.map((filter) => this.transformFilter(filter));
8910
+ }
8911
+ transformFilter(filter) {
8912
+ const { operator, value, filters, field } = filter;
8913
+ // Find the operator (either default or custom)
8914
+ const filterOperator = this.operators[operator?.type ?? ''] || null;
8915
+ // Start by transforming the filter itself
8916
+ const transformedFilter = {
8917
+ ...filter, // Keep the original filter structure
8918
+ operator: filterOperator ? filterOperator : operator, // Add operator name
8919
+ };
8920
+ // If the filter contains nested filters, recursively transform them
8921
+ if (filters && filters.length > 0) {
8922
+ transformedFilter.filters = this.transformFilters(filters); // Recursively transform nested filters
8923
+ }
8924
+ return transformedFilter;
8925
+ }
8926
+ getOperator(key) {
8927
+ return this.operators[key];
8928
+ }
8929
+ // Helper function to return the default operators
8930
+ getDefaultOperators() {
8931
+ return ALL_DEFAULT_OPERATORS.reduce((acc, operator) => {
8932
+ acc[operator.name] = {
8933
+ type: operator.name,
8934
+ };
8935
+ return acc;
8936
+ }, {});
8937
+ }
8938
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPFilterOperatorMiddlewareServiceImpl, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
8939
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPFilterOperatorMiddlewareServiceImpl }); }
8940
+ }
8941
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPFilterOperatorMiddlewareServiceImpl, decorators: [{
8942
+ type: Injectable
8943
+ }] });
8944
+
8945
+ class AXPErrorHandlerRegistryService {
8946
+ constructor(injector) {
8947
+ this.injector = injector;
8948
+ this.errorHandlers = [];
8949
+ }
8950
+ register(...plugins) {
8951
+ plugins.forEach(t => {
8952
+ const childInjector = Injector.create({ providers: [{ provide: t, useClass: t, deps: [] }], parent: this.injector });
8953
+ const handler = childInjector.get(t);
8954
+ if (handler) {
8955
+ this.errorHandlers.push(handler);
8956
+ }
8957
+ });
8958
+ }
8959
+ get handlers() {
8960
+ return this.errorHandlers;
8961
+ }
8962
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPErrorHandlerRegistryService, deps: [{ token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable }); }
8963
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPErrorHandlerRegistryService, providedIn: 'root' }); }
8964
+ }
8965
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPErrorHandlerRegistryService, decorators: [{
8966
+ type: Injectable,
8967
+ args: [{
8968
+ providedIn: 'root'
8969
+ }]
8970
+ }], ctorParameters: () => [{ type: i0.Injector }] });
8971
+
8972
+ //#region ---- Payload readers ----
8973
+ function readBodyRecord(body) {
8974
+ if (body == null || typeof body !== 'object' || Array.isArray(body)) {
8975
+ return null;
8976
+ }
8977
+ return body;
8978
+ }
8979
+ function readPayload(body) {
8980
+ const record = readBodyRecord(body);
8981
+ if (!record) {
8982
+ return null;
8983
+ }
8984
+ const nestedError = readBodyRecord(record['error']);
8985
+ if (nestedError && (nestedError['code'] != null || nestedError['message'] != null)) {
8986
+ return {
8987
+ ...record,
8988
+ ...nestedError,
8989
+ };
8990
+ }
8991
+ const nestedMessage = readBodyRecord(record['message']);
8992
+ if (nestedMessage && (nestedMessage['code'] != null || nestedMessage['message'] != null)) {
8993
+ return {
8994
+ ...record,
8995
+ ...nestedMessage,
8996
+ };
8997
+ }
8998
+ return record;
8999
+ }
9000
+ function readStringParam(value) {
9001
+ return typeof value === 'string' && value.trim() ? value : undefined;
9002
+ }
9003
+ function flattenDetailsParams(details) {
9004
+ const record = readBodyRecord(details);
9005
+ if (!record) {
9006
+ return {};
9007
+ }
9008
+ const params = {};
9009
+ for (const key of ['jobId', 'status', 'scheduleId', 'field', 'name', 'entityName']) {
9010
+ const value = readStringParam(record[key]);
9011
+ if (value) {
9012
+ params[key] = value;
9013
+ }
9014
+ }
9015
+ return params;
8478
9016
  }
8479
9017
  function isPayloadTooLargeHint(status, code, errorName, message) {
8480
9018
  if (status === 413 || code === AXP_PLATFORM_ERROR_CODES.PAYLOAD_TOO_LARGE) {
@@ -10518,19 +11056,20 @@ class AXPCommonModule {
10518
11056
  /**
10519
11057
  * @ignore
10520
11058
  */
10521
- constructor(instances, _keyboardShortcutsHelp, formatterRegistry) {
11059
+ constructor(instances, _keyboardShortcutsHelp, _browserTitle, formatterRegistry) {
10522
11060
  formatterRegistry.register(AXPTranslateFormatter);
10523
11061
  instances.forEach((f) => {
10524
11062
  f();
10525
11063
  });
10526
11064
  }
10527
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPCommonModule, deps: [{ token: 'AXPCommonModuleFactory' }, { token: AXPKeyboardShortcutsHelpService }, { token: i2$1.AXFormatterRegistryService }], target: i0.ɵɵFactoryTarget.NgModule }); }
10528
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.0.8", ngImport: i0, type: AXPCommonModule, imports: [i3$2.AXPComponentSlotModule, AXPopupModule,
11065
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPCommonModule, deps: [{ token: 'AXPCommonModuleFactory' }, { token: AXPKeyboardShortcutsHelpService }, { token: AXPBrowserTitleService }, { token: i3$1.AXFormatterRegistryService }], target: i0.ɵɵFactoryTarget.NgModule }); }
11066
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.0.8", ngImport: i0, type: AXPCommonModule, imports: [i4$2.AXPComponentSlotModule, AXPopupModule,
10529
11067
  AXDateTimeModule,
10530
11068
  AXToastModule,
10531
11069
  AXNotificationModule,
10532
- AXPModuleManifestModule, i4$2.RouterModule], exports: [RouterModule] }); }
11070
+ AXPModuleManifestModule, i5.RouterModule], exports: [RouterModule] }); }
10533
11071
  static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPCommonModule, providers: [
11072
+ ...provideLocalEntityOfflineRuntime(),
10534
11073
  provideAXPUserNotificationService(),
10535
11074
  {
10536
11075
  provide: ErrorHandler,
@@ -10596,7 +11135,7 @@ class AXPCommonModule {
10596
11135
  provide: AXP_SETTING_DEFINITION_PROVIDER,
10597
11136
  useFactory: async () => {
10598
11137
  const injector = inject(Injector);
10599
- const provider = (await import('./acorex-platform-framework-client-common-common-settings.provider-CzBr0cRi.mjs')).AXPCommonSettingProvider;
11138
+ const provider = (await import('./acorex-platform-framework-client-common-common-settings.provider-ChU2tvyt.mjs')).AXPCommonSettingProvider;
10600
11139
  return new provider(injector);
10601
11140
  },
10602
11141
  multi: true,
@@ -10606,6 +11145,16 @@ class AXPCommonModule {
10606
11145
  key: 'navigate',
10607
11146
  command: () => Promise.resolve().then(function () { return navigate_command; }).then((c) => c.AXPNavigateCommand),
10608
11147
  },
11148
+ {
11149
+ key: 'Page:RunAction',
11150
+ command: () => Promise.resolve().then(function () { return pageRunAction_command; }).then((c) => c.AXPPageRunActionCommand),
11151
+ },
11152
+ ]),
11153
+ provideQuerySetups([
11154
+ {
11155
+ key: 'Page:GetContext',
11156
+ loader: () => Promise.resolve().then(function () { return pageGetContext_query; }).then((c) => c.AXPPageGetContextQuery),
11157
+ },
10609
11158
  ]),
10610
11159
  ], imports: [AXPComponentSlotModule.forChild({
10611
11160
  'root-footer-end': [
@@ -10643,6 +11192,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
10643
11192
  ],
10644
11193
  exports: [RouterModule],
10645
11194
  providers: [
11195
+ ...provideLocalEntityOfflineRuntime(),
10646
11196
  provideAXPUserNotificationService(),
10647
11197
  {
10648
11198
  provide: ErrorHandler,
@@ -10708,7 +11258,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
10708
11258
  provide: AXP_SETTING_DEFINITION_PROVIDER,
10709
11259
  useFactory: async () => {
10710
11260
  const injector = inject(Injector);
10711
- const provider = (await import('./acorex-platform-framework-client-common-common-settings.provider-CzBr0cRi.mjs')).AXPCommonSettingProvider;
11261
+ const provider = (await import('./acorex-platform-framework-client-common-common-settings.provider-ChU2tvyt.mjs')).AXPCommonSettingProvider;
10712
11262
  return new provider(injector);
10713
11263
  },
10714
11264
  multi: true,
@@ -10718,13 +11268,23 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
10718
11268
  key: 'navigate',
10719
11269
  command: () => Promise.resolve().then(function () { return navigate_command; }).then((c) => c.AXPNavigateCommand),
10720
11270
  },
11271
+ {
11272
+ key: 'Page:RunAction',
11273
+ command: () => Promise.resolve().then(function () { return pageRunAction_command; }).then((c) => c.AXPPageRunActionCommand),
11274
+ },
11275
+ ]),
11276
+ provideQuerySetups([
11277
+ {
11278
+ key: 'Page:GetContext',
11279
+ loader: () => Promise.resolve().then(function () { return pageGetContext_query; }).then((c) => c.AXPPageGetContextQuery),
11280
+ },
10721
11281
  ]),
10722
11282
  ],
10723
11283
  }]
10724
11284
  }], ctorParameters: () => [{ type: undefined, decorators: [{
10725
11285
  type: Inject,
10726
11286
  args: ['AXPCommonModuleFactory']
10727
- }] }, { type: AXPKeyboardShortcutsHelpService }, { type: i2$1.AXFormatterRegistryService }] });
11287
+ }] }, { type: AXPKeyboardShortcutsHelpService }, { type: AXPBrowserTitleService }, { type: i3$1.AXFormatterRegistryService }] });
10728
11288
 
10729
11289
  /**
10730
11290
  * Resolves post-create list behavior from user settings and optional action overrides.
@@ -11399,30 +11959,8 @@ const AXP_INTEGRATION_CONNECTION_LIFECYCLE = new InjectionToken('AXP_INTEGRATION
11399
11959
  //#endregion
11400
11960
 
11401
11961
  //#region ----- Types -----
11402
- //#endregion
11403
-
11404
- //#region ----- Imports -----
11405
- //#endregion
11406
- //#region ----- Constants -----
11407
- const AXP_LOCAL_ENTITY_DEFAULT_MAX_ITEMS = 100;
11408
- const AXP_LOCAL_ENTITY_BROADCAST_CHANNEL = 'axp-local-entity';
11409
- //#endregion
11410
- //#region ----- Dexie DB -----
11411
- class AXPLocalEntityIndexedDb extends Dexie {
11412
- constructor() {
11413
- super('ACoreXLocalEntity');
11414
- this.version(1).stores({
11415
- items: 'storageId, entityKey, userKey, [entityKey+userKey], sortAt',
11416
- meta: 'id, entityKey, userKey, [entityKey+userKey]',
11417
- });
11418
- }
11419
- }
11420
- const axpLocalEntityIndexedDb = new AXPLocalEntityIndexedDb();
11421
- function buildLocalEntityStorageId(entityKey, userKey, id) {
11422
- return `${entityKey}|${userKey}|${id}`;
11423
- }
11424
- function buildLocalEntityMetaId(entityKey, userKey) {
11425
- return `${entityKey}|${userKey}`;
11962
+ function axpLocalEntitySupportsOfflineWrite(mode) {
11963
+ return mode === 'offline-write';
11426
11964
  }
11427
11965
  //#endregion
11428
11966
 
@@ -11878,12 +12416,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
11878
12416
  }], ctorParameters: () => [] });
11879
12417
  //#endregion
11880
12418
  //#region ----- Policy normalize -----
12419
+ function normalizeMode(mode) {
12420
+ if (mode === 'cache' || mode === 'offline-read' || mode === 'offline-write' || mode === 'local-first') {
12421
+ return mode;
12422
+ }
12423
+ return 'local-first';
12424
+ }
11881
12425
  function normalizePolicy(policy) {
11882
12426
  const maxItems = typeof policy?.maxItems === 'number' && policy.maxItems > 0
11883
12427
  ? Math.floor(policy.maxItems)
11884
12428
  : AXP_LOCAL_ENTITY_DEFAULT_MAX_ITEMS;
11885
12429
  return {
11886
- mode: policy?.mode === 'cache' ? 'cache' : 'local-first',
12430
+ mode: normalizeMode(policy?.mode),
11887
12431
  maxItems,
11888
12432
  role: policy?.role,
11889
12433
  sortField: typeof policy?.sortField === 'string' && policy.sortField.trim() ? policy.sortField.trim() : undefined,
@@ -12195,7 +12739,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
12195
12739
 
12196
12740
  //#endregion
12197
12741
  //#region ---- Constants ----
12198
- const SESSION_KEY_PREFIX = 'axp-entity-list-return:';
12742
+ const SESSION_KEY_PREFIX$1 = 'axp-entity-list-return:';
12199
12743
  //#endregion
12200
12744
  //#region ---- Route Parsing ----
12201
12745
  /** Parses an entity master list route (`.../m/{module}/e/{entity}/list`). */
@@ -12225,8 +12769,8 @@ function axpParseEntityDetailsRoute(url) {
12225
12769
  }
12226
12770
  //#endregion
12227
12771
  //#region ---- Session Storage ----
12228
- function buildStorageKey(module, entity) {
12229
- return `${SESSION_KEY_PREFIX}${module}.${entity}`;
12772
+ function buildStorageKey$1(module, entity) {
12773
+ return `${SESSION_KEY_PREFIX$1}${module}.${entity}`;
12230
12774
  }
12231
12775
  /** Persists the last list URL (including query params) used before opening entity details. */
12232
12776
  function axpSaveEntityListReturnUrl(module, entity, url) {
@@ -12238,7 +12782,7 @@ function axpSaveEntityListReturnUrl(module, entity, url) {
12238
12782
  return;
12239
12783
  }
12240
12784
  try {
12241
- sessionStorage.setItem(buildStorageKey(module, entity), normalizeRouterUrl(url));
12785
+ sessionStorage.setItem(buildStorageKey$1(module, entity), normalizeRouterUrl(url));
12242
12786
  }
12243
12787
  catch {
12244
12788
  // sessionStorage may be unavailable
@@ -12247,7 +12791,7 @@ function axpSaveEntityListReturnUrl(module, entity, url) {
12247
12791
  /** Returns the stored list URL for the entity, or the provided fallback path. */
12248
12792
  function axpGetEntityListReturnUrl(module, entity, fallbackPath) {
12249
12793
  try {
12250
- const stored = sessionStorage.getItem(buildStorageKey(module, entity));
12794
+ const stored = sessionStorage.getItem(buildStorageKey$1(module, entity));
12251
12795
  if (!stored || !axpIsEntityListPath(stored)) {
12252
12796
  return fallbackPath;
12253
12797
  }
@@ -12263,6 +12807,233 @@ function axpGetEntityListReturnUrl(module, entity, fallbackPath) {
12263
12807
  }
12264
12808
  //#endregion
12265
12809
 
12810
+ //#endregion
12811
+ //#region ----- Constants -----
12812
+ const SESSION_KEY_PREFIX = 'axp-entity-details-nav-trail:';
12813
+ const HOME_BREADCRUMB_TITLE = '@general:terms.interface.navigation.home';
12814
+ const MAX_ORIGIN_CRUMBS = 12;
12815
+ const AXP_BREADCRUMB_COLLAPSE_HEAD_COUNT = 1;
12816
+ const AXP_BREADCRUMB_COLLAPSE_TAIL_COUNT = 3;
12817
+ //#endregion
12818
+ //#region ----- Path Helpers -----
12819
+ function axpGetBreadcrumbNavigatePath(item) {
12820
+ if (item.command?.name !== 'navigate') {
12821
+ return null;
12822
+ }
12823
+ const path = item.command.options?.['path'];
12824
+ return typeof path === 'string' && path.trim() ? path : null;
12825
+ }
12826
+ function pathWithoutQuery(url) {
12827
+ return url.split('?')[0].split('#')[0];
12828
+ }
12829
+ function isSameDetailsPath(left, right) {
12830
+ const a = axpParseEntityDetailsRoute(left);
12831
+ const b = axpParseEntityDetailsRoute(right);
12832
+ return !!a && !!b && a.module === b.module && a.entity === b.entity && a.id === b.id;
12833
+ }
12834
+ function isSameListPath(left, right) {
12835
+ const a = axpParseEntityListRoute(left);
12836
+ const b = axpParseEntityListRoute(right);
12837
+ return !!a && !!b && a.module === b.module && a.entity === b.entity;
12838
+ }
12839
+ //#endregion
12840
+ //#region ----- Clone / Strip -----
12841
+ function axpCloneBreadcrumbItems(items) {
12842
+ try {
12843
+ return JSON.parse(JSON.stringify(items));
12844
+ }
12845
+ catch {
12846
+ return [];
12847
+ }
12848
+ }
12849
+ function axpStripHomeBreadcrumb(items) {
12850
+ if (!items.length) {
12851
+ return items;
12852
+ }
12853
+ const title = items[0]?.title;
12854
+ if (title === HOME_BREADCRUMB_TITLE) {
12855
+ return items.slice(1);
12856
+ }
12857
+ return items;
12858
+ }
12859
+ function axpStripTrailingCommandlessCrumbs(items) {
12860
+ const result = [...items];
12861
+ while (result.length && !axpGetBreadcrumbNavigatePath(result[result.length - 1])) {
12862
+ result.pop();
12863
+ }
12864
+ return result;
12865
+ }
12866
+ function capOriginCrumbs(items) {
12867
+ if (items.length <= MAX_ORIGIN_CRUMBS) {
12868
+ return items;
12869
+ }
12870
+ return items.slice(-MAX_ORIGIN_CRUMBS);
12871
+ }
12872
+ function isValidTrailItems(value) {
12873
+ if (!Array.isArray(value)) {
12874
+ return false;
12875
+ }
12876
+ return value.every((item) => item != null && typeof item === 'object' && 'title' in item);
12877
+ }
12878
+ //#endregion
12879
+ //#region ----- Compose -----
12880
+ function axpTrimNavTrailBeforeTarget(origin, listPath, viewPath) {
12881
+ let trail = [...origin];
12882
+ if (viewPath) {
12883
+ const viewIdx = trail.findIndex((item) => {
12884
+ const path = axpGetBreadcrumbNavigatePath(item);
12885
+ return !!path && isSameDetailsPath(path, viewPath);
12886
+ });
12887
+ if (viewIdx >= 0) {
12888
+ trail = trail.slice(0, viewIdx);
12889
+ }
12890
+ }
12891
+ if (listPath && trail.length) {
12892
+ const lastPath = axpGetBreadcrumbNavigatePath(trail[trail.length - 1]);
12893
+ if (lastPath && isSameListPath(lastPath, listPath)) {
12894
+ trail = trail.slice(0, -1);
12895
+ }
12896
+ }
12897
+ return trail;
12898
+ }
12899
+ function axpComposeEntityDetailsNavTrail(origin, listCrumb, recordCrumb) {
12900
+ const listPath = axpGetBreadcrumbNavigatePath(listCrumb);
12901
+ const viewPath = axpGetBreadcrumbNavigatePath(recordCrumb);
12902
+ const trimmed = axpTrimNavTrailBeforeTarget(axpStripTrailingCommandlessCrumbs(axpStripHomeBreadcrumb(origin)), listPath, viewPath);
12903
+ return [...trimmed, listCrumb, recordCrumb];
12904
+ }
12905
+ function axpPrepareOriginNavTrail(items) {
12906
+ return capOriginCrumbs(axpStripTrailingCommandlessCrumbs(axpStripHomeBreadcrumb(axpCloneBreadcrumbItems(items))));
12907
+ }
12908
+ //#endregion
12909
+ //#region ----- Session Storage -----
12910
+ function buildStorageKey(module, entity, id) {
12911
+ return `${SESSION_KEY_PREFIX}${module}.${entity}/${id}`;
12912
+ }
12913
+ function axpSaveEntityDetailsNavTrail(module, entity, id, items) {
12914
+ if (!module || !entity || !id) {
12915
+ return;
12916
+ }
12917
+ try {
12918
+ const origin = axpPrepareOriginNavTrail(items);
12919
+ sessionStorage.setItem(buildStorageKey(module, entity, id), JSON.stringify(origin));
12920
+ }
12921
+ catch {
12922
+ // sessionStorage may be unavailable
12923
+ }
12924
+ }
12925
+ function axpGetEntityDetailsNavTrail(module, entity, id) {
12926
+ if (!module || !entity || !id) {
12927
+ return [];
12928
+ }
12929
+ try {
12930
+ const raw = sessionStorage.getItem(buildStorageKey(module, entity, id));
12931
+ if (!raw) {
12932
+ return [];
12933
+ }
12934
+ const parsed = JSON.parse(raw);
12935
+ if (!isValidTrailItems(parsed)) {
12936
+ return [];
12937
+ }
12938
+ return axpCloneBreadcrumbItems(parsed);
12939
+ }
12940
+ catch {
12941
+ return [];
12942
+ }
12943
+ }
12944
+ function axpClearEntityDetailsNavTrail(module, entity, id) {
12945
+ if (!module || !entity || !id) {
12946
+ return;
12947
+ }
12948
+ try {
12949
+ sessionStorage.removeItem(buildStorageKey(module, entity, id));
12950
+ }
12951
+ catch {
12952
+ // sessionStorage may be unavailable
12953
+ }
12954
+ }
12955
+ //#endregion
12956
+ //#region ----- Display Collapse -----
12957
+ function axpSplitCollapsedBreadcrumbs(items) {
12958
+ const headCount = AXP_BREADCRUMB_COLLAPSE_HEAD_COUNT;
12959
+ const tailCount = AXP_BREADCRUMB_COLLAPSE_TAIL_COUNT;
12960
+ if (items.length <= headCount + tailCount) {
12961
+ return {
12962
+ collapsed: false,
12963
+ head: items,
12964
+ middle: [],
12965
+ tail: [],
12966
+ };
12967
+ }
12968
+ return {
12969
+ collapsed: true,
12970
+ head: items.slice(0, headCount),
12971
+ middle: items.slice(headCount, items.length - tailCount),
12972
+ tail: items.slice(-tailCount),
12973
+ };
12974
+ }
12975
+ function axpIsSameEntityDetailsRecord(leftUrl, rightUrl) {
12976
+ return isSameDetailsPath(pathWithoutQuery(leftUrl), pathWithoutQuery(rightUrl));
12977
+ }
12978
+ //#endregion
12979
+
12980
+ //#region ----- Entity Details Navigation Trail -----
12981
+ /**
12982
+ * Publishes the active page breadcrumb trail and captures it when navigating
12983
+ * from one entity details record to another (related-entity wayfinding).
12984
+ */
12985
+ class AXPEntityDetailsNavTrailService {
12986
+ //#endregion
12987
+ //#region ----- Lifecycle -----
12988
+ constructor() {
12989
+ //#region ----- Services & Dependencies -----
12990
+ this.router = inject(Router);
12991
+ this.destroyRef = inject(DestroyRef);
12992
+ //#endregion
12993
+ //#region ----- State -----
12994
+ this.activeTrail = [];
12995
+ this.router.events
12996
+ .pipe(filter$1((event) => event instanceof NavigationStart), takeUntilDestroyed(this.destroyRef))
12997
+ .subscribe((event) => this.captureOnNavigation(event.url));
12998
+ }
12999
+ //#endregion
13000
+ //#region ----- Active Trail -----
13001
+ /** Stores the current page crumbs (Home excluded) for the next details-to-details hop. */
13002
+ setActiveTrail(items) {
13003
+ this.activeTrail = axpCloneBreadcrumbItems(items);
13004
+ }
13005
+ getOriginTrail(module, entity, id) {
13006
+ return axpGetEntityDetailsNavTrail(module, entity, id);
13007
+ }
13008
+ //#endregion
13009
+ //#region ----- Capture -----
13010
+ captureOnNavigation(targetUrl) {
13011
+ const fromUrl = this.router.url;
13012
+ if (!axpIsEntityDetailsPath(targetUrl)) {
13013
+ return;
13014
+ }
13015
+ const to = axpParseEntityDetailsRoute(targetUrl);
13016
+ if (!to) {
13017
+ return;
13018
+ }
13019
+ const fromDetails = axpIsEntityDetailsPath(fromUrl);
13020
+ if (fromDetails && axpIsSameEntityDetailsRecord(fromUrl, targetUrl)) {
13021
+ return;
13022
+ }
13023
+ if (fromDetails) {
13024
+ axpSaveEntityDetailsNavTrail(to.module, to.entity, to.id, this.activeTrail);
13025
+ return;
13026
+ }
13027
+ axpClearEntityDetailsNavTrail(to.module, to.entity, to.id);
13028
+ }
13029
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPEntityDetailsNavTrailService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
13030
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPEntityDetailsNavTrailService, providedIn: 'root' }); }
13031
+ }
13032
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPEntityDetailsNavTrailService, decorators: [{
13033
+ type: Injectable,
13034
+ args: [{ providedIn: 'root' }]
13035
+ }], ctorParameters: () => [] });
13036
+
12266
13037
  class AXPClipBoardService {
12267
13038
  constructor() {
12268
13039
  //#region ---- Services & Dependencies ----
@@ -12674,7 +13445,7 @@ class AXMOrgChartPrintPage extends AXBasePageComponent {
12674
13445
  <ax-icon class="fa-solid fa-print"> </ax-icon>
12675
13446
  </ax-button>
12676
13447
  </ax-suffix>
12677
- </ax-footer>`, isInline: true, dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: AXCheckBoxModule }, { kind: "ngmodule", type: AXNumberBoxModule }, { kind: "component", type: i2$3.AXNumberBoxComponent, selector: "ax-number-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "value", "state", "name", "id", "look", "minValue", "maxValue", "showSpinButtons", "thousandsSeparator", "decimals", "changeOnScroll", "step"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress", "thousandsSeparatorChange"] }, { kind: "ngmodule", type: AXTextBoxModule }, { kind: "ngmodule", type: AXLabelModule }, { kind: "component", type: i3$3.AXLabelComponent, selector: "ax-label", inputs: ["required", "for"], outputs: ["requiredChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i2.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXColorBoxModule }, { kind: "component", type: i6$1.AXColorBoxComponent, selector: "ax-color-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "value", "state", "name", "id", "look", "showBadge", "showValue", "showClearButton", "showIcon"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onOpened", "onClosed"] }], changeDetection: i0.ChangeDetectionStrategy.Eager }); }
13448
+ </ax-footer>`, isInline: true, dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: AXCheckBoxModule }, { kind: "ngmodule", type: AXNumberBoxModule }, { kind: "component", type: i2$2.AXNumberBoxComponent, selector: "ax-number-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "value", "state", "name", "id", "look", "minValue", "maxValue", "showSpinButtons", "thousandsSeparator", "decimals", "changeOnScroll", "step"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress", "thousandsSeparatorChange"] }, { kind: "ngmodule", type: AXTextBoxModule }, { kind: "ngmodule", type: AXLabelModule }, { kind: "component", type: i3$3.AXLabelComponent, selector: "ax-label", inputs: ["required", "for"], outputs: ["requiredChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i2.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXColorBoxModule }, { kind: "component", type: i6$1.AXColorBoxComponent, selector: "ax-color-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "value", "state", "name", "id", "look", "showBadge", "showValue", "showClearButton", "showIcon"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onOpened", "onClosed"] }], changeDetection: i0.ChangeDetectionStrategy.Eager }); }
12678
13449
  }
12679
13450
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMOrgChartPrintPage, decorators: [{
12680
13451
  type: Component,
@@ -12983,9 +13754,217 @@ const axpNavigateCommandDefinition = defineCommand({
12983
13754
  categories: [AXP_COMMAND_DEFINITION_CATEGORY_PLATFORM],
12984
13755
  });
12985
13756
 
13757
+ //#region ----- Imports -----
13758
+ //#endregion
13759
+ //#region ----- Helpers -----
13760
+ function coerceArgs(raw) {
13761
+ if (!raw) {
13762
+ return {};
13763
+ }
13764
+ if (typeof raw === 'string') {
13765
+ try {
13766
+ const parsed = JSON.parse(raw);
13767
+ if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
13768
+ return parsed;
13769
+ }
13770
+ }
13771
+ catch {
13772
+ return {};
13773
+ }
13774
+ return {};
13775
+ }
13776
+ if (typeof raw === 'object' && !Array.isArray(raw)) {
13777
+ return raw;
13778
+ }
13779
+ return {};
13780
+ }
13781
+ function resolveArgs(input) {
13782
+ const fromArgs = coerceArgs(input.args);
13783
+ const rest = {};
13784
+ for (const [key, value] of Object.entries(input)) {
13785
+ if (key === 'actionId' || key === 'args') {
13786
+ continue;
13787
+ }
13788
+ if (value !== undefined) {
13789
+ rest[key] = value;
13790
+ }
13791
+ }
13792
+ return { ...rest, ...fromArgs };
13793
+ }
13794
+ function readActionId(input) {
13795
+ if (typeof input.actionId === 'string' && input.actionId.trim()) {
13796
+ return input.actionId.trim();
13797
+ }
13798
+ const nested = resolveArgs(input)['actionId'];
13799
+ return typeof nested === 'string' ? nested.trim() : '';
13800
+ }
13801
+ //#endregion
13802
+ //#region ----- Command -----
13803
+ class AXPPageRunActionCommand {
13804
+ constructor() {
13805
+ //#region ----- Services & Dependencies -----
13806
+ this.pageContext = inject(AXPPageContextRegistry);
13807
+ }
13808
+ //#endregion
13809
+ //#region ----- Command Execution -----
13810
+ async execute(input = {}) {
13811
+ const actionId = readActionId(input);
13812
+ if (!actionId) {
13813
+ const snapshot = this.pageContext.getSnapshot();
13814
+ return runtimeCommandFailure('actionId is required for Page:RunAction.', { details: { snapshot } });
13815
+ }
13816
+ const result = await this.pageContext.runAction(actionId, resolveArgs(input));
13817
+ if (!result.success) {
13818
+ return runtimeCommandFailure(result.message ?? 'Page action failed.', {
13819
+ details: { snapshot: result.snapshot },
13820
+ });
13821
+ }
13822
+ return runtimeCommandSuccessObject({ snapshot: result.snapshot });
13823
+ }
13824
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPPageRunActionCommand, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
13825
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPPageRunActionCommand, providedIn: 'root' }); }
13826
+ }
13827
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPPageRunActionCommand, decorators: [{
13828
+ type: Injectable,
13829
+ args: [{ providedIn: 'root' }]
13830
+ }] });
13831
+
13832
+ var pageRunAction_command = /*#__PURE__*/Object.freeze({
13833
+ __proto__: null,
13834
+ AXPPageRunActionCommand: AXPPageRunActionCommand
13835
+ });
13836
+
13837
+ /**
13838
+ * Build-time only. Do not import from Angular modules.
13839
+ * Source: page-run-action.command.ts — AXPPageRunActionCommand.execute
13840
+ */
13841
+ const axpPageRunActionCommandDefinition = defineCommand({
13842
+ key: 'Page:RunAction',
13843
+ title: 'Run page action',
13844
+ description: 'Runs an advertised action on the currently visible page (set-view, set-filter, remove-filter, clear-filters, set-search, apply-layout). ' +
13845
+ 'Call Page:GetContext first and only use actionId values from snapshot.actions. Returns the new snapshot immediately; status may be loading. ' +
13846
+ 'Do not use Entity:Query:Default or Entity:OpenList to change the open list chrome.',
13847
+ executionMode: 'frontend',
13848
+ inputs: [
13849
+ {
13850
+ name: 'actionId',
13851
+ title: 'Action id',
13852
+ description: 'Must match an id from Page:GetContext snapshot.actions (e.g. set-view, set-filter, apply-layout).',
13853
+ interface: { name: 'text-editor' },
13854
+ validations: [{ rule: 'required' }],
13855
+ },
13856
+ {
13857
+ name: 'args',
13858
+ title: 'Action args',
13859
+ description: 'Object of params advertised on that action (viewName, field, operatorType, value, text, json).',
13860
+ interface: { name: 'json' },
13861
+ },
13862
+ ],
13863
+ outcomes: {
13864
+ mode: 'static',
13865
+ values: ['success', 'failure'],
13866
+ },
13867
+ ai: {
13868
+ shortDescription: 'Drive the visible page (list chrome or layout designer) and return the updated snapshot.',
13869
+ tags: ['page', 'ui', 'filter', 'list', 'frontend'],
13870
+ usage: {
13871
+ whenToUse: [
13872
+ 'User asked to change the current list tab, visible filter, search box, or the open layout designer canvas.',
13873
+ ],
13874
+ avoidWhen: [
13875
+ 'Changing stored rows — use Entity:Update:Default / Entity:Edit / Entity:Delete:Default.',
13876
+ 'Querying storage instead of the on-screen list — use Entity:Query:Default.',
13877
+ 'Opening a different entity list — use Entity:OpenList.',
13878
+ ],
13879
+ followUpTools: ['Page:GetContext'],
13880
+ },
13881
+ },
13882
+ capabilities: ['ai'],
13883
+ categories: [AXP_COMMAND_DEFINITION_CATEGORY_PLATFORM],
13884
+ });
13885
+
13886
+ //#region ----- Imports -----
13887
+ //#endregion
13888
+ //#region ----- Query -----
13889
+ class AXPPageGetContextQuery {
13890
+ constructor() {
13891
+ //#region ----- Services & Dependencies -----
13892
+ this.pageContext = inject(AXPPageContextRegistry);
13893
+ }
13894
+ //#endregion
13895
+ //#region ----- Query Execution -----
13896
+ async fetch(_input) {
13897
+ const snapshot = this.pageContext.getSnapshot();
13898
+ return runtimeQuerySuccessObject(snapshot);
13899
+ }
13900
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPPageGetContextQuery, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
13901
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPPageGetContextQuery, providedIn: 'root' }); }
13902
+ }
13903
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPPageGetContextQuery, decorators: [{
13904
+ type: Injectable,
13905
+ args: [{ providedIn: 'root' }]
13906
+ }] });
13907
+
13908
+ var pageGetContext_query = /*#__PURE__*/Object.freeze({
13909
+ __proto__: null,
13910
+ AXPPageGetContextQuery: AXPPageGetContextQuery
13911
+ });
13912
+
13913
+ /**
13914
+ * Build-time only. Do not import from Angular modules.
13915
+ * Source: page-get-context.query.ts — AXPPageGetContextQuery.fetch
13916
+ */
13917
+ const axpPageGetContextQueryDefinition = defineQuery({
13918
+ key: 'Page:GetContext',
13919
+ title: 'Get page context',
13920
+ description: 'Returns a live snapshot of the currently visible page plus advertised actions (entity list chrome, or layout-designer apply-layout). ' +
13921
+ 'Use when the user means this screen. Do not use Entity:Query:Default to change what is on screen. ' +
13922
+ 'When kind is none or actions is empty, the user is not on a driveable page — use list-entity-records / Entity:Query:Default for stored rows.',
13923
+ executionMode: 'frontend',
13924
+ kind: 'object',
13925
+ args: [],
13926
+ columns: [
13927
+ {
13928
+ name: 'kind',
13929
+ title: 'Kind',
13930
+ description: '`entity-list` when a master list is focused; `layout-designer` when the form/layout designer is focused; `none` otherwise.',
13931
+ interface: { name: 'text-editor' },
13932
+ },
13933
+ {
13934
+ name: 'status',
13935
+ title: 'Status',
13936
+ description: '`ready`, `loading` (grid still fetching), or `empty`.',
13937
+ interface: { name: 'text-editor' },
13938
+ },
13939
+ {
13940
+ name: 'actions',
13941
+ title: 'Actions',
13942
+ description: 'Advertised action ids for Page:RunAction. Only call ids from this array.',
13943
+ interface: { name: 'large-text-editor' },
13944
+ },
13945
+ ],
13946
+ ai: {
13947
+ shortDescription: 'Live snapshot of the visible page plus advertised actions (list chrome or layout designer).',
13948
+ tags: ['page', 'ui', 'filter', 'list', 'frontend'],
13949
+ usage: {
13950
+ whenToUse: [
13951
+ 'User refers to this list, this tab, visible filters, the search box, or the open layout designer canvas.',
13952
+ ],
13953
+ avoidWhen: [
13954
+ 'Listing or counting stored rows in storage — use Entity:Query:Default / list-entity-records.',
13955
+ 'Where-is / how-to navigation — use PlatformManagement:ListPlatformNavigationForAi.',
13956
+ 'Create / update / delete records — use Entity:* commands.',
13957
+ ],
13958
+ followUpTools: ['Page:RunAction'],
13959
+ },
13960
+ },
13961
+ capabilities: ['ai'],
13962
+ categories: [AXP_QUERY_DEFINITION_CATEGORY_PLATFORM],
13963
+ });
13964
+
12986
13965
  /**
12987
13966
  * Generated bundle index. Do not edit.
12988
13967
  */
12989
13968
 
12990
- export { ALL_DEFAULT_OPERATORS, AXPAcorexFileTypeBridgeProvider, AXPAcorexFileTypeModule, AXPAppVersionService, AXPBackgroundOperationCompletionService, AXPBackgroundOperationEntityStoreService, AXPBackgroundOperationHandler, AXPBackgroundOperationNotificationService, AXPBackgroundOperationProvider, AXPBackgroundOperationRootConfig, AXPBackgroundOperationService, AXPBackgroundOperationSlotComponent, AXPBrowserTitleService, AXPCleanNestedFilters, AXPClipBoardService, AXPCommonModule, AXPCommonSettings, AXPCustomOperatorService, AXPCustomOperatorServiceImpl, AXPDataProvider, AXPDefaultMultiLanguageConfigService, 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, AXPLocalEntityRealtimeBridge, AXPLockService, AXPLogoImageSrcResolverService, AXPMenuKeyboardShortcutService, AXPMenuMiddlewareRegistry, AXPMenuProviderService, AXPMenuRouteAccessService, AXPMenuRouteGuard, AXPMenuSearchDefinitionProvider, AXPMenuSearchProvider, AXPMenuService, AXPMenuVisibilityService, AXPNavBarSlotComponent, AXPNavigateCommand, AXPNetworkConnectivityService, AXPNotFoundCatchAllRoute, AXPNotFoundError, AXPOutputContractTranscriptSegmentService, 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_DOCUMENT_FILE_TYPE_PURPOSES, AXP_ENTITY_LIST_DISPLAY_MODE_DEFAULT, 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_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, 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, axpBuildBackgroundOperation, axpBuildTabKey, axpCoerceBackgroundOperationDate, axpCreateBackgroundOperationId, axpFallbackTabTitle, axpFindMenuItemByRoute, axpFormatBackgroundOperationDurationMs, axpGetEntityListReturnUrl, axpGetLeafRouteSnapshot, axpHasTabScope, axpInterpolateNavigatePath, axpIsActiveBackgroundOperationStatus, axpIsBackgroundOperationI18nText, axpIsCompletedBackgroundOperationStatus, axpIsCompletedPanelBackgroundOperation, axpIsEntityDetailsPath, axpIsEntityDetailsViewRoute, axpIsEntityListPath, axpIsEntityListRoute, axpIsEntityRecordNotFound, axpIsInProgressPanelBackgroundOperation, axpIsTabEligibleUrl, axpIsTrayVisibleBackgroundOperation, axpJoinTabTitleSegments, axpLocalEntityCanServeListLocally, axpLocalEntityHotListRequest, axpLocalEntityIndexedDb, axpLocalEntityRecordId, axpLocalEntitySortAt, axpLocalEntityToPayload, axpMenuPathsMatch, axpNavigateAppPath, axpNavigateCommandDefinition, axpParseAppPath, axpParseEntityDetailsRoute, axpParseEntityListRoute, axpPathFromSnapshot, axpPlatformSettingsAvailableGuard, axpRedirectToNotFound, axpRedirectToUnauthorized, axpReplaceEntityListRouteQueryParams, axpResolveNavigatePath, axpResolveTabKey, axpResolveTabKeyFromRouteConfig, axpResolveTabKeyFromSnapshot, axpResolveTabTitleParts, axpSaveEntityListReturnUrl, axpSettingsIndexedDb, 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, isSettingKeyCacheable, isSettingVisibleOnScope, isStoredImageFileId, normalizeAvailableLanguageCodes, normalizeDocumentFileTypePurposes, normalizeDocumentToFileListItem, normalizeOverridableAt, normalizePositiveNumberOption, normalizeRouterUrl, normalizeStoredImageRef, peelSettingValueKey, platformErrorI18nKey, primaryLanguageSubtag, printGraphicFromElement, projectSettingsValuesForIndexedDb, provideAXPUserNotificationService, provideDynamicHomePage, provideMenuMiddleware, purgeLegacyTenantScopedSettingsSnapshots, resolveDateFilterPresets, resolveEffectiveAvailableLanguageCodes, resolveEntityCreateListBehavior, 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 };
13969
+ 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_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, 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, 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, isSettingKeyCacheable, isSettingVisibleOnScope, isStoredImageFileId, normalizeAvailableLanguageCodes, normalizeDocumentFileTypePurposes, normalizeDocumentToFileListItem, normalizeOverridableAt, normalizePositiveNumberOption, normalizeRouterUrl, normalizeStoredImageRef, peelSettingValueKey, platformErrorI18nKey, primaryLanguageSubtag, printGraphicFromElement, projectSettingsValuesForIndexedDb, provideAXPUserNotificationService, provideDynamicHomePage, provideLocalEntityOfflineRuntime, provideMenuMiddleware, purgeLegacyTenantScopedSettingsSnapshots, resolveDateFilterPresets, resolveEffectiveAvailableLanguageCodes, resolveEntityCreateListBehavior, 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 };
12991
13970
  //# sourceMappingURL=acorex-platform-framework-client-common.mjs.map