@acorex/platform 21.0.0-next.5 → 21.0.0-next.51

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 (124) hide show
  1. package/fesm2022/acorex-platform-auth.mjs +281 -23
  2. package/fesm2022/acorex-platform-auth.mjs.map +1 -1
  3. package/fesm2022/acorex-platform-common-common-settings.provider-Bi1RYif5.mjs +163 -0
  4. package/fesm2022/acorex-platform-common-common-settings.provider-Bi1RYif5.mjs.map +1 -0
  5. package/fesm2022/acorex-platform-common.mjs +1047 -263
  6. package/fesm2022/acorex-platform-common.mjs.map +1 -1
  7. package/fesm2022/acorex-platform-core.mjs +1138 -510
  8. package/fesm2022/acorex-platform-core.mjs.map +1 -1
  9. package/fesm2022/acorex-platform-domain.mjs +557 -826
  10. package/fesm2022/acorex-platform-domain.mjs.map +1 -1
  11. package/fesm2022/acorex-platform-layout-builder.mjs +804 -186
  12. package/fesm2022/acorex-platform-layout-builder.mjs.map +1 -1
  13. package/fesm2022/acorex-platform-layout-components-binding-expression-editor-popup.component-CXEdvDTf.mjs +121 -0
  14. package/fesm2022/acorex-platform-layout-components-binding-expression-editor-popup.component-CXEdvDTf.mjs.map +1 -0
  15. package/fesm2022/acorex-platform-layout-components.mjs +6208 -2344
  16. package/fesm2022/acorex-platform-layout-components.mjs.map +1 -1
  17. package/fesm2022/acorex-platform-layout-designer.mjs +456 -204
  18. package/fesm2022/acorex-platform-layout-designer.mjs.map +1 -1
  19. package/fesm2022/acorex-platform-layout-entity.mjs +18632 -10286
  20. package/fesm2022/acorex-platform-layout-entity.mjs.map +1 -1
  21. package/fesm2022/acorex-platform-layout-views.mjs +538 -168
  22. package/fesm2022/acorex-platform-layout-views.mjs.map +1 -1
  23. package/fesm2022/acorex-platform-layout-widget-core.mjs +720 -456
  24. package/fesm2022/acorex-platform-layout-widget-core.mjs.map +1 -1
  25. package/fesm2022/{acorex-platform-layout-widgets-button-widget-designer.component-C3VoBb_b.mjs → acorex-platform-layout-widgets-button-widget-designer.component-Dy7jF-oD.mjs} +10 -10
  26. package/fesm2022/acorex-platform-layout-widgets-button-widget-designer.component-Dy7jF-oD.mjs.map +1 -0
  27. package/fesm2022/acorex-platform-layout-widgets-file-list-popup.component-CDYAGBku.mjs +103 -0
  28. package/fesm2022/acorex-platform-layout-widgets-file-list-popup.component-CDYAGBku.mjs.map +1 -0
  29. package/fesm2022/{acorex-platform-layout-widgets-image-preview.popup-V31OpYah.mjs → acorex-platform-layout-widgets-image-preview.popup-C_EPAvCU.mjs} +6 -7
  30. package/fesm2022/acorex-platform-layout-widgets-image-preview.popup-C_EPAvCU.mjs.map +1 -0
  31. package/fesm2022/{acorex-platform-layout-widgets-page-widget-designer.component-BtZMBxYp.mjs → acorex-platform-layout-widgets-page-widget-designer.component-D10yO28c.mjs} +12 -12
  32. package/fesm2022/acorex-platform-layout-widgets-page-widget-designer.component-D10yO28c.mjs.map +1 -0
  33. package/fesm2022/acorex-platform-layout-widgets-repeater-widget-column.component-BGO75IMz.mjs +116 -0
  34. package/fesm2022/acorex-platform-layout-widgets-repeater-widget-column.component-BGO75IMz.mjs.map +1 -0
  35. package/fesm2022/{acorex-platform-layout-widgets-tabular-data-edit-popup.component-Ck7-wpT2.mjs → acorex-platform-layout-widgets-tabular-data-edit-popup.component-DmzNTYiS.mjs} +6 -6
  36. package/fesm2022/acorex-platform-layout-widgets-tabular-data-edit-popup.component-DmzNTYiS.mjs.map +1 -0
  37. package/fesm2022/{acorex-platform-layout-widgets-tabular-data-view-popup.component-y8vjUiVs.mjs → acorex-platform-layout-widgets-tabular-data-view-popup.component-BNG_588B.mjs} +5 -5
  38. package/fesm2022/acorex-platform-layout-widgets-tabular-data-view-popup.component-BNG_588B.mjs.map +1 -0
  39. package/fesm2022/{acorex-platform-layout-widgets-text-block-widget-designer.component-Df1BFkSa.mjs → acorex-platform-layout-widgets-text-block-widget-designer.component-Vo4fWHtX.mjs} +6 -6
  40. package/fesm2022/acorex-platform-layout-widgets-text-block-widget-designer.component-Vo4fWHtX.mjs.map +1 -0
  41. package/fesm2022/acorex-platform-layout-widgets.mjs +8728 -4269
  42. package/fesm2022/acorex-platform-layout-widgets.mjs.map +1 -1
  43. package/fesm2022/acorex-platform-native.mjs +8 -7
  44. package/fesm2022/acorex-platform-native.mjs.map +1 -1
  45. package/fesm2022/acorex-platform-runtime.mjs +391 -166
  46. package/fesm2022/acorex-platform-runtime.mjs.map +1 -1
  47. package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-Cx1lLUaR.mjs +160 -0
  48. package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-Cx1lLUaR.mjs.map +1 -0
  49. package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-AOrcgjDF.mjs +120 -0
  50. package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-AOrcgjDF.mjs.map +1 -0
  51. package/fesm2022/{acorex-platform-themes-default-entity-master-single-view.component-eMBby9k4.mjs → acorex-platform-themes-default-entity-master-single-view.component-BfCeUU5F.mjs} +19 -26
  52. package/fesm2022/acorex-platform-themes-default-entity-master-single-view.component-BfCeUU5F.mjs.map +1 -0
  53. package/fesm2022/{acorex-platform-themes-default-error-401.component-cfREo88K.mjs → acorex-platform-themes-default-error-401.component-C7EYJzSr.mjs} +4 -4
  54. package/fesm2022/acorex-platform-themes-default-error-401.component-C7EYJzSr.mjs.map +1 -0
  55. package/fesm2022/{acorex-platform-themes-default-error-404.component-CdCV5ZoA.mjs → acorex-platform-themes-default-error-404.component-7MVLMwIa.mjs} +4 -4
  56. package/fesm2022/acorex-platform-themes-default-error-404.component-7MVLMwIa.mjs.map +1 -0
  57. package/fesm2022/acorex-platform-themes-default-error-offline.component-DR6G8gPC.mjs +19 -0
  58. package/fesm2022/acorex-platform-themes-default-error-offline.component-DR6G8gPC.mjs.map +1 -0
  59. package/fesm2022/acorex-platform-themes-default.mjs +1836 -67
  60. package/fesm2022/acorex-platform-themes-default.mjs.map +1 -1
  61. package/fesm2022/{acorex-platform-themes-shared-icon-chooser-column.component-C0EpfU2k.mjs → acorex-platform-themes-shared-icon-chooser-column.component-CqkWJYdv.mjs} +6 -6
  62. package/fesm2022/acorex-platform-themes-shared-icon-chooser-column.component-CqkWJYdv.mjs.map +1 -0
  63. package/fesm2022/{acorex-platform-themes-shared-icon-chooser-view.component-9W52W6Nu.mjs → acorex-platform-themes-shared-icon-chooser-view.component-BOTuLdWN.mjs} +6 -6
  64. package/fesm2022/acorex-platform-themes-shared-icon-chooser-view.component-BOTuLdWN.mjs.map +1 -0
  65. package/fesm2022/{acorex-platform-themes-shared-settings.provider-DSs1o1M6.mjs → acorex-platform-themes-shared-settings.provider-DK6R87Lf.mjs} +24 -25
  66. package/fesm2022/acorex-platform-themes-shared-settings.provider-DK6R87Lf.mjs.map +1 -0
  67. package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-column.component-D566Kdvy.mjs +94 -0
  68. package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-column.component-D566Kdvy.mjs.map +1 -0
  69. package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-view.component-D7-rCGl7.mjs +86 -0
  70. package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-view.component-D7-rCGl7.mjs.map +1 -0
  71. package/fesm2022/acorex-platform-themes-shared.mjs +674 -573
  72. package/fesm2022/acorex-platform-themes-shared.mjs.map +1 -1
  73. package/fesm2022/acorex-platform-workflow.mjs +1715 -535
  74. package/fesm2022/acorex-platform-workflow.mjs.map +1 -1
  75. package/fesm2022/acorex-platform.mjs.map +1 -1
  76. package/package.json +37 -37
  77. package/{auth/index.d.ts → types/acorex-platform-auth.d.ts} +241 -4
  78. package/{common/index.d.ts → types/acorex-platform-common.d.ts} +598 -80
  79. package/{core/index.d.ts → types/acorex-platform-core.d.ts} +595 -132
  80. package/{domain/index.d.ts → types/acorex-platform-domain.d.ts} +744 -412
  81. package/{layout/builder/index.d.ts → types/acorex-platform-layout-builder.d.ts} +193 -48
  82. package/types/acorex-platform-layout-components.d.ts +2979 -0
  83. package/{layout/designer/index.d.ts → types/acorex-platform-layout-designer.d.ts} +96 -18
  84. package/{layout/entity/index.d.ts → types/acorex-platform-layout-entity.d.ts} +1601 -261
  85. package/{layout/views/index.d.ts → types/acorex-platform-layout-views.d.ts} +116 -55
  86. package/{layout/widget-core/index.d.ts → types/acorex-platform-layout-widget-core.d.ts} +272 -124
  87. package/{layout/widgets/index.d.ts → types/acorex-platform-layout-widgets.d.ts} +1055 -157
  88. package/{native/index.d.ts → types/acorex-platform-native.d.ts} +0 -7
  89. package/types/acorex-platform-runtime.d.ts +571 -0
  90. package/{themes/default/index.d.ts → types/acorex-platform-themes-default.d.ts} +122 -5
  91. package/{themes/shared/index.d.ts → types/acorex-platform-themes-shared.d.ts} +1 -1
  92. package/types/acorex-platform-workflow.d.ts +1884 -0
  93. package/fesm2022/acorex-platform-common-common-settings.provider-zhqNP3xb.mjs +0 -71
  94. package/fesm2022/acorex-platform-common-common-settings.provider-zhqNP3xb.mjs.map +0 -1
  95. package/fesm2022/acorex-platform-layout-widgets-button-widget-designer.component-C3VoBb_b.mjs.map +0 -1
  96. package/fesm2022/acorex-platform-layout-widgets-file-list-popup.component-CxrsI6Hn.mjs +0 -135
  97. package/fesm2022/acorex-platform-layout-widgets-file-list-popup.component-CxrsI6Hn.mjs.map +0 -1
  98. package/fesm2022/acorex-platform-layout-widgets-image-preview.popup-V31OpYah.mjs.map +0 -1
  99. package/fesm2022/acorex-platform-layout-widgets-page-widget-designer.component-BtZMBxYp.mjs.map +0 -1
  100. package/fesm2022/acorex-platform-layout-widgets-tabular-data-edit-popup.component-Ck7-wpT2.mjs.map +0 -1
  101. package/fesm2022/acorex-platform-layout-widgets-tabular-data-view-popup.component-y8vjUiVs.mjs.map +0 -1
  102. package/fesm2022/acorex-platform-layout-widgets-text-block-widget-designer.component-Df1BFkSa.mjs.map +0 -1
  103. package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-VIGuU5M4.mjs +0 -157
  104. package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-VIGuU5M4.mjs.map +0 -1
  105. package/fesm2022/acorex-platform-themes-default-entity-master-list-view.component-DyDa_hyd.mjs +0 -1542
  106. package/fesm2022/acorex-platform-themes-default-entity-master-list-view.component-DyDa_hyd.mjs.map +0 -1
  107. package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-Ua3ZA5hk.mjs +0 -101
  108. package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-Ua3ZA5hk.mjs.map +0 -1
  109. package/fesm2022/acorex-platform-themes-default-entity-master-single-view.component-eMBby9k4.mjs.map +0 -1
  110. package/fesm2022/acorex-platform-themes-default-error-401.component-cfREo88K.mjs.map +0 -1
  111. package/fesm2022/acorex-platform-themes-default-error-404.component-CdCV5ZoA.mjs.map +0 -1
  112. package/fesm2022/acorex-platform-themes-default-error-offline.component-E7SzBcAt.mjs +0 -19
  113. package/fesm2022/acorex-platform-themes-default-error-offline.component-E7SzBcAt.mjs.map +0 -1
  114. package/fesm2022/acorex-platform-themes-shared-icon-chooser-column.component-C0EpfU2k.mjs.map +0 -1
  115. package/fesm2022/acorex-platform-themes-shared-icon-chooser-view.component-9W52W6Nu.mjs.map +0 -1
  116. package/fesm2022/acorex-platform-themes-shared-settings.provider-DSs1o1M6.mjs.map +0 -1
  117. package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-column.component-DTnfRy5f.mjs +0 -65
  118. package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-column.component-DTnfRy5f.mjs.map +0 -1
  119. package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-view.component-DY0JtT1v.mjs +0 -64
  120. package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-view.component-DY0JtT1v.mjs.map +0 -1
  121. package/layout/components/index.d.ts +0 -1669
  122. package/runtime/index.d.ts +0 -307
  123. package/workflow/index.d.ts +0 -1808
  124. /package/{index.d.ts → types/acorex-platform.d.ts} +0 -0
@@ -1,8 +1,12 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, inject, Injectable, computed, input, effect, Directive, EventEmitter, HostListener, Output, ViewContainerRef, ElementRef, signal, output, DestroyRef, Renderer2, untracked, Injector, runInInjectionContext, provideAppInitializer, NgModule, Pipe } from '@angular/core';
2
+ import { InjectionToken, inject, Injectable, Directive, computed, Injector, ChangeDetectionStrategy, Component, input, ElementRef, ViewContainerRef, signal, effect, runInInjectionContext, Optional, Inject, NgModule, EventEmitter, HostListener, Output, provideAppInitializer, Pipe } from '@angular/core';
3
+ import { get, isPlainObject, set, isNil, isEmpty, isArray, merge, isObjectLike, transform, isEqual, differenceWith, union, cloneDeep, has, sortBy, isUndefined, endsWith, startsWith, includes, lte, gte, lt, gt, orderBy } from 'lodash-es';
3
4
  import { signalStore, withState, withComputed, withMethods, patchState } from '@ngrx/signals';
4
- import { get, isPlainObject, set, isArray, merge, isNil, isObjectLike, transform, isEmpty, isEqual, differenceWith, union, cloneDeep, isUndefined, endsWith, startsWith, includes, lte, gte, lt, gt, orderBy } from 'lodash-es';
5
+ import * as i1 from '@acorex/components/skeleton';
6
+ import { AXSkeletonModule } from '@acorex/components/skeleton';
5
7
  import { Subject, interval, fromEvent } from 'rxjs';
8
+ import { AXDataSource } from '@acorex/cdk/common';
9
+ import { resolveMultiLanguageString } from '@acorex/core/translation';
6
10
  import { AXCalendarService } from '@acorex/core/date-time';
7
11
  import { startWith, map, debounceTime } from 'rxjs/operators';
8
12
 
@@ -17,10 +21,10 @@ class AXPActivityLogService {
17
21
  async getHistoryByIds(refId, refType, ids) {
18
22
  return (await Promise.all(this.providers?.map((p) => p.getHistoryByIds(refId, refType, ids)) ?? [])).flat();
19
23
  }
20
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPActivityLogService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
21
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPActivityLogService, providedIn: 'root' }); }
24
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPActivityLogService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
25
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPActivityLogService, providedIn: 'root' }); }
22
26
  }
23
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPActivityLogService, decorators: [{
27
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPActivityLogService, decorators: [{
24
28
  type: Injectable,
25
29
  args: [{ providedIn: 'root' }]
26
30
  }] });
@@ -170,10 +174,10 @@ class AXPColorPaletteService {
170
174
  const uniquePalettes = allPalettes.filter((palette, index, self) => index === self.findIndex((p) => p.name === palette.name));
171
175
  this.cache = uniquePalettes;
172
176
  }
173
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPColorPaletteService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
174
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPColorPaletteService, providedIn: 'root' }); }
177
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPColorPaletteService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
178
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPColorPaletteService, providedIn: 'root' }); }
175
179
  }
176
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPColorPaletteService, decorators: [{
180
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPColorPaletteService, decorators: [{
177
181
  type: Injectable,
178
182
  args: [{
179
183
  providedIn: 'root',
@@ -288,13 +292,241 @@ class AXPDefaultColorPalettesProvider extends AXPColorPaletteProvider {
288
292
  },
289
293
  ];
290
294
  }
291
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPDefaultColorPalettesProvider, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
292
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPDefaultColorPalettesProvider }); }
295
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPDefaultColorPalettesProvider, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
296
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPDefaultColorPalettesProvider }); }
293
297
  }
294
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPDefaultColorPalettesProvider, decorators: [{
298
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPDefaultColorPalettesProvider, decorators: [{
295
299
  type: Injectable
296
300
  }] });
297
301
 
302
+ //#region ---- Column Width Provider ----
303
+ /**
304
+ * Injection token for column width providers
305
+ * Use this to register multiple column width providers with multi: true
306
+ *
307
+ * @example
308
+ * ```typescript
309
+ * providers: [
310
+ * {
311
+ * provide: AXP_COLUMN_WIDTH_PROVIDER,
312
+ * useValue: {
313
+ * matchers: [
314
+ * { name: 'title', width: '300px', priority: 10 },
315
+ * { widgetType: /text-box/i, width: '200px' }
316
+ * ],
317
+ * priority: 150
318
+ * },
319
+ * multi: true
320
+ * }
321
+ * ]
322
+ * ```
323
+ */
324
+ const AXP_COLUMN_WIDTH_PROVIDER = new InjectionToken('AXP_COLUMN_WIDTH_PROVIDER');
325
+ //#endregion
326
+
327
+ //#region ---- Column Width Service ----
328
+ /**
329
+ * Service for resolving column widths based on registered providers
330
+ * Supports matching by column name (priority) and widget type (fallback)
331
+ * Uses multi-provider pattern for extensibility
332
+ */
333
+ class AXPColumnWidthService {
334
+ constructor() {
335
+ //#region ---- Services & Dependencies ----
336
+ this.providers = inject(AXP_COLUMN_WIDTH_PROVIDER, {
337
+ optional: true,
338
+ }) ?? [];
339
+ }
340
+ //#region ---- Public Methods ----
341
+ /**
342
+ * Resolve width for a column based on registered providers
343
+ * Only returns a width if column doesn't already have one set
344
+ *
345
+ * @param column Column to resolve width for
346
+ * @returns Resolved width string (normalized) or undefined if no match or column already has width
347
+ */
348
+ resolveWidth(column) {
349
+ // If column already has a width set, don't override
350
+ const existingWidth = column.width || column.options?.width;
351
+ if (existingWidth) {
352
+ return undefined;
353
+ }
354
+ // Get widget type from column (support both widget.type and showAs.type)
355
+ const widgetType = column.widget?.type || column.showAs?.type;
356
+ // Collect all matchers from all providers
357
+ const allMatchers = this.collectMatchers();
358
+ // Try name-based matches first (higher priority)
359
+ const nameMatch = this.findNameMatch(column.name, allMatchers);
360
+ if (nameMatch) {
361
+ return this.normalizeWidth(nameMatch.width);
362
+ }
363
+ // Fallback to widget-type matches (case-insensitive)
364
+ if (widgetType) {
365
+ const widgetMatch = this.findWidgetTypeMatch(widgetType, allMatchers);
366
+ if (widgetMatch) {
367
+ return this.normalizeWidth(widgetMatch.width);
368
+ }
369
+ }
370
+ return undefined;
371
+ }
372
+ /**
373
+ * Apply resolved width to a column (mutates the column)
374
+ * Only applies if column doesn't already have a width
375
+ *
376
+ * @param column Column to apply width to
377
+ * @returns true if width was applied, false if column already had width or no match found
378
+ */
379
+ applyWidth(column) {
380
+ const width = this.resolveWidth(column);
381
+ if (!width) {
382
+ return false;
383
+ }
384
+ // Apply to the appropriate property
385
+ if (column.options) {
386
+ column.options.width = width;
387
+ }
388
+ else {
389
+ column.width = width;
390
+ }
391
+ return true;
392
+ }
393
+ //#endregion
394
+ //#region ---- Private Methods ----
395
+ /**
396
+ * Collect all matchers from all providers, sorted by provider priority and matcher priority
397
+ */
398
+ collectMatchers() {
399
+ const allMatchers = [];
400
+ for (const provider of this.providers) {
401
+ const providerPriority = provider.priority ?? 100;
402
+ for (const matcher of provider.matchers) {
403
+ allMatchers.push({
404
+ matcher,
405
+ providerPriority,
406
+ });
407
+ }
408
+ }
409
+ // Sort by provider priority (descending), then by matcher priority (descending)
410
+ allMatchers.sort((a, b) => {
411
+ if (a.providerPriority !== b.providerPriority) {
412
+ return b.providerPriority - a.providerPriority; // Higher priority first
413
+ }
414
+ const priorityA = a.matcher.priority ?? 0;
415
+ const priorityB = b.matcher.priority ?? 0;
416
+ return priorityB - priorityA; // Higher priority first
417
+ });
418
+ return allMatchers;
419
+ }
420
+ /**
421
+ * Find first matching matcher by column name
422
+ * Name matches take precedence over widget type matches
423
+ */
424
+ findNameMatch(columnName, allMatchers) {
425
+ for (const { matcher } of allMatchers) {
426
+ if (!matcher.name) {
427
+ continue; // Skip if no name matcher
428
+ }
429
+ if (typeof matcher.name === 'string') {
430
+ // Exact string match (case-sensitive for names)
431
+ if (matcher.name === columnName) {
432
+ return matcher;
433
+ }
434
+ }
435
+ else if (matcher.name instanceof RegExp) {
436
+ // RegExp match
437
+ if (matcher.name.test(columnName)) {
438
+ return matcher;
439
+ }
440
+ }
441
+ }
442
+ return undefined;
443
+ }
444
+ /**
445
+ * Find first matching matcher by widget type (case-insensitive)
446
+ */
447
+ findWidgetTypeMatch(widgetType, allMatchers) {
448
+ const widgetTypeLower = widgetType.toLowerCase();
449
+ for (const { matcher } of allMatchers) {
450
+ if (!matcher.widgetType) {
451
+ continue; // Skip if no widget type matcher
452
+ }
453
+ if (typeof matcher.widgetType === 'string') {
454
+ // Case-insensitive string match
455
+ if (matcher.widgetType.toLowerCase() === widgetTypeLower) {
456
+ return matcher;
457
+ }
458
+ }
459
+ else if (matcher.widgetType instanceof RegExp) {
460
+ // RegExp match (should already be case-insensitive if needed, but we'll test case-insensitively)
461
+ // Create a new regex with case-insensitive flag if not already present
462
+ let regex = matcher.widgetType;
463
+ if (!regex.flags.includes('i')) {
464
+ regex = new RegExp(regex.source, regex.flags + 'i');
465
+ }
466
+ if (regex.test(widgetType)) {
467
+ return matcher;
468
+ }
469
+ }
470
+ }
471
+ return undefined;
472
+ }
473
+ /**
474
+ * Normalize width value to string format
475
+ * Numbers are converted to pixels (e.g., 150 -> '150px')
476
+ * Strings are preserved as-is (supports any CSS unit)
477
+ */
478
+ normalizeWidth(width) {
479
+ if (typeof width === 'number') {
480
+ return `${width}px`;
481
+ }
482
+ return width;
483
+ }
484
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPColumnWidthService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
485
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPColumnWidthService, providedIn: 'root' }); }
486
+ }
487
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPColumnWidthService, decorators: [{
488
+ type: Injectable,
489
+ args: [{
490
+ providedIn: 'root',
491
+ }]
492
+ }] });
493
+
494
+ //#region ---- Column Width Types ----
495
+ //#endregion
496
+
497
+ //#region ---- Default Column Width Provider ----
498
+ /**
499
+ * Default column width configuration
500
+ * Migrated from DEFAULT_COLUMN_WIDTHS in column-width.middleware.ts
501
+ * Provides sensible defaults for common column names
502
+ */
503
+ const defaultColumnWidthProvider = {
504
+ priority: 100,
505
+ matchers: [
506
+ // Priority: name-based matches (higher priority = more specific)
507
+ { name: 'code', width: '150px', priority: 10 },
508
+ { name: 'name', width: '250px', priority: 10 },
509
+ { name: 'title', width: '250px', priority: 10 },
510
+ { name: 'description', width: '350px', priority: 10 },
511
+ { name: 'note', width: '350px', priority: 10 },
512
+ { name: 'notes', width: '350px', priority: 10 },
513
+ { name: 'content', width: '500px', priority: 10 },
514
+ { name: 'level', width: '100px', priority: 10 },
515
+ { name: 'order', width: '100px', priority: 10 },
516
+ { name: 'phones', width: '300px', priority: 10 },
517
+ { name: 'emails', width: '300px', priority: 10 },
518
+ ],
519
+ };
520
+ //#endregion
521
+
522
+ class AXPComponentSlot {
523
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPComponentSlot, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
524
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: AXPComponentSlot, isStandalone: true, ngImport: i0 }); }
525
+ }
526
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPComponentSlot, decorators: [{
527
+ type: Directive
528
+ }] });
529
+
298
530
  function extractNestedFieldsWildcard(obj, basePath, fields) {
299
531
  const result = {};
300
532
  if (fields.length === 1 && fields[0] === '*') {
@@ -313,7 +545,41 @@ function setSmart(obj, smartPath, value) {
313
545
  const lastPart = pathParts[pathParts.length - 1];
314
546
  const fieldMatch = lastPart.match(/^\{(.+)\}$/);
315
547
  if (!fieldMatch) {
548
+ // Fix: If value is undefined and we're setting a nested property,
549
+ // check if the parent object exists and if setting this would result in
550
+ // all properties being undefined. If so, set the parent to null instead.
551
+ if (isNil(value) && pathParts.length > 1) {
552
+ const parentPath = pathParts.slice(0, -1).join('.');
553
+ const parentObj = get(obj, parentPath);
554
+ // If parent is already null/undefined, don't recreate the object structure
555
+ if (isNil(parentObj)) {
556
+ return obj;
557
+ }
558
+ // Check if parent is a plain object (not array, not null)
559
+ if (isPlainObject(parentObj)) {
560
+ const existingKeys = Object.keys(parentObj);
561
+ // Check if all existing properties are null/undefined using lodash
562
+ const allNil = isEmpty(existingKeys) || existingKeys.every((key) => isNil(parentObj[key]));
563
+ if (allNil) {
564
+ // Set parent to null instead of creating/keeping an object with all undefined properties
565
+ set(obj, parentPath, null);
566
+ return obj;
567
+ }
568
+ }
569
+ }
316
570
  set(obj, smartPath, value);
571
+ // After setting, check again if parent should be null using lodash
572
+ if (isNil(value) && pathParts.length > 1) {
573
+ const parentPath = pathParts.slice(0, -1).join('.');
574
+ const parentObj = get(obj, parentPath);
575
+ if (isPlainObject(parentObj)) {
576
+ // Use lodash to check if all properties are null/undefined
577
+ const allNil = Object.keys(parentObj).every((key) => isNil(parentObj[key]));
578
+ if (allNil) {
579
+ set(obj, parentPath, null);
580
+ }
581
+ }
582
+ }
317
583
  return obj;
318
584
  }
319
585
  const fields = fieldMatch[1].split(',').map((f) => f.trim());
@@ -525,9 +791,10 @@ function getEnumValues(enumType) {
525
791
 
526
792
  class AXPContextChangeEvent {
527
793
  }
528
- const AXPContextStore = signalStore({
529
- providedIn: 'root',
530
- },
794
+ //#endregion
795
+ //#region ---- Context signal store ----
796
+ // Shared reactive context: root injector has a default instance; widget/layout trees
797
+ const AXPContextStore = signalStore(
531
798
  // Initial State
532
799
  withState(() => ({
533
800
  data: {}, // Shared context data
@@ -577,7 +844,7 @@ withMethods((store) => ({
577
844
  lastChange: changeEvent,
578
845
  });
579
846
  },
580
- patch(context) {
847
+ patch(context, skipDirtyTracking = false) {
581
848
  const currentData = cloneDeep(store.data());
582
849
  // Update the value and prepare the change event
583
850
  const updatedData = { ...currentData, ...context };
@@ -587,7 +854,7 @@ withMethods((store) => ({
587
854
  };
588
855
  // Patch the state
589
856
  patchState(store, {
590
- previousSnapshot: store.snapshot(), // Save the previous state
857
+ ...(skipDirtyTracking ? {} : { previousSnapshot: store.snapshot() }),
591
858
  data: updatedData,
592
859
  state: 'changed',
593
860
  lastChange: changeEvent,
@@ -635,7 +902,432 @@ withMethods((store) => ({
635
902
  getValue(path) {
636
903
  return getSmart(store.data(), path);
637
904
  },
905
+ // Check if a path exists in the context
906
+ hasValue(path) {
907
+ return has(store.data(), path);
908
+ },
638
909
  })));
910
+ //#endregion
911
+
912
+ class AXPExpressionEvaluatorScopeProviderContext {
913
+ constructor() {
914
+ this.scopes = {};
915
+ }
916
+ addScope(namespace, functions) {
917
+ this.scopes[namespace] = { ...this.scopes[namespace], ...functions };
918
+ }
919
+ getScopes() {
920
+ return this.scopes;
921
+ }
922
+ }
923
+ const AXP_EXPRESSION_EVALUATOR_SCOPE_PROVIDER = new InjectionToken('AXP_EXPRESSION_EVALUATOR_SCOPE_PROVIDER');
924
+ class AXPExpressionEvaluatorScopeProviderService {
925
+ constructor() {
926
+ this.injector = inject(Injector);
927
+ this.cache = null;
928
+ }
929
+ async load() {
930
+ if (this.cache)
931
+ return;
932
+ const raw = this.injector.get(AXP_EXPRESSION_EVALUATOR_SCOPE_PROVIDER, [], { optional: true });
933
+ const providers = Array.isArray(raw)
934
+ ? raw
935
+ : typeof raw === 'function'
936
+ ? raw()
937
+ : [];
938
+ const context = new AXPExpressionEvaluatorScopeProviderContext();
939
+ for (const provider of providers) {
940
+ // Resolve lazy-loaded providers (provideLazyProvider useFactory returns Promise<Provider>)
941
+ const resolved = await Promise.resolve(provider);
942
+ if (!resolved || typeof resolved.provide !== 'function') {
943
+ continue;
944
+ }
945
+ await resolved.provide(context);
946
+ }
947
+ this.cache = context.getScopes();
948
+ }
949
+ async getScopesAsync() {
950
+ await this.load();
951
+ return this.cache || {};
952
+ }
953
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPExpressionEvaluatorScopeProviderService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
954
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPExpressionEvaluatorScopeProviderService, providedIn: 'root' }); }
955
+ }
956
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPExpressionEvaluatorScopeProviderService, decorators: [{
957
+ type: Injectable,
958
+ args: [{ providedIn: 'root' }]
959
+ }] });
960
+
961
+ class AXPExpressionEvaluatorService {
962
+ constructor() {
963
+ // Memoization cache for compiled expressions
964
+ this.expressionCache = new Map();
965
+ this.providerService = inject(AXPExpressionEvaluatorScopeProviderService);
966
+ }
967
+ getOrCompileFunction(expression) {
968
+ if (!this.expressionCache.has(expression)) {
969
+ // Check if expression contains multiple statements (has semicolons or newlines)
970
+ const hasMultipleStatements = expression.includes(';') || expression.includes('\n');
971
+ let fn;
972
+ if (hasMultipleStatements) {
973
+ // For multiple statements, execute them in sequence and return the last expression
974
+ fn = new Function('scope', `with (scope) { return (async function() { ${expression} })(); }`);
975
+ }
976
+ else {
977
+ // For single expressions, use return
978
+ fn = new Function('scope', `with (scope) { return (async function() { return ${expression}; })(); }`);
979
+ }
980
+ this.expressionCache.set(expression, fn);
981
+ }
982
+ return this.expressionCache.get(expression);
983
+ }
984
+ async getMergedScope(userScope) {
985
+ const pluginScopes = await this.providerService.getScopesAsync();
986
+ // Merge pluginScopes and userScope (userScope takes precedence)
987
+ return { ...pluginScopes, ...userScope };
988
+ }
989
+ async evaluate(source, scope = {}) {
990
+ try {
991
+ const mergedScope = await this.getMergedScope(scope);
992
+ if (typeof source === 'string' && source.includes('{{')) {
993
+ return await this.evaluateStringExpression(source, mergedScope);
994
+ }
995
+ else if (Array.isArray(source)) {
996
+ const evaluatedArray = [];
997
+ for (const item of source) {
998
+ evaluatedArray.push(await this.evaluate(item, mergedScope));
999
+ }
1000
+ return evaluatedArray;
1001
+ }
1002
+ else if (typeof source === 'object' && source !== null) {
1003
+ const evaluatedObject = {};
1004
+ for (const key in source) {
1005
+ if (source.hasOwnProperty(key)) {
1006
+ evaluatedObject[key] = await this.evaluate(source[key], mergedScope);
1007
+ }
1008
+ }
1009
+ return evaluatedObject;
1010
+ }
1011
+ else {
1012
+ return source;
1013
+ }
1014
+ }
1015
+ catch (error) {
1016
+ console.error('Expression evaluator - Error evaluating expression:', source, error);
1017
+ return false;
1018
+ }
1019
+ }
1020
+ async evaluateStringExpression(templateExpression, scope) {
1021
+ // Check if the input is exactly a single {{ ... }} expression (handle multiline)
1022
+ const exactMatch = templateExpression.match(/^\s*\{\{\s*([\s\S]*?)\s*\}\}\s*$/);
1023
+ if (exactMatch) {
1024
+ const expression = exactMatch[1];
1025
+ const sandbox = this.getOrCompileFunction(expression);
1026
+ const result = await sandbox(scope);
1027
+ return result;
1028
+ }
1029
+ // Otherwise, interpolate all {{ ... }} expressions in the string
1030
+ const regex = /\{\{\s*([\s\S]*?)\s*\}\}/g;
1031
+ // Collect all matches and their positions
1032
+ const matches = [];
1033
+ let match;
1034
+ while ((match = regex.exec(templateExpression)) !== null) {
1035
+ matches.push({
1036
+ expression: match[1],
1037
+ start: match.index,
1038
+ end: regex.lastIndex,
1039
+ raw: match[0],
1040
+ });
1041
+ }
1042
+ // Evaluate all expressions in parallel
1043
+ const values = await Promise.all(matches.map((m) => {
1044
+ const sandbox = this.getOrCompileFunction(m.expression);
1045
+ return sandbox(scope);
1046
+ }));
1047
+ // Reconstruct the string with evaluated values
1048
+ let result = '';
1049
+ let lastIndex = 0;
1050
+ matches.forEach((m, i) => {
1051
+ result += templateExpression.slice(lastIndex, m.start);
1052
+ const value = values[i];
1053
+ result += value !== undefined && value !== null ? value : '';
1054
+ lastIndex = m.end;
1055
+ });
1056
+ result += templateExpression.slice(lastIndex);
1057
+ return result;
1058
+ }
1059
+ isExpression(expression) {
1060
+ if (typeof expression === 'string') {
1061
+ return expression.trim().startsWith('{{') && expression.trim().endsWith('}}');
1062
+ }
1063
+ return false;
1064
+ }
1065
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPExpressionEvaluatorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1066
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPExpressionEvaluatorService, providedIn: 'root' }); }
1067
+ }
1068
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPExpressionEvaluatorService, decorators: [{
1069
+ type: Injectable,
1070
+ args: [{ providedIn: 'root' }]
1071
+ }] });
1072
+
1073
+ class AXPComponentSlotPlaceholderComponent {
1074
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPComponentSlotPlaceholderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1075
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.9", type: AXPComponentSlotPlaceholderComponent, isStandalone: true, selector: "axp-component-slot-placeholder", ngImport: i0, template: `<div>
1076
+ <ax-skeleton class="ax-w-full ax-h-10 ax-rounded-md"></ax-skeleton>
1077
+ </div>`, isInline: true, dependencies: [{ kind: "ngmodule", type: AXSkeletonModule }, { kind: "component", type: i1.AXSkeletonComponent, selector: "ax-skeleton", inputs: ["animated"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1078
+ }
1079
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPComponentSlotPlaceholderComponent, decorators: [{
1080
+ type: Component,
1081
+ args: [{
1082
+ selector: 'axp-component-slot-placeholder',
1083
+ template: `<div>
1084
+ <ax-skeleton class="ax-w-full ax-h-10 ax-rounded-md"></ax-skeleton>
1085
+ </div>`,
1086
+ changeDetection: ChangeDetectionStrategy.OnPush,
1087
+ imports: [AXSkeletonModule],
1088
+ standalone: true,
1089
+ }]
1090
+ }] });
1091
+
1092
+ class AXPComponentSlotRegistryService {
1093
+ constructor() {
1094
+ this.registry = new Map();
1095
+ }
1096
+ register(slotName, config) {
1097
+ let configs = this.registry.get(slotName) || [];
1098
+ // Check if the component is already registered in this slot
1099
+ const isDuplicate = configs.some(existingConfig => existingConfig.name === config.name);
1100
+ if (!isDuplicate) {
1101
+ configs = [...configs, config]; // Add the new configuration
1102
+ this.registry.set(slotName, configs);
1103
+ }
1104
+ }
1105
+ get(slotName) {
1106
+ return this.registry.get(slotName) || [];
1107
+ }
1108
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPComponentSlotRegistryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1109
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPComponentSlotRegistryService, providedIn: 'root' }); }
1110
+ }
1111
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPComponentSlotRegistryService, decorators: [{
1112
+ type: Injectable,
1113
+ args: [{
1114
+ providedIn: 'root'
1115
+ }]
1116
+ }] });
1117
+
1118
+ class AXPComponentSlotDirective {
1119
+ constructor() {
1120
+ this.name = input.required(...(ngDevMode ? [{ debugName: "name" }] : /* istanbul ignore next */ []));
1121
+ this.host = input(...(ngDevMode ? [undefined, { debugName: "host" }] : /* istanbul ignore next */ []));
1122
+ this.context = input(...(ngDevMode ? [undefined, { debugName: "context" }] : /* istanbul ignore next */ []));
1123
+ this.elementRef = inject(ElementRef);
1124
+ this.registryService = inject(AXPComponentSlotRegistryService);
1125
+ this.injector = inject(Injector);
1126
+ this.evaluator = inject(AXPExpressionEvaluatorService);
1127
+ this.viewContainerRef = inject(ViewContainerRef);
1128
+ this.contextStore = inject(AXPContextStore);
1129
+ this.isEmpty = computed(() => this._viewCount() === 0, ...(ngDevMode ? [{ debugName: "isEmpty" }] : /* istanbul ignore next */ []));
1130
+ // Create a signal to store the count of children
1131
+ this._viewCount = signal(0, ...(ngDevMode ? [{ debugName: "_viewCount" }] : /* istanbul ignore next */ []));
1132
+ // Track component references for updates
1133
+ this.componentRefs = [];
1134
+ // Track placeholder references for replacement
1135
+ this.placeholderRefs = new Map();
1136
+ // Watch for context changes and update component instances
1137
+ effect(() => {
1138
+ const currentContext = this.context();
1139
+ const currentHost = this.host();
1140
+ // Update all component references with new context and host
1141
+ this.componentRefs.forEach((componentRef) => {
1142
+ if (componentRef.instance) {
1143
+ Object.assign(componentRef.instance, {
1144
+ host: currentHost,
1145
+ context: currentContext,
1146
+ });
1147
+ }
1148
+ });
1149
+ });
1150
+ }
1151
+ async ngOnInit() {
1152
+ await this.loadComponents();
1153
+ // Update the signal after loading
1154
+ this._viewCount.set(this.viewContainerRef.length);
1155
+ }
1156
+ async loadComponents() {
1157
+ this.viewContainerRef.clear();
1158
+ // Clear previous component references
1159
+ this.componentRefs = [];
1160
+ this.placeholderRefs.clear();
1161
+ const configs = sortBy(this.registryService.get(this.name()), (c) => c.priority ?? 0);
1162
+ if (!configs) {
1163
+ console.error(`No component found for slot ${this.name()}`);
1164
+ return;
1165
+ }
1166
+ // Evaluate conditions and check features in parallel for performance
1167
+ const results = await Promise.all(configs.map(async (c) => {
1168
+ // Check condition if provided
1169
+ const conditionPassed = c.condition ? await this.evaluateCondition(c.condition) : true;
1170
+ // Check features if provided
1171
+ // const featuresPassed =
1172
+ // c.features && c.features.length > 0 ? this.sessionService.isFeatureEnabled(...c.features) : true;
1173
+ return {
1174
+ config: c,
1175
+ // visible: conditionPassed && featuresPassed,
1176
+ visible: conditionPassed,
1177
+ };
1178
+ }));
1179
+ // Filter visible components while preserving priority order
1180
+ const slots = results.filter((r) => r.visible).map((r) => r.config);
1181
+ // Create skeleton placeholders immediately in priority order
1182
+ slots.forEach((config, index) => {
1183
+ const placeholderRef = this.viewContainerRef.createComponent(AXPComponentSlotPlaceholderComponent);
1184
+ this.placeholderRefs.set(index, placeholderRef);
1185
+ });
1186
+ // Load all components in parallel and replace placeholders as they become ready
1187
+ const loadPromises = slots.map(async (config, index) => {
1188
+ let component;
1189
+ let options = {};
1190
+ // load component
1191
+ if (typeof config.loadComponent === 'function') {
1192
+ await runInInjectionContext(this.injector, async () => {
1193
+ component = await config.loadComponent?.();
1194
+ });
1195
+ }
1196
+ else if (config.component) {
1197
+ component = config.component;
1198
+ }
1199
+ // load options
1200
+ if (typeof config.options === 'function') {
1201
+ await runInInjectionContext(this.injector, async () => {
1202
+ const fun = config.options;
1203
+ options = await fun();
1204
+ });
1205
+ }
1206
+ else if (config.options) {
1207
+ options = await this.evaluator.evaluate(config.options, {});
1208
+ }
1209
+ // Replace placeholder with actual component as soon as it's ready
1210
+ if (!component) {
1211
+ console.warn(`Component failed to load for slot ${this.name()} at index ${index}`);
1212
+ // Remove placeholder if component failed to load
1213
+ const placeholderRef = this.placeholderRefs.get(index);
1214
+ if (placeholderRef) {
1215
+ placeholderRef.destroy();
1216
+ this.placeholderRefs.delete(index);
1217
+ }
1218
+ return;
1219
+ }
1220
+ // Get the placeholder reference at this index
1221
+ const placeholderRef = this.placeholderRefs.get(index);
1222
+ if (!placeholderRef) {
1223
+ console.warn(`Placeholder not found for index ${index}`);
1224
+ return;
1225
+ }
1226
+ // Get the index of the placeholder in the view container
1227
+ const placeholderIndex = this.viewContainerRef.indexOf(placeholderRef.hostView);
1228
+ // Remove the placeholder
1229
+ placeholderRef.destroy();
1230
+ this.placeholderRefs.delete(index);
1231
+ // Create the actual component at the same position
1232
+ const componentRef = this.viewContainerRef.createComponent(component, { index: placeholderIndex });
1233
+ // Store the component reference for future updates
1234
+ this.componentRefs.push(componentRef);
1235
+ Object.assign(componentRef.instance, {
1236
+ host: this.host(),
1237
+ context: this.context(),
1238
+ ...options,
1239
+ });
1240
+ });
1241
+ // Wait for all components to finish loading (they render as they become ready)
1242
+ await Promise.all(loadPromises);
1243
+ }
1244
+ async evaluateCondition(condition) {
1245
+ if (typeof condition === 'string') {
1246
+ const result = await this.evaluator.evaluate(condition, {});
1247
+ return result;
1248
+ }
1249
+ return condition(this.contextStore.data());
1250
+ //return condition(this.context());
1251
+ }
1252
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPComponentSlotDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1253
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: AXPComponentSlotDirective, isStandalone: false, selector: "axp-component-slot", inputs: { name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: true, transformFunction: null }, host: { classPropertyName: "host", publicName: "host", isSignal: true, isRequired: false, transformFunction: null }, context: { classPropertyName: "context", publicName: "context", isSignal: true, isRequired: false, transformFunction: null } }, exportAs: ["slot"], ngImport: i0 }); }
1254
+ }
1255
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPComponentSlotDirective, decorators: [{
1256
+ type: Directive,
1257
+ args: [{
1258
+ selector: 'axp-component-slot',
1259
+ standalone: false,
1260
+ exportAs: 'slot',
1261
+ }]
1262
+ }], ctorParameters: () => [], propDecorators: { name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: true }] }], host: [{ type: i0.Input, args: [{ isSignal: true, alias: "host", required: false }] }], context: [{ type: i0.Input, args: [{ isSignal: true, alias: "context", required: false }] }] } });
1263
+
1264
+ class AXPComponentSlotModule {
1265
+ static forRoot(configs) {
1266
+ return {
1267
+ ngModule: AXPComponentSlotModule,
1268
+ providers: [
1269
+ {
1270
+ provide: 'AXPComponentSlotModuleFactory',
1271
+ useFactory: (registry) => () => {
1272
+ if (configs) {
1273
+ for (const [key, value] of Object.entries(configs)) {
1274
+ value.forEach(v => {
1275
+ registry.register(key, v);
1276
+ });
1277
+ }
1278
+ }
1279
+ },
1280
+ deps: [AXPComponentSlotRegistryService],
1281
+ multi: true
1282
+ }
1283
+ ]
1284
+ };
1285
+ }
1286
+ static forChild(configs) {
1287
+ return {
1288
+ ngModule: AXPComponentSlotModule,
1289
+ providers: [
1290
+ {
1291
+ provide: 'AXPComponentSlotModuleFactory',
1292
+ useFactory: (registry) => () => {
1293
+ if (configs) {
1294
+ for (const [key, value] of Object.entries(configs)) {
1295
+ value.forEach(v => {
1296
+ registry.register(key, v);
1297
+ });
1298
+ }
1299
+ }
1300
+ },
1301
+ deps: [AXPComponentSlotRegistryService],
1302
+ multi: true
1303
+ }
1304
+ ]
1305
+ };
1306
+ }
1307
+ /**
1308
+ * @ignore
1309
+ */
1310
+ constructor(instances) {
1311
+ instances?.forEach(f => {
1312
+ f();
1313
+ });
1314
+ }
1315
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPComponentSlotModule, deps: [{ token: 'AXPComponentSlotModuleFactory', optional: true }], target: i0.ɵɵFactoryTarget.NgModule }); }
1316
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.9", ngImport: i0, type: AXPComponentSlotModule, declarations: [AXPComponentSlotDirective], exports: [AXPComponentSlotDirective] }); }
1317
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPComponentSlotModule }); }
1318
+ }
1319
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPComponentSlotModule, decorators: [{
1320
+ type: NgModule,
1321
+ args: [{
1322
+ declarations: [AXPComponentSlotDirective],
1323
+ exports: [AXPComponentSlotDirective]
1324
+ }]
1325
+ }], ctorParameters: () => [{ type: undefined, decorators: [{
1326
+ type: Optional
1327
+ }, {
1328
+ type: Inject,
1329
+ args: ['AXPComponentSlotModuleFactory']
1330
+ }] }] });
639
1331
 
640
1332
  class AXPDataGenerator {
641
1333
  static uuid() {
@@ -829,11 +1521,14 @@ class AXPDataSourceDefinitionProviderService {
829
1521
  }
830
1522
  async items() {
831
1523
  const items = [];
832
- // Load from DI tokens
1524
+ // Load from DI tokens; resolve lazy providers (provideLazyProvider uses useFactory that returns Promise<T>)
833
1525
  if (Array.isArray(this.providers)) {
834
- for (const provider of this.providers) {
835
- set(provider, '__parent__', this);
836
- items.push(...(await provider.items()));
1526
+ for (const raw of this.providers) {
1527
+ const provider = await Promise.resolve(raw);
1528
+ if (provider && typeof provider.items === 'function') {
1529
+ set(provider, '__parent__', this);
1530
+ items.push(...(await provider.items()));
1531
+ }
837
1532
  }
838
1533
  }
839
1534
  return items;
@@ -841,52 +1536,32 @@ class AXPDataSourceDefinitionProviderService {
841
1536
  async get(name) {
842
1537
  return (await this.items()).find((c) => c.name == name);
843
1538
  }
844
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPDataSourceDefinitionProviderService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
845
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPDataSourceDefinitionProviderService, providedIn: 'root' }); }
1539
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPDataSourceDefinitionProviderService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1540
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPDataSourceDefinitionProviderService, providedIn: 'root' }); }
846
1541
  }
847
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPDataSourceDefinitionProviderService, decorators: [{
1542
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPDataSourceDefinitionProviderService, decorators: [{
848
1543
  type: Injectable,
849
1544
  args: [{ providedIn: 'root' }]
850
1545
  }] });
851
1546
 
852
- class AXPElementDataDirective {
853
- constructor(elementRef) {
854
- this.elementRef = elementRef;
855
- this.data = input(null, ...(ngDevMode ? [{ debugName: "data", alias: 'axp-data' }] : [{ alias: 'axp-data' }]));
856
- this.path = input('__data__', ...(ngDevMode ? [{ debugName: "path", alias: 'axp-data-path' }] : [{ alias: 'axp-data-path' }]));
857
- // Effect to update element data when inputs change
858
- this.updateEffect = effect(() => {
859
- const currentData = this.data();
860
- const currentPath = this.path();
861
- set(this.elementRef.nativeElement, currentPath, currentData);
862
- }, ...(ngDevMode ? [{ debugName: "updateEffect" }] : []));
863
- }
864
- ngOnInit() {
865
- // Initial data setup
866
- set(this.elementRef.nativeElement, this.path(), this.data());
867
- }
868
- /**
869
- * Get data from the element
870
- */
871
- getData() {
872
- return get(this.elementRef.nativeElement, this.path());
873
- }
874
- /**
875
- * Update data at runtime
876
- */
877
- setData(data) {
878
- set(this.elementRef.nativeElement, this.path(), data);
1547
+ // src/app/directives/grid-layout.directive.ts
1548
+ class AXPContentCheckerDirective {
1549
+ constructor() {
1550
+ this.viewContainerRef = inject(ViewContainerRef);
1551
+ this.elementRef = inject((ElementRef));
1552
+ this.isEmpty = computed(() => this.viewContainerRef.length === 0, ...(ngDevMode ? [{ debugName: "isEmpty" }] : /* istanbul ignore next */ []));
879
1553
  }
880
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPElementDataDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); }
881
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.3.12", type: AXPElementDataDirective, isStandalone: true, selector: "[axp-data]", inputs: { data: { classPropertyName: "data", publicName: "axp-data", isSignal: true, isRequired: false, transformFunction: null }, path: { classPropertyName: "path", publicName: "axp-data-path", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
1554
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPContentCheckerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1555
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: AXPContentCheckerDirective, isStandalone: true, selector: "[axp-content-checker]", exportAs: ["checker"], ngImport: i0 }); }
882
1556
  }
883
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPElementDataDirective, decorators: [{
1557
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPContentCheckerDirective, decorators: [{
884
1558
  type: Directive,
885
1559
  args: [{
886
- selector: '[axp-data]',
887
- standalone: true
1560
+ selector: '[axp-content-checker]',
1561
+ standalone: true,
1562
+ exportAs: 'checker'
888
1563
  }]
889
- }], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "axp-data", required: false }] }], path: [{ type: i0.Input, args: [{ isSignal: true, alias: "axp-data-path", required: false }] }] } });
1564
+ }] });
890
1565
 
891
1566
  class AXPDblClickDirective {
892
1567
  constructor() {
@@ -909,10 +1584,10 @@ class AXPDblClickDirective {
909
1584
  }
910
1585
  this.lastTap = currentTime;
911
1586
  }
912
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPDblClickDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
913
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.12", type: AXPDblClickDirective, isStandalone: true, selector: "[onDblClick]", outputs: { onDblClick: "onDblClick" }, host: { listeners: { "dblclick": "handleOnDblClick($event)", "touchend": "onTouchEnd($event)" } }, ngImport: i0 }); }
1587
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPDblClickDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1588
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: AXPDblClickDirective, isStandalone: true, selector: "[onDblClick]", outputs: { onDblClick: "onDblClick" }, host: { listeners: { "dblclick": "handleOnDblClick($event)", "touchend": "onTouchEnd($event)" } }, ngImport: i0 }); }
914
1589
  }
915
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPDblClickDirective, decorators: [{
1590
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPDblClickDirective, decorators: [{
916
1591
  type: Directive,
917
1592
  args: [{
918
1593
  selector: '[onDblClick]'
@@ -927,12 +1602,51 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
927
1602
  args: ['touchend', ['$event']]
928
1603
  }] } });
929
1604
 
1605
+ class AXPElementDataDirective {
1606
+ constructor(elementRef) {
1607
+ this.elementRef = elementRef;
1608
+ this.data = input(null, { ...(ngDevMode ? { debugName: "data" } : /* istanbul ignore next */ {}), alias: 'axp-data' });
1609
+ this.path = input('__data__', { ...(ngDevMode ? { debugName: "path" } : /* istanbul ignore next */ {}), alias: 'axp-data-path' });
1610
+ // Effect to update element data when inputs change
1611
+ this.updateEffect = effect(() => {
1612
+ const currentData = this.data();
1613
+ const currentPath = this.path();
1614
+ set(this.elementRef.nativeElement, currentPath, currentData);
1615
+ }, ...(ngDevMode ? [{ debugName: "updateEffect" }] : /* istanbul ignore next */ []));
1616
+ }
1617
+ ngOnInit() {
1618
+ // Initial data setup
1619
+ set(this.elementRef.nativeElement, this.path(), this.data());
1620
+ }
1621
+ /**
1622
+ * Get data from the element
1623
+ */
1624
+ getData() {
1625
+ return get(this.elementRef.nativeElement, this.path());
1626
+ }
1627
+ /**
1628
+ * Update data at runtime
1629
+ */
1630
+ setData(data) {
1631
+ set(this.elementRef.nativeElement, this.path(), data);
1632
+ }
1633
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPElementDataDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); }
1634
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: AXPElementDataDirective, isStandalone: true, selector: "[axp-data]", inputs: { data: { classPropertyName: "data", publicName: "axp-data", isSignal: true, isRequired: false, transformFunction: null }, path: { classPropertyName: "path", publicName: "axp-data-path", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
1635
+ }
1636
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPElementDataDirective, decorators: [{
1637
+ type: Directive,
1638
+ args: [{
1639
+ selector: '[axp-data]',
1640
+ standalone: true
1641
+ }]
1642
+ }], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "axp-data", required: false }] }], path: [{ type: i0.Input, args: [{ isSignal: true, alias: "axp-data-path", required: false }] }] } });
1643
+
930
1644
  // src/app/directives/grid-layout.directive.ts
931
1645
  class AXPGridLayoutDirective {
932
1646
  constructor(el, renderer) {
933
1647
  this.el = el;
934
1648
  this.renderer = renderer;
935
- this.options = input.required(...(ngDevMode ? [{ debugName: "options", alias: 'axp-grid-layout' }] : [{ alias: 'axp-grid-layout' }]));
1649
+ this.options = input.required({ ...(ngDevMode ? { debugName: "options" } : /* istanbul ignore next */ {}), alias: 'axp-grid-layout' });
936
1650
  }
937
1651
  ngOnChanges(changes) {
938
1652
  if (changes['options']) {
@@ -976,232 +1690,16 @@ class AXPGridLayoutDirective {
976
1690
  }
977
1691
  });
978
1692
  }
979
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPGridLayoutDirective, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive }); }
980
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.3.12", type: AXPGridLayoutDirective, isStandalone: true, selector: "[axp-grid-layout]", inputs: { options: { classPropertyName: "options", publicName: "axp-grid-layout", isSignal: true, isRequired: true, transformFunction: null } }, usesOnChanges: true, ngImport: i0 }); }
1693
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPGridLayoutDirective, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive }); }
1694
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: AXPGridLayoutDirective, isStandalone: true, selector: "[axp-grid-layout]", inputs: { options: { classPropertyName: "options", publicName: "axp-grid-layout", isSignal: true, isRequired: true, transformFunction: null } }, usesOnChanges: true, ngImport: i0 }); }
981
1695
  }
982
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPGridLayoutDirective, decorators: [{
1696
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPGridLayoutDirective, decorators: [{
983
1697
  type: Directive,
984
1698
  args: [{
985
1699
  selector: '[axp-grid-layout]',
986
1700
  standalone: true,
987
1701
  }]
988
- }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "axp-grid-layout", required: true }] }] } });
989
-
990
- // src/app/directives/grid-layout.directive.ts
991
- class AXPContentCheckerDirective {
992
- constructor() {
993
- this.viewContainerRef = inject(ViewContainerRef);
994
- this.elementRef = inject((ElementRef));
995
- this.isEmpty = computed(() => this.viewContainerRef.length === 0, ...(ngDevMode ? [{ debugName: "isEmpty" }] : []));
996
- }
997
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPContentCheckerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
998
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.12", type: AXPContentCheckerDirective, isStandalone: true, selector: "[axp-content-checker]", exportAs: ["checker"], ngImport: i0 }); }
999
- }
1000
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPContentCheckerDirective, decorators: [{
1001
- type: Directive,
1002
- args: [{
1003
- selector: '[axp-content-checker]',
1004
- standalone: true,
1005
- exportAs: 'checker'
1006
- }]
1007
- }] });
1008
-
1009
- //#region ---- Imports ----
1010
- //#endregion
1011
- //#region ---- Directive ----
1012
- /**
1013
- * Fullscreen directive that provides CSS-based fullscreen functionality
1014
- * Usage: <element axFullscreen #fullscreen="axFullscreen"></element>
1015
- * Then: fullscreen.toggle() or fullscreen.enter() or fullscreen.exit()
1016
- */
1017
- class AXFullscreenDirective {
1018
- constructor(elementRef) {
1019
- this.elementRef = elementRef;
1020
- //#region ---- Properties ----
1021
- /**
1022
- * Current fullscreen state
1023
- */
1024
- this.isFullscreenState = signal(false, ...(ngDevMode ? [{ debugName: "isFullscreenState" }] : []));
1025
- /**
1026
- * Original element styles to restore
1027
- */
1028
- this.originalStyles = {};
1029
- /**
1030
- * Original parent element reference
1031
- */
1032
- this.originalParent = null;
1033
- /**
1034
- * Fullscreen container element
1035
- */
1036
- this.fullscreenContainer = null;
1037
- /**
1038
- * Fullscreen change event
1039
- */
1040
- this.fullscreenChange = output();
1041
- //#endregion
1042
- //#region ---- Constructor ----
1043
- this.destroyRef = inject(DestroyRef);
1044
- this.renderer = inject(Renderer2);
1045
- // Sync state changes to output
1046
- effect(() => {
1047
- const isFullscreen = this.isFullscreenState();
1048
- untracked(() => {
1049
- this.fullscreenChange.emit(isFullscreen);
1050
- });
1051
- });
1052
- }
1053
- //#endregion
1054
- //#region ---- Public API ----
1055
- /**
1056
- * Toggle fullscreen state
1057
- */
1058
- async toggle() {
1059
- if (this.isFullscreenState()) {
1060
- await this.exit();
1061
- }
1062
- else {
1063
- await this.enter();
1064
- }
1065
- }
1066
- /**
1067
- * Enter fullscreen mode using CSS
1068
- */
1069
- async enter() {
1070
- if (this.isFullscreenState()) {
1071
- return;
1072
- }
1073
- const element = this.elementRef.nativeElement;
1074
- try {
1075
- // Store original styles and parent
1076
- this.storeOriginalStyles(element);
1077
- this.originalParent = element.parentElement;
1078
- // Create fullscreen container
1079
- this.fullscreenContainer = this.renderer.createElement('div');
1080
- this.renderer.setStyle(this.fullscreenContainer, 'position', 'fixed');
1081
- this.renderer.setStyle(this.fullscreenContainer, 'top', '0');
1082
- this.renderer.setStyle(this.fullscreenContainer, 'left', '0');
1083
- this.renderer.setStyle(this.fullscreenContainer, 'width', '100vw');
1084
- this.renderer.setStyle(this.fullscreenContainer, 'height', '100vh');
1085
- this.renderer.setStyle(this.fullscreenContainer, 'z-index', '9999');
1086
- this.renderer.setStyle(this.fullscreenContainer, 'background-color', '#ffffff');
1087
- this.renderer.setStyle(this.fullscreenContainer, 'overflow', 'auto');
1088
- // Move element to container
1089
- this.renderer.appendChild(this.fullscreenContainer, element);
1090
- // Apply fullscreen styles to element
1091
- this.renderer.setStyle(element, 'position', 'relative');
1092
- this.renderer.setStyle(element, 'width', '100%');
1093
- this.renderer.setStyle(element, 'height', '100%');
1094
- this.renderer.setStyle(element, 'margin', '0');
1095
- this.renderer.setStyle(element, 'padding', '0');
1096
- // Append container to body
1097
- this.renderer.appendChild(document.body, this.fullscreenContainer);
1098
- // Prevent body scroll
1099
- this.renderer.setStyle(document.body, 'overflow', 'hidden');
1100
- this.isFullscreenState.set(true);
1101
- }
1102
- catch (error) {
1103
- console.error('Error entering fullscreen:', error);
1104
- this.restoreOriginalStyles(element);
1105
- }
1106
- }
1107
- /**
1108
- * Exit fullscreen mode
1109
- */
1110
- async exit() {
1111
- if (!this.isFullscreenState()) {
1112
- return;
1113
- }
1114
- const element = this.elementRef.nativeElement;
1115
- try {
1116
- // Restore body scroll
1117
- this.renderer.removeStyle(document.body, 'overflow');
1118
- // Move element back to original parent
1119
- if (this.fullscreenContainer && this.originalParent) {
1120
- this.renderer.removeChild(this.fullscreenContainer, element);
1121
- this.renderer.appendChild(this.originalParent, element);
1122
- // Remove container
1123
- this.renderer.removeChild(document.body, this.fullscreenContainer);
1124
- this.fullscreenContainer = null;
1125
- }
1126
- // Restore original styles
1127
- this.restoreOriginalStyles(element);
1128
- this.isFullscreenState.set(false);
1129
- }
1130
- catch (error) {
1131
- console.error('Error exiting fullscreen:', error);
1132
- }
1133
- }
1134
- /**
1135
- * Check if currently in fullscreen mode
1136
- */
1137
- isFullscreen() {
1138
- return this.isFullscreenState();
1139
- }
1140
- //#endregion
1141
- //#region ---- Private Methods ----
1142
- /**
1143
- * Store original element styles
1144
- */
1145
- storeOriginalStyles(element) {
1146
- const computedStyle = window.getComputedStyle(element);
1147
- this.originalStyles = {
1148
- position: computedStyle.position,
1149
- top: computedStyle.top,
1150
- left: computedStyle.left,
1151
- width: computedStyle.width,
1152
- height: computedStyle.height,
1153
- zIndex: computedStyle.zIndex,
1154
- backgroundColor: computedStyle.backgroundColor,
1155
- margin: computedStyle.margin,
1156
- padding: computedStyle.padding,
1157
- };
1158
- }
1159
- /**
1160
- * Restore original element styles
1161
- */
1162
- restoreOriginalStyles(element) {
1163
- if (!this.originalStyles) {
1164
- return;
1165
- }
1166
- // Restore each style property
1167
- Object.entries(this.originalStyles).forEach(([key, value]) => {
1168
- const styleKey = this.camelToKebabCase(key);
1169
- if (value) {
1170
- this.renderer.setStyle(element, styleKey, value);
1171
- }
1172
- else {
1173
- this.renderer.removeStyle(element, styleKey);
1174
- }
1175
- });
1176
- this.originalStyles = {};
1177
- }
1178
- /**
1179
- * Convert camelCase to kebab-case for CSS properties
1180
- */
1181
- camelToKebabCase(str) {
1182
- return str.replace(/([a-z0-9]|(?=[A-Z]))([A-Z])/g, '$1-$2').toLowerCase();
1183
- }
1184
- //#endregion
1185
- //#region ---- Lifecycle ----
1186
- ngOnDestroy() {
1187
- // Exit fullscreen if still active
1188
- if (this.isFullscreenState()) {
1189
- this.exit().catch(() => {
1190
- // Ignore errors during cleanup
1191
- });
1192
- }
1193
- }
1194
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXFullscreenDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); }
1195
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.12", type: AXFullscreenDirective, isStandalone: true, selector: "[axFullscreen]", outputs: { fullscreenChange: "fullscreenChange" }, exportAs: ["axFullscreen"], ngImport: i0 }); }
1196
- }
1197
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXFullscreenDirective, decorators: [{
1198
- type: Directive,
1199
- args: [{
1200
- selector: '[axFullscreen]',
1201
- standalone: true,
1202
- exportAs: 'axFullscreen',
1203
- }]
1204
- }], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { fullscreenChange: [{ type: i0.Output, args: ["fullscreenChange"] }] } });
1702
+ }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "axp-grid-layout", required: true }] }] } });
1205
1703
 
1206
1704
  const AXP_DISTRIBUTED_EVENT_LISTENER_PROVIDER = new InjectionToken('AXP_DISTRIBUTED_EVENT_LISTENER_PROVIDER');
1207
1705
 
@@ -1339,10 +1837,10 @@ class AXPDistributedEventListenerService {
1339
1837
  this.listenersByKey.clear();
1340
1838
  this.providersLoaded = false;
1341
1839
  }
1342
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPDistributedEventListenerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1343
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPDistributedEventListenerService, providedIn: 'root' }); }
1840
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPDistributedEventListenerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1841
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPDistributedEventListenerService, providedIn: 'root' }); }
1344
1842
  }
1345
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPDistributedEventListenerService, decorators: [{
1843
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPDistributedEventListenerService, decorators: [{
1346
1844
  type: Injectable,
1347
1845
  args: [{
1348
1846
  providedIn: 'root',
@@ -1466,168 +1964,16 @@ class AXPBroadcastEventService {
1466
1964
  // Cleanup multi-tab event history
1467
1965
  this.multiTabEventHistory.clear();
1468
1966
  }
1469
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPBroadcastEventService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1470
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPBroadcastEventService, providedIn: 'root' }); }
1967
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPBroadcastEventService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1968
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPBroadcastEventService, providedIn: 'root' }); }
1471
1969
  }
1472
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPBroadcastEventService, decorators: [{
1970
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPBroadcastEventService, decorators: [{
1473
1971
  type: Injectable,
1474
1972
  args: [{
1475
1973
  providedIn: 'root',
1476
1974
  }]
1477
1975
  }], ctorParameters: () => [] });
1478
1976
 
1479
- class AXPExpressionEvaluatorScopeProviderContext {
1480
- constructor() {
1481
- this.scopes = {};
1482
- }
1483
- addScope(namespace, functions) {
1484
- this.scopes[namespace] = { ...this.scopes[namespace], ...functions };
1485
- }
1486
- getScopes() {
1487
- return this.scopes;
1488
- }
1489
- }
1490
- const AXP_EXPRESSION_EVALUATOR_SCOPE_PROVIDER = new InjectionToken('AXP_EXPRESSION_EVALUATOR_SCOPE_PROVIDER');
1491
- class AXPExpressionEvaluatorScopeProviderService {
1492
- constructor() {
1493
- this.providers = inject(AXP_EXPRESSION_EVALUATOR_SCOPE_PROVIDER, { optional: true });
1494
- this.cache = null;
1495
- }
1496
- async load() {
1497
- if (this.cache)
1498
- return;
1499
- const context = new AXPExpressionEvaluatorScopeProviderContext();
1500
- if (Array.isArray(this.providers)) {
1501
- for (const provider of this.providers) {
1502
- await provider.provide(context);
1503
- }
1504
- }
1505
- this.cache = context.getScopes();
1506
- }
1507
- async getScopesAsync() {
1508
- await this.load();
1509
- return this.cache || {};
1510
- }
1511
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPExpressionEvaluatorScopeProviderService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1512
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPExpressionEvaluatorScopeProviderService, providedIn: 'root' }); }
1513
- }
1514
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPExpressionEvaluatorScopeProviderService, decorators: [{
1515
- type: Injectable,
1516
- args: [{ providedIn: 'root' }]
1517
- }] });
1518
-
1519
- class AXPExpressionEvaluatorService {
1520
- constructor() {
1521
- // Memoization cache for compiled expressions
1522
- this.expressionCache = new Map();
1523
- this.providerService = inject(AXPExpressionEvaluatorScopeProviderService);
1524
- }
1525
- getOrCompileFunction(expression) {
1526
- if (!this.expressionCache.has(expression)) {
1527
- // Check if expression contains multiple statements (has semicolons or newlines)
1528
- const hasMultipleStatements = expression.includes(';') || expression.includes('\n');
1529
- let fn;
1530
- if (hasMultipleStatements) {
1531
- // For multiple statements, execute them in sequence and return the last expression
1532
- fn = new Function('scope', `with (scope) { return (async function() { ${expression} })(); }`);
1533
- }
1534
- else {
1535
- // For single expressions, use return
1536
- fn = new Function('scope', `with (scope) { return (async function() { return ${expression}; })(); }`);
1537
- }
1538
- this.expressionCache.set(expression, fn);
1539
- }
1540
- return this.expressionCache.get(expression);
1541
- }
1542
- async getMergedScope(userScope) {
1543
- const pluginScopes = await this.providerService.getScopesAsync();
1544
- // Merge pluginScopes and userScope (userScope takes precedence)
1545
- return { ...pluginScopes, ...userScope };
1546
- }
1547
- async evaluate(source, scope = {}) {
1548
- try {
1549
- const mergedScope = await this.getMergedScope(scope);
1550
- if (typeof source === 'string' && source.includes('{{')) {
1551
- return await this.evaluateStringExpression(source, mergedScope);
1552
- }
1553
- else if (Array.isArray(source)) {
1554
- const evaluatedArray = [];
1555
- for (const item of source) {
1556
- evaluatedArray.push(await this.evaluate(item, mergedScope));
1557
- }
1558
- return evaluatedArray;
1559
- }
1560
- else if (typeof source === 'object' && source !== null) {
1561
- const evaluatedObject = {};
1562
- for (const key in source) {
1563
- if (source.hasOwnProperty(key)) {
1564
- evaluatedObject[key] = await this.evaluate(source[key], mergedScope);
1565
- }
1566
- }
1567
- return evaluatedObject;
1568
- }
1569
- else {
1570
- return source;
1571
- }
1572
- }
1573
- catch (error) {
1574
- console.error('Expression evaluator - Error evaluating expression:', source, error);
1575
- return false;
1576
- }
1577
- }
1578
- async evaluateStringExpression(templateExpression, scope) {
1579
- // Check if the input is exactly a single {{ ... }} expression (handle multiline)
1580
- const exactMatch = templateExpression.match(/^\s*\{\{\s*([\s\S]*?)\s*\}\}\s*$/);
1581
- if (exactMatch) {
1582
- const expression = exactMatch[1];
1583
- const sandbox = this.getOrCompileFunction(expression);
1584
- const result = await sandbox(scope);
1585
- return result;
1586
- }
1587
- // Otherwise, interpolate all {{ ... }} expressions in the string
1588
- const regex = /\{\{\s*([\s\S]*?)\s*\}\}/g;
1589
- // Collect all matches and their positions
1590
- const matches = [];
1591
- let match;
1592
- while ((match = regex.exec(templateExpression)) !== null) {
1593
- matches.push({
1594
- expression: match[1],
1595
- start: match.index,
1596
- end: regex.lastIndex,
1597
- raw: match[0],
1598
- });
1599
- }
1600
- // Evaluate all expressions in parallel
1601
- const values = await Promise.all(matches.map((m) => {
1602
- const sandbox = this.getOrCompileFunction(m.expression);
1603
- return sandbox(scope);
1604
- }));
1605
- // Reconstruct the string with evaluated values
1606
- let result = '';
1607
- let lastIndex = 0;
1608
- matches.forEach((m, i) => {
1609
- result += templateExpression.slice(lastIndex, m.start);
1610
- const value = values[i];
1611
- result += value !== undefined && value !== null ? value : '';
1612
- lastIndex = m.end;
1613
- });
1614
- result += templateExpression.slice(lastIndex);
1615
- return result;
1616
- }
1617
- isExpression(expression) {
1618
- if (typeof expression === 'string') {
1619
- return expression.includes('{{');
1620
- }
1621
- return false;
1622
- }
1623
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPExpressionEvaluatorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1624
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPExpressionEvaluatorService, providedIn: 'root' }); }
1625
- }
1626
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPExpressionEvaluatorService, decorators: [{
1627
- type: Injectable,
1628
- args: [{ providedIn: 'root' }]
1629
- }] });
1630
-
1631
1977
  class AXPHookService {
1632
1978
  constructor() {
1633
1979
  this.listenerProviders = inject(AXP_DISTRIBUTED_EVENT_LISTENER_PROVIDER, { optional: true }) || [];
@@ -1674,10 +2020,10 @@ class AXPHookService {
1674
2020
  }
1675
2021
  return data;
1676
2022
  }
1677
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPHookService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1678
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPHookService, providedIn: 'root' }); }
2023
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPHookService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2024
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPHookService, providedIn: 'root' }); }
1679
2025
  }
1680
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPHookService, decorators: [{
2026
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPHookService, decorators: [{
1681
2027
  type: Injectable,
1682
2028
  args: [{ providedIn: 'root' }]
1683
2029
  }] });
@@ -1957,14 +2303,85 @@ class AXPModuleManifestRegistry {
1957
2303
  }
1958
2304
  return { missingModules, missingFeatures };
1959
2305
  }
1960
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPModuleManifestRegistry, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1961
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPModuleManifestRegistry, providedIn: 'root' }); }
2306
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPModuleManifestRegistry, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2307
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPModuleManifestRegistry, providedIn: 'root' }); }
1962
2308
  }
1963
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPModuleManifestRegistry, decorators: [{
2309
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPModuleManifestRegistry, decorators: [{
1964
2310
  type: Injectable,
1965
2311
  args: [{ providedIn: 'root' }]
1966
2312
  }] });
1967
2313
 
2314
+ //#region ---- Imports ----
2315
+ //#endregion
2316
+ //#region ---- Module manifests data source ----
2317
+ /**
2318
+ * Registered module manifests for select widgets via dataSource name {@link MODULE_MANIFESTS_DATASOURCE_NAME}.
2319
+ */
2320
+ const MODULE_MANIFESTS_DATASOURCE_NAME = 'platform-module-manifests';
2321
+ /**
2322
+ * Data source definition for module names/titles from {@link AXPModuleManifestRegistry}.
2323
+ */
2324
+ class AXPModuleManifestsDataSourceDefinition {
2325
+ constructor() {
2326
+ //#region ---- Services & Dependencies ----
2327
+ this.manifestRegistry = inject(AXPModuleManifestRegistry);
2328
+ //#endregion
2329
+ }
2330
+ //#endregion
2331
+ //#region ---- Public API ----
2332
+ async items() {
2333
+ return [
2334
+ {
2335
+ name: MODULE_MANIFESTS_DATASOURCE_NAME,
2336
+ title: 'Module manifests',
2337
+ source: () => new AXDataSource({
2338
+ key: 'id',
2339
+ load: async () => {
2340
+ await this.manifestRegistry.initialize();
2341
+ const list = this.manifestRegistry.getAll().map((m) => ({
2342
+ id: m.name,
2343
+ title: m.title || m.name,
2344
+ }));
2345
+ return { items: list, total: list.length };
2346
+ },
2347
+ byKey: async (key) => {
2348
+ await this.manifestRegistry.initialize();
2349
+ const m = this.manifestRegistry.getAll().find((x) => x.name === key);
2350
+ return m ? { id: m.name, title: m.title || m.name } : undefined;
2351
+ },
2352
+ pageSize: 1000,
2353
+ }),
2354
+ columns: [
2355
+ {
2356
+ name: 'id',
2357
+ title: 'ID',
2358
+ datatype: 'string',
2359
+ type: 'text-editor',
2360
+ },
2361
+ {
2362
+ name: 'title',
2363
+ title: 'Title',
2364
+ datatype: 'string',
2365
+ type: 'text-editor',
2366
+ },
2367
+ ],
2368
+ filters: [
2369
+ {
2370
+ field: 'title',
2371
+ title: 'Title',
2372
+ operator: { type: 'equal' },
2373
+ widget: { type: 'text-editor' },
2374
+ filterType: { advance: true, inline: true },
2375
+ },
2376
+ ],
2377
+ textField: { name: 'title', title: 'Title' },
2378
+ valueField: { name: 'id', title: 'ID' },
2379
+ },
2380
+ ];
2381
+ }
2382
+ }
2383
+ //#endregion
2384
+
1968
2385
  class AXPAppStartUpService {
1969
2386
  constructor() {
1970
2387
  this.tasks = [];
@@ -1984,10 +2401,10 @@ class AXPAppStartUpService {
1984
2401
  loadingText.innerHTML = status;
1985
2402
  }
1986
2403
  }
1987
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPAppStartUpService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1988
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPAppStartUpService, providedIn: 'root' }); }
2404
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPAppStartUpService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2405
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPAppStartUpService, providedIn: 'root' }); }
1989
2406
  }
1990
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPAppStartUpService, decorators: [{
2407
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPAppStartUpService, decorators: [{
1991
2408
  type: Injectable,
1992
2409
  args: [{
1993
2410
  providedIn: 'root',
@@ -2025,17 +2442,50 @@ class AXPModuleManifestModule {
2025
2442
  },
2026
2443
  });
2027
2444
  }
2028
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPModuleManifestModule, deps: [{ token: AXPAppStartUpService }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.NgModule }); }
2029
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.12", ngImport: i0, type: AXPModuleManifestModule }); }
2030
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPModuleManifestModule }); }
2445
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPModuleManifestModule, deps: [{ token: AXPAppStartUpService }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.NgModule }); }
2446
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.9", ngImport: i0, type: AXPModuleManifestModule }); }
2447
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPModuleManifestModule }); }
2031
2448
  }
2032
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPModuleManifestModule, decorators: [{
2449
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPModuleManifestModule, decorators: [{
2033
2450
  type: NgModule,
2034
2451
  args: [{
2035
2452
  providers: [],
2036
2453
  }]
2037
2454
  }], ctorParameters: () => [{ type: AXPAppStartUpService }, { type: i0.Injector }] });
2038
2455
 
2456
+ //#region ---- Imports ----
2457
+ //#endregion
2458
+ //#region ---- Compare & sort ----
2459
+ const DEFAULT_COLLATOR_OPTIONS = { sensitivity: 'base' };
2460
+ /**
2461
+ * Locale-aware comparison of {@link AXPMultiLanguageString} values (plain string, `@scope:key`, or locale map).
2462
+ * Resolves each side with {@link resolveMultiLanguageString} for `locale`, then compares with `String#localeCompare`.
2463
+ */
2464
+ function compareMultiLanguageStrings(a, b, locale, collatorOptions = DEFAULT_COLLATOR_OPTIONS) {
2465
+ const sa = resolveMultiLanguageString(a ?? '', locale);
2466
+ const sb = resolveMultiLanguageString(b ?? '', locale);
2467
+ return sa.localeCompare(sb, locale, collatorOptions);
2468
+ }
2469
+ /**
2470
+ * Stable sort copy: orders items by resolved string for `getValue(item)` using the active `locale`.
2471
+ */
2472
+ function sortByMultiLanguageString(items, getValue, locale, collatorOptions) {
2473
+ return [...items].sort((x, y) => compareMultiLanguageStrings(getValue(x), getValue(y), locale, collatorOptions));
2474
+ }
2475
+ /**
2476
+ * True when the resolved value contains `query` (case-insensitive) for `locale`.
2477
+ * Useful for search/filter flows over {@link AXPMultiLanguageString}.
2478
+ */
2479
+ function searchInMultiLanguageString(value, query, locale) {
2480
+ const q = query.trim().toLocaleLowerCase(locale);
2481
+ if (!q) {
2482
+ return true;
2483
+ }
2484
+ const text = resolveMultiLanguageString(value ?? '', locale).toLocaleLowerCase(locale);
2485
+ return text.includes(q);
2486
+ }
2487
+ //#endregion
2488
+
2039
2489
  //#region ---- Tag Types ----
2040
2490
  //#endregion
2041
2491
 
@@ -2187,10 +2637,10 @@ class AXPTagService {
2187
2637
  const uniqueTags = allTags.filter((tag, index, self) => index === self.findIndex((t) => t.title.toLowerCase() === tag.title.toLowerCase()));
2188
2638
  this.cache = uniqueTags;
2189
2639
  }
2190
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPTagService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2191
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPTagService, providedIn: 'root' }); }
2640
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPTagService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2641
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPTagService, providedIn: 'root' }); }
2192
2642
  }
2193
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPTagService, decorators: [{
2643
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPTagService, decorators: [{
2194
2644
  type: Injectable,
2195
2645
  args: [{
2196
2646
  providedIn: 'root',
@@ -3121,14 +3571,25 @@ function getNestedKeys(obj, prefix = '') {
3121
3571
  }
3122
3572
  return keys;
3123
3573
  }
3574
+ /** Normalizes definition categories to an array for iteration and serialization. */
3575
+ function normalizeDefinitionCategories(categories) {
3576
+ if (categories == null) {
3577
+ return [];
3578
+ }
3579
+ return Array.isArray(categories) ? categories : [categories];
3580
+ }
3581
+
3582
+ //#region ---- Imports ----
3583
+ //#endregion
3124
3584
 
3125
3585
  function applySystemActionDefault(action, type) {
3126
3586
  const systemAction = getSystemActions(type);
3127
3587
  return {
3128
- name: systemAction.key,
3129
- title: systemAction.title,
3130
- icon: systemAction.icon,
3131
- color: systemAction.color,
3588
+ ...action,
3589
+ name: action.name ?? systemAction.key,
3590
+ title: action.title ?? systemAction.title,
3591
+ icon: action.icon ?? systemAction.icon,
3592
+ color: action.color ?? systemAction.color,
3132
3593
  };
3133
3594
  }
3134
3595
 
@@ -3153,8 +3614,6 @@ class AXPIconLogoConfig {
3153
3614
 
3154
3615
  var AXPPlatformScope;
3155
3616
  (function (AXPPlatformScope) {
3156
- AXPPlatformScope["Environment"] = "C";
3157
- AXPPlatformScope["Global"] = "G";
3158
3617
  AXPPlatformScope["Platform"] = "P";
3159
3618
  AXPPlatformScope["Tenant"] = "T";
3160
3619
  AXPPlatformScope["User"] = "U";
@@ -3162,8 +3621,6 @@ var AXPPlatformScope;
3162
3621
  ;
3163
3622
  function resolvePlatformScopeKey(name) {
3164
3623
  const scopeMap = {
3165
- environment: AXPPlatformScope.Environment,
3166
- global: AXPPlatformScope.Global,
3167
3624
  platform: AXPPlatformScope.Platform,
3168
3625
  tenant: AXPPlatformScope.Tenant,
3169
3626
  user: AXPPlatformScope.User,
@@ -3172,8 +3629,6 @@ function resolvePlatformScopeKey(name) {
3172
3629
  }
3173
3630
  function resolvePlatformScopeName(scope) {
3174
3631
  const scopeMap = {
3175
- C: 'environment',
3176
- G: 'global',
3177
3632
  P: 'platform',
3178
3633
  T: 'tenant',
3179
3634
  U: 'user',
@@ -3193,7 +3648,7 @@ var AXPExportTemplateToken;
3193
3648
  class AXPCountdownPipe {
3194
3649
  constructor() {
3195
3650
  this.calendarService = inject(AXCalendarService);
3196
- this.countdownSignal = signal(this.setupTimer(), ...(ngDevMode ? [{ debugName: "countdownSignal" }] : []));
3651
+ this.countdownSignal = signal(this.setupTimer(), ...(ngDevMode ? [{ debugName: "countdownSignal" }] : /* istanbul ignore next */ []));
3197
3652
  this.targetDate = 0;
3198
3653
  this.prevValue = 0;
3199
3654
  }
@@ -3222,10 +3677,10 @@ class AXPCountdownPipe {
3222
3677
  updateTargetDate(value) {
3223
3678
  this.targetDate = new Date(value).getTime();
3224
3679
  }
3225
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPCountdownPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
3226
- static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.3.12", ngImport: i0, type: AXPCountdownPipe, isStandalone: true, name: "countdown", pure: false }); }
3680
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPCountdownPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
3681
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.2.9", ngImport: i0, type: AXPCountdownPipe, isStandalone: true, name: "countdown", pure: false }); }
3227
3682
  }
3228
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPCountdownPipe, decorators: [{
3683
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPCountdownPipe, decorators: [{
3229
3684
  type: Pipe,
3230
3685
  args: [{
3231
3686
  name: 'countdown',
@@ -3235,6 +3690,41 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
3235
3690
  }] });
3236
3691
 
3237
3692
  const loggingEnabled = false; // Set to true to enable logging, false to disable
3693
+ //#region ---- Multilingual string helpers ----
3694
+ /**
3695
+ * Per-locale string map as produced by multilingual editors (e.g. `{ "en-US": "...", "fa-IR": "..." }`).
3696
+ */
3697
+ function isLocaleStringMap(value) {
3698
+ if (value === null || typeof value !== 'object' || Array.isArray(value) || value instanceof Date) {
3699
+ return false;
3700
+ }
3701
+ const values = Object.values(value);
3702
+ return values.length > 0 && values.every((v) => typeof v === 'string');
3703
+ }
3704
+ /**
3705
+ * Lowercased text for client-side filtering: plain string or all locale values joined.
3706
+ */
3707
+ function toFilterSearchText(value) {
3708
+ if (typeof value === 'string') {
3709
+ return value.toLowerCase();
3710
+ }
3711
+ if (isLocaleStringMap(value)) {
3712
+ return Object.values(value).join(' ').toLowerCase();
3713
+ }
3714
+ return undefined;
3715
+ }
3716
+ function filterValuesAreEqual(itemRaw, condRaw) {
3717
+ if (typeof condRaw === 'string' && isLocaleStringMap(itemRaw)) {
3718
+ return Object.values(itemRaw).some((v) => v.toLowerCase() === condRaw.toLowerCase());
3719
+ }
3720
+ if (typeof itemRaw === 'string' && isLocaleStringMap(condRaw)) {
3721
+ return Object.values(condRaw).some((v) => v.toLowerCase() === itemRaw.toLowerCase());
3722
+ }
3723
+ const itemScalar = typeof itemRaw === 'string' ? itemRaw.toLowerCase() : itemRaw;
3724
+ const condScalar = typeof condRaw === 'string' ? condRaw.toLowerCase() : condRaw;
3725
+ return isEqual(itemScalar, condScalar);
3726
+ }
3727
+ //#endregion
3238
3728
  function applyCondition(item, condition) {
3239
3729
  const rawValue = condition.field ? get(item, condition.field) : null;
3240
3730
  const itemValue = typeof rawValue === 'string' ? rawValue.toLowerCase() : rawValue;
@@ -3255,7 +3745,12 @@ function applyCondition(item, condition) {
3255
3745
  switch (op) {
3256
3746
  case 'equal':
3257
3747
  case 'eq':
3258
- result = isEqual(valueToCompare, conditionValue);
3748
+ if (!isNil(condition.field) && condition.field !== '') {
3749
+ result = filterValuesAreEqual(rawValue, condition.value);
3750
+ }
3751
+ else {
3752
+ result = isEqual(valueToCompare, conditionValue);
3753
+ }
3259
3754
  if (loggingEnabled) {
3260
3755
  console.log('Equal check result:', result);
3261
3756
  }
@@ -3263,7 +3758,12 @@ function applyCondition(item, condition) {
3263
3758
  case 'notEqual':
3264
3759
  case 'ne':
3265
3760
  case 'neq':
3266
- result = !isEqual(valueToCompare, conditionValue);
3761
+ if (!isNil(condition.field) && condition.field !== '') {
3762
+ result = !filterValuesAreEqual(rawValue, condition.value);
3763
+ }
3764
+ else {
3765
+ result = !isEqual(valueToCompare, conditionValue);
3766
+ }
3267
3767
  if (loggingEnabled) {
3268
3768
  console.log('Not equal check result:', result);
3269
3769
  }
@@ -3296,12 +3796,15 @@ function applyCondition(item, condition) {
3296
3796
  console.log('Less than or equal check result:', result);
3297
3797
  }
3298
3798
  break;
3299
- case 'contains':
3300
- if (typeof valueToCompare === 'string') {
3301
- result = includes(valueToCompare, conditionValue);
3799
+ case 'contains': {
3800
+ const needle = toFilterSearchText(condition.value) ??
3801
+ (condition.value == null ? '' : String(condition.value).toLowerCase());
3802
+ const haystack = toFilterSearchText(rawValue);
3803
+ if (haystack !== undefined) {
3804
+ result = includes(haystack, needle);
3302
3805
  }
3303
- else if (Array.isArray(valueToCompare)) {
3304
- result = includes(valueToCompare.map((val) => val.toString().toLowerCase()), conditionValue);
3806
+ else if (Array.isArray(rawValue)) {
3807
+ result = includes(rawValue.map((val) => toFilterSearchText(val) ?? val.toString().toLowerCase()), needle);
3305
3808
  }
3306
3809
  else {
3307
3810
  result = false;
@@ -3310,13 +3813,18 @@ function applyCondition(item, condition) {
3310
3813
  console.log('Contains check result:', result);
3311
3814
  }
3312
3815
  break;
3816
+ }
3313
3817
  case 'in':
3314
3818
  if (Array.isArray(conditionValue)) {
3315
3819
  if (typeof valueToCompare === 'string') {
3316
- result = conditionValue.some(val => typeof val === 'string' ? val.toLowerCase() === valueToCompare : val === valueToCompare);
3820
+ result = conditionValue.some((val) => typeof val === 'string' ? val.toLowerCase() === valueToCompare : val === valueToCompare);
3821
+ }
3822
+ else if (isLocaleStringMap(rawValue)) {
3823
+ const localeValues = Object.values(rawValue).map((v) => v.toLowerCase());
3824
+ result = localeValues.some((localeVal) => conditionValue.some((val) => typeof val === 'string' ? val.toLowerCase() === localeVal : val === localeVal));
3317
3825
  }
3318
3826
  else if (Array.isArray(valueToCompare)) {
3319
- result = valueToCompare.some(val => conditionValue.some(condVal => typeof val === 'string' && typeof condVal === 'string'
3827
+ result = valueToCompare.some((val) => conditionValue.some((condVal) => typeof val === 'string' && typeof condVal === 'string'
3320
3828
  ? val.toLowerCase() === condVal.toLowerCase()
3321
3829
  : val === condVal));
3322
3830
  }
@@ -3331,12 +3839,15 @@ function applyCondition(item, condition) {
3331
3839
  console.log('In check result:', result);
3332
3840
  }
3333
3841
  break;
3334
- case 'notContains':
3335
- if (typeof valueToCompare === 'string') {
3336
- result = !includes(valueToCompare, conditionValue);
3842
+ case 'notContains': {
3843
+ const needleNc = toFilterSearchText(condition.value) ??
3844
+ (condition.value == null ? '' : String(condition.value).toLowerCase());
3845
+ const haystackNc = toFilterSearchText(rawValue);
3846
+ if (haystackNc !== undefined) {
3847
+ result = !includes(haystackNc, needleNc);
3337
3848
  }
3338
- else if (Array.isArray(valueToCompare)) {
3339
- result = !includes(valueToCompare.map((val) => val.toString().toLowerCase()), conditionValue);
3849
+ else if (Array.isArray(rawValue)) {
3850
+ result = !includes(rawValue.map((val) => toFilterSearchText(val) ?? val.toString().toLowerCase()), needleNc);
3340
3851
  }
3341
3852
  else {
3342
3853
  result = false;
@@ -3345,18 +3856,27 @@ function applyCondition(item, condition) {
3345
3856
  console.log('Not contains check result:', result);
3346
3857
  }
3347
3858
  break;
3348
- case 'startsWith':
3349
- result = typeof valueToCompare === 'string' && startsWith(valueToCompare, conditionValue);
3859
+ }
3860
+ case 'startsWith': {
3861
+ const prefix = toFilterSearchText(condition.value) ??
3862
+ (condition.value == null ? '' : String(condition.value).toLowerCase());
3863
+ const haystackSw = toFilterSearchText(rawValue);
3864
+ result = haystackSw !== undefined && startsWith(haystackSw, prefix);
3350
3865
  if (loggingEnabled) {
3351
3866
  console.log('Starts with check result:', result);
3352
3867
  }
3353
3868
  break;
3354
- case 'endsWith':
3355
- result = typeof valueToCompare === 'string' && endsWith(valueToCompare, conditionValue);
3869
+ }
3870
+ case 'endsWith': {
3871
+ const suffix = toFilterSearchText(condition.value) ??
3872
+ (condition.value == null ? '' : String(condition.value).toLowerCase());
3873
+ const haystackEw = toFilterSearchText(rawValue);
3874
+ result = haystackEw !== undefined && endsWith(haystackEw, suffix);
3356
3875
  if (loggingEnabled) {
3357
3876
  console.log('Ends with check result:', result);
3358
3877
  }
3359
3878
  break;
3879
+ }
3360
3880
  case 'isEmpty':
3361
3881
  result = isEmpty(valueToCompare);
3362
3882
  if (loggingEnabled) {
@@ -3508,45 +4028,45 @@ class AXPDeviceService {
3508
4028
  /**
3509
4029
  * Current screen size (Small, Medium, Large)
3510
4030
  */
3511
- this.screenSize = signal(getScreenSize(), ...(ngDevMode ? [{ debugName: "screenSize" }] : []));
4031
+ this.screenSize = signal(getScreenSize(), ...(ngDevMode ? [{ debugName: "screenSize" }] : /* istanbul ignore next */ []));
3512
4032
  /**
3513
4033
  * Current device type (Mobile, Tablet, Desktop)
3514
4034
  */
3515
- this.deviceType = signal(getDeviceType(), ...(ngDevMode ? [{ debugName: "deviceType" }] : []));
4035
+ this.deviceType = signal(getDeviceType(), ...(ngDevMode ? [{ debugName: "deviceType" }] : /* istanbul ignore next */ []));
3516
4036
  /**
3517
4037
  * Whether the device supports touch input
3518
4038
  */
3519
- this.isTouchDevice = signal(isTouchDevice(), ...(ngDevMode ? [{ debugName: "isTouchDevice" }] : []));
4039
+ this.isTouchDevice = signal(isTouchDevice(), ...(ngDevMode ? [{ debugName: "isTouchDevice" }] : /* istanbul ignore next */ []));
3520
4040
  //#endregion
3521
4041
  //#region ---- Computed Signals ----
3522
4042
  /**
3523
4043
  * Whether the screen size is Small
3524
4044
  */
3525
- this.isSmall = computed(() => this.screenSize() === AXPScreenSize.Small, ...(ngDevMode ? [{ debugName: "isSmall" }] : []));
4045
+ this.isSmall = computed(() => this.screenSize() === AXPScreenSize.Small, ...(ngDevMode ? [{ debugName: "isSmall" }] : /* istanbul ignore next */ []));
3526
4046
  /**
3527
4047
  * Whether the screen size is Medium
3528
4048
  */
3529
- this.isMedium = computed(() => this.screenSize() === AXPScreenSize.Medium, ...(ngDevMode ? [{ debugName: "isMedium" }] : []));
4049
+ this.isMedium = computed(() => this.screenSize() === AXPScreenSize.Medium, ...(ngDevMode ? [{ debugName: "isMedium" }] : /* istanbul ignore next */ []));
3530
4050
  /**
3531
4051
  * Whether the screen size is Large
3532
4052
  */
3533
- this.isLarge = computed(() => this.screenSize() === AXPScreenSize.Large, ...(ngDevMode ? [{ debugName: "isLarge" }] : []));
4053
+ this.isLarge = computed(() => this.screenSize() === AXPScreenSize.Large, ...(ngDevMode ? [{ debugName: "isLarge" }] : /* istanbul ignore next */ []));
3534
4054
  /**
3535
4055
  * Whether the device is Mobile
3536
4056
  */
3537
- this.isMobileDevice = computed(() => this.deviceType() === AXPDeviceType.Mobile, ...(ngDevMode ? [{ debugName: "isMobileDevice" }] : []));
4057
+ this.isMobileDevice = computed(() => this.deviceType() === AXPDeviceType.Mobile, ...(ngDevMode ? [{ debugName: "isMobileDevice" }] : /* istanbul ignore next */ []));
3538
4058
  /**
3539
4059
  * Whether the device is Tablet
3540
4060
  */
3541
- this.isTabletDevice = computed(() => this.deviceType() === AXPDeviceType.Tablet, ...(ngDevMode ? [{ debugName: "isTabletDevice" }] : []));
4061
+ this.isTabletDevice = computed(() => this.deviceType() === AXPDeviceType.Tablet, ...(ngDevMode ? [{ debugName: "isTabletDevice" }] : /* istanbul ignore next */ []));
3542
4062
  /**
3543
4063
  * Whether the device is Desktop
3544
4064
  */
3545
- this.isDesktopDevice = computed(() => this.deviceType() === AXPDeviceType.Desktop, ...(ngDevMode ? [{ debugName: "isDesktopDevice" }] : []));
4065
+ this.isDesktopDevice = computed(() => this.deviceType() === AXPDeviceType.Desktop, ...(ngDevMode ? [{ debugName: "isDesktopDevice" }] : /* istanbul ignore next */ []));
3546
4066
  /**
3547
4067
  * Whether the device supports touch (alias for isTouchDevice)
3548
4068
  */
3549
- this.isTouchScreen = computed(() => this.isTouchDevice(), ...(ngDevMode ? [{ debugName: "isTouchScreen" }] : []));
4069
+ this.isTouchScreen = computed(() => this.isTouchDevice(), ...(ngDevMode ? [{ debugName: "isTouchScreen" }] : /* istanbul ignore next */ []));
3550
4070
  //#endregion
3551
4071
  //#region ---- Private Properties ----
3552
4072
  this._resizeListener = null;
@@ -3612,10 +4132,10 @@ class AXPDeviceService {
3612
4132
  destroy() {
3613
4133
  this._removeResizeListener();
3614
4134
  }
3615
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPDeviceService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
3616
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPDeviceService, providedIn: 'root' }); }
4135
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPDeviceService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
4136
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPDeviceService, providedIn: 'root' }); }
3617
4137
  }
3618
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXPDeviceService, decorators: [{
4138
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPDeviceService, decorators: [{
3619
4139
  type: Injectable,
3620
4140
  args: [{
3621
4141
  providedIn: 'root',
@@ -3719,10 +4239,10 @@ class AXHighlightService {
3719
4239
  resultHTML += '</span>';
3720
4240
  return resultHTML;
3721
4241
  }
3722
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXHighlightService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
3723
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXHighlightService, providedIn: 'root' }); }
4242
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXHighlightService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
4243
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXHighlightService, providedIn: 'root' }); }
3724
4244
  }
3725
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXHighlightService, decorators: [{
4245
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXHighlightService, decorators: [{
3726
4246
  type: Injectable,
3727
4247
  args: [{
3728
4248
  providedIn: 'root',
@@ -3754,17 +4274,23 @@ async function createProviderWithInjectionContext(loader) {
3754
4274
  *
3755
4275
  * @param token - The injection token to provide
3756
4276
  * @param loader - Function that returns a promise resolving to the provider class
3757
- * @param multi - Whether the provider is multi-provider (defaults to true)
4277
+ * @param multi - Optional. Whether the provider is a multi-provider (array of values). Defaults to `true`. Pass `false` for a single provider.
3758
4278
  * @returns Provider configuration object
3759
4279
  *
3760
4280
  * @example
3761
4281
  * ```typescript
3762
- * providers: [
3763
- * provideLazyProvider(
3764
- * AXP_SETTING_DEFINITION_PROVIDER,
3765
- * () => import('./settings.provider').then(m => m.AXMSettingProvider)
3766
- * )
3767
- * ]
4282
+ * // Multi-provider (default)
4283
+ * provideLazyProvider(
4284
+ * AXP_DATASOURCE_DEFINITION_PROVIDER,
4285
+ * () => import('./datasource.provider').then(m => m.AXMDataSourceProvider)
4286
+ * )
4287
+ *
4288
+ * // Single provider
4289
+ * provideLazyProvider(
4290
+ * SOME_TOKEN,
4291
+ * () => import('./my.provider').then(m => m.MyProvider),
4292
+ * false
4293
+ * )
3768
4294
  * ```
3769
4295
  */
3770
4296
  function provideLazyProvider(token, loader, multi = true) {
@@ -3775,11 +4301,113 @@ function provideLazyProvider(token, loader, multi = true) {
3775
4301
  };
3776
4302
  }
3777
4303
 
4304
+ //#region ---- Unwrapping ----
4305
+ /**
4306
+ * If `raw` is a plain non-array object with a `value` property, returns `value`; otherwise returns `raw`.
4307
+ */
4308
+ function unwrapValueProperty(raw) {
4309
+ if (raw && typeof raw === 'object' && !Array.isArray(raw) && !(raw instanceof Date) && 'value' in raw) {
4310
+ return raw.value;
4311
+ }
4312
+ return raw;
4313
+ }
4314
+ //#endregion
4315
+ //#region ---- Scalar coercion ----
4316
+ /**
4317
+ * Coerces to a trimmed string. Plain objects may carry `{ value }` from setting widgets or `{ id }` from select payloads using `valueField: 'id'`.
4318
+ */
4319
+ function coerceUnknownToTrimmedString(raw) {
4320
+ if (typeof raw === 'string') {
4321
+ return raw.trim();
4322
+ }
4323
+ if (raw && typeof raw === 'object' && !Array.isArray(raw) && !(raw instanceof Date)) {
4324
+ const r = raw;
4325
+ if ('value' in r && r['value'] != null) {
4326
+ return String(r['value']).trim();
4327
+ }
4328
+ if ('id' in r && r['id'] != null) {
4329
+ return String(r['id']).trim();
4330
+ }
4331
+ }
4332
+ return '';
4333
+ }
4334
+ /**
4335
+ * Coerces to boolean: direct booleans pass through; wrapped `{ value: true | 'true' }` is respected; otherwise false.
4336
+ */
4337
+ function coerceUnknownToBoolean(raw) {
4338
+ if (typeof raw === 'boolean') {
4339
+ return raw;
4340
+ }
4341
+ if (raw && typeof raw === 'object' && 'value' in raw) {
4342
+ const v = raw.value;
4343
+ return v === true || v === 'true';
4344
+ }
4345
+ return false;
4346
+ }
4347
+ /** Parses a finite number after optional `{ value }` unwrap; non-finite or empty string yields NaN. */
4348
+ function coerceUnknownToFiniteNumber(raw) {
4349
+ const v = unwrapValueProperty(raw);
4350
+ if (v === null || v === undefined) {
4351
+ return NaN;
4352
+ }
4353
+ if (typeof v === 'number') {
4354
+ return Number.isFinite(v) ? v : NaN;
4355
+ }
4356
+ if (typeof v === 'boolean') {
4357
+ return v ? 1 : 0;
4358
+ }
4359
+ if (typeof v === 'string') {
4360
+ const t = v.trim();
4361
+ if (t === '') {
4362
+ return NaN;
4363
+ }
4364
+ const n = Number(t);
4365
+ return Number.isFinite(n) ? n : NaN;
4366
+ }
4367
+ return NaN;
4368
+ }
4369
+ /** Parses a Date after optional `{ value }` unwrap; invalid input yields Invalid Date. */
4370
+ function coerceUnknownToDate(raw) {
4371
+ const v = unwrapValueProperty(raw);
4372
+ if (v === null || v === undefined) {
4373
+ return new Date(NaN);
4374
+ }
4375
+ if (v instanceof Date) {
4376
+ return new Date(v.getTime());
4377
+ }
4378
+ if (typeof v === 'number' && Number.isFinite(v)) {
4379
+ return new Date(v);
4380
+ }
4381
+ if (typeof v === 'string') {
4382
+ const t = v.trim();
4383
+ if (t === '') {
4384
+ return new Date(NaN);
4385
+ }
4386
+ return new Date(t);
4387
+ }
4388
+ return new Date(NaN);
4389
+ }
4390
+ //#endregion
4391
+
3778
4392
  function extractTextFromHtml(value) {
3779
4393
  const div = document.createElement('div');
3780
4394
  div.innerHTML = value;
3781
4395
  return div.textContent || div.innerText || '';
3782
4396
  }
4397
+ /**
4398
+ * True when the string likely contains HTML markup (e.g. `<p>`, `<ul>`), as opposed to plain text.
4399
+ * Used to choose innerHTML vs text interpolation for multilingual fields.
4400
+ */
4401
+ function containsHtmlMarkup(value) {
4402
+ if (value == null) {
4403
+ return false;
4404
+ }
4405
+ const t = value.trim();
4406
+ if (!t) {
4407
+ return false;
4408
+ }
4409
+ return /<\/?[a-z][\s\S]*?>/i.test(t);
4410
+ }
3783
4411
  /**
3784
4412
  * Generate kebab-case group name from title
3785
4413
  */
@@ -3797,5 +4425,5 @@ function generateKebabCase(title) {
3797
4425
  * Generated bundle index. Do not edit.
3798
4426
  */
3799
4427
 
3800
- export { AXFullscreenDirective, AXHighlightService, AXPActivityLogProvider, AXPActivityLogService, AXPAppStartUpProvider, AXPAppStartUpService, AXPBroadcastEventService, AXPColorPaletteProvider, AXPColorPaletteService, AXPComponentLogoConfig, AXPContentCheckerDirective, AXPContextChangeEvent, AXPContextStore, AXPCountdownPipe, AXPDataGenerator, AXPDataSourceDefinitionProviderService, AXPDblClickDirective, AXPDefaultColorPalettesProvider, AXPDeviceService, AXPDeviceType, AXPDistributedEventListenerService, AXPElementDataDirective, AXPExportTemplateToken, AXPExpressionEvaluatorScopeProviderContext, AXPExpressionEvaluatorScopeProviderService, AXPExpressionEvaluatorService, AXPFeatureDefinitionProviderContext, AXPGridLayoutDirective, AXPHookService, AXPIconLogoConfig, AXPImageUrlLogoConfig, AXPModuleManifestModule, AXPModuleManifestRegistry, AXPPlatformScope, AXPScreenSize, AXPSystemActionType, AXPSystemActions, AXPTagProvider, AXPTagService, AXP_ACTIVITY_LOG_PROVIDER, AXP_COLOR_PALETTE_PROVIDER, AXP_DATASOURCE_DEFINITION_PROVIDER, AXP_DISTRIBUTED_EVENT_LISTENER_PROVIDER, AXP_EXPRESSION_EVALUATOR_SCOPE_PROVIDER, AXP_FEATURE_DEFINITION_PROVIDER, AXP_MODULE_MANIFEST_PROVIDER, AXP_SESSION_SERVICE, AXP_TAG_PROVIDER, applyFilterArray, applyPagination, applyQueryArray, applySortArray, applySystemActionDefault, cleanDeep, createProviderWithInjectionContext, extractNestedFieldsWildcard, extractTextFromHtml, extractValue, generateKebabCase, getActionButton, getChangedPaths, getDetailedChanges, getEnumValues, getNestedKeys, getSmart, getSystemActions, objectKeyValueTransforms, provideLazyProvider, resolveActionLook, resolvePlatformScopeKey, resolvePlatformScopeName, setSmart };
4428
+ export { AXHighlightService, AXPActivityLogProvider, AXPActivityLogService, AXPAppStartUpProvider, AXPAppStartUpService, AXPBroadcastEventService, AXPColorPaletteProvider, AXPColorPaletteService, AXPColumnWidthService, AXPComponentLogoConfig, AXPComponentSlot, AXPComponentSlotDirective, AXPComponentSlotModule, AXPComponentSlotRegistryService, AXPContentCheckerDirective, AXPContextChangeEvent, AXPContextStore, AXPCountdownPipe, AXPDataGenerator, AXPDataSourceDefinitionProviderService, AXPDblClickDirective, AXPDefaultColorPalettesProvider, AXPDeviceService, AXPDeviceType, AXPDistributedEventListenerService, AXPElementDataDirective, AXPExportTemplateToken, AXPExpressionEvaluatorScopeProviderContext, AXPExpressionEvaluatorScopeProviderService, AXPExpressionEvaluatorService, AXPFeatureDefinitionProviderContext, AXPGridLayoutDirective, AXPHookService, AXPIconLogoConfig, AXPImageUrlLogoConfig, AXPModuleManifestModule, AXPModuleManifestRegistry, AXPModuleManifestsDataSourceDefinition, AXPPlatformScope, AXPScreenSize, AXPSystemActionType, AXPSystemActions, AXPTagProvider, AXPTagService, AXP_ACTIVITY_LOG_PROVIDER, AXP_COLOR_PALETTE_PROVIDER, AXP_COLUMN_WIDTH_PROVIDER, AXP_DATASOURCE_DEFINITION_PROVIDER, AXP_DISTRIBUTED_EVENT_LISTENER_PROVIDER, AXP_EXPRESSION_EVALUATOR_SCOPE_PROVIDER, AXP_FEATURE_DEFINITION_PROVIDER, AXP_MODULE_MANIFEST_PROVIDER, AXP_SESSION_SERVICE, AXP_TAG_PROVIDER, MODULE_MANIFESTS_DATASOURCE_NAME, applyFilterArray, applyPagination, applyQueryArray, applySortArray, applySystemActionDefault, cleanDeep, coerceUnknownToBoolean, coerceUnknownToDate, coerceUnknownToFiniteNumber, coerceUnknownToTrimmedString, compareMultiLanguageStrings, containsHtmlMarkup, createProviderWithInjectionContext, defaultColumnWidthProvider, extractNestedFieldsWildcard, extractTextFromHtml, extractValue, generateKebabCase, getActionButton, getChangedPaths, getDetailedChanges, getEnumValues, getNestedKeys, getSmart, getSystemActions, normalizeDefinitionCategories, objectKeyValueTransforms, provideLazyProvider, resolveActionLook, resolvePlatformScopeKey, resolvePlatformScopeName, searchInMultiLanguageString, setSmart, sortByMultiLanguageString, unwrapValueProperty };
3801
4429
  //# sourceMappingURL=acorex-platform-core.mjs.map