@acorex/platform 20.6.0-next.8 → 21.0.0-next.0

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 (88) hide show
  1. package/auth/index.d.ts +91 -12
  2. package/common/index.d.ts +615 -44
  3. package/core/index.d.ts +718 -422
  4. package/fesm2022/acorex-platform-auth.mjs +152 -39
  5. package/fesm2022/acorex-platform-auth.mjs.map +1 -1
  6. package/fesm2022/acorex-platform-common.mjs +1009 -112
  7. package/fesm2022/acorex-platform-common.mjs.map +1 -1
  8. package/fesm2022/acorex-platform-core.mjs +887 -408
  9. package/fesm2022/acorex-platform-core.mjs.map +1 -1
  10. package/fesm2022/acorex-platform-domain.mjs +99 -11
  11. package/fesm2022/acorex-platform-domain.mjs.map +1 -1
  12. package/fesm2022/acorex-platform-layout-builder.mjs +555 -492
  13. package/fesm2022/acorex-platform-layout-builder.mjs.map +1 -1
  14. package/fesm2022/acorex-platform-layout-components.mjs +2446 -2733
  15. package/fesm2022/acorex-platform-layout-components.mjs.map +1 -1
  16. package/fesm2022/acorex-platform-layout-designer.mjs +9 -9
  17. package/fesm2022/acorex-platform-layout-designer.mjs.map +1 -1
  18. package/fesm2022/acorex-platform-layout-entity.mjs +9708 -4721
  19. package/fesm2022/acorex-platform-layout-entity.mjs.map +1 -1
  20. package/fesm2022/acorex-platform-layout-views.mjs +32 -26
  21. package/fesm2022/acorex-platform-layout-views.mjs.map +1 -1
  22. package/fesm2022/acorex-platform-layout-widget-core.mjs +252 -182
  23. package/fesm2022/acorex-platform-layout-widget-core.mjs.map +1 -1
  24. package/fesm2022/{acorex-platform-layout-widgets-file-list-popup.component-D0y-9nE5.mjs → acorex-platform-layout-widgets-file-list-popup.component-CxrsI6Hn.mjs} +2 -2
  25. package/fesm2022/acorex-platform-layout-widgets-file-list-popup.component-CxrsI6Hn.mjs.map +1 -0
  26. package/fesm2022/acorex-platform-layout-widgets-image-preview.popup-V31OpYah.mjs +30 -0
  27. package/fesm2022/acorex-platform-layout-widgets-image-preview.popup-V31OpYah.mjs.map +1 -0
  28. package/fesm2022/{acorex-platform-layout-widgets-tabular-data-edit-popup.component-C1l2KSDa.mjs → acorex-platform-layout-widgets-tabular-data-edit-popup.component-Ck7-wpT2.mjs} +2 -2
  29. package/fesm2022/acorex-platform-layout-widgets-tabular-data-edit-popup.component-Ck7-wpT2.mjs.map +1 -0
  30. package/fesm2022/{acorex-platform-layout-widgets-tabular-data-view-popup.component-D-31ej0C.mjs → acorex-platform-layout-widgets-tabular-data-view-popup.component-y8vjUiVs.mjs} +2 -2
  31. package/fesm2022/acorex-platform-layout-widgets-tabular-data-view-popup.component-y8vjUiVs.mjs.map +1 -0
  32. package/fesm2022/acorex-platform-layout-widgets.mjs +9789 -6817
  33. package/fesm2022/acorex-platform-layout-widgets.mjs.map +1 -1
  34. package/fesm2022/acorex-platform-runtime.mjs +79 -3
  35. package/fesm2022/acorex-platform-runtime.mjs.map +1 -1
  36. package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-VIGuU5M4.mjs +157 -0
  37. package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-VIGuU5M4.mjs.map +1 -0
  38. package/fesm2022/acorex-platform-themes-default-entity-master-list-view.component-DyDa_hyd.mjs +1542 -0
  39. package/fesm2022/acorex-platform-themes-default-entity-master-list-view.component-DyDa_hyd.mjs.map +1 -0
  40. package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-Ua3ZA5hk.mjs +101 -0
  41. package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-Ua3ZA5hk.mjs.map +1 -0
  42. package/fesm2022/{acorex-platform-themes-default-entity-master-single-view.component-B_P0a5KW.mjs → acorex-platform-themes-default-entity-master-single-view.component-eMBby9k4.mjs} +3 -3
  43. package/fesm2022/acorex-platform-themes-default-entity-master-single-view.component-eMBby9k4.mjs.map +1 -0
  44. package/fesm2022/acorex-platform-themes-default.mjs +282 -43
  45. package/fesm2022/acorex-platform-themes-default.mjs.map +1 -1
  46. package/fesm2022/acorex-platform-themes-shared-icon-chooser-column.component-C0EpfU2k.mjs +55 -0
  47. package/fesm2022/acorex-platform-themes-shared-icon-chooser-column.component-C0EpfU2k.mjs.map +1 -0
  48. package/fesm2022/acorex-platform-themes-shared.mjs +42 -137
  49. package/fesm2022/acorex-platform-themes-shared.mjs.map +1 -1
  50. package/fesm2022/acorex-platform-workflow.mjs +658 -45
  51. package/fesm2022/acorex-platform-workflow.mjs.map +1 -1
  52. package/layout/builder/index.d.ts +10 -34
  53. package/layout/components/index.d.ts +694 -375
  54. package/layout/designer/index.d.ts +4 -4
  55. package/layout/entity/index.d.ts +802 -183
  56. package/layout/views/index.d.ts +5 -58
  57. package/layout/widget-core/index.d.ts +63 -75
  58. package/layout/widgets/README.md +0 -1
  59. package/layout/widgets/index.d.ts +498 -129
  60. package/package.json +5 -5
  61. package/runtime/index.d.ts +36 -8
  62. package/themes/default/index.d.ts +44 -75
  63. package/themes/shared/index.d.ts +11 -49
  64. package/workflow/index.d.ts +401 -90
  65. package/fesm2022/acorex-platform-layout-entity-create-entity.command-DGeylNSY.mjs +0 -52
  66. package/fesm2022/acorex-platform-layout-entity-create-entity.command-DGeylNSY.mjs.map +0 -1
  67. package/fesm2022/acorex-platform-layout-widgets-extra-properties-schema-widget-edit.component-fhhZOWul.mjs +0 -50
  68. package/fesm2022/acorex-platform-layout-widgets-extra-properties-schema-widget-edit.component-fhhZOWul.mjs.map +0 -1
  69. package/fesm2022/acorex-platform-layout-widgets-extra-properties-schema-widget-view.component-C3Qbs0fz.mjs +0 -42
  70. package/fesm2022/acorex-platform-layout-widgets-extra-properties-schema-widget-view.component-C3Qbs0fz.mjs.map +0 -1
  71. package/fesm2022/acorex-platform-layout-widgets-extra-properties-values-widget-edit.component-CngQBUlN.mjs +0 -55
  72. package/fesm2022/acorex-platform-layout-widgets-extra-properties-values-widget-edit.component-CngQBUlN.mjs.map +0 -1
  73. package/fesm2022/acorex-platform-layout-widgets-extra-properties-values-widget-view.component-DSNo9e4W.mjs +0 -50
  74. package/fesm2022/acorex-platform-layout-widgets-extra-properties-values-widget-view.component-DSNo9e4W.mjs.map +0 -1
  75. package/fesm2022/acorex-platform-layout-widgets-extra-properties-widget-edit.component-CL0CwEHX.mjs +0 -48
  76. package/fesm2022/acorex-platform-layout-widgets-extra-properties-widget-edit.component-CL0CwEHX.mjs.map +0 -1
  77. package/fesm2022/acorex-platform-layout-widgets-extra-properties-widget-view.component-B6Fi0xTw.mjs +0 -42
  78. package/fesm2022/acorex-platform-layout-widgets-extra-properties-widget-view.component-B6Fi0xTw.mjs.map +0 -1
  79. package/fesm2022/acorex-platform-layout-widgets-file-list-popup.component-D0y-9nE5.mjs.map +0 -1
  80. package/fesm2022/acorex-platform-layout-widgets-tabular-data-edit-popup.component-C1l2KSDa.mjs.map +0 -1
  81. package/fesm2022/acorex-platform-layout-widgets-tabular-data-view-popup.component-D-31ej0C.mjs.map +0 -1
  82. package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-WbPPqDON.mjs +0 -115
  83. package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-WbPPqDON.mjs.map +0 -1
  84. package/fesm2022/acorex-platform-themes-default-entity-master-list-view.component-CD7rJIMh.mjs +0 -803
  85. package/fesm2022/acorex-platform-themes-default-entity-master-list-view.component-CD7rJIMh.mjs.map +0 -1
  86. package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-BTA6h7Xd.mjs +0 -101
  87. package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-BTA6h7Xd.mjs.map +0 -1
  88. package/fesm2022/acorex-platform-themes-default-entity-master-single-view.component-B_P0a5KW.mjs.map +0 -1
@@ -4,8 +4,8 @@ import { kebabCase, merge, sortBy, cloneDeep, get, omit } from 'lodash-es';
4
4
  import { Router, ROUTES, RouterModule } from '@angular/router';
5
5
  import { AXPSessionService, AXPSessionStatus } from '@acorex/platform/auth';
6
6
  import { Subject, distinctUntilChanged, merge as merge$1 } from 'rxjs';
7
- import * as i1$1 from '@acorex/platform/core';
8
- import { AXPPlatformScope, AXPBroadcastEventService, objectKeyValueTransforms, AXPComponentLogoConfig, AXPImageUrlLogoConfig, AXPSystemActionType, AXPAppStartUpProvider, AXP_EXPRESSION_EVALUATOR_SCOPE_PROVIDER } from '@acorex/platform/core';
7
+ import * as i1 from '@acorex/platform/core';
8
+ import { AXPModuleProviderRegistry, AXPPlatformScope, AXPBroadcastEventService, objectKeyValueTransforms, AXPSystemActionType, AXP_MODULE_PROVIDER_INITIALIZER, AXPAppStartUpProvider, AXP_EXPRESSION_EVALUATOR_SCOPE_PROVIDER, AXPModuleManifestRegistry } from '@acorex/platform/core';
9
9
  import { AXTranslationService } from '@acorex/core/translation';
10
10
  import { AXPWidgetsCatalog } from '@acorex/platform/layout/widget-core';
11
11
  import { AXPopupModule, AXPopupService } from '@acorex/components/popup';
@@ -13,14 +13,7 @@ import { AXToastService, AXToastModule } from '@acorex/components/toast';
13
13
  import { AXDateTimeModule } from '@acorex/core/date-time';
14
14
  import * as i3 from '@acorex/platform/workflow';
15
15
  import { AXPWorkflowService, createWorkFlowEvent, AXPWorkflowAction, AXPWorkflowError, AXPWorkflowModule } from '@acorex/platform/workflow';
16
- import * as i4 from '@acorex/components/decorators';
17
- import { AXDecoratorModule } from '@acorex/components/decorators';
18
- import * as i2 from '@acorex/components/image';
19
- import { AXImageModule } from '@acorex/components/image';
20
- import { AXPlatform } from '@acorex/core/platform';
21
- import * as i1 from '@angular/common';
22
- import { CommonModule } from '@angular/common';
23
- import { AXPCommandExecutor } from '@acorex/platform/runtime';
16
+ import { AXPCommandExecutor, AXPCommandService } from '@acorex/platform/runtime';
24
17
  import { signalStore, withState, withMethods, patchState, withHooks } from '@ngrx/signals';
25
18
  import { AXFormatService } from '@acorex/core/format';
26
19
  import { AXDialogService } from '@acorex/components/dialog';
@@ -29,13 +22,15 @@ import { AXButtonModule } from '@acorex/components/button';
29
22
  import { AXCheckBoxModule } from '@acorex/components/check-box';
30
23
  import * as i6 from '@acorex/components/color-box';
31
24
  import { AXColorBoxModule } from '@acorex/components/color-box';
25
+ import * as i4 from '@acorex/components/decorators';
26
+ import { AXDecoratorModule } from '@acorex/components/decorators';
32
27
  import * as i3$1 from '@acorex/components/label';
33
28
  import { AXLabelModule } from '@acorex/components/label';
34
- import * as i2$1 from '@acorex/components/number-box';
29
+ import * as i2 from '@acorex/components/number-box';
35
30
  import { AXNumberBoxModule } from '@acorex/components/number-box';
36
31
  import { AXBasePageComponent } from '@acorex/components/page';
37
32
  import { AXTextBoxModule } from '@acorex/components/text-box';
38
- import * as i1$2 from '@angular/forms';
33
+ import * as i1$1 from '@angular/forms';
39
34
  import { FormsModule } from '@angular/forms';
40
35
 
41
36
  const AXP_APP_VERSION_PROVIDER = new InjectionToken('AXP_APP_VERSION_PROVIDER', {
@@ -133,24 +128,24 @@ function createAllQueryView(params = {
133
128
  });
134
129
  }
135
130
 
136
- const EQ_OPER = { name: 'equal', title: 'Equal', hasValue: true };
137
- const NOT_EQ_OPER = { name: 'notEqual', title: 'Not Equal', hasValue: true };
138
- const GT_OPER = { name: 'greaterThan', title: 'Greater Than', hasValue: true };
139
- const LT_OPER = { name: 'lessThan', title: 'Less Than', hasValue: true };
131
+ const EQ_OPER = { name: 'equal', title: '@general:terms.operators.equal', hasValue: true };
132
+ const NOT_EQ_OPER = { name: 'notEqual', title: '@general:terms.operators.not-equal', hasValue: true };
133
+ const GT_OPER = { name: 'greaterThan', title: '@general:terms.operators.greater-than', hasValue: true };
134
+ const LT_OPER = { name: 'lessThan', title: '@general:terms.operators.less-than', hasValue: true };
140
135
  const GTE_OPER = {
141
136
  name: 'greaterThanOrEqual',
142
- title: 'Greater Than or Equal',
137
+ title: '@general:terms.operators.greater-than-or-equal',
143
138
  hasValue: true,
144
139
  };
145
- const LTE_OPER = { name: 'lessThanOrEqual', title: 'Less Than or Equal', hasValue: true };
146
- const CONTAINS_OPER = { name: 'contains', title: 'Contains', hasValue: true };
147
- const NOT_CONTAINS_OPER = { name: 'notContains', title: 'Does Not Contain', hasValue: true };
148
- const IN_OPER = { name: 'in', title: 'In', hasValue: true };
149
- const STARTS_WITH_OPER = { name: 'startsWith', title: 'Starts With', hasValue: true };
150
- const ENDS_WITH_OPER = { name: 'endsWith', title: 'Ends With', hasValue: true };
151
- const IS_EMPTY_OPER = { name: 'isEmpty', title: 'Is Empty', hasValue: false };
152
- const IS_NOT_EMPTY_OPER = { name: 'isNotEmpty', title: 'Is Not Empty', hasValue: false };
153
- const BETWEEN_OPER = { name: 'between', title: 'Between', hasValue: true };
140
+ const LTE_OPER = { name: 'lessThanOrEqual', title: '@general:terms.operators.less-than-or-equal', hasValue: true };
141
+ const CONTAINS_OPER = { name: 'contains', title: '@general:terms.operators.contains', hasValue: true };
142
+ const NOT_CONTAINS_OPER = { name: 'notContains', title: '@general:terms.operators.not-contains', hasValue: true };
143
+ const IN_OPER = { name: 'in', title: '@general:terms.operators.in', hasValue: true };
144
+ const STARTS_WITH_OPER = { name: 'startsWith', title: '@general:terms.operators.starts-with', hasValue: true };
145
+ const ENDS_WITH_OPER = { name: 'endsWith', title: '@general:terms.operators.ends-with', hasValue: true };
146
+ const IS_EMPTY_OPER = { name: 'isEmpty', title: '@general:terms.operators.is-empty', hasValue: false };
147
+ const IS_NOT_EMPTY_OPER = { name: 'isNotEmpty', title: '@general:terms.operators.is-not-empty', hasValue: false };
148
+ const BETWEEN_OPER = { name: 'between', title: '@general:terms.operators.between', hasValue: true };
154
149
  const STRING_OPERATORS = [
155
150
  EQ_OPER,
156
151
  NOT_EQ_OPER,
@@ -327,6 +322,7 @@ const AXP_SETTING_DEFINITION_PROVIDER = new InjectionToken('AXP_SETTING_DEFINITI
327
322
  class AXPSettingDefinitionProviderService {
328
323
  constructor() {
329
324
  this.providers = inject(AXP_SETTING_DEFINITION_PROVIDER, { optional: true });
325
+ this.providerRegistry = inject(AXPModuleProviderRegistry);
330
326
  this.cache = null;
331
327
  }
332
328
  async load() {
@@ -334,6 +330,7 @@ class AXPSettingDefinitionProviderService {
334
330
  return;
335
331
  }
336
332
  const context = new AXPSettingDefinitionProviderContext();
333
+ // Load providers from DI tokens (backward compatibility)
337
334
  if (Array.isArray(this.providers)) {
338
335
  for (const provider of this.providers) {
339
336
  if (provider instanceof Promise) {
@@ -347,6 +344,11 @@ class AXPSettingDefinitionProviderService {
347
344
  }
348
345
  }
349
346
  }
347
+ // Load providers from registry (manifest-based, conditionally loaded)
348
+ const registryProviders = this.providerRegistry.getSettingProviders();
349
+ for (const provider of registryProviders) {
350
+ await provider.provide(context);
351
+ }
350
352
  this.cache = context.getGroups();
351
353
  }
352
354
  async reload() {
@@ -556,7 +558,7 @@ class AXPSettingValueProviderDefault {
556
558
  }
557
559
  }
558
560
 
559
- class AXPSettingService {
561
+ class AXPSettingsService {
560
562
  constructor() {
561
563
  this.providers = inject(AXP_SETTING_VALUE_PROVIDER);
562
564
  this.injector = inject(Injector);
@@ -676,10 +678,10 @@ class AXPSettingService {
676
678
  this.onChanged.next(event);
677
679
  this.eventService.publish('AXPSettingChangedEvent', event);
678
680
  }
679
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPSettingService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
680
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPSettingService, providedIn: 'root' }); }
681
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPSettingsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
682
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPSettingsService, providedIn: 'root' }); }
681
683
  }
682
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPSettingService, decorators: [{
684
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPSettingsService, decorators: [{
683
685
  type: Injectable,
684
686
  args: [{
685
687
  providedIn: 'root',
@@ -735,9 +737,38 @@ class ScopedSettingService {
735
737
  }
736
738
  }
737
739
 
740
+ /**
741
+ * Regional settings keys for date, time, and locale formatting.
742
+ * These keys are used by platform widgets and components to access regional settings.
743
+ * The actual setting definitions and providers are implemented in the locale-management module.
744
+ */
745
+ var AXPRegionalSetting;
746
+ (function (AXPRegionalSetting) {
747
+ AXPRegionalSetting["LocaleProfile"] = "LocaleManagement:Setting:Regional.LocaleProfile";
748
+ AXPRegionalSetting["TimeZone"] = "LocaleManagement:Setting:Regional.TimeZone";
749
+ AXPRegionalSetting["Language"] = "LocaleManagement:Setting:Regional.Language";
750
+ AXPRegionalSetting["Country"] = "LocaleManagement:Setting:Regional.Country";
751
+ AXPRegionalSetting["Calendar"] = "LocaleManagement:Setting:Regional.Calendar";
752
+ AXPRegionalSetting["FirstDayOfWeek"] = "LocaleManagement:Setting:Regional.FirstDayOfWeek";
753
+ AXPRegionalSetting["WeekendDays"] = "LocaleManagement:Setting:Regional.WeekendDays";
754
+ AXPRegionalSetting["ShortDate"] = "LocaleManagement:Setting:Regional.ShortDate";
755
+ AXPRegionalSetting["MediumDate"] = "LocaleManagement:Setting:Regional.MediumDate";
756
+ AXPRegionalSetting["LongDate"] = "LocaleManagement:Setting:Regional.LongDate";
757
+ AXPRegionalSetting["ShortTime"] = "LocaleManagement:Setting:Regional.ShortTime";
758
+ AXPRegionalSetting["MediumTime"] = "LocaleManagement:Setting:Regional.MediumTime";
759
+ AXPRegionalSetting["LongTime"] = "LocaleManagement:Setting:Regional.LongTime";
760
+ AXPRegionalSetting["MeasurementUnits"] = "LocaleManagement:Setting:Regional.MeasurementUnits";
761
+ AXPRegionalSetting["TemperatureUnits"] = "LocaleManagement:Setting:Regional.TemperatureUnits";
762
+ AXPRegionalSetting["DistanceUnits"] = "LocaleManagement:Setting:Regional.DistanceUnits";
763
+ AXPRegionalSetting["WeightUnits"] = "LocaleManagement:Setting:Regional.WeightUnits";
764
+ AXPRegionalSetting["VolumeUnits"] = "LocaleManagement:Setting:Regional.VolumeUnits";
765
+ AXPRegionalSetting["SpeedUnits"] = "LocaleManagement:Setting:Regional.SpeedUnits";
766
+ AXPRegionalSetting["AreaUnits"] = "LocaleManagement:Setting:Regional.AreaUnits";
767
+ })(AXPRegionalSetting || (AXPRegionalSetting = {}));
768
+
738
769
  var AXPHomePageSettings;
739
770
  (function (AXPHomePageSettings) {
740
- AXPHomePageSettings["UserHomePath"] = "general:startup:home-page";
771
+ AXPHomePageSettings["UserHomePath"] = "Common:Setting:Startup.HomePage";
741
772
  })(AXPHomePageSettings || (AXPHomePageSettings = {}));
742
773
 
743
774
  class AXPHomePageService {
@@ -748,7 +779,7 @@ class AXPHomePageService {
748
779
  this.defaultHomePageKey = inject(AXP_HOME_PAGE_DEFAULT_KEY, { optional: true }) ?? 'home';
749
780
  this.userHomePageKey = null;
750
781
  this.candidates = inject(AXP_HOME_PAGES, { optional: true }) ?? [];
751
- this.settingsService = inject(AXPSettingService);
782
+ this.settingsService = inject(AXPSettingsService);
752
783
  this.sessionService = inject(AXPSessionService);
753
784
  this.injector = inject(Injector);
754
785
  this.originalConfig = null;
@@ -1081,43 +1112,61 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
1081
1112
  args: [{ providedIn: 'root' }]
1082
1113
  }], ctorParameters: () => [{ type: i0.Injector }, { type: AXPErrorHandlerRegistryService }] });
1083
1114
 
1084
- const AXP_GLOBAL_VARIABLE_DEFINITION_PROVIDER = new InjectionToken('AXP_GLOBAL_VARIABLE_DEFINITION_PROVIDER', {
1115
+ const AXP_TOKEN_DEFINITION_PROVIDER = new InjectionToken('AXP_TOKEN_DEFINITION_PROVIDER', {
1085
1116
  factory: () => [],
1086
1117
  });
1087
1118
 
1088
1119
  //#region ---- Imports ----
1089
1120
  //#endregion
1090
- class AXPGlobalVariableDefinitionService {
1121
+ class AXPTokenDefinitionService {
1091
1122
  constructor() {
1092
1123
  //#region ---- Providers & Caches ----
1093
- this.definitionProviders = inject(AXP_GLOBAL_VARIABLE_DEFINITION_PROVIDER, { optional: true }) || [];
1124
+ this.definitionProviders = inject(AXP_TOKEN_DEFINITION_PROVIDER, { optional: true }) || [];
1094
1125
  /** Cache for definitions by name. */
1095
1126
  this.definitionsByName = new Map();
1096
1127
  }
1097
1128
  //#endregion
1098
1129
  //#region ---- Public API ----
1099
1130
  /**
1100
- * Returns a report definition by its id.
1131
+ * Returns a token definition by its name.
1101
1132
  * First checks the cache, then queries all providers if not found.
1102
- * @param name The global variable name.
1103
- * @returns The global variable definition if found, undefined otherwise.
1133
+ * @param name The token name.
1134
+ * @returns The token definition if found, undefined otherwise.
1104
1135
  */
1105
- async getByName(name) {
1136
+ async getDefinition(name) {
1106
1137
  // Check cache first
1107
1138
  if (this.definitionsByName.has(name)) {
1108
1139
  return this.definitionsByName.get(name);
1109
1140
  }
1110
- // Not in cache, query providers (each provider is itself a global variable definition)
1141
+ // Not in cache, query providers
1142
+ // Resolve all providers (some may be promises, some may be arrays)
1111
1143
  const resolvedProviders = await Promise.all(this.definitionProviders);
1112
- const match = resolvedProviders.find(def => def?.name === name);
1144
+ // Flatten the array - some providers may be arrays of providers (e.g., dynamic token providers)
1145
+ const flattenedProviders = [];
1146
+ for (const provider of resolvedProviders) {
1147
+ if (Array.isArray(provider)) {
1148
+ // If provider is an array, add all items
1149
+ flattenedProviders.push(...provider);
1150
+ }
1151
+ else if (provider) {
1152
+ // If provider is a single provider, add it
1153
+ flattenedProviders.push(provider);
1154
+ }
1155
+ }
1156
+ const match = flattenedProviders.find(def => def?.name === name);
1113
1157
  if (match) {
1114
1158
  this.definitionsByName.set(name, match);
1115
1159
  return match;
1116
1160
  }
1117
1161
  return undefined;
1118
1162
  }
1119
- async execute(name) {
1120
- const definition = await this.getByName(name);
1163
+ /**
1164
+ * Gets the resolved value of a token by its name.
1165
+ * @param name The token name.
1166
+ * @returns The resolved token value, or undefined if the token is not found.
1167
+ */
1168
+ async getValue(name) {
1169
+ const definition = await this.getDefinition(name);
1121
1170
  if (definition) {
1122
1171
  return await definition.execute();
1123
1172
  }
@@ -1129,24 +1178,24 @@ class AXPGlobalVariableDefinitionService {
1129
1178
  clearDefinitionsCache() {
1130
1179
  this.definitionsByName.clear();
1131
1180
  }
1132
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPGlobalVariableDefinitionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1133
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPGlobalVariableDefinitionService, providedIn: 'root' }); }
1181
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPTokenDefinitionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1182
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPTokenDefinitionService, providedIn: 'root' }); }
1134
1183
  }
1135
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPGlobalVariableDefinitionService, decorators: [{
1184
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPTokenDefinitionService, decorators: [{
1136
1185
  type: Injectable,
1137
1186
  args: [{
1138
1187
  providedIn: 'root',
1139
1188
  }]
1140
1189
  }] });
1141
1190
 
1142
- class AXPGlobalVariableEvaluatorScopeProvider {
1191
+ class AXPTokenEvaluatorScopeProvider {
1143
1192
  constructor() {
1144
- this.globalVariableService = inject(AXPGlobalVariableDefinitionService);
1193
+ this.tokenService = inject(AXPTokenDefinitionService);
1145
1194
  }
1146
1195
  async provide(context) {
1147
- context.addScope('variables', {
1148
- execute: async (name) => {
1149
- return await this.globalVariableService.execute(name);
1196
+ context.addScope('tokens', {
1197
+ get: async (name) => {
1198
+ return await this.tokenService.getValue(name);
1150
1199
  }
1151
1200
  });
1152
1201
  }
@@ -1256,46 +1305,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
1256
1305
  type: Input
1257
1306
  }] } });
1258
1307
 
1259
- class AXPLogoComponent {
1260
- constructor() {
1261
- this.platform = inject(AXPlatform);
1262
- }
1263
- ngOnInit() {
1264
- this.setLogoType();
1265
- this.platform.themeMode$.subscribe(() => {
1266
- this.setLogoTheme();
1267
- });
1268
- }
1269
- ngOnChanges() {
1270
- this.setLogoTheme();
1271
- }
1272
- setLogoType() {
1273
- switch (true) {
1274
- case this.source instanceof AXPImageUrlLogoConfig:
1275
- this.logoType = 'url';
1276
- break;
1277
- case this.source instanceof AXPComponentLogoConfig:
1278
- this.logoType = 'component';
1279
- break;
1280
- default:
1281
- break;
1282
- }
1283
- }
1284
- setLogoTheme() {
1285
- if (this.source && this.source.dark && this.source.light) {
1286
- this.source = this.platform.isDark() ? this.source.dark : this.source.light;
1287
- }
1288
- }
1289
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPLogoComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1290
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: AXPLogoComponent, isStandalone: true, selector: "axp-logo", inputs: { source: "source" }, host: { classAttribute: "ax-flex ax-justify-center" }, usesOnChanges: true, ngImport: i0, template: "@switch (logoType) { @case ('url') {\n<ax-image [width]=\"source.width\" [height]=\"source.height\" [src]=\"source.url\"></ax-image>\n} @case ('component') {\n<ng-container *ngComponentOutlet=\"source.component\"></ng-container>\n} }\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"], exportAs: ["ngComponentOutlet"] }, { kind: "ngmodule", type: AXImageModule }, { kind: "component", type: i2.AXImageComponent, selector: "ax-image", inputs: ["width", "height", "overlayMode", "src", "alt", "priority", "lazy"], outputs: ["onLoad", "onError"] }, { kind: "ngmodule", type: AXDecoratorModule }] }); }
1291
- }
1292
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPLogoComponent, decorators: [{
1293
- type: Component,
1294
- args: [{ selector: 'axp-logo', imports: [CommonModule, AXImageModule, AXDecoratorModule], host: { class: 'ax-flex ax-justify-center' }, template: "@switch (logoType) { @case ('url') {\n<ax-image [width]=\"source.width\" [height]=\"source.height\" [src]=\"source.url\"></ax-image>\n} @case ('component') {\n<ng-container *ngComponentOutlet=\"source.component\"></ng-container>\n} }\n" }]
1295
- }], propDecorators: { source: [{
1296
- type: Input
1297
- }] } });
1298
-
1299
1308
  //#region ---- Menu Context Builder ----
1300
1309
  /**
1301
1310
  * Creates a rich context for menu manipulation
@@ -1627,10 +1636,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
1627
1636
  }] });
1628
1637
 
1629
1638
  const AXP_MENU_PROVIDER = new InjectionToken('AXP_MENU_PROVIDER');
1639
+ //TODO: check performance of this service
1630
1640
  class AXPMenuProviderService {
1631
1641
  constructor() {
1632
1642
  //#region ---- Dependencies ----
1633
1643
  this.providers = inject(AXP_MENU_PROVIDER, { optional: true });
1644
+ this.providerRegistry = inject(AXPModuleProviderRegistry);
1634
1645
  this.middlewareRegistry = inject(AXPMenuMiddlewareRegistry);
1635
1646
  //#endregion
1636
1647
  //#region ---- State ----
@@ -1658,11 +1669,17 @@ class AXPMenuProviderService {
1658
1669
  }
1659
1670
  const items = [];
1660
1671
  const context = this.createMenuProviderContext(items);
1672
+ // Load providers from DI tokens (backward compatibility)
1661
1673
  if (Array.isArray(this.providers)) {
1662
1674
  for (const provider of this.providers) {
1663
1675
  await provider.provide(context);
1664
1676
  }
1665
1677
  }
1678
+ // Load providers from registry (manifest-based, conditionally loaded)
1679
+ const registryProviders = this.providerRegistry.getMenuProviders();
1680
+ for (const provider of registryProviders) {
1681
+ await provider.provide(context);
1682
+ }
1666
1683
  // Apply pending operations
1667
1684
  this.applyPendingOperations(items);
1668
1685
  // Sort items by priority
@@ -1682,11 +1699,17 @@ class AXPMenuProviderService {
1682
1699
  async rawItems() {
1683
1700
  const items = [];
1684
1701
  const context = this.createMenuProviderContext(items);
1702
+ // Load providers from DI tokens (backward compatibility)
1685
1703
  if (Array.isArray(this.providers)) {
1686
1704
  for (const provider of this.providers) {
1687
1705
  await provider.provide(context);
1688
1706
  }
1689
1707
  }
1708
+ // Load providers from registry (manifest-based, conditionally loaded)
1709
+ const registryProviders = this.providerRegistry.getMenuProviders();
1710
+ for (const provider of registryProviders) {
1711
+ await provider.provide(context);
1712
+ }
1690
1713
  // Apply pending operations
1691
1714
  this.applyPendingOperations(items);
1692
1715
  // Sort items by priority
@@ -1732,10 +1755,29 @@ class AXPMenuProviderService {
1732
1755
  createMenuProviderContext(items) {
1733
1756
  return {
1734
1757
  addItems: (newItems) => {
1735
- items.push(...newItems);
1758
+ for (const newItem of newItems) {
1759
+ if (newItem.name) {
1760
+ const existingItem = this.findItemByName(items, newItem.name);
1761
+ if (existingItem) {
1762
+ // Update existing item, merging properties
1763
+ this.mergeMenuItem(existingItem, newItem);
1764
+ }
1765
+ else {
1766
+ // Add new item if it doesn't exist
1767
+ items.push(newItem);
1768
+ }
1769
+ }
1770
+ else {
1771
+ // Add item without name (no way to check for duplicates)
1772
+ items.push(newItem);
1773
+ }
1774
+ }
1736
1775
  },
1737
1776
  find: (target) => {
1777
+ const foundItemInfo = this.findItemWithParent(items, target);
1778
+ const exists = foundItemInfo.foundItem !== null;
1738
1779
  return {
1780
+ exists,
1739
1781
  insert: (newItems, position) => {
1740
1782
  this.pendingInserts.push({ target, newItems, position });
1741
1783
  },
@@ -1761,13 +1803,48 @@ class AXPMenuProviderService {
1761
1803
  items.push(...newItems);
1762
1804
  }
1763
1805
  else {
1764
- if (position == 'inside') {
1765
- foundItem.children?.push(...newItems);
1806
+ if (position === 'inside') {
1807
+ if (!foundItem.children) {
1808
+ foundItem.children = [];
1809
+ }
1810
+ // Check for duplicates by name and merge or add
1811
+ for (const newItem of newItems) {
1812
+ if (newItem.name) {
1813
+ const existingChild = this.findItemByName(foundItem.children, newItem.name);
1814
+ if (existingChild) {
1815
+ this.mergeMenuItem(existingChild, newItem);
1816
+ }
1817
+ else {
1818
+ foundItem.children.push(newItem);
1819
+ }
1820
+ }
1821
+ else {
1822
+ foundItem.children.push(newItem);
1823
+ }
1824
+ }
1766
1825
  }
1767
1826
  else {
1768
- const index = parentItems.indexOf(foundItem);
1769
- const insertPosition = position === 'before' ? index : index + 1;
1770
- parentItems.splice(insertPosition, 0, ...newItems);
1827
+ // For 'before' and 'after', check for duplicates in parent items
1828
+ const itemsToInsert = [];
1829
+ for (const newItem of newItems) {
1830
+ if (newItem.name) {
1831
+ const existingItem = this.findItemByName(parentItems, newItem.name);
1832
+ if (existingItem) {
1833
+ this.mergeMenuItem(existingItem, newItem);
1834
+ }
1835
+ else {
1836
+ itemsToInsert.push(newItem);
1837
+ }
1838
+ }
1839
+ else {
1840
+ itemsToInsert.push(newItem);
1841
+ }
1842
+ }
1843
+ if (itemsToInsert.length > 0) {
1844
+ const index = parentItems.indexOf(foundItem);
1845
+ const insertPosition = position === 'before' ? index : index + 1;
1846
+ parentItems.splice(insertPosition, 0, ...itemsToInsert);
1847
+ }
1771
1848
  }
1772
1849
  }
1773
1850
  }
@@ -1802,7 +1879,21 @@ class AXPMenuProviderService {
1802
1879
  if (!foundItem.children) {
1803
1880
  foundItem.children = [];
1804
1881
  }
1805
- foundItem.children.push(...newItems);
1882
+ // Check for duplicates by name and merge or add
1883
+ for (const newItem of newItems) {
1884
+ if (newItem.name) {
1885
+ const existingChild = this.findItemByName(foundItem.children, newItem.name);
1886
+ if (existingChild) {
1887
+ this.mergeMenuItem(existingChild, newItem);
1888
+ }
1889
+ else {
1890
+ foundItem.children.push(newItem);
1891
+ }
1892
+ }
1893
+ else {
1894
+ foundItem.children.push(newItem);
1895
+ }
1896
+ }
1806
1897
  }
1807
1898
  }
1808
1899
  // Clear pending operations after applying them
@@ -1825,6 +1916,70 @@ class AXPMenuProviderService {
1825
1916
  }
1826
1917
  return { foundItem: null, parentItems: items };
1827
1918
  }
1919
+ /**
1920
+ * Find menu item by name in the items tree (recursive search)
1921
+ */
1922
+ findItemByName(items, name) {
1923
+ for (const item of items) {
1924
+ if (item.name === name) {
1925
+ return item;
1926
+ }
1927
+ if (item.children) {
1928
+ const found = this.findItemByName(item.children, name);
1929
+ if (found) {
1930
+ return found;
1931
+ }
1932
+ }
1933
+ }
1934
+ return null;
1935
+ }
1936
+ /**
1937
+ * Merge new item properties into existing item, handling children merge
1938
+ */
1939
+ mergeMenuItem(existingItem, newItem) {
1940
+ // Merge top-level properties (newItem properties override existing only if defined)
1941
+ if (newItem.text !== undefined)
1942
+ existingItem.text = newItem.text;
1943
+ if (newItem.description !== undefined)
1944
+ existingItem.description = newItem.description;
1945
+ if (newItem.icon !== undefined)
1946
+ existingItem.icon = newItem.icon;
1947
+ if (newItem.path !== undefined)
1948
+ existingItem.path = newItem.path;
1949
+ if (newItem.priority !== undefined)
1950
+ existingItem.priority = newItem.priority;
1951
+ if (newItem.type !== undefined)
1952
+ existingItem.type = newItem.type;
1953
+ if (newItem.command !== undefined)
1954
+ existingItem.command = newItem.command;
1955
+ if (newItem.badgeKey !== undefined)
1956
+ existingItem.badgeKey = newItem.badgeKey;
1957
+ if (newItem.data !== undefined)
1958
+ existingItem.data = newItem.data;
1959
+ if (newItem.policy !== undefined)
1960
+ existingItem.policy = newItem.policy;
1961
+ // Merge children if both have children
1962
+ if (newItem.children && newItem.children.length > 0) {
1963
+ if (!existingItem.children) {
1964
+ existingItem.children = [];
1965
+ }
1966
+ // For each child in newItem, check if it exists by name and merge or add
1967
+ for (const newChild of newItem.children) {
1968
+ if (newChild.name) {
1969
+ const existingChild = this.findItemByName(existingItem.children, newChild.name);
1970
+ if (existingChild) {
1971
+ this.mergeMenuItem(existingChild, newChild);
1972
+ }
1973
+ else {
1974
+ existingItem.children.push(newChild);
1975
+ }
1976
+ }
1977
+ else {
1978
+ existingItem.children.push(newChild);
1979
+ }
1980
+ }
1981
+ }
1982
+ }
1828
1983
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPMenuProviderService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1829
1984
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPMenuProviderService, providedIn: 'root' }); }
1830
1985
  }
@@ -2051,6 +2206,105 @@ withMethods((store, router = inject(Router), workflow = inject(AXPWorkflowServic
2051
2206
  };
2052
2207
  }));
2053
2208
 
2209
+ /**
2210
+ * Service for checking menu item visibility based on permissions, features, and children.
2211
+ * This service helps filter out empty menu items that have no visible children.
2212
+ */
2213
+ class AXPMenuVisibilityService {
2214
+ constructor() {
2215
+ this.sessionService = inject(AXPSessionService);
2216
+ }
2217
+ /**
2218
+ * Checks if a menu item should be visible based on permissions and features.
2219
+ */
2220
+ isItemVisible(item) {
2221
+ const policy = item.policy;
2222
+ if (!policy) {
2223
+ return true; // No policy means visible
2224
+ }
2225
+ // Check permissions
2226
+ if (policy.permissions && policy.permissions.length > 0) {
2227
+ const permissionKeys = Array.isArray(policy.permissions) ? policy.permissions : [policy.permissions];
2228
+ if (!this.sessionService.authorize(...permissionKeys)) {
2229
+ return false;
2230
+ }
2231
+ }
2232
+ // Check features
2233
+ if (policy.features && policy.features.length > 0) {
2234
+ const featureKeys = Array.isArray(policy.features) ? policy.features : [policy.features];
2235
+ if (!this.sessionService.isFeatureEnabled(...featureKeys)) {
2236
+ return false;
2237
+ }
2238
+ }
2239
+ return true;
2240
+ }
2241
+ /**
2242
+ * Recursively checks if a menu item has any visible children.
2243
+ * @param item The menu item to check
2244
+ * @param getRouterLink Optional function to check if an item has a router link
2245
+ */
2246
+ hasVisibleChildren(item, getRouterLink) {
2247
+ if (!item.children || item.children.length === 0) {
2248
+ return false;
2249
+ }
2250
+ return item.children.some((child) => {
2251
+ // Check if child itself is visible
2252
+ if (!this.isItemVisible(child)) {
2253
+ return false;
2254
+ }
2255
+ // If child has a routerLink, it's visible
2256
+ if (getRouterLink && getRouterLink(child)) {
2257
+ return true;
2258
+ }
2259
+ // If child has visible children, it's visible
2260
+ if (this.hasVisibleChildren(child, getRouterLink)) {
2261
+ return true;
2262
+ }
2263
+ // For items without routerLink, check if they have a command (non-empty menu items)
2264
+ if (child.command) {
2265
+ return true;
2266
+ }
2267
+ return false;
2268
+ });
2269
+ }
2270
+ /**
2271
+ * Determines if a menu item should be rendered.
2272
+ * A menu item should be rendered if:
2273
+ * 1. It has a routerLink, OR
2274
+ * 2. It has visible children, OR
2275
+ * 3. It has a command (for non-router navigation)
2276
+ *
2277
+ * @param item The menu item to check
2278
+ * @param getRouterLink Optional function to check if an item has a router link
2279
+ */
2280
+ shouldRenderMenuItem(item, getRouterLink) {
2281
+ // Check if item itself is visible (permissions/features)
2282
+ if (!this.isItemVisible(item)) {
2283
+ return false;
2284
+ }
2285
+ // If it has a routerLink, render it
2286
+ if (getRouterLink && getRouterLink(item)) {
2287
+ return true;
2288
+ }
2289
+ // If it has visible children, render it
2290
+ if (this.hasVisibleChildren(item, getRouterLink)) {
2291
+ return true;
2292
+ }
2293
+ // If it has a command (for non-router navigation), render it
2294
+ if (item.command) {
2295
+ return true;
2296
+ }
2297
+ // Otherwise, don't render empty menu items
2298
+ return false;
2299
+ }
2300
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPMenuVisibilityService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2301
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPMenuVisibilityService, providedIn: 'root' }); }
2302
+ }
2303
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPMenuVisibilityService, decorators: [{
2304
+ type: Injectable,
2305
+ args: [{ providedIn: 'root' }]
2306
+ }] });
2307
+
2054
2308
  class AXPMenuSearchDefinitionProvider {
2055
2309
  async provide(context) {
2056
2310
  context.addDefinition('menu', 'Menu', 'menu', 'fa-thin fa-bars', 2, {
@@ -2245,6 +2499,7 @@ const AXP_SEARCH_DEFINITION_PROVIDER = new InjectionToken('AXP_SEARCH_DEFINITION
2245
2499
  class AXPSearchDefinitionProviderService {
2246
2500
  constructor() {
2247
2501
  this.providers = inject(AXP_SEARCH_DEFINITION_PROVIDER, { optional: true });
2502
+ this.providerRegistry = inject(AXPModuleProviderRegistry);
2248
2503
  this.cache = null;
2249
2504
  }
2250
2505
  async load() {
@@ -2252,11 +2507,14 @@ class AXPSearchDefinitionProviderService {
2252
2507
  return;
2253
2508
  }
2254
2509
  const context = new AXPSearchDefinitionProviderContext();
2510
+ // Load providers from DI tokens (backward compatibility)
2255
2511
  if (Array.isArray(this.providers)) {
2256
2512
  for (const provider of this.providers) {
2257
2513
  await provider.provide(context);
2258
2514
  }
2259
2515
  }
2516
+ // Note: Search definition providers are different from search command providers
2517
+ // Search command providers are handled separately in search.service.ts
2260
2518
  this.cache = context.getDefinitions();
2261
2519
  }
2262
2520
  async getListAsync() {
@@ -2304,6 +2562,7 @@ const AXP_SEARCH_PROVIDER = new InjectionToken('AXP_SEARCH_PROVIDER');
2304
2562
  class AXPSearchService {
2305
2563
  constructor() {
2306
2564
  this.providers = inject(AXP_SEARCH_PROVIDER, { optional: true });
2565
+ this.providerRegistry = inject(AXPModuleProviderRegistry);
2307
2566
  this.definitionService = inject(AXPSearchDefinitionProviderService);
2308
2567
  this.formatService = inject(AXFormatService);
2309
2568
  }
@@ -2312,11 +2571,24 @@ class AXPSearchService {
2312
2571
  if (this.definitionService.getList().length == 0) {
2313
2572
  await this.definitionService.getListAsync();
2314
2573
  }
2315
- if (!this.providers || (this.providers?.length || 0) === 0) {
2316
- throw new Error('No search providers available'); // No providers available
2574
+ // Collect providers from both DI tokens and registry
2575
+ const allProviders = [];
2576
+ // Load from DI tokens (backward compatibility)
2577
+ if (Array.isArray(this.providers)) {
2578
+ allProviders.push(...this.providers);
2579
+ }
2580
+ else if (this.providers) {
2581
+ allProviders.push(this.providers);
2582
+ }
2583
+ // Load from registry (manifest-based, conditionally loaded)
2584
+ // Note: Registry stores AXPSearchCommandProvider which implements AXPSearchProvider
2585
+ const registryProviders = this.providerRegistry.getSearchProviders();
2586
+ allProviders.push(...registryProviders);
2587
+ if (allProviders.length === 0) {
2588
+ throw new Error('No search providers available');
2317
2589
  }
2318
2590
  const mergeData = [];
2319
- const promises = this.providers.map((provider) => provider.search(text));
2591
+ const promises = allProviders.map((provider) => provider.search(text));
2320
2592
  const results = await Promise.all(promises);
2321
2593
  for (const resultArray of results) {
2322
2594
  for (const result of resultArray) {
@@ -2382,8 +2654,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
2382
2654
 
2383
2655
  var AXPCommonSettings;
2384
2656
  (function (AXPCommonSettings) {
2385
- AXPCommonSettings["EnableOperationToasts"] = "general:notifications:enable-operation-toasts";
2386
- AXPCommonSettings["EntityFilterApplyMode"] = "general:entity:filter-apply-mode";
2657
+ AXPCommonSettings["EnableOperationToasts"] = "Common:Setting:Notifications.EnableOperationToasts";
2658
+ AXPCommonSettings["EntityFilterApplyMode"] = "Common:Setting:Entity.FilterApplyMode";
2387
2659
  })(AXPCommonSettings || (AXPCommonSettings = {}));
2388
2660
 
2389
2661
  //TODO Loading, Redirect, Drawer, Show toast
@@ -2438,10 +2710,10 @@ class AXPToastAction extends AXPWorkflowAction {
2438
2710
  super(...arguments);
2439
2711
  this.toastService = inject(AXToastService);
2440
2712
  this.translationService = inject(AXTranslationService);
2441
- this.settingService = inject(AXPSettingService);
2713
+ this.settingsService = inject(AXPSettingsService);
2442
2714
  }
2443
2715
  async execute(context) {
2444
- const showResult = await this.settingService.get(AXPCommonSettings.EnableOperationToasts);
2716
+ const showResult = await this.settingsService.get(AXPCommonSettings.EnableOperationToasts);
2445
2717
  if (showResult) {
2446
2718
  this.toastService.show({
2447
2719
  color: this.color,
@@ -2577,10 +2849,13 @@ class AXPCommonModule {
2577
2849
  /**
2578
2850
  * @ignore
2579
2851
  */
2580
- constructor(instances, appInitService, settingsService) {
2852
+ constructor(instances, appInitService, settingsService, manifestInitializer, injector) {
2581
2853
  instances.forEach((f) => {
2582
2854
  f();
2583
2855
  });
2856
+ appInitService.registerTask(manifestInitializer.createStartupTask());
2857
+ const moduleProviderInitializer = injector.get(AXP_MODULE_PROVIDER_INITIALIZER);
2858
+ appInitService.registerTask(moduleProviderInitializer.createRequiredModulesTask());
2584
2859
  appInitService.registerTask({
2585
2860
  name: 'Settings',
2586
2861
  statusText: 'Loading Settings ...',
@@ -2589,8 +2864,9 @@ class AXPCommonModule {
2589
2864
  await settingsService.load();
2590
2865
  },
2591
2866
  });
2867
+ appInitService.registerTask(moduleProviderInitializer.createStartupTask());
2592
2868
  }
2593
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPCommonModule, deps: [{ token: 'AXPCommonModuleFactory' }, { token: i1$1.AXPAppStartUpService }, { token: AXPSettingService }], target: i0.ɵɵFactoryTarget.NgModule }); }
2869
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPCommonModule, deps: [{ token: 'AXPCommonModuleFactory' }, { token: i1.AXPAppStartUpService }, { token: AXPSettingsService }, { token: i1.AXPModuleManifestInitializer }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.NgModule }); }
2594
2870
  static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.12", ngImport: i0, type: AXPCommonModule, imports: [i3.AXPWorkflowModule, AXPopupModule,
2595
2871
  AXDateTimeModule,
2596
2872
  AXToastModule], exports: [RouterModule] }); }
@@ -2620,7 +2896,7 @@ class AXPCommonModule {
2620
2896
  },
2621
2897
  {
2622
2898
  provide: AXP_EXPRESSION_EVALUATOR_SCOPE_PROVIDER,
2623
- useClass: AXPGlobalVariableEvaluatorScopeProvider,
2899
+ useClass: AXPTokenEvaluatorScopeProvider,
2624
2900
  multi: true,
2625
2901
  },
2626
2902
  {
@@ -2693,7 +2969,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
2693
2969
  },
2694
2970
  {
2695
2971
  provide: AXP_EXPRESSION_EVALUATOR_SCOPE_PROVIDER,
2696
- useClass: AXPGlobalVariableEvaluatorScopeProvider,
2972
+ useClass: AXPTokenEvaluatorScopeProvider,
2697
2973
  multi: true,
2698
2974
  },
2699
2975
  {
@@ -2710,7 +2986,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
2710
2986
  }], ctorParameters: () => [{ type: undefined, decorators: [{
2711
2987
  type: Inject,
2712
2988
  args: ['AXPCommonModuleFactory']
2713
- }] }, { type: i1$1.AXPAppStartUpService }, { type: AXPSettingService }] });
2989
+ }] }, { type: i1.AXPAppStartUpService }, { type: AXPSettingsService }, { type: i1.AXPModuleManifestInitializer }, { type: i0.Injector }] });
2714
2990
 
2715
2991
  const ENVIRONMENT = new InjectionToken('ENVIRONMENT');
2716
2992
  const AXP_PLATFORM_CONFIG_TOKEN = new InjectionToken('AXP_PLATFORM_CONFIG_TOKEN', {
@@ -2782,6 +3058,510 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
2782
3058
  type: Injectable
2783
3059
  }] });
2784
3060
 
3061
+ /**
3062
+ * Status Definition Types
3063
+ * Defines the structure for status definitions and their transitions
3064
+ */
3065
+ /**
3066
+ * Abstract class for status providers
3067
+ * Similar to AXPTaskBadgeProvider pattern
3068
+ */
3069
+ class AXPStatusProvider {
3070
+ }
3071
+ //#endregion
3072
+
3073
+ //#region ---- Injection Token ----
3074
+ /**
3075
+ * Injection token for status providers
3076
+ * Use with multi: true to register multiple providers
3077
+ */
3078
+ const AXP_STATUS_PROVIDERS = new InjectionToken('AXP_STATUS_PROVIDERS');
3079
+ //#endregion
3080
+ //#region ---- Provider Service ----
3081
+ /**
3082
+ * Service for managing status definitions from multiple providers
3083
+ * Similar to AXPTaskBadgeService pattern - no cache, direct access
3084
+ *
3085
+ * @example
3086
+ * ```typescript
3087
+ * // In a module providers array:
3088
+ * {
3089
+ * provide: AXP_STATUS_PROVIDERS,
3090
+ * useClass: TaskStatusProvider,
3091
+ * multi: true,
3092
+ * }
3093
+ *
3094
+ * // Example provider implementation:
3095
+ * export class TaskStatusProvider extends AXPStatusProvider {
3096
+ * readonly key = 'task-management.status';
3097
+ * readonly statuses = [
3098
+ * { name: 'todo', title: 'To Do', color: '#6b7280', icon: 'fa-light fa-circle', isInitial: true },
3099
+ * { name: 'in-progress', title: 'In Progress', color: '#3b82f6', icon: 'fa-light fa-play' },
3100
+ * { name: 'done', title: 'Done', color: '#10b981', icon: 'fa-light fa-check-circle', isFinal: true },
3101
+ * ];
3102
+ * readonly transitions = [
3103
+ * { from: 'todo', to: 'in-progress', title: 'Start', condition: '{{user.canEdit}}' },
3104
+ * { from: 'in-progress', to: 'done', title: 'Complete' },
3105
+ * ];
3106
+ * readonly defaultStatus = 'todo';
3107
+ * }
3108
+ *
3109
+ * // Later, get the status:
3110
+ * const status = statusService.getStatus('task-management.status');
3111
+ * if (status) {
3112
+ * console.log('Statuses:', status.statuses);
3113
+ * console.log('Transitions:', status.transitions);
3114
+ * }
3115
+ * ```
3116
+ */
3117
+ class AXPStatusDefinitionProviderService {
3118
+ //#endregion
3119
+ //#region ---- Constructor ----
3120
+ constructor() {
3121
+ //#region ---- Dependencies ----
3122
+ this.providers = inject(AXP_STATUS_PROVIDERS, { optional: true }) ?? [];
3123
+ this.commandService = inject(AXPCommandService);
3124
+ //#endregion
3125
+ //#region ---- State ----
3126
+ this.statusMap = new Map();
3127
+ // Register all providers in constructor (like badge service)
3128
+ for (const provider of this.providers) {
3129
+ if (this.statusMap.has(provider.key)) {
3130
+ console.warn(`Status with key "${provider.key}" already exists. Overwriting with new status.`);
3131
+ }
3132
+ this.statusMap.set(provider.key, provider);
3133
+ }
3134
+ }
3135
+ //#endregion
3136
+ //#region ---- Public API ----
3137
+ /**
3138
+ * Get a status provider by key
3139
+ * Direct access from Map (no lazy load, no cache)
3140
+ *
3141
+ * @param key - Status key (e.g., 'task-management.status')
3142
+ * @returns Status provider with all statuses and transitions, or undefined if not found
3143
+ *
3144
+ * @example
3145
+ * ```typescript
3146
+ * const status = statusService.getStatus('task-management.status');
3147
+ * if (status) {
3148
+ * console.log('Statuses:', status.statuses);
3149
+ * console.log('Transitions:', status.transitions);
3150
+ * }
3151
+ * ```
3152
+ */
3153
+ getStatus(key) {
3154
+ return this.statusMap.get(key);
3155
+ }
3156
+ /**
3157
+ * Execute a status transition workflow action
3158
+ * Uses transition.command if provided, otherwise defaults to Entity:UpdateStatus
3159
+ * Validates the transition is allowed before executing
3160
+ *
3161
+ * @param definitionKey - Status definition key
3162
+ * @param transition - The transition to execute
3163
+ * @param context - Context data for the command (must include entity name and id/ids)
3164
+ * @returns Promise that resolves when the command execution completes
3165
+ *
3166
+ * @example
3167
+ * ```typescript
3168
+ * await statusService.executeTransition(
3169
+ * 'task-management.status',
3170
+ * { from: 'todo', to: 'in-progress' },
3171
+ * { entity: 'TaskManagement.Task', id: '123', ...entityData }
3172
+ * );
3173
+ * ```
3174
+ */
3175
+ async executeTransition(definitionKey, transition, context) {
3176
+ const provider = this.getStatus(definitionKey);
3177
+ if (!provider) {
3178
+ throw new Error(`Status provider with key "${definitionKey}" not found.`);
3179
+ }
3180
+ // Validate transition is allowed
3181
+ if (!this.isValidTransition(provider, transition.from, transition.to)) {
3182
+ throw new Error(`Invalid transition from "${transition.from}" to "${transition.to}"`);
3183
+ }
3184
+ // Determine which command to use
3185
+ let commandName;
3186
+ let commandOptions;
3187
+ if (transition.command) {
3188
+ // Use transition's explicit command
3189
+ commandName = transition.command.name;
3190
+ commandOptions = {
3191
+ ...(transition.command.options ?? {}),
3192
+ ...context,
3193
+ };
3194
+ }
3195
+ else {
3196
+ // Use default Entity:UpdateStatus command
3197
+ const entity = context['entityName'] ?? context['__meta__']?.config?.name;
3198
+ if (!entity) {
3199
+ throw new Error('Entity name is required in context when using default status update command');
3200
+ }
3201
+ const id = context['id'];
3202
+ const ids = context['ids'];
3203
+ if (!id && !ids) {
3204
+ throw new Error('Either id or ids must be provided in context');
3205
+ }
3206
+ commandName = 'Entity:UpdateStatus';
3207
+ commandOptions = {
3208
+ entity,
3209
+ status: transition.to,
3210
+ statusField: context['statusField'] ?? 'statusId',
3211
+ ...(id ? { id } : {}),
3212
+ ...(ids ? { ids } : {}),
3213
+ };
3214
+ }
3215
+ // Execute the command
3216
+ const result = await this.commandService.execute(commandName, commandOptions);
3217
+ if (!result?.success) {
3218
+ throw new Error(result?.message?.text || 'Failed to execute status transition command');
3219
+ }
3220
+ }
3221
+ /**
3222
+ * Validate if a transition is allowed
3223
+ * Checks if the transition exists in the provider's transitions list
3224
+ */
3225
+ isValidTransition(provider, from, to) {
3226
+ return provider.transitions.some((transition) => transition.from === from && transition.to === to);
3227
+ }
3228
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPStatusDefinitionProviderService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
3229
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPStatusDefinitionProviderService, providedIn: 'root' }); }
3230
+ }
3231
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPStatusDefinitionProviderService, decorators: [{
3232
+ type: Injectable,
3233
+ args: [{ providedIn: 'root' }]
3234
+ }], ctorParameters: () => [] });
3235
+
3236
+ /**
3237
+ * Standard system status types
3238
+ * These are the predefined status values used across the platform
3239
+ */
3240
+ var AXPSystemStatusType;
3241
+ (function (AXPSystemStatusType) {
3242
+ AXPSystemStatusType["Todo"] = "todo";
3243
+ AXPSystemStatusType["InProgress"] = "in-progress";
3244
+ AXPSystemStatusType["InReview"] = "in-review";
3245
+ AXPSystemStatusType["Open"] = "open";
3246
+ AXPSystemStatusType["Closed"] = "closed";
3247
+ AXPSystemStatusType["Blocked"] = "blocked";
3248
+ AXPSystemStatusType["Done"] = "done";
3249
+ AXPSystemStatusType["Cancelled"] = "cancelled";
3250
+ AXPSystemStatusType["Draft"] = "draft";
3251
+ AXPSystemStatusType["PendingReview"] = "pending-review";
3252
+ AXPSystemStatusType["Approved"] = "approved";
3253
+ AXPSystemStatusType["Published"] = "published";
3254
+ AXPSystemStatusType["Archived"] = "archived";
3255
+ AXPSystemStatusType["Rejected"] = "rejected";
3256
+ AXPSystemStatusType["Active"] = "active";
3257
+ AXPSystemStatusType["Inactive"] = "inactive";
3258
+ AXPSystemStatusType["Pending"] = "pending";
3259
+ AXPSystemStatusType["Completed"] = "completed";
3260
+ AXPSystemStatusType["Suspended"] = "suspended";
3261
+ AXPSystemStatusType["Failed"] = "failed";
3262
+ AXPSystemStatusType["Review"] = "review";
3263
+ AXPSystemStatusType["Expired"] = "expired";
3264
+ })(AXPSystemStatusType || (AXPSystemStatusType = {}));
3265
+ const i18n = (key) => `@general:statuses.${key}`;
3266
+ /**
3267
+ * Standard system status definitions
3268
+ * Provides consistent status definitions across the platform
3269
+ * Uses AXPStatusDefinition interface from status-definition.types.ts
3270
+ */
3271
+ const AXPSystemStatuses = Object.freeze({
3272
+ Open: {
3273
+ name: AXPSystemStatusType.Open,
3274
+ title: i18n('open.title'),
3275
+ icon: 'fa-light fa-circle',
3276
+ color: 'secondary',
3277
+ description: i18n('open.description'),
3278
+ order: 1,
3279
+ isInitial: true,
3280
+ isFinal: false,
3281
+ },
3282
+ Closed: {
3283
+ name: AXPSystemStatusType.Closed,
3284
+ title: i18n('closed.title'),
3285
+ icon: 'fa-light fa-circle',
3286
+ color: 'danger',
3287
+ description: i18n('closed.description'),
3288
+ order: 2,
3289
+ isInitial: false,
3290
+ isFinal: true,
3291
+ },
3292
+ Todo: {
3293
+ name: AXPSystemStatusType.Todo,
3294
+ title: i18n('todo.title'),
3295
+ icon: 'fa-light fa-circle',
3296
+ color: 'secondary',
3297
+ description: i18n('todo.description'),
3298
+ order: 1,
3299
+ isInitial: true,
3300
+ isFinal: false,
3301
+ },
3302
+ InProgress: {
3303
+ name: AXPSystemStatusType.InProgress,
3304
+ title: i18n('in-progress.title'),
3305
+ icon: 'fa-light fa-play',
3306
+ color: 'info',
3307
+ description: i18n('in-progress.description'),
3308
+ order: 2,
3309
+ isInitial: false,
3310
+ isFinal: false,
3311
+ },
3312
+ InReview: {
3313
+ name: AXPSystemStatusType.InReview,
3314
+ title: i18n('in-review.title'),
3315
+ icon: 'fa-light fa-eye',
3316
+ color: 'info',
3317
+ description: i18n('in-review.description'),
3318
+ order: 3,
3319
+ isInitial: false,
3320
+ isFinal: false,
3321
+ },
3322
+ Blocked: {
3323
+ name: AXPSystemStatusType.Blocked,
3324
+ title: i18n('blocked.title'),
3325
+ icon: 'fa-light fa-ban',
3326
+ color: 'danger',
3327
+ description: i18n('blocked.description'),
3328
+ order: 4,
3329
+ isInitial: false,
3330
+ isFinal: false,
3331
+ },
3332
+ Done: {
3333
+ name: AXPSystemStatusType.Done,
3334
+ title: i18n('done.title'),
3335
+ icon: 'fa-light fa-check-circle',
3336
+ color: 'success',
3337
+ description: i18n('done.description'),
3338
+ order: 5,
3339
+ isInitial: false,
3340
+ isFinal: true,
3341
+ },
3342
+ Cancelled: {
3343
+ name: AXPSystemStatusType.Cancelled,
3344
+ title: i18n('cancelled.title'),
3345
+ icon: 'fa-light fa-times-circle',
3346
+ color: 'neutral',
3347
+ description: i18n('cancelled.description'),
3348
+ order: 6,
3349
+ isInitial: false,
3350
+ isFinal: true,
3351
+ },
3352
+ Draft: {
3353
+ name: AXPSystemStatusType.Draft,
3354
+ title: i18n('draft.title'),
3355
+ icon: 'fa-light fa-file-pen',
3356
+ color: 'neutral',
3357
+ description: i18n('draft.description'),
3358
+ order: 1,
3359
+ isInitial: true,
3360
+ isFinal: false,
3361
+ },
3362
+ PendingReview: {
3363
+ name: AXPSystemStatusType.PendingReview,
3364
+ title: i18n('pending-review.title'),
3365
+ icon: 'fa-light fa-clock',
3366
+ color: 'warning',
3367
+ description: i18n('pending-review.description'),
3368
+ order: 2,
3369
+ isInitial: false,
3370
+ isFinal: false,
3371
+ },
3372
+ Approved: {
3373
+ name: AXPSystemStatusType.Approved,
3374
+ title: i18n('approved.title'),
3375
+ icon: 'fa-light fa-check-circle',
3376
+ color: 'success',
3377
+ description: i18n('approved.description'),
3378
+ order: 3,
3379
+ isInitial: false,
3380
+ isFinal: false,
3381
+ },
3382
+ Published: {
3383
+ name: AXPSystemStatusType.Published,
3384
+ title: i18n('published.title'),
3385
+ icon: 'fa-light fa-globe',
3386
+ color: 'primary',
3387
+ description: i18n('published.description'),
3388
+ order: 4,
3389
+ isInitial: false,
3390
+ isFinal: false,
3391
+ },
3392
+ Archived: {
3393
+ name: AXPSystemStatusType.Archived,
3394
+ title: i18n('archived.title'),
3395
+ icon: 'fa-light fa-archive',
3396
+ color: 'danger',
3397
+ description: i18n('archived.description'),
3398
+ order: 5,
3399
+ isInitial: false,
3400
+ isFinal: true,
3401
+ },
3402
+ Rejected: {
3403
+ name: AXPSystemStatusType.Rejected,
3404
+ title: i18n('rejected.title'),
3405
+ icon: 'fa-light fa-times-circle',
3406
+ color: 'danger',
3407
+ description: i18n('rejected.description'),
3408
+ order: 6,
3409
+ isInitial: false,
3410
+ isFinal: true,
3411
+ },
3412
+ Active: {
3413
+ name: AXPSystemStatusType.Active,
3414
+ title: i18n('active.title'),
3415
+ icon: 'fa-light fa-check-circle',
3416
+ color: 'success',
3417
+ description: i18n('active.description'),
3418
+ order: 1,
3419
+ isInitial: false,
3420
+ isFinal: false,
3421
+ },
3422
+ Inactive: {
3423
+ name: AXPSystemStatusType.Inactive,
3424
+ title: i18n('inactive.title'),
3425
+ icon: 'fa-light fa-circle',
3426
+ color: 'secondary',
3427
+ description: i18n('inactive.description'),
3428
+ order: 2,
3429
+ isInitial: false,
3430
+ isFinal: false,
3431
+ },
3432
+ Pending: {
3433
+ name: AXPSystemStatusType.Pending,
3434
+ title: i18n('pending.title'),
3435
+ icon: 'fa-light fa-clock',
3436
+ color: 'warning',
3437
+ description: i18n('pending.description'),
3438
+ order: 1,
3439
+ isInitial: true,
3440
+ isFinal: false,
3441
+ },
3442
+ Completed: {
3443
+ name: AXPSystemStatusType.Completed,
3444
+ title: i18n('completed.title'),
3445
+ icon: 'fa-light fa-check-circle',
3446
+ color: 'success',
3447
+ description: i18n('completed.description'),
3448
+ order: 10,
3449
+ isInitial: false,
3450
+ isFinal: true,
3451
+ },
3452
+ Suspended: {
3453
+ name: AXPSystemStatusType.Suspended,
3454
+ title: i18n('suspended.title'),
3455
+ icon: 'fa-light fa-pause-circle',
3456
+ color: 'neutral',
3457
+ description: i18n('suspended.description'),
3458
+ order: 5,
3459
+ isInitial: false,
3460
+ isFinal: false,
3461
+ },
3462
+ Failed: {
3463
+ name: AXPSystemStatusType.Failed,
3464
+ title: i18n('failed.title'),
3465
+ icon: 'fa-light fa-xmark-circle',
3466
+ color: 'danger',
3467
+ description: i18n('failed.description'),
3468
+ order: 10,
3469
+ isInitial: false,
3470
+ isFinal: true,
3471
+ },
3472
+ Review: {
3473
+ name: AXPSystemStatusType.Review,
3474
+ title: i18n('review.title'),
3475
+ icon: 'fa-light fa-eye',
3476
+ color: 'info',
3477
+ description: i18n('review.description'),
3478
+ order: 3,
3479
+ },
3480
+ Expired: {
3481
+ name: AXPSystemStatusType.Expired,
3482
+ title: i18n('expired.title'),
3483
+ icon: 'fa-light fa-clock',
3484
+ color: 'danger',
3485
+ description: i18n('expired.description'),
3486
+ order: 10,
3487
+ isInitial: false,
3488
+ isFinal: true,
3489
+ },
3490
+ });
3491
+ /**
3492
+ * Get system status definition by type
3493
+ * @param type - Status type
3494
+ * @returns System status definition or undefined
3495
+ */
3496
+ function getSystemStatus(type) {
3497
+ return Object.values(AXPSystemStatuses).find(status => status.name === type);
3498
+ }
3499
+ /**
3500
+ * Resolves the visual appearance (color and icon) for status
3501
+ * using the system statuses from the core module.
3502
+ * @param statusType - Status type string
3503
+ * @returns Color and icon for the status
3504
+ */
3505
+ function resolveStatusLook(statusType) {
3506
+ // Try to get system status first
3507
+ const systemStatusType = statusType;
3508
+ if (systemStatusType) {
3509
+ const systemStatus = getSystemStatus(systemStatusType);
3510
+ if (systemStatus) {
3511
+ // Convert hex color to semantic color type if needed
3512
+ // For now, return as-is and let the UI handle it
3513
+ return {
3514
+ color: systemStatus.color,
3515
+ icon: systemStatus.icon || ''
3516
+ };
3517
+ }
3518
+ }
3519
+ // Fallback for unknown statuses
3520
+ return {
3521
+ color: 'secondary',
3522
+ icon: ''
3523
+ };
3524
+ }
3525
+ /**
3526
+ * Resolves the complete status information (title, description, icon, color) for a status
3527
+ * using the system statuses from the core module.
3528
+ * @param statusType - Status type string
3529
+ * @returns Complete status information as AXPStatusDefinition
3530
+ */
3531
+ function getStatusInfo(statusType) {
3532
+ const systemStatusType = statusType;
3533
+ if (systemStatusType) {
3534
+ const systemStatus = getSystemStatus(systemStatusType);
3535
+ if (systemStatus) {
3536
+ return systemStatus;
3537
+ }
3538
+ }
3539
+ // Fallback for unknown statuses
3540
+ return {
3541
+ name: statusType,
3542
+ title: statusType,
3543
+ description: `Status: ${statusType}`,
3544
+ icon: '',
3545
+ color: 'secondary'
3546
+ };
3547
+ }
3548
+ /**
3549
+ * Get system status definition directly (no conversion needed since it's already AXPStatusDefinition)
3550
+ * @param statusType - Status type
3551
+ * @param overrides - Optional overrides for the status definition
3552
+ * @returns AXPStatusDefinition
3553
+ */
3554
+ function systemStatusToDefinition(statusType, overrides) {
3555
+ const systemStatus = getSystemStatus(statusType);
3556
+ if (!systemStatus) {
3557
+ throw new Error(`System status ${statusType} not found`);
3558
+ }
3559
+ return {
3560
+ ...systemStatus,
3561
+ ...overrides,
3562
+ };
3563
+ }
3564
+
2785
3565
  class AXPClipBoardService {
2786
3566
  constructor() {
2787
3567
  this.toast = inject(AXToastService);
@@ -2805,6 +3585,123 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
2805
3585
  }]
2806
3586
  }] });
2807
3587
 
3588
+ //#region ---- Imports ----
3589
+ //#endregion
3590
+ //#region ---- Debug Service ----
3591
+ /**
3592
+ * Service for debugging user access information.
3593
+ * Displays loaded modules, features, and permissions for the current user.
3594
+ */
3595
+ class AXPDebugService {
3596
+ constructor() {
3597
+ //#region ---- Services & Dependencies ----
3598
+ this.sessionService = inject(AXPSessionService);
3599
+ this.manifestRegistry = inject(AXPModuleManifestRegistry);
3600
+ }
3601
+ //#endregion
3602
+ //#region ---- Public Methods ----
3603
+ /**
3604
+ * Display all loaded modules, features, and permissions for the current user.
3605
+ */
3606
+ async displayUserAccessInfo() {
3607
+ try {
3608
+ // Ensure registry is initialized
3609
+ await this.manifestRegistry.initialize();
3610
+ // Get all registered modules
3611
+ const allManifests = this.manifestRegistry.getAll();
3612
+ // Get all feature definitions
3613
+ const allFeatures = this.manifestRegistry.getAllFeatureDefinitions();
3614
+ // Get current user permissions
3615
+ const userPermissions = this.sessionService.permissions;
3616
+ const user = this.sessionService.user;
3617
+ console.group('🔐 User Access Information');
3618
+ console.log(`User: ${user?.name || user?.title || 'Unknown'} (${user?.id || 'N/A'})`);
3619
+ console.log('');
3620
+ if (allManifests.length === 0) {
3621
+ console.log('No modules loaded');
3622
+ console.groupEnd();
3623
+ return;
3624
+ }
3625
+ // Group features by module
3626
+ const featuresByModule = new Map();
3627
+ allFeatures.forEach((feature) => {
3628
+ const moduleName = feature.module;
3629
+ if (!featuresByModule.has(moduleName)) {
3630
+ featuresByModule.set(moduleName, []);
3631
+ }
3632
+ featuresByModule.get(moduleName).push(feature);
3633
+ });
3634
+ // Group permissions by module (if they follow ModuleName:PermissionKey pattern)
3635
+ const permissionsByModule = new Map();
3636
+ const ungroupedPermissions = [];
3637
+ userPermissions.forEach((permission) => {
3638
+ const parts = permission.split(':');
3639
+ if (parts.length >= 2) {
3640
+ const moduleName = parts[0];
3641
+ if (!permissionsByModule.has(moduleName)) {
3642
+ permissionsByModule.set(moduleName, []);
3643
+ }
3644
+ permissionsByModule.get(moduleName).push(permission);
3645
+ }
3646
+ else {
3647
+ ungroupedPermissions.push(permission);
3648
+ }
3649
+ });
3650
+ // Display modules in tree format
3651
+ allManifests.forEach((manifest) => {
3652
+ const moduleName = manifest.name;
3653
+ const moduleFeatures = featuresByModule.get(moduleName) || [];
3654
+ const modulePermissions = permissionsByModule.get(moduleName) || [];
3655
+ console.group(`📦 ${moduleName}`);
3656
+ // Display Features
3657
+ if (moduleFeatures.length > 0) {
3658
+ console.log(' --- Features:');
3659
+ moduleFeatures.forEach((feature) => {
3660
+ console.log(` • ${feature.name}`);
3661
+ });
3662
+ }
3663
+ else {
3664
+ console.log(' --- Features: (none)');
3665
+ }
3666
+ // Display Permissions
3667
+ if (modulePermissions.length > 0) {
3668
+ console.log(' --- Permissions:');
3669
+ modulePermissions.forEach((permission) => {
3670
+ console.log(` • ${permission}`);
3671
+ });
3672
+ }
3673
+ else {
3674
+ console.log(' --- Permissions: (none)');
3675
+ }
3676
+ console.groupEnd();
3677
+ });
3678
+ // Display ungrouped permissions if any
3679
+ if (ungroupedPermissions.length > 0) {
3680
+ console.group('📁 Other Permissions');
3681
+ ungroupedPermissions.forEach((permission) => {
3682
+ console.log(` • ${permission}`);
3683
+ });
3684
+ console.groupEnd();
3685
+ }
3686
+ // Summary
3687
+ console.log('');
3688
+ console.log(`Summary: ${allManifests.length} modules, ${allFeatures.length} features, ${userPermissions.length} permissions`);
3689
+ console.groupEnd();
3690
+ }
3691
+ catch (error) {
3692
+ console.error('[AXPDebugService] Failed to display user access info:', error);
3693
+ }
3694
+ }
3695
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPDebugService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
3696
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPDebugService, providedIn: 'root' }); }
3697
+ }
3698
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPDebugService, decorators: [{
3699
+ type: Injectable,
3700
+ args: [{
3701
+ providedIn: 'root',
3702
+ }]
3703
+ }] });
3704
+
2808
3705
  class AXMOrgChartPrintPage extends AXBasePageComponent {
2809
3706
  constructor() {
2810
3707
  super(...arguments);
@@ -2903,7 +3800,7 @@ class AXMOrgChartPrintPage extends AXBasePageComponent {
2903
3800
  <ax-icon class="fa-solid fa-print"> </ax-icon>
2904
3801
  </ax-button>
2905
3802
  </ax-suffix>
2906
- </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$1.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$1.AXLabelComponent, selector: "ax-label", inputs: ["required", "for"], outputs: ["requiredChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i4.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i4.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: i5.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "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.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"] }] }); }
3803
+ </ax-footer>`, isInline: true, dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.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.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$1.AXLabelComponent, selector: "ax-label", inputs: ["required", "for"], outputs: ["requiredChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i4.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i4.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: i5.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "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.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"] }] }); }
2907
3804
  }
2908
3805
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXMOrgChartPrintPage, decorators: [{
2909
3806
  type: Component,
@@ -3069,5 +3966,5 @@ class AXPVersioningService {
3069
3966
  * Generated bundle index. Do not edit.
3070
3967
  */
3071
3968
 
3072
- export { ALL_DEFAULT_OPERATORS, AXMWorkflowErrorHandler, AXPAppVersionService, AXPCleanNestedFilters, AXPClipBoardService, AXPCommonModule, AXPCommonSettings, AXPCustomOperatorService, AXPCustomOperatorServiceImpl, AXPDataProvider, AXPDialogConfirmAction, AXPEntityCommandScope, AXPEntityQueryType, AXPErrorHandlerRegistryService, AXPExportService, AXPFileStorageService, AXPFileStorageStatus, AXPFileTypeProviderService, AXPFilterOperatorMiddlewareService, AXPFilterOperatorMiddlewareServiceImpl, AXPFooterTextSlotComponent, AXPGlobalErrorHandler, AXPGlobalVariableDefinitionService, AXPGlobalVariableEvaluatorScopeProvider, AXPHomePageModule, AXPHomePageService, AXPLockService, AXPLogoComponent, AXPMenuMiddlewareRegistry, AXPMenuProviderService, AXPMenuSearchDefinitionProvider, AXPMenuSearchProvider, AXPMenuService, AXPNavBarSlotComponent, AXPNavigateWorkflow, AXPPlatformDefaultConfigs, AXPRedirectEvent, AXPRefreshEvent, AXPRelationshipCardinality, AXPRelationshipKind, AXPReloadAction, AXPReloadEvent, AXPSearchCommandProvider, AXPSearchDefinitionActionBuilder, AXPSearchDefinitionBuilder, AXPSearchDefinitionProviderContext, AXPSearchDefinitionProviderService, AXPSearchService, AXPSettingDefaultValuesAggregatorService, AXPSettingDefinitionGroupBuilder, AXPSettingDefinitionProviderContext, AXPSettingDefinitionProviderService, AXPSettingDefinitionSectionBuilder, AXPSettingService, AXPStickyDirective, AXPToastAction, AXPVersioningService, AXPWorkflowNavigateAction, AXPWorkflowRouterNavigateAction, AXP_APP_VERSION_PROVIDER, AXP_FILE_TYPE_INFO_PROVIDER, AXP_GLOBAL_VARIABLE_DEFINITION_PROVIDER, AXP_HOME_PAGES, AXP_HOME_PAGE_DEFAULT_KEY, AXP_MENU_MIDDLEWARE, AXP_MENU_PROVIDER, AXP_PLATFORM_CONFIG_TOKEN, AXP_ROOT_CONFIG_TOKEN, AXP_SEARCH_DEFINITION_PROVIDER, AXP_SEARCH_PROVIDER, AXP_SETTING_DEFAULT_VALUES_PROVIDERS, AXP_SETTING_DEFINITION_PROVIDER, AXP_SETTING_VALUE_PROVIDER, AXVChangeType, BETWEEN_OPER, BOOLEAN_OPERATORS, CONTAINS_OPER, DATE_OPERATORS, ENDS_WITH_OPER, ENVIRONMENT, EQ_OPER, GTE_OPER, GT_OPER, IN_OPER, IS_EMPTY_OPER, IS_NOT_EMPTY_OPER, LTE_OPER, LT_OPER, NOT_CONTAINS_OPER, NOT_EQ_OPER, NUMBER_OPERATORS, STARTS_WITH_OPER, STRING_OPERATORS, configPlatform, createAllQueryView, createMenuContext, createMenuMiddleware, createQueryView, getEntityInfo, provideDynamicHomePage, provideMenuMiddleware };
3969
+ export { ALL_DEFAULT_OPERATORS, AXMWorkflowErrorHandler, AXPAppVersionService, AXPCleanNestedFilters, AXPClipBoardService, AXPCommonModule, AXPCommonSettings, AXPCustomOperatorService, AXPCustomOperatorServiceImpl, AXPDataProvider, AXPDebugService, AXPDialogConfirmAction, AXPEntityCommandScope, AXPEntityQueryType, AXPErrorHandlerRegistryService, AXPExportService, AXPFileStorageService, AXPFileStorageStatus, AXPFileTypeProviderService, AXPFilterOperatorMiddlewareService, AXPFilterOperatorMiddlewareServiceImpl, AXPFooterTextSlotComponent, AXPGlobalErrorHandler, AXPHomePageModule, AXPHomePageService, AXPLockService, AXPMenuMiddlewareRegistry, AXPMenuProviderService, AXPMenuSearchDefinitionProvider, AXPMenuSearchProvider, AXPMenuService, AXPMenuVisibilityService, AXPNavBarSlotComponent, AXPNavigateWorkflow, AXPPlatformDefaultConfigs, AXPRedirectEvent, AXPRefreshEvent, AXPRegionalSetting, AXPRelationshipCardinality, AXPRelationshipKind, AXPReloadAction, AXPReloadEvent, AXPSearchCommandProvider, AXPSearchDefinitionActionBuilder, AXPSearchDefinitionBuilder, AXPSearchDefinitionProviderContext, AXPSearchDefinitionProviderService, AXPSearchService, AXPSettingDefaultValuesAggregatorService, AXPSettingDefinitionGroupBuilder, AXPSettingDefinitionProviderContext, AXPSettingDefinitionProviderService, AXPSettingDefinitionSectionBuilder, AXPSettingsService, AXPStatusDefinitionProviderService, AXPStatusProvider, AXPStickyDirective, AXPSystemStatusType, AXPSystemStatuses, AXPToastAction, AXPTokenDefinitionService, AXPTokenEvaluatorScopeProvider, AXPVersioningService, AXPWorkflowNavigateAction, AXPWorkflowRouterNavigateAction, AXP_APP_VERSION_PROVIDER, AXP_FILE_TYPE_INFO_PROVIDER, AXP_HOME_PAGES, AXP_HOME_PAGE_DEFAULT_KEY, AXP_MENU_MIDDLEWARE, AXP_MENU_PROVIDER, AXP_PLATFORM_CONFIG_TOKEN, AXP_ROOT_CONFIG_TOKEN, AXP_SEARCH_DEFINITION_PROVIDER, AXP_SEARCH_PROVIDER, AXP_SETTING_DEFAULT_VALUES_PROVIDERS, AXP_SETTING_DEFINITION_PROVIDER, AXP_SETTING_VALUE_PROVIDER, AXP_STATUS_PROVIDERS, AXP_TOKEN_DEFINITION_PROVIDER, AXVChangeType, BETWEEN_OPER, BOOLEAN_OPERATORS, CONTAINS_OPER, DATE_OPERATORS, ENDS_WITH_OPER, ENVIRONMENT, EQ_OPER, GTE_OPER, GT_OPER, IN_OPER, IS_EMPTY_OPER, IS_NOT_EMPTY_OPER, LTE_OPER, LT_OPER, NOT_CONTAINS_OPER, NOT_EQ_OPER, NUMBER_OPERATORS, STARTS_WITH_OPER, STRING_OPERATORS, configPlatform, createAllQueryView, createMenuContext, createMenuMiddleware, createQueryView, getEntityInfo, getStatusInfo, getSystemStatus, provideDynamicHomePage, provideMenuMiddleware, resolveStatusLook, systemStatusToDefinition };
3073
3970
  //# sourceMappingURL=acorex-platform-common.mjs.map