@acorex/platform 20.3.0-next.1 → 20.3.0-next.11

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 (119) hide show
  1. package/common/index.d.ts +125 -12
  2. package/core/index.d.ts +656 -100
  3. package/fesm2022/acorex-platform-auth.mjs +20 -20
  4. package/fesm2022/acorex-platform-auth.mjs.map +1 -1
  5. package/fesm2022/acorex-platform-common.mjs +120 -148
  6. package/fesm2022/acorex-platform-common.mjs.map +1 -1
  7. package/fesm2022/acorex-platform-core.mjs +885 -261
  8. package/fesm2022/acorex-platform-core.mjs.map +1 -1
  9. package/fesm2022/acorex-platform-domain.mjs +16 -16
  10. package/fesm2022/acorex-platform-domain.mjs.map +1 -1
  11. package/fesm2022/acorex-platform-layout-builder.mjs +1615 -662
  12. package/fesm2022/acorex-platform-layout-builder.mjs.map +1 -1
  13. package/fesm2022/acorex-platform-layout-components.mjs +3327 -157
  14. package/fesm2022/acorex-platform-layout-components.mjs.map +1 -1
  15. package/fesm2022/acorex-platform-layout-designer.mjs +172 -210
  16. package/fesm2022/acorex-platform-layout-designer.mjs.map +1 -1
  17. package/fesm2022/acorex-platform-layout-entity-create-entity.command-764ie8R8.mjs +52 -0
  18. package/fesm2022/acorex-platform-layout-entity-create-entity.command-764ie8R8.mjs.map +1 -0
  19. package/fesm2022/acorex-platform-layout-entity.mjs +4522 -1643
  20. package/fesm2022/acorex-platform-layout-entity.mjs.map +1 -1
  21. package/fesm2022/acorex-platform-layout-views.mjs +398 -89
  22. package/fesm2022/acorex-platform-layout-views.mjs.map +1 -1
  23. package/fesm2022/acorex-platform-native.mjs +7 -7
  24. package/fesm2022/acorex-platform-native.mjs.map +1 -1
  25. package/fesm2022/acorex-platform-runtime.mjs +40 -40
  26. package/fesm2022/acorex-platform-runtime.mjs.map +1 -1
  27. package/fesm2022/{acorex-platform-themes-default-entity-master-create-view.component-hHXxHlFG.mjs → acorex-platform-themes-default-entity-master-create-view.component-Ct-ri59W.mjs} +7 -7
  28. package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-Ct-ri59W.mjs.map +1 -0
  29. package/fesm2022/acorex-platform-themes-default-entity-master-list-view.component-7BB4LdjK.mjs +706 -0
  30. package/fesm2022/acorex-platform-themes-default-entity-master-list-view.component-7BB4LdjK.mjs.map +1 -0
  31. package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-BDJR088o.mjs +101 -0
  32. package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-BDJR088o.mjs.map +1 -0
  33. package/fesm2022/acorex-platform-themes-default-entity-master-single-view.component-BExtm1JE.mjs +244 -0
  34. package/fesm2022/acorex-platform-themes-default-entity-master-single-view.component-BExtm1JE.mjs.map +1 -0
  35. package/fesm2022/{acorex-platform-themes-default-error-401.component-D4glpFvU.mjs → acorex-platform-themes-default-error-401.component-DrO1PEOH.mjs} +4 -4
  36. package/fesm2022/{acorex-platform-themes-default-error-401.component-D4glpFvU.mjs.map → acorex-platform-themes-default-error-401.component-DrO1PEOH.mjs.map} +1 -1
  37. package/fesm2022/{acorex-platform-themes-default-error-404.component-BvGeDMjo.mjs → acorex-platform-themes-default-error-404.component-DqVq0oHX.mjs} +4 -4
  38. package/fesm2022/{acorex-platform-themes-default-error-404.component-BvGeDMjo.mjs.map → acorex-platform-themes-default-error-404.component-DqVq0oHX.mjs.map} +1 -1
  39. package/fesm2022/{acorex-platform-themes-default-error-offline.component-BINy-Zo3.mjs → acorex-platform-themes-default-error-offline.component-Bt2PTL7_.mjs} +4 -4
  40. package/fesm2022/{acorex-platform-themes-default-error-offline.component-BINy-Zo3.mjs.map → acorex-platform-themes-default-error-offline.component-Bt2PTL7_.mjs.map} +1 -1
  41. package/fesm2022/acorex-platform-themes-default.mjs +64 -509
  42. package/fesm2022/acorex-platform-themes-default.mjs.map +1 -1
  43. package/fesm2022/{acorex-platform-themes-shared-icon-chooser-view.component-C833prGO.mjs → acorex-platform-themes-shared-icon-chooser-view.component-BgEh06Tn.mjs} +24 -14
  44. package/fesm2022/acorex-platform-themes-shared-icon-chooser-view.component-BgEh06Tn.mjs.map +1 -0
  45. package/fesm2022/{acorex-platform-themes-shared-settings.provider-CXiRmniv.mjs → acorex-platform-themes-shared-settings.provider-CLUKU4y0.mjs} +2 -2
  46. package/fesm2022/acorex-platform-themes-shared-settings.provider-CLUKU4y0.mjs.map +1 -0
  47. package/fesm2022/{acorex-platform-themes-shared-color-chooser-column.component-DjKLg513.mjs → acorex-platform-themes-shared-theme-color-chooser-column.component-AeOQxjbS.mjs} +23 -8
  48. package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-column.component-AeOQxjbS.mjs.map +1 -0
  49. package/fesm2022/{acorex-platform-themes-shared-color-chooser-view.component-DE0wO98F.mjs → acorex-platform-themes-shared-theme-color-chooser-view.component-DEVzRd6-.mjs} +23 -8
  50. package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-view.component-DEVzRd6-.mjs.map +1 -0
  51. package/fesm2022/acorex-platform-themes-shared.mjs +250 -85
  52. package/fesm2022/acorex-platform-themes-shared.mjs.map +1 -1
  53. package/fesm2022/{acorex-platform-widgets-button-widget-designer.component-lNF95FJv.mjs → acorex-platform-widgets-button-widget-designer.component-DSaD9Fwc.mjs} +7 -7
  54. package/fesm2022/acorex-platform-widgets-button-widget-designer.component-DSaD9Fwc.mjs.map +1 -0
  55. package/fesm2022/acorex-platform-widgets-extra-properties-schema-widget-edit.component-D9mf08rU.mjs +50 -0
  56. package/fesm2022/acorex-platform-widgets-extra-properties-schema-widget-edit.component-D9mf08rU.mjs.map +1 -0
  57. package/fesm2022/acorex-platform-widgets-extra-properties-schema-widget-view.component-D6GQ-eyr.mjs +42 -0
  58. package/fesm2022/acorex-platform-widgets-extra-properties-schema-widget-view.component-D6GQ-eyr.mjs.map +1 -0
  59. package/fesm2022/acorex-platform-widgets-extra-properties-values-widget-edit.component-DVbIdVZ6.mjs +55 -0
  60. package/fesm2022/acorex-platform-widgets-extra-properties-values-widget-edit.component-DVbIdVZ6.mjs.map +1 -0
  61. package/fesm2022/acorex-platform-widgets-extra-properties-values-widget-view.component-D-aM64Hu.mjs +50 -0
  62. package/fesm2022/acorex-platform-widgets-extra-properties-values-widget-view.component-D-aM64Hu.mjs.map +1 -0
  63. package/fesm2022/acorex-platform-widgets-extra-properties-widget-edit.component-em2-aU8E.mjs +48 -0
  64. package/fesm2022/acorex-platform-widgets-extra-properties-widget-edit.component-em2-aU8E.mjs.map +1 -0
  65. package/fesm2022/acorex-platform-widgets-extra-properties-widget-view.component-BeuIofdr.mjs +42 -0
  66. package/fesm2022/acorex-platform-widgets-extra-properties-widget-view.component-BeuIofdr.mjs.map +1 -0
  67. package/fesm2022/{acorex-platform-widgets-file-list-popup.component-DFbPO0ud.mjs → acorex-platform-widgets-file-list-popup.component-Cmtq2bBV.mjs} +72 -7
  68. package/fesm2022/acorex-platform-widgets-file-list-popup.component-Cmtq2bBV.mjs.map +1 -0
  69. package/fesm2022/{acorex-platform-widgets-page-widget-designer.component-DRsLkulH.mjs → acorex-platform-widgets-page-widget-designer.component-B-ZEi2yd.mjs} +79 -69
  70. package/fesm2022/acorex-platform-widgets-page-widget-designer.component-B-ZEi2yd.mjs.map +1 -0
  71. package/fesm2022/{acorex-platform-widgets-tabular-data-edit-popup.component-nLZYiPnF.mjs → acorex-platform-widgets-tabular-data-edit-popup.component-CMqq_iOj.mjs} +13 -13
  72. package/fesm2022/acorex-platform-widgets-tabular-data-edit-popup.component-CMqq_iOj.mjs.map +1 -0
  73. package/fesm2022/{acorex-platform-widgets-tabular-data-view-popup.component-D6kiasYM.mjs → acorex-platform-widgets-tabular-data-view-popup.component-CRpjdiNz.mjs} +8 -7
  74. package/fesm2022/acorex-platform-widgets-tabular-data-view-popup.component-CRpjdiNz.mjs.map +1 -0
  75. package/fesm2022/{acorex-platform-widgets-text-block-widget-designer.component-CCMQtH3e.mjs → acorex-platform-widgets-text-block-widget-designer.component-DeSmBqMa.mjs} +9 -14
  76. package/fesm2022/acorex-platform-widgets-text-block-widget-designer.component-DeSmBqMa.mjs.map +1 -0
  77. package/fesm2022/acorex-platform-widgets.mjs +9152 -7181
  78. package/fesm2022/acorex-platform-widgets.mjs.map +1 -1
  79. package/fesm2022/acorex-platform-workflow.mjs +28 -25
  80. package/fesm2022/acorex-platform-workflow.mjs.map +1 -1
  81. package/layout/builder/index.d.ts +419 -185
  82. package/layout/components/index.d.ts +1129 -24
  83. package/layout/designer/index.d.ts +20 -49
  84. package/layout/entity/index.d.ts +424 -332
  85. package/layout/views/index.d.ts +129 -22
  86. package/package.json +23 -37
  87. package/widgets/index.d.ts +1908 -783
  88. package/workflow/index.d.ts +4 -1
  89. package/fesm2022/acorex-platform-themes-default-create-entity-view.component-SY0oMDoH.mjs +0 -22
  90. package/fesm2022/acorex-platform-themes-default-create-entity-view.component-SY0oMDoH.mjs.map +0 -1
  91. package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-hHXxHlFG.mjs.map +0 -1
  92. package/fesm2022/acorex-platform-themes-default-entity-master-list-view.component-hf4QOz_4.mjs +0 -665
  93. package/fesm2022/acorex-platform-themes-default-entity-master-list-view.component-hf4QOz_4.mjs.map +0 -1
  94. package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-DC3MrDtI.mjs +0 -108
  95. package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-DC3MrDtI.mjs.map +0 -1
  96. package/fesm2022/acorex-platform-themes-default-entity-master-single-view.component-Bb90PeHq.mjs +0 -236
  97. package/fesm2022/acorex-platform-themes-default-entity-master-single-view.component-Bb90PeHq.mjs.map +0 -1
  98. package/fesm2022/acorex-platform-themes-shared-color-chooser-column.component-DjKLg513.mjs.map +0 -1
  99. package/fesm2022/acorex-platform-themes-shared-color-chooser-view.component-DE0wO98F.mjs.map +0 -1
  100. package/fesm2022/acorex-platform-themes-shared-icon-chooser-view.component-C833prGO.mjs.map +0 -1
  101. package/fesm2022/acorex-platform-themes-shared-settings.provider-CXiRmniv.mjs.map +0 -1
  102. package/fesm2022/acorex-platform-widgets-button-widget-designer.component-lNF95FJv.mjs.map +0 -1
  103. package/fesm2022/acorex-platform-widgets-checkbox-widget-column.component-BNBOATPB.mjs +0 -85
  104. package/fesm2022/acorex-platform-widgets-checkbox-widget-column.component-BNBOATPB.mjs.map +0 -1
  105. package/fesm2022/acorex-platform-widgets-checkbox-widget-designer.component-BI18uzNZ.mjs +0 -55
  106. package/fesm2022/acorex-platform-widgets-checkbox-widget-designer.component-BI18uzNZ.mjs.map +0 -1
  107. package/fesm2022/acorex-platform-widgets-checkbox-widget-view.component-C6-QPsnb.mjs +0 -76
  108. package/fesm2022/acorex-platform-widgets-checkbox-widget-view.component-C6-QPsnb.mjs.map +0 -1
  109. package/fesm2022/acorex-platform-widgets-color-box-widget-designer.component-pYOQv5g8.mjs +0 -55
  110. package/fesm2022/acorex-platform-widgets-color-box-widget-designer.component-pYOQv5g8.mjs.map +0 -1
  111. package/fesm2022/acorex-platform-widgets-file-list-popup.component-DFbPO0ud.mjs.map +0 -1
  112. package/fesm2022/acorex-platform-widgets-file-rename-popup.component-DA_CgIvm.mjs +0 -211
  113. package/fesm2022/acorex-platform-widgets-file-rename-popup.component-DA_CgIvm.mjs.map +0 -1
  114. package/fesm2022/acorex-platform-widgets-page-widget-designer.component-DRsLkulH.mjs.map +0 -1
  115. package/fesm2022/acorex-platform-widgets-rich-text-popup.component-CM_v-cL4.mjs +0 -40
  116. package/fesm2022/acorex-platform-widgets-rich-text-popup.component-CM_v-cL4.mjs.map +0 -1
  117. package/fesm2022/acorex-platform-widgets-tabular-data-edit-popup.component-nLZYiPnF.mjs.map +0 -1
  118. package/fesm2022/acorex-platform-widgets-tabular-data-view-popup.component-D6kiasYM.mjs.map +0 -1
  119. package/fesm2022/acorex-platform-widgets-text-block-widget-designer.component-CCMQtH3e.mjs.map +0 -1
@@ -1,54 +1,104 @@
1
- import * as i2$2 from '@acorex/components/button';
1
+ import * as i3 from '@acorex/components/button';
2
2
  import { AXButtonModule } from '@acorex/components/button';
3
+ import * as i1$2 from '@acorex/cdk/common';
3
4
  import { AXCommonModule } from '@acorex/cdk/common';
4
- import * as i3 from '@acorex/components/decorators';
5
+ import * as i2$1 from '@acorex/components/decorators';
5
6
  import { AXDecoratorModule } from '@acorex/components/decorators';
6
- import * as i2 from '@acorex/core/translation';
7
- import { AXTranslationService, AXTranslationModule } from '@acorex/core/translation';
8
- import * as i3$1 from '@acorex/components/skeleton';
7
+ import * as i5 from '@acorex/core/translation';
8
+ import { AXTranslationModule, AXTranslationService } from '@acorex/core/translation';
9
+ import * as i2 from '@acorex/components/skeleton';
9
10
  import { AXSkeletonModule } from '@acorex/components/skeleton';
10
- import * as i5 from '@acorex/core/format';
11
+ import * as i4 from '@acorex/core/format';
11
12
  import { AXFormatModule } from '@acorex/core/format';
12
13
  import { getSystemActions, AXPExpressionEvaluatorService, AXPContextStore } from '@acorex/platform/core';
13
14
  import { AXPWorkflowService } from '@acorex/platform/workflow';
14
- import * as i4 from '@angular/common';
15
+ import * as i1 from '@angular/common';
15
16
  import { CommonModule } from '@angular/common';
16
17
  import * as i0 from '@angular/core';
17
- import { inject, input, signal, effect, ViewEncapsulation, ChangeDetectionStrategy, Component, InjectionToken, computed, Injectable, Directive, viewChild, contentChild, ElementRef, Injector, ViewContainerRef, runInInjectionContext, Optional, Inject, NgModule, output, linkedSignal, untracked, ViewChildren } from '@angular/core';
18
+ import { input, ChangeDetectionStrategy, ViewEncapsulation, Component, inject, signal, effect, InjectionToken, computed, Injectable, Directive, viewChild, contentChild, ElementRef, output, model, Injector, ViewContainerRef, runInInjectionContext, Optional, Inject, NgModule, viewChildren, Input, EventEmitter, untracked, Output, linkedSignal, ViewChildren } from '@angular/core';
18
19
  import { AXAccordionCdkModule } from '@acorex/cdk/accordion';
19
20
  import { AXTagModule } from '@acorex/components/tag';
20
21
  import { SIGNAL, signalSetFn } from '@angular/core/primitives/signals';
21
22
  import * as i8 from '@acorex/components/badge';
22
23
  import { AXBadgeComponent, AXBadgeModule } from '@acorex/components/badge';
23
- import * as i1$1 from '@acorex/components/form';
24
+ import * as i4$1 from '@acorex/components/search-box';
25
+ import { AXSearchBoxModule } from '@acorex/components/search-box';
26
+ import * as i2$2 from '@acorex/components/tree-view';
27
+ import { AXTreeViewModule } from '@acorex/components/tree-view';
28
+ import * as i6 from '@acorex/components/dropdown';
29
+ import { AXDropdownModule } from '@acorex/components/dropdown';
30
+ import * as i3$1 from '@acorex/components/switch';
31
+ import { AXSwitchModule } from '@acorex/components/switch';
32
+ import * as i9 from '@angular/cdk/drag-drop';
33
+ import { moveItemInArray, CdkDropList, CdkDrag, CdkDragHandle, DragDropModule } from '@angular/cdk/drag-drop';
34
+ import * as i1$1 from '@angular/forms';
35
+ import { FormsModule } from '@angular/forms';
36
+ import { cloneDeep, sortBy, isEmpty, isNil, isEqual, get, camelCase, merge, capitalize, unionBy, isArray, set } from 'lodash-es';
37
+ import * as i2$4 from '@acorex/components/form';
24
38
  import { AXFormModule, AXFormComponent } from '@acorex/components/form';
39
+ import * as i4$4 from '@acorex/components/text-box';
25
40
  import { AXTextBoxModule } from '@acorex/components/text-box';
26
- import * as i2$1 from '@acorex/components/check-box';
41
+ import * as i2$3 from '@acorex/components/check-box';
27
42
  import { AXCheckBoxModule } from '@acorex/components/check-box';
28
- import * as i1 from '@acorex/components/label';
43
+ import * as i3$2 from '@acorex/components/label';
29
44
  import { AXLabelModule, AXLabelComponent } from '@acorex/components/label';
30
- import * as i3$2 from '@acorex/platform/layout/builder';
31
- import { AXPLayoutBuilderModule, AXPWidgetContainerComponent, AXPPageStatus } from '@acorex/platform/layout/builder';
32
- import { sortBy } from 'lodash-es';
45
+ import * as i3$3 from '@acorex/platform/layout/builder';
46
+ import { AXPLayoutBuilderModule, AXPWidgetContainerComponent, AXPPageStatus, AXPWidgetRegistryService, AXPWidgetsCatalog } from '@acorex/platform/layout/builder';
47
+ import * as i4$2 from '@acorex/components/data-table';
48
+ import { AXDataTableModule } from '@acorex/components/data-table';
49
+ import * as i4$3 from '@acorex/components/dropdown-button';
50
+ import { AXDropdownButtonModule } from '@acorex/components/dropdown-button';
51
+ import { AXBasePageComponent } from '@acorex/components/page';
52
+ import { AXPopupService } from '@acorex/components/popup';
53
+ import * as i5$1 from '@acorex/components/loading';
54
+ import { AXLoadingModule } from '@acorex/components/loading';
33
55
  import { AXValidationModule } from '@acorex/core/validation';
34
- import { AXPGridLayoutDirective, AXPFilterOperatorMiddlewareService, ALL_DEFAULT_OPERATORS } from '@acorex/platform/common';
35
- import * as i1$2 from '@angular/forms';
36
- import { FormsModule } from '@angular/forms';
56
+ import * as i1$3 from '@acorex/components/step-wizard';
57
+ import { AXStepWizardComponent, AXStepWizardModule } from '@acorex/components/step-wizard';
58
+ import { AXPGridLayoutDirective, AXPStickyDirective, AXPFilterOperatorMiddlewareService, ALL_DEFAULT_OPERATORS } from '@acorex/platform/common';
59
+ import * as i5$2 from '@acorex/components/select-box';
60
+ import { AXSelectBoxModule } from '@acorex/components/select-box';
61
+ import * as i1$4 from '@acorex/components/collapse';
62
+ import { AXCollapseModule } from '@acorex/components/collapse';
63
+ import * as i2$5 from '@acorex/components/tabs';
64
+ import { AXTabsModule } from '@acorex/components/tabs';
37
65
  import * as i7 from '@acorex/cdk/list-navigation';
38
66
  import { AXListNavigationModule } from '@acorex/cdk/list-navigation';
39
- import * as i4$1 from '@acorex/components/popover';
67
+ import * as i4$5 from '@acorex/components/popover';
40
68
  import { AXPopoverModule } from '@acorex/components/popover';
41
69
  import { AXSelectionListModule } from '@acorex/components/selection-list';
42
- import * as i5$1 from '@acorex/components/tag-box';
70
+ import * as i5$3 from '@acorex/components/tag-box';
43
71
  import { AXTagBoxModule } from '@acorex/components/tag-box';
44
72
  import { AXCalendarService } from '@acorex/core/date-time';
45
73
  import { BehaviorSubject, timer, Subject, takeUntil } from 'rxjs';
46
74
  import { tap } from 'rxjs/operators';
47
- import * as i1$3 from '@acorex/components/avatar';
75
+ import * as i1$5 from '@acorex/components/avatar';
48
76
  import { AXAvatarModule } from '@acorex/components/avatar';
49
- import * as i3$3 from '@acorex/components/image';
77
+ import * as i3$4 from '@acorex/components/image';
50
78
  import { AXImageModule } from '@acorex/components/image';
51
79
 
80
+ //#endregion
81
+ //#region ---- Component Definition ----
82
+ //#endregion
83
+ //#region ---- Component Class ----
84
+ class AXPStateMessageComponent {
85
+ constructor() {
86
+ // Core properties
87
+ this.mode = input('empty', ...(ngDevMode ? [{ debugName: "mode" }] : []));
88
+ this.icon = input('', ...(ngDevMode ? [{ debugName: "icon" }] : []));
89
+ this.title = input('', ...(ngDevMode ? [{ debugName: "title" }] : []));
90
+ this.description = input('', ...(ngDevMode ? [{ debugName: "description" }] : []));
91
+ // Optional styling
92
+ this.variant = input('default', ...(ngDevMode ? [{ debugName: "variant" }] : []));
93
+ }
94
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPStateMessageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
95
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.1.8", type: AXPStateMessageComponent, isStandalone: true, selector: "axp-state-message", inputs: { mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"axp-state-message\" [attr.data-mode]=\"mode()\" [attr.data-variant]=\"variant()\">\n <div class=\"__icon\" *ngIf=\"icon()\">\n <i [class]=\"icon()\"></i>\n </div>\n <div class=\"__content\">\n <h3 class=\"__title\" *ngIf=\"title()\">{{ title() | translate | async }}</h3>\n <p class=\"__description\" *ngIf=\"description()\">{{ description() | translate | async }}</p>\n <div class=\"__actions\">\n <ng-content select=\"[slot=actions]\"></ng-content>\n </div>\n </div>\n</div>\n", styles: [".axp-state-message{display:flex;height:100%;flex-direction:column;align-items:center;justify-content:center;padding:3rem 1rem;text-align:center}.axp-state-message .__icon{margin-bottom:1rem}.axp-state-message .__icon i{opacity:74%;display:block;font-weight:400;font-size:2.25rem!important;line-height:2.5rem!important}.axp-state-message .__content{max-width:28rem}.axp-state-message .__title{margin-bottom:.5rem;font-size:1.125rem;line-height:1.75rem;font-weight:500}.axp-state-message .__description{margin-bottom:1rem;opacity:74%;display:block;font-weight:400;font-size:.875rem!important;line-height:1.25rem!important}.axp-state-message .__actions{display:flex;flex-direction:column;align-items:center;gap:.5rem}.axp-state-message[data-mode=empty] .__icon i{--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.axp-state-message[data-mode=error] .__icon i{--tw-text-opacity: 1;color:rgb(239 68 68 / var(--tw-text-opacity, 1))}.axp-state-message[data-mode=error] .__title{--tw-text-opacity: 1;color:rgb(220 38 38 / var(--tw-text-opacity, 1))}.axp-state-message[data-mode=loading] .__icon i{--tw-text-opacity: 1;color:rgb(59 130 246 / var(--tw-text-opacity, 1))}.axp-state-message[data-mode=loading] .__title{--tw-text-opacity: 1;color:rgb(37 99 235 / var(--tw-text-opacity, 1))}.axp-state-message[data-mode=warning] .__icon i{--tw-text-opacity: 1;color:rgb(249 115 22 / var(--tw-text-opacity, 1))}.axp-state-message[data-mode=warning] .__title{--tw-text-opacity: 1;color:rgb(234 88 12 / var(--tw-text-opacity, 1))}.axp-state-message[data-mode=info] .__icon i{--tw-text-opacity: 1;color:rgb(59 130 246 / var(--tw-text-opacity, 1))}.axp-state-message[data-mode=info] .__title{--tw-text-opacity: 1;color:rgb(37 99 235 / var(--tw-text-opacity, 1))}.axp-state-message[data-mode=success] .__icon i{--tw-text-opacity: 1;color:rgb(34 197 94 / var(--tw-text-opacity, 1))}.axp-state-message[data-mode=success] .__title{--tw-text-opacity: 1;color:rgb(22 163 74 / var(--tw-text-opacity, 1))}.axp-state-message[data-variant=compact]{padding:1.5rem .75rem}.axp-state-message[data-variant=compact] .__icon{margin-bottom:.5rem}.axp-state-message[data-variant=compact] .__icon i{font-size:1.5rem!important;line-height:2rem!important}.axp-state-message[data-variant=compact] .__title{margin-bottom:.25rem;font-size:1rem;line-height:1.5rem}.axp-state-message[data-variant=compact] .__description{margin-bottom:.5rem;font-size:.75rem;line-height:1rem}.axp-state-message[data-variant=minimal]{padding:1rem .5rem}.axp-state-message[data-variant=minimal] .__icon{margin-bottom:.25rem}.axp-state-message[data-variant=minimal] .__icon i{font-size:1.25rem!important;line-height:1.75rem!important}.axp-state-message[data-variant=minimal] .__title{margin-bottom:.25rem;font-size:.875rem;line-height:1.25rem}.axp-state-message[data-variant=minimal] .__description{margin-bottom:.25rem;font-size:.75rem;line-height:1rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
96
+ }
97
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPStateMessageComponent, decorators: [{
98
+ type: Component,
99
+ args: [{ selector: 'axp-state-message', standalone: true, imports: [CommonModule, AXTranslationModule], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"axp-state-message\" [attr.data-mode]=\"mode()\" [attr.data-variant]=\"variant()\">\n <div class=\"__icon\" *ngIf=\"icon()\">\n <i [class]=\"icon()\"></i>\n </div>\n <div class=\"__content\">\n <h3 class=\"__title\" *ngIf=\"title()\">{{ title() | translate | async }}</h3>\n <p class=\"__description\" *ngIf=\"description()\">{{ description() | translate | async }}</p>\n <div class=\"__actions\">\n <ng-content select=\"[slot=actions]\"></ng-content>\n </div>\n </div>\n</div>\n", styles: [".axp-state-message{display:flex;height:100%;flex-direction:column;align-items:center;justify-content:center;padding:3rem 1rem;text-align:center}.axp-state-message .__icon{margin-bottom:1rem}.axp-state-message .__icon i{opacity:74%;display:block;font-weight:400;font-size:2.25rem!important;line-height:2.5rem!important}.axp-state-message .__content{max-width:28rem}.axp-state-message .__title{margin-bottom:.5rem;font-size:1.125rem;line-height:1.75rem;font-weight:500}.axp-state-message .__description{margin-bottom:1rem;opacity:74%;display:block;font-weight:400;font-size:.875rem!important;line-height:1.25rem!important}.axp-state-message .__actions{display:flex;flex-direction:column;align-items:center;gap:.5rem}.axp-state-message[data-mode=empty] .__icon i{--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.axp-state-message[data-mode=error] .__icon i{--tw-text-opacity: 1;color:rgb(239 68 68 / var(--tw-text-opacity, 1))}.axp-state-message[data-mode=error] .__title{--tw-text-opacity: 1;color:rgb(220 38 38 / var(--tw-text-opacity, 1))}.axp-state-message[data-mode=loading] .__icon i{--tw-text-opacity: 1;color:rgb(59 130 246 / var(--tw-text-opacity, 1))}.axp-state-message[data-mode=loading] .__title{--tw-text-opacity: 1;color:rgb(37 99 235 / var(--tw-text-opacity, 1))}.axp-state-message[data-mode=warning] .__icon i{--tw-text-opacity: 1;color:rgb(249 115 22 / var(--tw-text-opacity, 1))}.axp-state-message[data-mode=warning] .__title{--tw-text-opacity: 1;color:rgb(234 88 12 / var(--tw-text-opacity, 1))}.axp-state-message[data-mode=info] .__icon i{--tw-text-opacity: 1;color:rgb(59 130 246 / var(--tw-text-opacity, 1))}.axp-state-message[data-mode=info] .__title{--tw-text-opacity: 1;color:rgb(37 99 235 / var(--tw-text-opacity, 1))}.axp-state-message[data-mode=success] .__icon i{--tw-text-opacity: 1;color:rgb(34 197 94 / var(--tw-text-opacity, 1))}.axp-state-message[data-mode=success] .__title{--tw-text-opacity: 1;color:rgb(22 163 74 / var(--tw-text-opacity, 1))}.axp-state-message[data-variant=compact]{padding:1.5rem .75rem}.axp-state-message[data-variant=compact] .__icon{margin-bottom:.5rem}.axp-state-message[data-variant=compact] .__icon i{font-size:1.5rem!important;line-height:2rem!important}.axp-state-message[data-variant=compact] .__title{margin-bottom:.25rem;font-size:1rem;line-height:1.5rem}.axp-state-message[data-variant=compact] .__description{margin-bottom:.5rem;font-size:.75rem;line-height:1rem}.axp-state-message[data-variant=minimal]{padding:1rem .5rem}.axp-state-message[data-variant=minimal] .__icon{margin-bottom:.25rem}.axp-state-message[data-variant=minimal] .__icon i{font-size:1.25rem!important;line-height:1.75rem!important}.axp-state-message[data-variant=minimal] .__title{margin-bottom:.25rem;font-size:.875rem;line-height:1.25rem}.axp-state-message[data-variant=minimal] .__description{margin-bottom:.25rem;font-size:.75rem;line-height:1rem}\n"] }]
100
+ }] });
101
+
52
102
  //#region ---- Component Definition ----
53
103
  class AXPActivityLogComponent {
54
104
  //#endregion
@@ -178,10 +228,10 @@ class AXPActivityLogComponent {
178
228
  const currentIndex = this.activities().findIndex(a => a.id === activity.id);
179
229
  return currentIndex > 0; // Can compare if not the first activity
180
230
  }
181
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPActivityLogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
182
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", type: AXPActivityLogComponent, isStandalone: true, selector: "axp-activity-log", inputs: { activities: { classPropertyName: "activities", publicName: "activities", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"axp-activity-log ax-accent2\" *translate=\"let t\">\n\n <!-- Activity Log Content -->\n <div class=\"__content\">\n\n <!-- Loading State -->\n @if (loading()) {\n <div class=\"__loading\">\n @for (item of [1,2,3,4]; track $index) {\n <div class=\"__item\">\n <ax-skeleton [animated]=\"true\" class=\"__avatar\"></ax-skeleton>\n <div class=\"__content\">\n <ax-skeleton [animated]=\"true\" class=\"__title\"></ax-skeleton>\n <ax-skeleton [animated]=\"true\" class=\"__subtitle\"></ax-skeleton>\n <ax-skeleton [animated]=\"true\" class=\"__description\"></ax-skeleton>\n <ax-skeleton [animated]=\"true\" class=\"__time\"></ax-skeleton>\n </div>\n </div>\n }\n </div>\n }\n\n <!-- Activity Feed -->\n @if (!loading() && activities().length > 0) {\n <div class=\"__feed\">\n @for (activity of activities(); track activity.id) {\n @let changeClasses = getChangeClasses(activity.changeType);\n @let isItemExpanded = isExpanded(activity.id);\n @let hasExpandableContentItem = hasExpandableContent(activity);\n <div class=\"__item\" [class.__collapsed]=\"!isItemExpanded\" [class.__expandable]=\"hasExpandableContentItem\">\n\n <div\n class=\"ax-size-10 ax-rounded-full ax-border ax-flex ax-items-center ax-justify-center ax-lightest-surface \">\n <i class=\"{{changeClasses.icon}} {{changeClasses.text}} fa-solid\"></i>\n </div>\n\n <!-- Activity Content -->\n <div class=\"__content\">\n <!-- Main Activity Info -->\n <div class=\"__main-info\">\n\n <!-- User and Action with Toggle Button -->\n <div class=\"__action-line __header-line\" (click)=\"toggleExpanded(activity.id)\">\n <span class=\"__user-name\">{{ activity.user.title }}</span>\n <span class=\"__action-type\">\n {{ t(`actions.${activity.changeType}.title`, {\n scope: 'general' }) | async }}\n </span>\n <span class=\"__action-text\">\n {{ activity.title | translate | async }}\n </span>\n\n <!-- Compare Button -->\n @if (canCompare(activity)) {\n <button type=\"button\" class=\"__compare-button\" (click)=\"handleCompare(activity, $event)\"\n [attr.aria-label]=\"t('compare.title', { scope: i18nScope }) | async\">\n <i class=\"fa-solid fa-code-compare\"></i>\n </button>\n }\n\n <!-- Toggle Button (only show if there's expandable content) -->\n @if (hasExpandableContentItem) {\n <button type=\"button\" class=\"__toggle-button\" [attr.aria-expanded]=\"isItemExpanded\"\n [attr.aria-label]=\"isItemExpanded ? 'Collapse details' : 'Expand details'\">\n <i class=\"fa-solid\" [class.fa-chevron-down]=\"!isItemExpanded\"\n [class.fa-chevron-up]=\"isItemExpanded\"></i>\n </button>\n }\n </div>\n\n <!-- Expandable Description/Changes -->\n @if (hasExpandableContentItem && isItemExpanded && activity.changes.length > 0) {\n <div class=\"__action-lines __expandable-content\"\n [class.__animated]=\"shouldAnimate(activity.id)\">\n @for (change of activity.changes; track $index) {\n @let changeClasses = getChangeClasses(change.type);\n <div class=\"__action-line\">\n <div class=\"ax-rounded-full ax-size-7 ax-grid ax-place-items-center\">\n <i class=\"{{changeClasses.icon}} {{changeClasses.text}}\"></i>\n </div>\n <span class=\"__action-text\">{{\n change.description | translate | async }}</span>\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Time -->\n <div class=\"__time\">\n {{ activity.date | format: 'datetime' : 'short' | async }}\n </div>\n\n </div>\n\n </div>\n }\n </div>\n }\n\n <!-- Empty State -->\n @if (!loading() && activities().length === 0) {\n <div class=\"__empty\">\n <div class=\"__icon\">\n <ax-icon icon=\"fa-light fa-history\" class=\"__svg\"></ax-icon>\n </div>\n <div class=\"__content\">\n <h4 class=\"__title\">{{ t('no-history.title', { scope: i18nScope }) | async }}</h4>\n <p class=\"__message\">{{ t('no-history.message', { scope: i18nScope }) | async }}\n </p>\n </div>\n </div>\n }\n\n </div>\n</div>\n\n<!-- \n\nax-success-surface\nax-primary-surface\nax-danger-surface\nax-warning-surface\nax-info-surface\nax-muted-surface\nax-text-success\n\n -->", styles: [".axp-activity-log{height:100%;width:100%}.axp-activity-log .__content .__loading>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.axp-activity-log .__content .__loading .__item{display:flex;align-items:flex-start;gap:1rem}.axp-activity-log .__content .__loading .__item .__avatar{height:3rem;width:3rem;flex-shrink:0;border-radius:9999px}.axp-activity-log .__content .__loading .__item .__content{flex:1 1 0%}.axp-activity-log .__content .__loading .__item .__content>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.axp-activity-log .__content .__loading .__item .__content .__title{height:1rem;width:75%;border-radius:.25rem}.axp-activity-log .__content .__loading .__item .__content .__subtitle{height:.75rem;width:50%;border-radius:.25rem}.axp-activity-log .__content .__loading .__item .__content .__description{height:.75rem;width:83.333333%;border-radius:.25rem}.axp-activity-log .__content .__loading .__item .__content .__time{height:.75rem;width:25%;border-radius:.25rem}.axp-activity-log .__content .__feed{position:relative}.axp-activity-log .__content .__feed>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))}.axp-activity-log .__content .__feed:before{content:\"\";position:absolute;inset-inline-start:1.25rem;top:.5rem;bottom:.5rem;width:0px;border-left:1px solid rgba(var(--ax-sys-color-border-surface));z-index:0}.axp-activity-log .__content .__feed .__item{position:relative;display:flex;align-items:flex-start;gap:1rem}.axp-activity-log .__content .__feed .__item axp-user-avatar{position:relative;z-index:10}.axp-activity-log .__content .__feed .__item .__content{min-width:0px;flex:1 1 0%}.axp-activity-log .__content .__feed .__item .__content .__main-info{margin-bottom:.25rem}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line{margin-top:.25rem;display:flex;flex-wrap:wrap;align-items:center;gap:.25rem;line-height:1.5}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line .__user-name{font-weight:600}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line .__action-type,.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line .__action-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.875rem;line-height:1.25rem;opacity:.85}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line{align-items:center;border-radius:.375rem;padding:.25rem .5rem}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line:hover{background-color:rgb(var(--ax-sys-color-lighter-surface));color:rgb(var(--ax-sys-color-on-lighter-surface));border-color:rgb(var(--ax-sys-color-border-lighter-surface))}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line .__compare-button{margin-left:.5rem;border-radius:9999px;padding:.25rem;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s;animation-duration:.2s;display:flex;width:1.5rem;height:1.5rem;align-items:center;justify-content:center;--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-primary-500),var(--tw-text-opacity, 1))}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line .__compare-button:hover{background-color:rgb(var(--ax-sys-color-primary-surface));color:rgb(var(--ax-sys-color-on-primary-surface));border-color:rgb(var(--ax-sys-color-border-primary-surface))}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line .__compare-button:focus{outline:2px solid transparent;outline-offset:2px;--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000);--tw-ring-opacity: 1;--tw-ring-color: rgba(var(--ax-sys-color-primary-500), var(--tw-ring-opacity, 1));--tw-ring-offset-width: 1px}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line .__compare-button i{font-size:.75rem;line-height:1rem}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line .__toggle-button{margin-left:auto;border-radius:9999px;padding:.25rem;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s;animation-duration:.2s;display:flex;width:1.5rem;height:1.5rem;align-items:center;justify-content:center}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line .__toggle-button:focus{outline:2px solid transparent;outline-offset:2px;--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000);--tw-ring-opacity: 1;--tw-ring-color: rgba(var(--ax-sys-color-primary-500), var(--tw-ring-opacity, 1));--tw-ring-offset-width: 1px}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line .__toggle-button i{font-size:.75rem;line-height:1rem;transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s;animation-duration:.2s}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-lines{margin-top:.5rem;margin-bottom:.5rem;display:flex;flex-direction:column;font-size:.875rem;line-height:1.25rem}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-lines.__expandable-content{overflow:hidden}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-lines.__expandable-content.__animated{transition-property:all;transition-duration:.3s;transition-timing-function:cubic-bezier(.4,0,.2,1);animation-duration:.3s;animation-timing-function:cubic-bezier(.4,0,.2,1);animation:slideDown .3s ease-out}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-lines .__action-line{display:flex;align-items:center;gap:.5rem;padding-top:.25rem;padding-bottom:.25rem}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-lines .__action-line .__action-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.875rem;line-height:1.25rem;opacity:.85}.axp-activity-log .__content .__feed .__item .__content .__time{padding-left:.5rem;padding-right:.5rem;font-size:.75rem;line-height:1rem;opacity:.75}.axp-activity-log .__content .__feed .__item.__collapsed .__expandable-content{display:none}.axp-activity-log .__content .__feed .__item.__expandable .__header-line{cursor:pointer}.axp-activity-log .__content .__empty{display:flex;height:12rem;flex-direction:column;align-items:center;justify-content:center;padding:2rem;text-align:center}.axp-activity-log .__content .__empty .__icon{margin-bottom:1rem}.axp-activity-log .__content .__empty .__icon .__svg{font-size:2.25rem;line-height:2.5rem;--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.axp-activity-log .__content .__empty .__content .__title{margin-bottom:.5rem;font-size:1.125rem;line-height:1.75rem;font-weight:600;--tw-text-opacity: 1;color:rgb(17 24 39 / var(--tw-text-opacity, 1))}.axp-activity-log .__content .__empty .__content .__message{max-width:20rem;line-height:1.625;--tw-text-opacity: 1;color:rgb(75 85 99 / var(--tw-text-opacity, 1))}@media (min-width: 640px){.axp-activity-log .__content .__feed .__item{gap:.625rem}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line{flex-wrap:nowrap}}@keyframes slideDown{0%{opacity:0;max-height:0;transform:translateY(-10px)}to{opacity:1;max-height:200px;transform:translateY(0)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "ngmodule", type: AXCommonModule }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i3.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "directive", type: i2.AXTranslatorDirective, selector: "[translate]" }, { kind: "ngmodule", type: AXSkeletonModule }, { kind: "component", type: i3$1.AXSkeletonComponent, selector: "ax-skeleton", inputs: ["animated"] }, { kind: "ngmodule", type: AXFormatModule }, { kind: "ngmodule", type: AXTagModule }, { kind: "ngmodule", type: AXAccordionCdkModule }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }, { kind: "pipe", type: i2.AXTranslatorPipe, name: "translate" }, { kind: "pipe", type: i5.AXFormatPipe, name: "format" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
231
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPActivityLogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
232
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.8", type: AXPActivityLogComponent, isStandalone: true, selector: "axp-activity-log", inputs: { activities: { classPropertyName: "activities", publicName: "activities", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"axp-activity-log ax-accent2\" *translate=\"let t\">\n <!-- Activity Log Content -->\n <div class=\"__content\">\n <!-- Loading State -->\n @if (loading()) {\n <div class=\"__loading\">\n @for (item of [1, 2, 3, 4]; track $index) {\n <div class=\"__item\">\n <ax-skeleton [animated]=\"true\" class=\"__avatar\"></ax-skeleton>\n <div class=\"__content\">\n <ax-skeleton [animated]=\"true\" class=\"__title\"></ax-skeleton>\n <ax-skeleton [animated]=\"true\" class=\"__subtitle\"></ax-skeleton>\n <ax-skeleton [animated]=\"true\" class=\"__description\"></ax-skeleton>\n <ax-skeleton [animated]=\"true\" class=\"__time\"></ax-skeleton>\n </div>\n </div>\n }\n </div>\n }\n\n <!-- Activity Feed -->\n @if (!loading() && activities().length > 0) {\n <div class=\"__feed\">\n @for (activity of activities(); track activity.id) {\n @let changeClasses = getChangeClasses(activity.changeType);\n @let isItemExpanded = isExpanded(activity.id);\n @let hasExpandableContentItem = hasExpandableContent(activity);\n <div class=\"__item\" [class.__collapsed]=\"!isItemExpanded\" [class.__expandable]=\"hasExpandableContentItem\">\n <div\n class=\"ax-size-10 ax-rounded-full ax-border ax-flex ax-items-center ax-justify-center ax-lightest-surface\"\n >\n <i class=\"{{ changeClasses.icon }} {{ changeClasses.text }} fa-solid\"></i>\n </div>\n\n <!-- Activity Content -->\n <div class=\"__content\">\n <!-- Main Activity Info -->\n <div class=\"__main-info\">\n <!-- User and Action with Toggle Button -->\n <div class=\"__action-line __header-line\" (click)=\"toggleExpanded(activity.id)\">\n <span class=\"__user-name\">{{ activity.user.title }}</span>\n <span class=\"__action-type\">\n {{ t(`@general:actions.${activity.changeType}.title`) | async }}\n </span>\n <span class=\"__action-text\">\n {{ activity.title | translate | async }}\n </span>\n\n <!-- Compare Button -->\n @if (canCompare(activity)) {\n <button\n type=\"button\"\n class=\"__compare-button\"\n (click)=\"handleCompare(activity, $event)\"\n [attr.aria-label]=\"t('compare.title', { scope: i18nScope }) | async\"\n >\n <i class=\"fa-solid fa-code-compare\"></i>\n </button>\n }\n\n <!-- Toggle Button (only show if there's expandable content) -->\n @if (hasExpandableContentItem) {\n <button\n type=\"button\"\n class=\"__toggle-button\"\n [attr.aria-expanded]=\"isItemExpanded\"\n [attr.aria-label]=\"isItemExpanded ? 'Collapse details' : 'Expand details'\"\n >\n <i\n class=\"fa-solid\"\n [class.fa-chevron-down]=\"!isItemExpanded\"\n [class.fa-chevron-up]=\"isItemExpanded\"\n ></i>\n </button>\n }\n </div>\n\n <!-- Expandable Description/Changes -->\n @if (hasExpandableContentItem && isItemExpanded && activity.changes.length > 0) {\n <div class=\"__action-lines __expandable-content\" [class.__animated]=\"shouldAnimate(activity.id)\">\n @for (change of activity.changes; track $index) {\n @let changeClasses = getChangeClasses(change.type);\n <div class=\"__action-line\">\n <div class=\"ax-rounded-full ax-size-7 ax-grid ax-place-items-center\">\n <i class=\"{{ changeClasses.icon }} {{ changeClasses.text }}\"></i>\n </div>\n <span class=\"__action-text\">{{ change.description | translate | async }}</span>\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Time -->\n <div class=\"__time\">\n {{ activity.date | format: 'datetime' : 'short' | async }}\n </div>\n </div>\n </div>\n }\n </div>\n }\n\n <!-- Empty State -->\n @if (!loading() && activities().length === 0) {\n <axp-state-message\n icon=\"fa-light fa-history\"\n [title]=\"'@general:no-history.title'\"\n [description]=\"'@general:no-history.message'\"\n >\n </axp-state-message>\n }\n </div>\n</div>\n\n<!-- \n\nax-success-surface\nax-primary-surface\nax-danger-surface\nax-warning-surface\nax-info-surface\nax-muted-surface\nax-text-success\n\n -->\n", styles: [".axp-activity-log{height:100%;width:100%}.axp-activity-log .__content .__loading>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.axp-activity-log .__content .__loading .__item{display:flex;align-items:flex-start;gap:1rem}.axp-activity-log .__content .__loading .__item .__avatar{height:3rem;width:3rem;flex-shrink:0;border-radius:9999px}.axp-activity-log .__content .__loading .__item .__content{flex:1 1 0%}.axp-activity-log .__content .__loading .__item .__content>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.axp-activity-log .__content .__loading .__item .__content .__title{height:1rem;width:75%;border-radius:.25rem}.axp-activity-log .__content .__loading .__item .__content .__subtitle{height:.75rem;width:50%;border-radius:.25rem}.axp-activity-log .__content .__loading .__item .__content .__description{height:.75rem;width:83.333333%;border-radius:.25rem}.axp-activity-log .__content .__loading .__item .__content .__time{height:.75rem;width:25%;border-radius:.25rem}.axp-activity-log .__content .__feed{position:relative}.axp-activity-log .__content .__feed>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))}.axp-activity-log .__content .__feed:before{content:\"\";position:absolute;inset-inline-start:1.25rem;top:.5rem;bottom:.5rem;width:0px;border-left:1px solid rgba(var(--ax-sys-color-border-surface));z-index:0}.axp-activity-log .__content .__feed .__item{position:relative;display:flex;align-items:flex-start;gap:1rem}.axp-activity-log .__content .__feed .__item axp-user-avatar{position:relative;z-index:10}.axp-activity-log .__content .__feed .__item .__content{min-width:0px;flex:1 1 0%}.axp-activity-log .__content .__feed .__item .__content .__main-info{margin-bottom:.25rem}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line{margin-top:.25rem;display:flex;flex-wrap:wrap;align-items:center;gap:.25rem;line-height:1.5}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line .__user-name{font-weight:600}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line .__action-type,.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line .__action-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.875rem;line-height:1.25rem;opacity:.85}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line{align-items:center;border-radius:.375rem;padding:.25rem .5rem}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line:hover{background-color:rgb(var(--ax-sys-color-lighter-surface));color:rgb(var(--ax-sys-color-on-lighter-surface));border-color:rgb(var(--ax-sys-color-border-lighter-surface))}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line .__compare-button{margin-left:.5rem;border-radius:9999px;padding:.25rem;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s;animation-duration:.2s;display:flex;width:1.5rem;height:1.5rem;align-items:center;justify-content:center;--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-primary-500),var(--tw-text-opacity, 1))}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line .__compare-button:hover{background-color:rgb(var(--ax-sys-color-primary-surface));color:rgb(var(--ax-sys-color-on-primary-surface));border-color:rgb(var(--ax-sys-color-border-primary-surface))}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line .__compare-button:focus{outline:2px solid transparent;outline-offset:2px;--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000);--tw-ring-opacity: 1;--tw-ring-color: rgba(var(--ax-sys-color-primary-500), var(--tw-ring-opacity, 1));--tw-ring-offset-width: 1px}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line .__compare-button i{font-size:.75rem;line-height:1rem}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line .__toggle-button{margin-left:auto;border-radius:9999px;padding:.25rem;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s;animation-duration:.2s;display:flex;width:1.5rem;height:1.5rem;align-items:center;justify-content:center}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line .__toggle-button:focus{outline:2px solid transparent;outline-offset:2px;--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000);--tw-ring-opacity: 1;--tw-ring-color: rgba(var(--ax-sys-color-primary-500), var(--tw-ring-opacity, 1));--tw-ring-offset-width: 1px}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line .__toggle-button i{font-size:.75rem;line-height:1rem;transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s;animation-duration:.2s}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-lines{margin-top:.5rem;margin-bottom:.5rem;display:flex;flex-direction:column;font-size:.875rem;line-height:1.25rem}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-lines.__expandable-content{overflow:hidden}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-lines.__expandable-content.__animated{transition-property:all;transition-duration:.3s;transition-timing-function:cubic-bezier(.4,0,.2,1);animation-duration:.3s;animation-timing-function:cubic-bezier(.4,0,.2,1);animation:slideDown .3s ease-out}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-lines .__action-line{display:flex;align-items:center;gap:.5rem;padding-top:.25rem;padding-bottom:.25rem}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-lines .__action-line .__action-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.875rem;line-height:1.25rem;opacity:.85}.axp-activity-log .__content .__feed .__item .__content .__time{padding-left:.5rem;padding-right:.5rem;font-size:.75rem;line-height:1rem;opacity:.75}.axp-activity-log .__content .__feed .__item.__collapsed .__expandable-content{display:none}.axp-activity-log .__content .__feed .__item.__expandable .__header-line{cursor:pointer}@media (min-width: 640px){.axp-activity-log .__content .__feed .__item{gap:.625rem}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line{flex-wrap:nowrap}}@keyframes slideDown{0%{opacity:0;max-height:0;transform:translateY(-10px)}to{opacity:1;max-height:200px;transform:translateY(0)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "ngmodule", type: AXCommonModule }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "directive", type: i5.AXTranslatorDirective, selector: "[translate]" }, { kind: "ngmodule", type: AXSkeletonModule }, { kind: "component", type: i2.AXSkeletonComponent, selector: "ax-skeleton", inputs: ["animated"] }, { kind: "ngmodule", type: AXFormatModule }, { kind: "ngmodule", type: AXTagModule }, { kind: "ngmodule", type: AXAccordionCdkModule }, { kind: "component", type: AXPStateMessageComponent, selector: "axp-state-message", inputs: ["mode", "icon", "title", "description", "variant"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }, { kind: "pipe", type: i4.AXFormatPipe, name: "format" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
183
233
  }
184
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPActivityLogComponent, decorators: [{
234
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPActivityLogComponent, decorators: [{
185
235
  type: Component,
186
236
  args: [{ selector: 'axp-activity-log', standalone: true, imports: [
187
237
  CommonModule,
@@ -193,7 +243,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
193
243
  AXFormatModule,
194
244
  AXTagModule,
195
245
  AXAccordionCdkModule,
196
- ], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<div class=\"axp-activity-log ax-accent2\" *translate=\"let t\">\n\n <!-- Activity Log Content -->\n <div class=\"__content\">\n\n <!-- Loading State -->\n @if (loading()) {\n <div class=\"__loading\">\n @for (item of [1,2,3,4]; track $index) {\n <div class=\"__item\">\n <ax-skeleton [animated]=\"true\" class=\"__avatar\"></ax-skeleton>\n <div class=\"__content\">\n <ax-skeleton [animated]=\"true\" class=\"__title\"></ax-skeleton>\n <ax-skeleton [animated]=\"true\" class=\"__subtitle\"></ax-skeleton>\n <ax-skeleton [animated]=\"true\" class=\"__description\"></ax-skeleton>\n <ax-skeleton [animated]=\"true\" class=\"__time\"></ax-skeleton>\n </div>\n </div>\n }\n </div>\n }\n\n <!-- Activity Feed -->\n @if (!loading() && activities().length > 0) {\n <div class=\"__feed\">\n @for (activity of activities(); track activity.id) {\n @let changeClasses = getChangeClasses(activity.changeType);\n @let isItemExpanded = isExpanded(activity.id);\n @let hasExpandableContentItem = hasExpandableContent(activity);\n <div class=\"__item\" [class.__collapsed]=\"!isItemExpanded\" [class.__expandable]=\"hasExpandableContentItem\">\n\n <div\n class=\"ax-size-10 ax-rounded-full ax-border ax-flex ax-items-center ax-justify-center ax-lightest-surface \">\n <i class=\"{{changeClasses.icon}} {{changeClasses.text}} fa-solid\"></i>\n </div>\n\n <!-- Activity Content -->\n <div class=\"__content\">\n <!-- Main Activity Info -->\n <div class=\"__main-info\">\n\n <!-- User and Action with Toggle Button -->\n <div class=\"__action-line __header-line\" (click)=\"toggleExpanded(activity.id)\">\n <span class=\"__user-name\">{{ activity.user.title }}</span>\n <span class=\"__action-type\">\n {{ t(`actions.${activity.changeType}.title`, {\n scope: 'general' }) | async }}\n </span>\n <span class=\"__action-text\">\n {{ activity.title | translate | async }}\n </span>\n\n <!-- Compare Button -->\n @if (canCompare(activity)) {\n <button type=\"button\" class=\"__compare-button\" (click)=\"handleCompare(activity, $event)\"\n [attr.aria-label]=\"t('compare.title', { scope: i18nScope }) | async\">\n <i class=\"fa-solid fa-code-compare\"></i>\n </button>\n }\n\n <!-- Toggle Button (only show if there's expandable content) -->\n @if (hasExpandableContentItem) {\n <button type=\"button\" class=\"__toggle-button\" [attr.aria-expanded]=\"isItemExpanded\"\n [attr.aria-label]=\"isItemExpanded ? 'Collapse details' : 'Expand details'\">\n <i class=\"fa-solid\" [class.fa-chevron-down]=\"!isItemExpanded\"\n [class.fa-chevron-up]=\"isItemExpanded\"></i>\n </button>\n }\n </div>\n\n <!-- Expandable Description/Changes -->\n @if (hasExpandableContentItem && isItemExpanded && activity.changes.length > 0) {\n <div class=\"__action-lines __expandable-content\"\n [class.__animated]=\"shouldAnimate(activity.id)\">\n @for (change of activity.changes; track $index) {\n @let changeClasses = getChangeClasses(change.type);\n <div class=\"__action-line\">\n <div class=\"ax-rounded-full ax-size-7 ax-grid ax-place-items-center\">\n <i class=\"{{changeClasses.icon}} {{changeClasses.text}}\"></i>\n </div>\n <span class=\"__action-text\">{{\n change.description | translate | async }}</span>\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Time -->\n <div class=\"__time\">\n {{ activity.date | format: 'datetime' : 'short' | async }}\n </div>\n\n </div>\n\n </div>\n }\n </div>\n }\n\n <!-- Empty State -->\n @if (!loading() && activities().length === 0) {\n <div class=\"__empty\">\n <div class=\"__icon\">\n <ax-icon icon=\"fa-light fa-history\" class=\"__svg\"></ax-icon>\n </div>\n <div class=\"__content\">\n <h4 class=\"__title\">{{ t('no-history.title', { scope: i18nScope }) | async }}</h4>\n <p class=\"__message\">{{ t('no-history.message', { scope: i18nScope }) | async }}\n </p>\n </div>\n </div>\n }\n\n </div>\n</div>\n\n<!-- \n\nax-success-surface\nax-primary-surface\nax-danger-surface\nax-warning-surface\nax-info-surface\nax-muted-surface\nax-text-success\n\n -->", styles: [".axp-activity-log{height:100%;width:100%}.axp-activity-log .__content .__loading>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.axp-activity-log .__content .__loading .__item{display:flex;align-items:flex-start;gap:1rem}.axp-activity-log .__content .__loading .__item .__avatar{height:3rem;width:3rem;flex-shrink:0;border-radius:9999px}.axp-activity-log .__content .__loading .__item .__content{flex:1 1 0%}.axp-activity-log .__content .__loading .__item .__content>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.axp-activity-log .__content .__loading .__item .__content .__title{height:1rem;width:75%;border-radius:.25rem}.axp-activity-log .__content .__loading .__item .__content .__subtitle{height:.75rem;width:50%;border-radius:.25rem}.axp-activity-log .__content .__loading .__item .__content .__description{height:.75rem;width:83.333333%;border-radius:.25rem}.axp-activity-log .__content .__loading .__item .__content .__time{height:.75rem;width:25%;border-radius:.25rem}.axp-activity-log .__content .__feed{position:relative}.axp-activity-log .__content .__feed>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))}.axp-activity-log .__content .__feed:before{content:\"\";position:absolute;inset-inline-start:1.25rem;top:.5rem;bottom:.5rem;width:0px;border-left:1px solid rgba(var(--ax-sys-color-border-surface));z-index:0}.axp-activity-log .__content .__feed .__item{position:relative;display:flex;align-items:flex-start;gap:1rem}.axp-activity-log .__content .__feed .__item axp-user-avatar{position:relative;z-index:10}.axp-activity-log .__content .__feed .__item .__content{min-width:0px;flex:1 1 0%}.axp-activity-log .__content .__feed .__item .__content .__main-info{margin-bottom:.25rem}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line{margin-top:.25rem;display:flex;flex-wrap:wrap;align-items:center;gap:.25rem;line-height:1.5}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line .__user-name{font-weight:600}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line .__action-type,.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line .__action-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.875rem;line-height:1.25rem;opacity:.85}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line{align-items:center;border-radius:.375rem;padding:.25rem .5rem}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line:hover{background-color:rgb(var(--ax-sys-color-lighter-surface));color:rgb(var(--ax-sys-color-on-lighter-surface));border-color:rgb(var(--ax-sys-color-border-lighter-surface))}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line .__compare-button{margin-left:.5rem;border-radius:9999px;padding:.25rem;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s;animation-duration:.2s;display:flex;width:1.5rem;height:1.5rem;align-items:center;justify-content:center;--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-primary-500),var(--tw-text-opacity, 1))}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line .__compare-button:hover{background-color:rgb(var(--ax-sys-color-primary-surface));color:rgb(var(--ax-sys-color-on-primary-surface));border-color:rgb(var(--ax-sys-color-border-primary-surface))}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line .__compare-button:focus{outline:2px solid transparent;outline-offset:2px;--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000);--tw-ring-opacity: 1;--tw-ring-color: rgba(var(--ax-sys-color-primary-500), var(--tw-ring-opacity, 1));--tw-ring-offset-width: 1px}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line .__compare-button i{font-size:.75rem;line-height:1rem}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line .__toggle-button{margin-left:auto;border-radius:9999px;padding:.25rem;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s;animation-duration:.2s;display:flex;width:1.5rem;height:1.5rem;align-items:center;justify-content:center}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line .__toggle-button:focus{outline:2px solid transparent;outline-offset:2px;--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000);--tw-ring-opacity: 1;--tw-ring-color: rgba(var(--ax-sys-color-primary-500), var(--tw-ring-opacity, 1));--tw-ring-offset-width: 1px}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line .__toggle-button i{font-size:.75rem;line-height:1rem;transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s;animation-duration:.2s}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-lines{margin-top:.5rem;margin-bottom:.5rem;display:flex;flex-direction:column;font-size:.875rem;line-height:1.25rem}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-lines.__expandable-content{overflow:hidden}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-lines.__expandable-content.__animated{transition-property:all;transition-duration:.3s;transition-timing-function:cubic-bezier(.4,0,.2,1);animation-duration:.3s;animation-timing-function:cubic-bezier(.4,0,.2,1);animation:slideDown .3s ease-out}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-lines .__action-line{display:flex;align-items:center;gap:.5rem;padding-top:.25rem;padding-bottom:.25rem}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-lines .__action-line .__action-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.875rem;line-height:1.25rem;opacity:.85}.axp-activity-log .__content .__feed .__item .__content .__time{padding-left:.5rem;padding-right:.5rem;font-size:.75rem;line-height:1rem;opacity:.75}.axp-activity-log .__content .__feed .__item.__collapsed .__expandable-content{display:none}.axp-activity-log .__content .__feed .__item.__expandable .__header-line{cursor:pointer}.axp-activity-log .__content .__empty{display:flex;height:12rem;flex-direction:column;align-items:center;justify-content:center;padding:2rem;text-align:center}.axp-activity-log .__content .__empty .__icon{margin-bottom:1rem}.axp-activity-log .__content .__empty .__icon .__svg{font-size:2.25rem;line-height:2.5rem;--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.axp-activity-log .__content .__empty .__content .__title{margin-bottom:.5rem;font-size:1.125rem;line-height:1.75rem;font-weight:600;--tw-text-opacity: 1;color:rgb(17 24 39 / var(--tw-text-opacity, 1))}.axp-activity-log .__content .__empty .__content .__message{max-width:20rem;line-height:1.625;--tw-text-opacity: 1;color:rgb(75 85 99 / var(--tw-text-opacity, 1))}@media (min-width: 640px){.axp-activity-log .__content .__feed .__item{gap:.625rem}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line{flex-wrap:nowrap}}@keyframes slideDown{0%{opacity:0;max-height:0;transform:translateY(-10px)}to{opacity:1;max-height:200px;transform:translateY(0)}}\n"] }]
246
+ AXPStateMessageComponent,
247
+ ], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<div class=\"axp-activity-log ax-accent2\" *translate=\"let t\">\n <!-- Activity Log Content -->\n <div class=\"__content\">\n <!-- Loading State -->\n @if (loading()) {\n <div class=\"__loading\">\n @for (item of [1, 2, 3, 4]; track $index) {\n <div class=\"__item\">\n <ax-skeleton [animated]=\"true\" class=\"__avatar\"></ax-skeleton>\n <div class=\"__content\">\n <ax-skeleton [animated]=\"true\" class=\"__title\"></ax-skeleton>\n <ax-skeleton [animated]=\"true\" class=\"__subtitle\"></ax-skeleton>\n <ax-skeleton [animated]=\"true\" class=\"__description\"></ax-skeleton>\n <ax-skeleton [animated]=\"true\" class=\"__time\"></ax-skeleton>\n </div>\n </div>\n }\n </div>\n }\n\n <!-- Activity Feed -->\n @if (!loading() && activities().length > 0) {\n <div class=\"__feed\">\n @for (activity of activities(); track activity.id) {\n @let changeClasses = getChangeClasses(activity.changeType);\n @let isItemExpanded = isExpanded(activity.id);\n @let hasExpandableContentItem = hasExpandableContent(activity);\n <div class=\"__item\" [class.__collapsed]=\"!isItemExpanded\" [class.__expandable]=\"hasExpandableContentItem\">\n <div\n class=\"ax-size-10 ax-rounded-full ax-border ax-flex ax-items-center ax-justify-center ax-lightest-surface\"\n >\n <i class=\"{{ changeClasses.icon }} {{ changeClasses.text }} fa-solid\"></i>\n </div>\n\n <!-- Activity Content -->\n <div class=\"__content\">\n <!-- Main Activity Info -->\n <div class=\"__main-info\">\n <!-- User and Action with Toggle Button -->\n <div class=\"__action-line __header-line\" (click)=\"toggleExpanded(activity.id)\">\n <span class=\"__user-name\">{{ activity.user.title }}</span>\n <span class=\"__action-type\">\n {{ t(`@general:actions.${activity.changeType}.title`) | async }}\n </span>\n <span class=\"__action-text\">\n {{ activity.title | translate | async }}\n </span>\n\n <!-- Compare Button -->\n @if (canCompare(activity)) {\n <button\n type=\"button\"\n class=\"__compare-button\"\n (click)=\"handleCompare(activity, $event)\"\n [attr.aria-label]=\"t('compare.title', { scope: i18nScope }) | async\"\n >\n <i class=\"fa-solid fa-code-compare\"></i>\n </button>\n }\n\n <!-- Toggle Button (only show if there's expandable content) -->\n @if (hasExpandableContentItem) {\n <button\n type=\"button\"\n class=\"__toggle-button\"\n [attr.aria-expanded]=\"isItemExpanded\"\n [attr.aria-label]=\"isItemExpanded ? 'Collapse details' : 'Expand details'\"\n >\n <i\n class=\"fa-solid\"\n [class.fa-chevron-down]=\"!isItemExpanded\"\n [class.fa-chevron-up]=\"isItemExpanded\"\n ></i>\n </button>\n }\n </div>\n\n <!-- Expandable Description/Changes -->\n @if (hasExpandableContentItem && isItemExpanded && activity.changes.length > 0) {\n <div class=\"__action-lines __expandable-content\" [class.__animated]=\"shouldAnimate(activity.id)\">\n @for (change of activity.changes; track $index) {\n @let changeClasses = getChangeClasses(change.type);\n <div class=\"__action-line\">\n <div class=\"ax-rounded-full ax-size-7 ax-grid ax-place-items-center\">\n <i class=\"{{ changeClasses.icon }} {{ changeClasses.text }}\"></i>\n </div>\n <span class=\"__action-text\">{{ change.description | translate | async }}</span>\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Time -->\n <div class=\"__time\">\n {{ activity.date | format: 'datetime' : 'short' | async }}\n </div>\n </div>\n </div>\n }\n </div>\n }\n\n <!-- Empty State -->\n @if (!loading() && activities().length === 0) {\n <axp-state-message\n icon=\"fa-light fa-history\"\n [title]=\"'@general:no-history.title'\"\n [description]=\"'@general:no-history.message'\"\n >\n </axp-state-message>\n }\n </div>\n</div>\n\n<!-- \n\nax-success-surface\nax-primary-surface\nax-danger-surface\nax-warning-surface\nax-info-surface\nax-muted-surface\nax-text-success\n\n -->\n", styles: [".axp-activity-log{height:100%;width:100%}.axp-activity-log .__content .__loading>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.axp-activity-log .__content .__loading .__item{display:flex;align-items:flex-start;gap:1rem}.axp-activity-log .__content .__loading .__item .__avatar{height:3rem;width:3rem;flex-shrink:0;border-radius:9999px}.axp-activity-log .__content .__loading .__item .__content{flex:1 1 0%}.axp-activity-log .__content .__loading .__item .__content>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.axp-activity-log .__content .__loading .__item .__content .__title{height:1rem;width:75%;border-radius:.25rem}.axp-activity-log .__content .__loading .__item .__content .__subtitle{height:.75rem;width:50%;border-radius:.25rem}.axp-activity-log .__content .__loading .__item .__content .__description{height:.75rem;width:83.333333%;border-radius:.25rem}.axp-activity-log .__content .__loading .__item .__content .__time{height:.75rem;width:25%;border-radius:.25rem}.axp-activity-log .__content .__feed{position:relative}.axp-activity-log .__content .__feed>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))}.axp-activity-log .__content .__feed:before{content:\"\";position:absolute;inset-inline-start:1.25rem;top:.5rem;bottom:.5rem;width:0px;border-left:1px solid rgba(var(--ax-sys-color-border-surface));z-index:0}.axp-activity-log .__content .__feed .__item{position:relative;display:flex;align-items:flex-start;gap:1rem}.axp-activity-log .__content .__feed .__item axp-user-avatar{position:relative;z-index:10}.axp-activity-log .__content .__feed .__item .__content{min-width:0px;flex:1 1 0%}.axp-activity-log .__content .__feed .__item .__content .__main-info{margin-bottom:.25rem}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line{margin-top:.25rem;display:flex;flex-wrap:wrap;align-items:center;gap:.25rem;line-height:1.5}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line .__user-name{font-weight:600}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line .__action-type,.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line .__action-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.875rem;line-height:1.25rem;opacity:.85}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line{align-items:center;border-radius:.375rem;padding:.25rem .5rem}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line:hover{background-color:rgb(var(--ax-sys-color-lighter-surface));color:rgb(var(--ax-sys-color-on-lighter-surface));border-color:rgb(var(--ax-sys-color-border-lighter-surface))}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line .__compare-button{margin-left:.5rem;border-radius:9999px;padding:.25rem;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s;animation-duration:.2s;display:flex;width:1.5rem;height:1.5rem;align-items:center;justify-content:center;--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-primary-500),var(--tw-text-opacity, 1))}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line .__compare-button:hover{background-color:rgb(var(--ax-sys-color-primary-surface));color:rgb(var(--ax-sys-color-on-primary-surface));border-color:rgb(var(--ax-sys-color-border-primary-surface))}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line .__compare-button:focus{outline:2px solid transparent;outline-offset:2px;--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000);--tw-ring-opacity: 1;--tw-ring-color: rgba(var(--ax-sys-color-primary-500), var(--tw-ring-opacity, 1));--tw-ring-offset-width: 1px}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line .__compare-button i{font-size:.75rem;line-height:1rem}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line .__toggle-button{margin-left:auto;border-radius:9999px;padding:.25rem;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s;animation-duration:.2s;display:flex;width:1.5rem;height:1.5rem;align-items:center;justify-content:center}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line .__toggle-button:focus{outline:2px solid transparent;outline-offset:2px;--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000);--tw-ring-opacity: 1;--tw-ring-color: rgba(var(--ax-sys-color-primary-500), var(--tw-ring-opacity, 1));--tw-ring-offset-width: 1px}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line .__toggle-button i{font-size:.75rem;line-height:1rem;transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s;animation-duration:.2s}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-lines{margin-top:.5rem;margin-bottom:.5rem;display:flex;flex-direction:column;font-size:.875rem;line-height:1.25rem}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-lines.__expandable-content{overflow:hidden}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-lines.__expandable-content.__animated{transition-property:all;transition-duration:.3s;transition-timing-function:cubic-bezier(.4,0,.2,1);animation-duration:.3s;animation-timing-function:cubic-bezier(.4,0,.2,1);animation:slideDown .3s ease-out}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-lines .__action-line{display:flex;align-items:center;gap:.5rem;padding-top:.25rem;padding-bottom:.25rem}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-lines .__action-line .__action-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.875rem;line-height:1.25rem;opacity:.85}.axp-activity-log .__content .__feed .__item .__content .__time{padding-left:.5rem;padding-right:.5rem;font-size:.75rem;line-height:1rem;opacity:.75}.axp-activity-log .__content .__feed .__item.__collapsed .__expandable-content{display:none}.axp-activity-log .__content .__feed .__item.__expandable .__header-line{cursor:pointer}@media (min-width: 640px){.axp-activity-log .__content .__feed .__item{gap:.625rem}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line{flex-wrap:nowrap}}@keyframes slideDown{0%{opacity:0;max-height:0;transform:translateY(-10px)}to{opacity:1;max-height:200px;transform:translateY(0)}}\n"] }]
197
248
  }], ctorParameters: () => [] });
198
249
 
199
250
  const AXP_TASK_BADGE_PROVIDERS = new InjectionToken('AXP_TASK_BADGE_PROVIDERS');
@@ -221,10 +272,10 @@ class AXPTaskBadgeService {
221
272
  this.computedCache.set(key, total);
222
273
  return total;
223
274
  }
224
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPTaskBadgeService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
225
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPTaskBadgeService, providedIn: 'root' }); }
275
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPTaskBadgeService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
276
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPTaskBadgeService, providedIn: 'root' }); }
226
277
  }
227
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPTaskBadgeService, decorators: [{
278
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPTaskBadgeService, decorators: [{
228
279
  type: Injectable,
229
280
  args: [{ providedIn: 'root' }]
230
281
  }], ctorParameters: () => [] });
@@ -255,10 +306,10 @@ class AXPTaskBadgeDirective {
255
306
  const node = signal[SIGNAL];
256
307
  signalSetFn(node, value);
257
308
  }
258
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPTaskBadgeDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
259
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.1.6", type: AXPTaskBadgeDirective, isStandalone: true, selector: "[axp-task-badge]", inputs: { badgeKey: { classPropertyName: "badgeKey", publicName: "badgeKey", isSignal: true, isRequired: false, transformFunction: null }, count: { classPropertyName: "count", publicName: "axp-task-badge", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
309
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPTaskBadgeDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
310
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.1.8", type: AXPTaskBadgeDirective, isStandalone: true, selector: "[axp-task-badge]", inputs: { badgeKey: { classPropertyName: "badgeKey", publicName: "badgeKey", isSignal: true, isRequired: false, transformFunction: null }, count: { classPropertyName: "count", publicName: "axp-task-badge", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
260
311
  }
261
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPTaskBadgeDirective, decorators: [{
312
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPTaskBadgeDirective, decorators: [{
262
313
  type: Directive,
263
314
  args: [{
264
315
  selector: '[axp-task-badge]',
@@ -280,10 +331,10 @@ class AXPMenuBadgeHelper {
280
331
  }
281
332
 
282
333
  class AXPThemeLayoutPagePrimaryActionsComponent {
283
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPThemeLayoutPagePrimaryActionsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
284
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.6", type: AXPThemeLayoutPagePrimaryActionsComponent, isStandalone: true, selector: "axp-layout-actions-primary", ngImport: i0, template: `<ng-content select="ax-button,ax-dropdown-button"></ng-content>`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
334
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutPagePrimaryActionsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
335
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.8", type: AXPThemeLayoutPagePrimaryActionsComponent, isStandalone: true, selector: "axp-layout-actions-primary", ngImport: i0, template: `<ng-content select="ax-button,ax-dropdown-button"></ng-content>`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
285
336
  }
286
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPThemeLayoutPagePrimaryActionsComponent, decorators: [{
337
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutPagePrimaryActionsComponent, decorators: [{
287
338
  type: Component,
288
339
  args: [{
289
340
  standalone: true,
@@ -294,10 +345,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
294
345
  }]
295
346
  }] });
296
347
  class AXPThemeLayoutPageSecondaryActionsComponent {
297
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPThemeLayoutPageSecondaryActionsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
298
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.6", type: AXPThemeLayoutPageSecondaryActionsComponent, isStandalone: true, selector: "axp-layout-actions-secondary", ngImport: i0, template: `<ng-content select="ax-button-item,ax-divider,ng-container"></ng-content>`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
348
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutPageSecondaryActionsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
349
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.8", type: AXPThemeLayoutPageSecondaryActionsComponent, isStandalone: true, selector: "axp-layout-actions-secondary", ngImport: i0, template: `<ng-content select="ax-button-item,ax-divider,ng-container"></ng-content>`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
299
350
  }
300
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPThemeLayoutPageSecondaryActionsComponent, decorators: [{
351
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutPageSecondaryActionsComponent, decorators: [{
301
352
  type: Component,
302
353
  args: [{
303
354
  standalone: true,
@@ -316,8 +367,8 @@ class AXPThemeLayoutActionsComponent {
316
367
  this.secondaryContent = contentChild(AXPThemeLayoutPageSecondaryActionsComponent, ...(ngDevMode ? [{ debugName: "secondaryContent" }] : []));
317
368
  this.hasSecondary = computed(() => this.secondaryContent() != null, ...(ngDevMode ? [{ debugName: "hasSecondary" }] : []));
318
369
  }
319
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPThemeLayoutActionsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
320
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "20.1.6", type: AXPThemeLayoutActionsComponent, isStandalone: true, selector: "axp-layout-actions", queries: [{ propertyName: "primaryContent", first: true, predicate: AXPThemeLayoutPagePrimaryActionsComponent, descendants: true, isSignal: true }, { propertyName: "secondaryContent", first: true, predicate: AXPThemeLayoutPageSecondaryActionsComponent, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "primaryTemplate", first: true, predicate: ["primary"], descendants: true, isSignal: true }, { propertyName: "secondaryTemplate", first: true, predicate: ["secondary"], descendants: true, isSignal: true }], ngImport: i0, template: `
370
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutActionsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
371
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "20.1.8", type: AXPThemeLayoutActionsComponent, isStandalone: true, selector: "axp-layout-actions", queries: [{ propertyName: "primaryContent", first: true, predicate: AXPThemeLayoutPagePrimaryActionsComponent, descendants: true, isSignal: true }, { propertyName: "secondaryContent", first: true, predicate: AXPThemeLayoutPageSecondaryActionsComponent, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "primaryTemplate", first: true, predicate: ["primary"], descendants: true, isSignal: true }, { propertyName: "secondaryTemplate", first: true, predicate: ["secondary"], descendants: true, isSignal: true }], ngImport: i0, template: `
321
372
 
322
373
  <ng-template #primary>
323
374
  <ng-content select="axp-layout-actions-primary"></ng-content>
@@ -330,7 +381,7 @@ class AXPThemeLayoutActionsComponent {
330
381
  <ng-content></ng-content>
331
382
  `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
332
383
  }
333
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPThemeLayoutActionsComponent, decorators: [{
384
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutActionsComponent, decorators: [{
334
385
  type: Component,
335
386
  args: [{
336
387
  imports: [],
@@ -358,10 +409,10 @@ class AXPThemeLayoutBlockComponent {
358
409
  this.elementRef = inject(ElementRef);
359
410
  this.hostElement = this.elementRef.nativeElement;
360
411
  }
361
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPThemeLayoutBlockComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
362
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.6", type: AXPThemeLayoutBlockComponent, isStandalone: true, selector: "\n\n axp-page-content, \n axp-page-footer-container,\n axp-page-footer,\n axp-page-header,\n axp-page-header-container,\n axp-page-toolbar,\n\n axp-layout-content, \n axp-layout-page-content, \n\n axp-layout-sections,\n axp-layout-body,\n axp-layout-page-body,\n axp-layout-prefix,\n axp-layout-suffix,\n axp-layout-title-bar,\n axp-layout-title, \n axp-layout-title-actions, \n axp-layout-nav-button, \n axp-layout-description, \n axp-layout-breadcrumbs,\n axp-layout-list-action,\n ", ngImport: i0, template: '<ng-content></ng-content>', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
412
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutBlockComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
413
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.8", type: AXPThemeLayoutBlockComponent, isStandalone: true, selector: "\n\n axp-page-content, \n axp-page-footer-container,\n axp-page-footer,\n axp-page-header,\n axp-page-header-container,\n axp-page-toolbar,\n\n axp-layout-content, \n axp-layout-page-content, \n\n axp-layout-sections,\n axp-layout-body,\n axp-layout-page-body,\n axp-layout-prefix,\n axp-layout-suffix,\n axp-layout-title-bar,\n axp-layout-title, \n axp-layout-title-actions, \n axp-layout-nav-button, \n axp-layout-description, \n axp-layout-breadcrumbs,\n axp-layout-list-action,\n ", ngImport: i0, template: '<ng-content></ng-content>', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
363
414
  }
364
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPThemeLayoutBlockComponent, decorators: [{
415
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutBlockComponent, decorators: [{
365
416
  type: Component,
366
417
  args: [{
367
418
  standalone: true,
@@ -397,14 +448,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
397
448
  }] });
398
449
 
399
450
  class AXPThemeLayoutFooterComponent {
400
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPThemeLayoutFooterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
401
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.6", type: AXPThemeLayoutFooterComponent, isStandalone: true, selector: "axp-layout-footer, axp-layout-page-footer", ngImport: i0, template: `
451
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutFooterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
452
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.8", type: AXPThemeLayoutFooterComponent, isStandalone: true, selector: "axp-layout-footer, axp-layout-page-footer", ngImport: i0, template: `
402
453
  <ng-content select="axp-layout-prefix"></ng-content>
403
454
  <ng-content></ng-content>
404
455
  <ng-content select="axp-layout-suffix"></ng-content>
405
456
  `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
406
457
  }
407
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPThemeLayoutFooterComponent, decorators: [{
458
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutFooterComponent, decorators: [{
408
459
  type: Component,
409
460
  args: [{
410
461
  imports: [],
@@ -429,8 +480,8 @@ class AXPThemeLayoutPageHeaderComponent {
429
480
  this.breadcrumbs = viewChild('breadcrumbs', ...(ngDevMode ? [{ debugName: "breadcrumbs" }] : []));
430
481
  this.navButton = viewChild('navButton', ...(ngDevMode ? [{ debugName: "navButton" }] : []));
431
482
  }
432
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPThemeLayoutPageHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
433
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "20.1.6", type: AXPThemeLayoutPageHeaderComponent, isStandalone: true, selector: "axp-layout-page-header", viewQueries: [{ propertyName: "title", first: true, predicate: ["title"], descendants: true, isSignal: true }, { propertyName: "description", first: true, predicate: ["description"], descendants: true, isSignal: true }, { propertyName: "actions", first: true, predicate: ["actions"], descendants: true, isSignal: true }, { propertyName: "navbar", first: true, predicate: ["navbar"], descendants: true, isSignal: true }, { propertyName: "breadcrumbs", first: true, predicate: ["breadcrumbs"], descendants: true, isSignal: true }, { propertyName: "navButton", first: true, predicate: ["navButton"], descendants: true, isSignal: true }], ngImport: i0, template: `
483
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutPageHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
484
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "20.1.8", type: AXPThemeLayoutPageHeaderComponent, isStandalone: true, selector: "axp-layout-page-header", viewQueries: [{ propertyName: "title", first: true, predicate: ["title"], descendants: true, isSignal: true }, { propertyName: "description", first: true, predicate: ["description"], descendants: true, isSignal: true }, { propertyName: "actions", first: true, predicate: ["actions"], descendants: true, isSignal: true }, { propertyName: "navbar", first: true, predicate: ["navbar"], descendants: true, isSignal: true }, { propertyName: "breadcrumbs", first: true, predicate: ["breadcrumbs"], descendants: true, isSignal: true }, { propertyName: "navButton", first: true, predicate: ["navButton"], descendants: true, isSignal: true }], ngImport: i0, template: `
434
485
  <ng-template #breadcrumbs>
435
486
  <ng-content select="axp-layout-breadcrumbs"></ng-content>
436
487
  </ng-template>
@@ -455,7 +506,7 @@ class AXPThemeLayoutPageHeaderComponent {
455
506
  </ng-template>
456
507
  `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
457
508
  }
458
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPThemeLayoutPageHeaderComponent, decorators: [{
509
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutPageHeaderComponent, decorators: [{
459
510
  type: Component,
460
511
  args: [{
461
512
  imports: [],
@@ -490,14 +541,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
490
541
  }]
491
542
  }] });
492
543
  class AXPThemeLayoutHeaderComponent {
493
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPThemeLayoutHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
494
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.6", type: AXPThemeLayoutHeaderComponent, isStandalone: true, selector: "axp-layout-header", ngImport: i0, template: `
544
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
545
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.8", type: AXPThemeLayoutHeaderComponent, isStandalone: true, selector: "axp-layout-header", ngImport: i0, template: `
495
546
  <ng-content select="axp-layout-prefix"></ng-content>
496
547
  <ng-content></ng-content>
497
548
  <ng-content select="axp-layout-suffix"></ng-content>
498
549
  `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
499
550
  }
500
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPThemeLayoutHeaderComponent, decorators: [{
551
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutHeaderComponent, decorators: [{
501
552
  type: Component,
502
553
  args: [{
503
554
  imports: [],
@@ -514,10 +565,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
514
565
  }] });
515
566
 
516
567
  class AXPThemeLayoutListComponent {
517
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPThemeLayoutListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
518
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.6", type: AXPThemeLayoutListComponent, isStandalone: true, selector: "axp-layout-list", ngImport: i0, template: `<ng-content select="axp-layout-list-item,axp-layout-list-group,ng-container"></ng-content>`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
568
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
569
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.8", type: AXPThemeLayoutListComponent, isStandalone: true, selector: "axp-layout-list", ngImport: i0, template: `<ng-content select="axp-layout-list-item,axp-layout-list-group,ng-container"></ng-content>`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
519
570
  }
520
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPThemeLayoutListComponent, decorators: [{
571
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutListComponent, decorators: [{
521
572
  type: Component,
522
573
  args: [{
523
574
  standalone: true,
@@ -528,10 +579,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
528
579
  }]
529
580
  }] });
530
581
  class AXPThemeLayoutListItemsGroupComponent {
531
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPThemeLayoutListItemsGroupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
532
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.6", type: AXPThemeLayoutListItemsGroupComponent, isStandalone: true, selector: "axp-layout-list-group", ngImport: i0, template: `<ng-content select="axp-layout-list-item, axp-layout-title, axp-layout-header ,ng-container"></ng-content>`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
582
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutListItemsGroupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
583
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.8", type: AXPThemeLayoutListItemsGroupComponent, isStandalone: true, selector: "axp-layout-list-group", ngImport: i0, template: `<ng-content select="axp-layout-list-item, axp-layout-title, axp-layout-header ,ng-container"></ng-content>`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
533
584
  }
534
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPThemeLayoutListItemsGroupComponent, decorators: [{
585
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutListItemsGroupComponent, decorators: [{
535
586
  type: Component,
536
587
  args: [{
537
588
  standalone: true,
@@ -542,10 +593,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
542
593
  }]
543
594
  }] });
544
595
  class AXPThemeLayoutListItemComponent {
545
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPThemeLayoutListItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
546
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.6", type: AXPThemeLayoutListItemComponent, isStandalone: true, selector: "axp-layout-list-item", ngImport: i0, template: `<ng-content select="axp-layout-content,axp-layout-prefix,axp-layout-suffix,ng-container"></ng-content>`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
596
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutListItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
597
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.8", type: AXPThemeLayoutListItemComponent, isStandalone: true, selector: "axp-layout-list-item", ngImport: i0, template: `<ng-content select="axp-layout-content,axp-layout-prefix,axp-layout-suffix,ng-container"></ng-content>`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
547
598
  }
548
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPThemeLayoutListItemComponent, decorators: [{
599
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutListItemComponent, decorators: [{
549
600
  type: Component,
550
601
  args: [{
551
602
  standalone: true,
@@ -557,13 +608,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
557
608
  }] });
558
609
 
559
610
  class AXPThemeLayoutSectionComponent {
560
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPThemeLayoutSectionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
561
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.6", type: AXPThemeLayoutSectionComponent, isStandalone: true, selector: "axp-layout-section", ngImport: i0, template: `
611
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutSectionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
612
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.8", type: AXPThemeLayoutSectionComponent, isStandalone: true, selector: "axp-layout-section", ngImport: i0, template: `
562
613
  <ng-content select="axp-layout-header"></ng-content>
563
614
  <ng-content select="axp-layout-content"></ng-content>
564
615
  `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
565
616
  }
566
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPThemeLayoutSectionComponent, decorators: [{
617
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutSectionComponent, decorators: [{
567
618
  type: Component,
568
619
  args: [{
569
620
  imports: [],
@@ -579,15 +630,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
579
630
  }] });
580
631
 
581
632
  class AXPThemeLayoutStartSideComponent {
582
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPThemeLayoutStartSideComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
583
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.6", type: AXPThemeLayoutStartSideComponent, isStandalone: true, selector: "axp-layout-page-start-side, axp-layout-start-side", ngImport: i0, template: `
633
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutStartSideComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
634
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.8", type: AXPThemeLayoutStartSideComponent, isStandalone: true, selector: "axp-layout-page-start-side, axp-layout-start-side", ngImport: i0, template: `
584
635
  <ng-content select="axp-layout-header"></ng-content>
585
636
  <ng-content select="axp-layout-content"></ng-content>
586
637
  <ng-content select="axp-layout-footer"></ng-content>
587
638
  <ng-content></ng-content>
588
639
  `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
589
640
  }
590
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPThemeLayoutStartSideComponent, decorators: [{
641
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutStartSideComponent, decorators: [{
591
642
  type: Component,
592
643
  args: [{
593
644
  imports: [],
@@ -604,14 +655,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
604
655
  }]
605
656
  }] });
606
657
  class AXPThemeLayoutEndSideComponent {
607
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPThemeLayoutEndSideComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
608
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.6", type: AXPThemeLayoutEndSideComponent, isStandalone: true, selector: "axp-layout-page-end-side, axp-layout-end-side", ngImport: i0, template: `
658
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutEndSideComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
659
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.8", type: AXPThemeLayoutEndSideComponent, isStandalone: true, selector: "axp-layout-page-end-side, axp-layout-end-side", ngImport: i0, template: `
609
660
  <ng-content select="axp-layout-header"></ng-content>
610
661
  <ng-content select="axp-layout-content"></ng-content>
611
662
  <ng-content select="axp-layout-footer"></ng-content>
612
663
  `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
613
664
  }
614
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPThemeLayoutEndSideComponent, decorators: [{
665
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutEndSideComponent, decorators: [{
615
666
  type: Component,
616
667
  args: [{
617
668
  imports: [],
@@ -628,14 +679,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
628
679
  }] });
629
680
 
630
681
  class AXPThemeLayoutToolbarComponent {
631
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPThemeLayoutToolbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
632
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.6", type: AXPThemeLayoutToolbarComponent, isStandalone: true, selector: "axp-layout-toolbar", ngImport: i0, template: `
682
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutToolbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
683
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.8", type: AXPThemeLayoutToolbarComponent, isStandalone: true, selector: "axp-layout-toolbar", ngImport: i0, template: `
633
684
  <ng-content select="axp-layout-prefix"></ng-content>
634
685
  <ng-content select="axp-layout-suffix"></ng-content>
635
686
  <ng-content></ng-content>
636
687
  `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
637
688
  }
638
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPThemeLayoutToolbarComponent, decorators: [{
689
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutToolbarComponent, decorators: [{
639
690
  type: Component,
640
691
  args: [{
641
692
  imports: [],
@@ -670,10 +721,10 @@ class AXPThemeLayoutContainerComponent {
670
721
  ngOnDestroy() {
671
722
  this.mutationObserver?.disconnect();
672
723
  }
673
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPThemeLayoutContainerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
674
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.6", type: AXPThemeLayoutContainerComponent, isStandalone: true, selector: "axp-layout-container", ngImport: i0, template: '<ng-content></ng-content>', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
724
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutContainerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
725
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.8", type: AXPThemeLayoutContainerComponent, isStandalone: true, selector: "axp-layout-container", ngImport: i0, template: '<ng-content></ng-content>', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
675
726
  }
676
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPThemeLayoutContainerComponent, decorators: [{
727
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutContainerComponent, decorators: [{
677
728
  type: Component,
678
729
  args: [{
679
730
  standalone: true,
@@ -684,6 +735,320 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
684
735
  }]
685
736
  }] });
686
737
 
738
+ class AXPCategoryTreeComponent {
739
+ constructor() {
740
+ //#region ---- Services & Dependencies ----
741
+ this.translationService = inject(AXTranslationService);
742
+ //#endregion
743
+ //#region ---- Inputs ----
744
+ this.dataSource = input.required(...(ngDevMode ? [{ debugName: "dataSource" }] : []));
745
+ this.config = input({
746
+ textField: 'title',
747
+ valueField: 'id',
748
+ expandedField: 'expand',
749
+ showCheckbox: false,
750
+ searchable: true,
751
+ searchPlaceholder: '@general:terms.interface.category.search.placeholder',
752
+ emptyStateTitle: '@general:terms.interface.category.search.no-records.title',
753
+ emptyStateDescription: '@general:terms.interface.category.search.no-records.description',
754
+ emptyStateIcon: 'fa-light fa-folder-open',
755
+ }, ...(ngDevMode ? [{ debugName: "config" }] : []));
756
+ this.actions = input({
757
+ canCreate: true,
758
+ canUpdate: true,
759
+ canDelete: true,
760
+ canCreateChild: true,
761
+ createLabel: 'Add New',
762
+ updateLabel: 'Edit',
763
+ deleteLabel: 'Delete',
764
+ createChildLabel: 'Add New Child',
765
+ }, ...(ngDevMode ? [{ debugName: "actions" }] : []));
766
+ this.events = input({}, ...(ngDevMode ? [{ debugName: "events" }] : []));
767
+ //#endregion
768
+ //#region ---- Outputs ----
769
+ this.nodeClick = output();
770
+ this.nodeSelect = output();
771
+ this.nodeCreate = output();
772
+ this.nodeUpdate = output();
773
+ this.nodeDelete = output();
774
+ this.searchChange = output();
775
+ this.collapseChange = output();
776
+ //#endregion
777
+ //#region ---- Component State ----
778
+ this.tree = viewChild('tree', ...(ngDevMode ? [{ debugName: "tree" }] : []));
779
+ this.isLoading = signal(true, ...(ngDevMode ? [{ debugName: "isLoading" }] : []));
780
+ this.searchValue = signal('', ...(ngDevMode ? [{ debugName: "searchValue" }] : []));
781
+ this.treeItems = signal([
782
+ {
783
+ id: 'root',
784
+ title: '@general:terms.interface.selection.all-items',
785
+ description: '',
786
+ parentId: undefined,
787
+ childCount: 0,
788
+ expand: true,
789
+ children: [],
790
+ },
791
+ ], ...(ngDevMode ? [{ debugName: "treeItems" }] : []));
792
+ //#endregion
793
+ //#region ---- Computed Properties ----
794
+ this.emptyStateTitle = computed(() => {
795
+ const title = this.config().emptyStateTitle || '';
796
+ return title;
797
+ }, ...(ngDevMode ? [{ debugName: "emptyStateTitle" }] : []));
798
+ this.emptyStateDescription = computed(() => {
799
+ const description = this.config().emptyStateDescription || '';
800
+ return description;
801
+ }, ...(ngDevMode ? [{ debugName: "emptyStateDescription" }] : []));
802
+ }
803
+ //#endregion
804
+ //#region ---- Lifecycle Methods ----
805
+ async ngOnInit() {
806
+ await this.loadRootNodes();
807
+ }
808
+ //#endregion
809
+ //#region ---- Data Loading Methods ----
810
+ async loadRootNodes() {
811
+ this.isLoading.set(true);
812
+ try {
813
+ const entities = await this.dataSource().loadRootNodes();
814
+ const nodes = this.convertEntitiesToTreeNodes(entities);
815
+ this.treeItems.update((prev) => prev.map((item) => ({
816
+ ...item,
817
+ children: nodes,
818
+ })));
819
+ }
820
+ catch (error) {
821
+ console.error('Error loading root nodes:', error);
822
+ }
823
+ finally {
824
+ this.isLoading.set(false);
825
+ }
826
+ }
827
+ async loadChildNodes(parentId) {
828
+ if (!this.dataSource().loadChildNodes)
829
+ return;
830
+ this.tree()?.setNodeLoading(parentId, true);
831
+ try {
832
+ const entities = await this.dataSource().loadChildNodes(parentId);
833
+ const children = this.convertEntitiesToTreeNodes(entities);
834
+ this.updateNodeChildren(parentId, children);
835
+ }
836
+ catch (error) {
837
+ console.error('Error loading child nodes:', error);
838
+ }
839
+ finally {
840
+ this.tree()?.setNodeLoading(parentId, false);
841
+ }
842
+ }
843
+ async searchNodes(searchValue) {
844
+ if (!this.dataSource().searchNodes)
845
+ return;
846
+ this.isLoading.set(true);
847
+ try {
848
+ const entities = await this.dataSource().searchNodes(searchValue);
849
+ const nodes = this.convertEntitiesToTreeNodes(entities);
850
+ this.treeItems.update((prev) => prev.map((item) => ({
851
+ ...item,
852
+ children: nodes,
853
+ })));
854
+ }
855
+ catch (error) {
856
+ console.error('Error searching nodes:', error);
857
+ }
858
+ finally {
859
+ this.isLoading.set(false);
860
+ }
861
+ }
862
+ //#endregion
863
+ //#region ---- Event Handlers ----
864
+ async handleNodeClick(event) {
865
+ const node = event.data;
866
+ // Extract the entity data (without tree-specific properties)
867
+ const entity = {
868
+ id: node.id,
869
+ title: node.title,
870
+ description: node.description,
871
+ parentId: node.parentId,
872
+ childCount: node.childCount
873
+ };
874
+ this.nodeClick.emit(entity);
875
+ this.events().onNodeClick?.(entity);
876
+ }
877
+ async handleCollapseChanged(event) {
878
+ const node = event.data;
879
+ // Extract the entity data (without tree-specific properties)
880
+ const entity = {
881
+ id: node.id,
882
+ title: node.title,
883
+ description: node.description,
884
+ parentId: node.parentId,
885
+ childCount: node.childCount
886
+ };
887
+ this.collapseChange.emit(entity);
888
+ this.events().onCollapseChange?.(entity);
889
+ // Load children if node is being expanded
890
+ // Check both expand property and active property (active seems to be the actual expansion state)
891
+ if ((node.expand || node.active) && this.dataSource().loadChildNodes) {
892
+ await this.loadChildNodes(node.id);
893
+ }
894
+ }
895
+ async handleSearchChange(event) {
896
+ const searchValue = event.value;
897
+ this.searchValue.set(searchValue);
898
+ this.searchChange.emit(searchValue);
899
+ this.events().onSearchChange?.(searchValue);
900
+ if (searchValue) {
901
+ await this.searchNodes(searchValue);
902
+ }
903
+ else {
904
+ await this.loadRootNodes();
905
+ }
906
+ }
907
+ //#endregion
908
+ //#region ---- CRUD Action Handlers ----
909
+ async handleCreateRootClick(event) {
910
+ event.nativeEvent.preventDefault();
911
+ event.nativeEvent.stopPropagation();
912
+ this.nodeCreate.emit(undefined);
913
+ this.events().onNodeCreate?.(undefined);
914
+ }
915
+ async handleCreateChildClick(node, event) {
916
+ event.nativeEvent.preventDefault();
917
+ event.nativeEvent.stopPropagation();
918
+ // Extract the entity data (without tree-specific properties)
919
+ const entity = {
920
+ id: node.id,
921
+ title: node.title,
922
+ description: node.description,
923
+ parentId: node.parentId,
924
+ childCount: node.childCount
925
+ };
926
+ this.nodeCreate.emit(entity);
927
+ this.events().onNodeCreate?.(entity);
928
+ }
929
+ async handleUpdateNodeClick(node, event) {
930
+ event.nativeEvent.preventDefault();
931
+ event.nativeEvent.stopPropagation();
932
+ // Extract the entity data (without tree-specific properties)
933
+ const entity = {
934
+ id: node.id,
935
+ title: node.title,
936
+ description: node.description,
937
+ parentId: node.parentId,
938
+ childCount: node.childCount
939
+ };
940
+ this.nodeUpdate.emit(entity);
941
+ this.events().onNodeUpdate?.(entity);
942
+ }
943
+ async handleDeleteNodeClick(node, event) {
944
+ event.nativeEvent.preventDefault();
945
+ event.nativeEvent.stopPropagation();
946
+ // Extract the entity data (without tree-specific properties)
947
+ const entity = {
948
+ id: node.id,
949
+ title: node.title,
950
+ description: node.description,
951
+ parentId: node.parentId,
952
+ childCount: node.childCount
953
+ };
954
+ this.nodeDelete.emit(entity);
955
+ this.events().onNodeDelete?.(entity);
956
+ }
957
+ //#endregion
958
+ //#region ---- Utility Methods ----
959
+ convertEntitiesToTreeNodes(entities) {
960
+ return entities.map(entity => ({
961
+ ...entity,
962
+ children: entity.childCount > 0 ? [] : undefined, // Set children to empty array if has children, undefined if no children
963
+ expand: false,
964
+ hasChild: entity.childCount > 0, // Set hasChild based on childCount
965
+ }));
966
+ }
967
+ updateNodeChildren(parentId, children) {
968
+ const updateChildrenAtPath = (items, id) => {
969
+ return items.map((item) => {
970
+ if (item.id === id) {
971
+ return { ...item, children };
972
+ }
973
+ if (item.children?.length) {
974
+ return { ...item, children: updateChildrenAtPath(item.children, id) };
975
+ }
976
+ return item;
977
+ });
978
+ };
979
+ this.treeItems.update((prev) => prev.map((item) => ({
980
+ ...item,
981
+ children: updateChildrenAtPath(item.children || [], parentId),
982
+ })));
983
+ }
984
+ async refreshTree(parentId) {
985
+ if (parentId) {
986
+ await this.loadChildNodes(parentId);
987
+ }
988
+ else {
989
+ await this.loadRootNodes();
990
+ }
991
+ }
992
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPCategoryTreeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
993
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.8", type: AXPCategoryTreeComponent, isStandalone: true, selector: "axp-category-tree", inputs: { dataSource: { classPropertyName: "dataSource", publicName: "dataSource", isSignal: true, isRequired: true, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null }, actions: { classPropertyName: "actions", publicName: "actions", isSignal: true, isRequired: false, transformFunction: null }, events: { classPropertyName: "events", publicName: "events", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { nodeClick: "nodeClick", nodeSelect: "nodeSelect", nodeCreate: "nodeCreate", nodeUpdate: "nodeUpdate", nodeDelete: "nodeDelete", searchChange: "searchChange", collapseChange: "collapseChange" }, viewQueries: [{ propertyName: "tree", first: true, predicate: ["tree"], descendants: true, isSignal: true }], ngImport: i0, template: "<axp-layout-header>\n <axp-layout-toolbar>\n @if (config().searchable) {\n <ax-search-box\n (onValueChanged)=\"handleSearchChange($event)\"\n [delayTime]=\"300\"\n [placeholder]=\"config().searchPlaceholder! | translate | async\"\n >\n </ax-search-box>\n }\n </axp-layout-toolbar>\n</axp-layout-header>\n\n<axp-layout-content>\n @if (isLoading()) {\n <div class=\"ax-p-4 ax-flex ax-flex-col ax-gap-3\" [class.ax-pt-2]=\"config().searchable\">\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n </div>\n } @else if (treeItems()[0].children?.length) {\n <div class=\"ax-px-4 ax-max-h-[calc(100vh-250px)] ax-overflow-auto\" [class.ax-pt-2]=\"config().searchable\">\n <ax-tree-view\n (onNodeClick)=\"handleNodeClick($event)\"\n (onCollapsedChanged)=\"handleCollapseChanged($event)\"\n [showCheckbox]=\"config().showCheckbox || false\"\n [itemTemplate]=\"itemTemplate\"\n #treeRef\n [textField]=\"config().textField || 'title'\"\n [valueField]=\"config().valueField || 'id'\"\n [expandedField]=\"config().expandedField || 'expand'\"\n [items]=\"treeItems()\"\n #tree\n >\n </ax-tree-view>\n </div>\n } @else {\n <axp-state-message\n [icon]=\"config().emptyStateIcon || 'fa-light fa-folder-open'\"\n [title]=\"emptyStateTitle()\"\n [description]=\"emptyStateDescription()\"\n >\n </axp-state-message>\n }\n\n <ng-template #itemTemplate let-item>\n <div class=\"ax-flex ax-items-center ax-justify-between ax-w-full ax-gap-2 ax-overflow-hidden\">\n <div class=\"ax-flex ax-items-center ax-gap-2 ax-min-w-0\">\n <ax-icon class=\"fas ax-text-warning fa-folder\"></ax-icon>\n <span class=\"ax-truncate\">{{ item.title | translate | async }}</span>\n </div>\n @if (item.id && item.id !== 'root') {\n @if (actions().canCreateChild || actions().canUpdate || actions().canDelete) {\n <div class=\"ax-flex ax-items-center ax-gap-1\">\n <ax-button class=\"ax-xs\" color=\"default\" look=\"blank\" (onClick)=\"$event.nativeEvent.stopPropagation()\">\n <ax-icon class=\"fas fa-ellipsis-v\"></ax-icon>\n <ax-dropdown-panel>\n <ax-button-item-list>\n @if (actions().canCreateChild) {\n <ax-button-item\n (onClick)=\"handleCreateChildClick(item, $event)\"\n look=\"blank\"\n color=\"default\"\n [text]=\"actions().createChildLabel || 'Add New Child'\"\n >\n <ax-icon class=\"fas fa-plus\"></ax-icon>\n </ax-button-item>\n }\n @if (actions().canUpdate) {\n <ax-button-item\n (onClick)=\"handleUpdateNodeClick(item, $event)\"\n look=\"blank\"\n [text]=\"actions().updateLabel || 'Edit'\"\n >\n <ax-icon class=\"fas fa-pen\"></ax-icon>\n </ax-button-item>\n }\n @if (actions().canDelete) {\n <ax-button-item\n (onClick)=\"handleDeleteNodeClick(item, $event)\"\n color=\"danger\"\n look=\"blank\"\n [text]=\"actions().deleteLabel || 'Delete'\"\n >\n <ax-icon class=\"fas fa-trash\"></ax-icon>\n </ax-button-item>\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-button>\n </div>\n }\n } @else if (item.id === 'root' && actions().canCreate) {\n <div class=\"ax-flex ax-items-center ax-gap-1\">\n <ax-button class=\"ax-xs\" (onClick)=\"handleCreateRootClick($event)\" look=\"blank\" color=\"default\">\n <ax-icon class=\"fas fa-plus\"></ax-icon>\n </ax-button>\n </div>\n }\n </div>\n </ng-template>\n</axp-layout-content>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "ngmodule", type: AXTreeViewModule }, { kind: "component", type: i2$2.AXTreeViewComponent, selector: "ax-tree-view", inputs: ["items", "showCheckbox", "hasCheckboxField", "selectionMode", "selectionBehavior", "selectionScope", "focusNodeEnabled", "valueField", "textField", "visibleField", "disableField", "hasChildField", "selectedField", "expandedField", "tooltipField", "childrenField", "activeField", "indeterminateField", "parentField", "iconField", "toggleIcons", "look", "showEmptyNodeMassage", "itemTemplate", "emptyTemplate", "expandOn"], outputs: ["onSelectionChanged", "onItemSelectedChanged", "onNodeClick", "onCollapsedChanged", "onNodedbClick"] }, { kind: "ngmodule", type: AXSkeletonModule }, { kind: "component", type: i2.AXSkeletonComponent, selector: "ax-skeleton", inputs: ["animated"] }, { kind: "component", type: AXPThemeLayoutBlockComponent, selector: "\n\n axp-page-content, \n axp-page-footer-container,\n axp-page-footer,\n axp-page-header,\n axp-page-header-container,\n axp-page-toolbar,\n\n axp-layout-content, \n axp-layout-page-content, \n\n axp-layout-sections,\n axp-layout-body,\n axp-layout-page-body,\n axp-layout-prefix,\n axp-layout-suffix,\n axp-layout-title-bar,\n axp-layout-title, \n axp-layout-title-actions, \n axp-layout-nav-button, \n axp-layout-description, \n axp-layout-breadcrumbs,\n axp-layout-list-action,\n " }, { kind: "ngmodule", type: AXSearchBoxModule }, { kind: "component", type: i4$1.AXSearchBoxComponent, selector: "ax-search-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "value", "state", "name", "id", "look", "class", "delayTime", "type"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "component", type: AXPThemeLayoutHeaderComponent, selector: "axp-layout-header" }, { kind: "component", type: AXPThemeLayoutToolbarComponent, selector: "axp-layout-toolbar" }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i3.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "component", type: i3.AXButtonItemComponent, selector: "ax-button-item", inputs: ["color", "disabled", "text", "selected", "divided", "data", "name"], outputs: ["onClick", "onFocus", "onBlur", "disabledChange"] }, { kind: "component", type: i3.AXButtonItemListComponent, selector: "ax-button-item-list", inputs: ["items"], outputs: ["onItemClick"] }, { kind: "ngmodule", type: AXDropdownModule }, { kind: "component", type: i6.AXDropdownPanelComponent, selector: "ax-dropdown-panel", inputs: ["isOpen", "fitParent", "dropdownWidth", "position", "placement", "_target", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "component", type: AXPStateMessageComponent, selector: "axp-state-message", inputs: ["mode", "icon", "title", "description", "variant"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }], encapsulation: i0.ViewEncapsulation.None }); }
994
+ }
995
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPCategoryTreeComponent, decorators: [{
996
+ type: Component,
997
+ args: [{ selector: 'axp-category-tree', standalone: true, encapsulation: ViewEncapsulation.None, imports: [
998
+ CommonModule,
999
+ AXDecoratorModule,
1000
+ AXTreeViewModule,
1001
+ AXSkeletonModule,
1002
+ AXPThemeLayoutBlockComponent,
1003
+ AXSearchBoxModule,
1004
+ AXPThemeLayoutHeaderComponent,
1005
+ AXPThemeLayoutToolbarComponent,
1006
+ AXTranslationModule,
1007
+ AXButtonModule,
1008
+ AXDropdownModule,
1009
+ AXPStateMessageComponent,
1010
+ ], template: "<axp-layout-header>\n <axp-layout-toolbar>\n @if (config().searchable) {\n <ax-search-box\n (onValueChanged)=\"handleSearchChange($event)\"\n [delayTime]=\"300\"\n [placeholder]=\"config().searchPlaceholder! | translate | async\"\n >\n </ax-search-box>\n }\n </axp-layout-toolbar>\n</axp-layout-header>\n\n<axp-layout-content>\n @if (isLoading()) {\n <div class=\"ax-p-4 ax-flex ax-flex-col ax-gap-3\" [class.ax-pt-2]=\"config().searchable\">\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n </div>\n } @else if (treeItems()[0].children?.length) {\n <div class=\"ax-px-4 ax-max-h-[calc(100vh-250px)] ax-overflow-auto\" [class.ax-pt-2]=\"config().searchable\">\n <ax-tree-view\n (onNodeClick)=\"handleNodeClick($event)\"\n (onCollapsedChanged)=\"handleCollapseChanged($event)\"\n [showCheckbox]=\"config().showCheckbox || false\"\n [itemTemplate]=\"itemTemplate\"\n #treeRef\n [textField]=\"config().textField || 'title'\"\n [valueField]=\"config().valueField || 'id'\"\n [expandedField]=\"config().expandedField || 'expand'\"\n [items]=\"treeItems()\"\n #tree\n >\n </ax-tree-view>\n </div>\n } @else {\n <axp-state-message\n [icon]=\"config().emptyStateIcon || 'fa-light fa-folder-open'\"\n [title]=\"emptyStateTitle()\"\n [description]=\"emptyStateDescription()\"\n >\n </axp-state-message>\n }\n\n <ng-template #itemTemplate let-item>\n <div class=\"ax-flex ax-items-center ax-justify-between ax-w-full ax-gap-2 ax-overflow-hidden\">\n <div class=\"ax-flex ax-items-center ax-gap-2 ax-min-w-0\">\n <ax-icon class=\"fas ax-text-warning fa-folder\"></ax-icon>\n <span class=\"ax-truncate\">{{ item.title | translate | async }}</span>\n </div>\n @if (item.id && item.id !== 'root') {\n @if (actions().canCreateChild || actions().canUpdate || actions().canDelete) {\n <div class=\"ax-flex ax-items-center ax-gap-1\">\n <ax-button class=\"ax-xs\" color=\"default\" look=\"blank\" (onClick)=\"$event.nativeEvent.stopPropagation()\">\n <ax-icon class=\"fas fa-ellipsis-v\"></ax-icon>\n <ax-dropdown-panel>\n <ax-button-item-list>\n @if (actions().canCreateChild) {\n <ax-button-item\n (onClick)=\"handleCreateChildClick(item, $event)\"\n look=\"blank\"\n color=\"default\"\n [text]=\"actions().createChildLabel || 'Add New Child'\"\n >\n <ax-icon class=\"fas fa-plus\"></ax-icon>\n </ax-button-item>\n }\n @if (actions().canUpdate) {\n <ax-button-item\n (onClick)=\"handleUpdateNodeClick(item, $event)\"\n look=\"blank\"\n [text]=\"actions().updateLabel || 'Edit'\"\n >\n <ax-icon class=\"fas fa-pen\"></ax-icon>\n </ax-button-item>\n }\n @if (actions().canDelete) {\n <ax-button-item\n (onClick)=\"handleDeleteNodeClick(item, $event)\"\n color=\"danger\"\n look=\"blank\"\n [text]=\"actions().deleteLabel || 'Delete'\"\n >\n <ax-icon class=\"fas fa-trash\"></ax-icon>\n </ax-button-item>\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-button>\n </div>\n }\n } @else if (item.id === 'root' && actions().canCreate) {\n <div class=\"ax-flex ax-items-center ax-gap-1\">\n <ax-button class=\"ax-xs\" (onClick)=\"handleCreateRootClick($event)\" look=\"blank\" color=\"default\">\n <ax-icon class=\"fas fa-plus\"></ax-icon>\n </ax-button>\n </div>\n }\n </div>\n </ng-template>\n</axp-layout-content>\n" }]
1011
+ }] });
1012
+
1013
+ //#region ---- Tree Node Interface ----
1014
+ //#endregion
1015
+
1016
+ class AXPQueryColumnsComponent {
1017
+ constructor() {
1018
+ this.columns = model([], ...(ngDevMode ? [{ debugName: "columns" }] : []));
1019
+ }
1020
+ handleVisibilityChange(e, name) {
1021
+ if (e.isUserInteraction) {
1022
+ this.columns.update((prev) => {
1023
+ return prev.map((c) => {
1024
+ return c.name === name ? { ...c, visible: e.value ?? true } : c;
1025
+ });
1026
+ });
1027
+ }
1028
+ }
1029
+ drop(event) {
1030
+ const columns = cloneDeep(this.columns());
1031
+ moveItemInArray(columns, event.previousIndex, event.currentIndex);
1032
+ this.columns.set(columns);
1033
+ }
1034
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPQueryColumnsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1035
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.8", type: AXPQueryColumnsComponent, isStandalone: true, selector: "axp-query-columns", inputs: { columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { columns: "columnsChange" }, ngImport: i0, template: "<div class=\"ax-flex ax-flex-col ax-gap-4 ax-select-none\" cdkDropList (cdkDropListDropped)=\"drop($event)\">\n <div class=\"ax-flex ax-flex-col ax-gap-3 ax-w-full ax-sorted-list ax-max-h-[calc(100vh-280px)] ax-overflow-auto\">\n @for (item of columns(); track item.name) {\n <div class=\"ax-flex ax-py-1 ax-items-center ax-justify-between\" cdkDrag cdkDragBoundary=\".ax-sorted-list\">\n <div class=\"ax-flex ax-items-center ax-gap-3\" cdkDragHandle>\n <ax-icon class=\"fa-solid fa-grip-dots-vertical ax-cursor-move\"></ax-icon>\n <p class=\"ax-font-medium ax-text-sm\">{{ item.title | translate | async }}</p>\n </div>\n <ax-switch\n class=\"ax-sm\"\n [ngModel]=\"item.visible\"\n (onValueChanged)=\"handleVisibilityChange($event, item.name)\"\n ></ax-switch>\n </div>\n }\n </div>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "ngmodule", type: AXSwitchModule }, { kind: "component", type: i3$1.AXSwitchComponent, selector: "ax-switch", inputs: ["disabled", "readonly", "color", "tabIndex", "value", "name", "isLoading"], outputs: ["onBlur", "onFocus", "valueChange", "onValueChanged", "readonlyChange", "disabledChange"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }] }); }
1036
+ }
1037
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPQueryColumnsComponent, decorators: [{
1038
+ type: Component,
1039
+ args: [{ selector: 'axp-query-columns', imports: [
1040
+ CommonModule,
1041
+ FormsModule,
1042
+ CdkDropList,
1043
+ CdkDrag,
1044
+ CdkDragHandle,
1045
+ AXButtonModule,
1046
+ AXDecoratorModule,
1047
+ AXSwitchModule,
1048
+ AXTranslationModule,
1049
+ ], template: "<div class=\"ax-flex ax-flex-col ax-gap-4 ax-select-none\" cdkDropList (cdkDropListDropped)=\"drop($event)\">\n <div class=\"ax-flex ax-flex-col ax-gap-3 ax-w-full ax-sorted-list ax-max-h-[calc(100vh-280px)] ax-overflow-auto\">\n @for (item of columns(); track item.name) {\n <div class=\"ax-flex ax-py-1 ax-items-center ax-justify-between\" cdkDrag cdkDragBoundary=\".ax-sorted-list\">\n <div class=\"ax-flex ax-items-center ax-gap-3\" cdkDragHandle>\n <ax-icon class=\"fa-solid fa-grip-dots-vertical ax-cursor-move\"></ax-icon>\n <p class=\"ax-font-medium ax-text-sm\">{{ item.title | translate | async }}</p>\n </div>\n <ax-switch\n class=\"ax-sm\"\n [ngModel]=\"item.visible\"\n (onValueChanged)=\"handleVisibilityChange($event, item.name)\"\n ></ax-switch>\n </div>\n }\n </div>\n</div>\n" }]
1050
+ }] });
1051
+
687
1052
  class AXPCompareViewComponent {
688
1053
  constructor() {
689
1054
  //#region ---- Component Properties ----
@@ -797,16 +1162,16 @@ class AXPCompareViewComponent {
797
1162
  }
798
1163
  ngOnDestroy() {
799
1164
  }
800
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPCompareViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
801
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", type: AXPCompareViewComponent, isStandalone: true, selector: "axp-compare-view", inputs: { inputs: { classPropertyName: "inputs", publicName: "inputs", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null } }, providers: [], ngImport: i0, template: "<!--\n #region ---- Compare View Table Layout ----\n-->\n<div class=\"axp-compare-view\">\n <div class=\"__table-container\">\n <table class=\"__table\">\n <thead class=\"__thead\">\n <tr class=\"__header-row\">\n <th class=\"__field-header\">\n <ax-check-box [value]=\"showOnlyChanges()\" (valueChange)=\"toggleShowOnlyChanges()\"\n class=\"__show-changes-toggle\">\n <ax-label>\n {{ 'compare-view.show-only-differences' | translate: { scope: 'common' } | async }}\n </ax-label>\n </ax-check-box>\n </th>\n @for (obj of remainingObjects(); track obj.id) {\n <th class=\"__object-header\" [attr.data-id]=\"obj.id\">\n <div class=\"__object-title\" [title]=\"obj.description\">\n <span>{{ obj.title | translate | async }}</span>\n @if (remainingObjects().length > 2) {\n <span class=\"__remove-object-button\" (click)=\"removeObject(obj.id)\">\n <i class=\"fa-light fa-times\"></i>\n </span>\n }\n </div>\n </th>\n }\n </tr>\n </thead>\n <tbody class=\"__tbody\">\n @for (field of filteredFields(); track field.path; let i = $index) {\n <tr class=\"__row\" [class.__row--odd]=\"i % 2 === 1\" [class.__row--has-differences]=\"hasUnequalValues(field.path)\"\n [class.__row--has-equal-values]=\"hasEqualValues(field.path)\">\n <td class=\"__field-cell\">\n <div class=\"__field-content\">\n <div class=\"__field-title\">\n {{ field.title | translate | async }}\n </div>\n @if (field.description) {\n <div class=\"__field-description\">{{ field.description }}</div>\n }\n </div>\n </td>\n @for (obj of remainingObjects(); track obj.id; let objIndex = $index) {\n <td class=\"__object-cell\" [attr.data-id]=\"obj.id\"\n [class.__cell--changed]=\"hasValueChangedFromPrevious(field.path, objIndex) && isChangesMode()\">\n @if (obj.context[field.path] !== undefined) {\n <div class=\"__object-content\">\n <axp-widgets-container [context]=\"obj.context\">\n <ng-container axp-widget-renderer [node]=\"field.widget\" [mode]=\"'view'\"></ng-container>\n </axp-widgets-container>\n </div>\n } @else {\n <div class=\"__object-placeholder\">---</div>\n }\n @if (hasValueChangingToNext(field.path, objIndex) && isChangesMode()) {\n <div class=\"__change-indicator\">\n <i class=\"fa-light fa-arrow-right\"></i>\n </div>\n }\n </td>\n }\n </tr>\n }\n </tbody>\n </table>\n </div>\n</div>\n<!--\n #endregion\n-->", styles: [".axp-compare-view{display:flex;height:100%;width:100%;flex-direction:column;border-radius:.375rem;border-width:1px;--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow);background-color:rgb(var(--ax-sys-color-lightest-surface));color:rgb(var(--ax-sys-color-on-lightest-surface));border-color:rgb(var(--ax-sys-color-border-lightest-surface));position:relative}.axp-compare-view .__filter-controls{flex-shrink:0;border-bottom-width:1px;padding:1rem;background-color:rgb(var(--ax-sys-color-light-surface));color:rgb(var(--ax-sys-color-on-light-surface));border-color:rgb(var(--ax-sys-color-border-light-surface))}.axp-compare-view .__filter-controls .__show-changes-toggle{font-size:.875rem;line-height:1.25rem}.axp-compare-view .__table-container{flex:1 1 0%;overflow:auto;position:relative}.axp-compare-view .__table{width:100%;border-collapse:separate;border-spacing:0;table-layout:fixed}.axp-compare-view .__table .__thead{position:-webkit-sticky;position:sticky;top:0;z-index:20}.axp-compare-view .__table .__thead .__header-row .__field-header{width:14rem;border-bottom-width:1px;border-right-width:1px;padding:.75rem 1rem;text-align:left;font-weight:700;background-color:rgb(var(--ax-sys-color-lighter-surface));color:rgb(var(--ax-sys-color-on-lighter-surface));border-color:rgb(var(--ax-sys-color-border-lighter-surface));position:-webkit-sticky;position:sticky;left:0;z-index:25}.axp-compare-view .__table .__thead .__header-row .__object-header{position:relative;border-bottom-width:1px;padding:.75rem 1rem;text-align:center;background-color:rgb(var(--ax-sys-color-lighter-surface));color:rgb(var(--ax-sys-color-on-lighter-surface));border-color:rgb(var(--ax-sys-color-border-lighter-surface));min-width:250px;width:250px}.axp-compare-view .__table .__thead .__header-row .__object-header .__object-title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.875rem;line-height:1.25rem;font-weight:600}.axp-compare-view .__table .__thead .__header-row .__object-header .__object-description{margin-top:.25rem;font-size:.75rem;line-height:1rem;opacity:.75}.axp-compare-view .__table .__thead .__header-row .__object-header .__remove-object-button{display:flex;width:1.5rem;height:1.5rem;cursor:pointer;align-items:center;justify-content:center;border-radius:9999px;--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-light-surface),var(--tw-bg-opacity, 1));font-size:.875rem;line-height:1.25rem;position:absolute;top:50%;inset-inline-end:0px;--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.axp-compare-view .__table .__thead .__header-row .__object-header .__remove-object-button:hover{--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-danger-100),var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-danger-600),var(--tw-text-opacity, 1))}.axp-compare-view .__table .__tbody .__row{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s;animation-duration:.2s}.axp-compare-view .__table .__tbody .__row.__row--odd{background-color:rgb(var(--ax-sys-color-lightest-surface));color:rgb(var(--ax-sys-color-on-lightest-surface));border-color:rgb(var(--ax-sys-color-border-lightest-surface))}.axp-compare-view .__table .__tbody .__row.__row--has-differences{border-left-width:4px;--tw-border-opacity: 1;border-left-color:rgba(var(--ax-sys-color-warning-500),var(--tw-border-opacity, 1))}.axp-compare-view .__table .__tbody .__row.__row--has-differences .__field-cell{background-color:rgba(var(--ax-sys-color-warning-500),var(--tw-bg-opacity, 1));--tw-bg-opacity: .05}.axp-compare-view .__table .__tbody .__row.__row--has-equal-values{border-left-width:4px;--tw-border-opacity: 1;border-left-color:rgba(var(--ax-sys-color-success-500),var(--tw-border-opacity, 1))}.axp-compare-view .__table .__tbody .__row.__row--has-equal-values .__field-cell{background-color:rgba(var(--ax-sys-color-success-500),var(--tw-bg-opacity, 1));--tw-bg-opacity: .05}.axp-compare-view .__table .__tbody .__row .__field-cell{width:14rem;border-bottom-width:1px;border-right-width:1px;padding:.75rem 1rem;vertical-align:top;background-color:rgb(var(--ax-sys-color-lightest-surface));color:rgb(var(--ax-sys-color-on-lightest-surface));border-color:rgb(var(--ax-sys-color-border-lightest-surface));position:-webkit-sticky;position:sticky;left:0;z-index:15}.axp-compare-view .__table .__tbody .__row .__field-cell .__field-content{display:flex;flex-direction:column;gap:.25rem}.axp-compare-view .__table .__tbody .__row .__field-cell .__field-content .__field-title{font-weight:500}.axp-compare-view .__table .__tbody .__row .__field-cell .__field-content .__field-description{font-size:.75rem;line-height:1rem;opacity:.75}.axp-compare-view .__table .__tbody .__row .__object-cell{border-bottom-width:1px;padding:.75rem 1rem;text-align:center;vertical-align:middle;position:relative}.axp-compare-view .__table .__tbody .__row .__object-cell.__cell--changed .__object-content{border-width:1px;border-style:dashed;--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-warning-200),var(--tw-border-opacity, 1));padding:.5rem}.axp-compare-view .__table .__tbody .__row .__object-cell .__object-content{position:relative;display:flex;align-items:center;justify-content:center}.axp-compare-view .__table .__tbody .__row .__object-cell .__change-indicator{position:absolute;inset-inline-end:-.25rem;top:50%;--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));line-height:1rem;--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-warning-500),var(--tw-text-opacity, 1));font-size:.875rem}.axp-compare-view .__table .__tbody .__row .__object-cell .__object-placeholder{opacity:.75}.axp-compare-view .__table .__tbody .__row.__row--has-differences .__field-cell{border-inline-start-width:4px;--tw-border-opacity: 1;border-inline-start-color:rgba(var(--ax-sys-color-warning-500),var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-warning-50),var(--tw-bg-opacity, 1))}.axp-compare-view .__table .__tbody .__row.__row--has-differences .__field-cell:is(.ax-dark *){--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-warning-900),var(--tw-bg-opacity, 1))}.axp-compare-view .__table .__tbody .__row.__row--has-equal-values .__field-cell{border-inline-start-width:4px;--tw-border-opacity: 1;border-inline-start-color:rgba(var(--ax-sys-color-success-500),var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-success-50),var(--tw-bg-opacity, 1))}.axp-compare-view .__table .__tbody .__row.__row--has-equal-values .__field-cell:is(.ax-dark *){--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-success-900),var(--tw-bg-opacity, 1))}\n"], dependencies: [{ kind: "ngmodule", type:
1165
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPCompareViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1166
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.8", type: AXPCompareViewComponent, isStandalone: true, selector: "axp-compare-view", inputs: { inputs: { classPropertyName: "inputs", publicName: "inputs", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null } }, providers: [], ngImport: i0, template: "<!--\n #region ---- Compare View Table Layout ----\n-->\n<div class=\"axp-compare-view\">\n <div class=\"__table-container\">\n <table class=\"__table\">\n <thead class=\"__thead\">\n <tr class=\"__header-row\">\n <th class=\"__field-header\">\n <ax-check-box\n [value]=\"showOnlyChanges()\"\n (valueChange)=\"toggleShowOnlyChanges()\"\n class=\"__show-changes-toggle\"\n >\n <ax-label>\n {{ '@activity-log:compare-view.show-only-differences' | translate | async }}\n </ax-label>\n </ax-check-box>\n </th>\n @for (obj of remainingObjects(); track obj.id) {\n <th class=\"__object-header\" [attr.data-id]=\"obj.id\">\n <div class=\"__object-title\" [title]=\"obj.description\">\n <span>{{ obj.title | translate | async }}</span>\n @if (remainingObjects().length > 2) {\n <span class=\"__remove-object-button\" (click)=\"removeObject(obj.id)\">\n <i class=\"fa-light fa-times\"></i>\n </span>\n }\n </div>\n </th>\n }\n </tr>\n </thead>\n <tbody class=\"__tbody\">\n @for (field of filteredFields(); track field.path; let i = $index) {\n <tr\n class=\"__row\"\n [class.__row--odd]=\"i % 2 === 1\"\n [class.__row--has-differences]=\"hasUnequalValues(field.path)\"\n [class.__row--has-equal-values]=\"hasEqualValues(field.path)\"\n >\n <td class=\"__field-cell\">\n <div class=\"__field-content\">\n <div class=\"__field-title\">\n {{ field.title | translate | async }}\n </div>\n @if (field.description) {\n <div class=\"__field-description\">{{ field.description }}</div>\n }\n </div>\n </td>\n @for (obj of remainingObjects(); track obj.id; let objIndex = $index) {\n <td\n class=\"__object-cell\"\n [attr.data-id]=\"obj.id\"\n [class.__cell--changed]=\"hasValueChangedFromPrevious(field.path, objIndex) && isChangesMode()\"\n >\n @if (obj.context[field.path] !== undefined) {\n <div class=\"__object-content\">\n <axp-widgets-container [context]=\"obj.context\">\n <ng-container axp-widget-renderer [node]=\"field.widget\" [mode]=\"'view'\"></ng-container>\n </axp-widgets-container>\n </div>\n } @else {\n <div class=\"__object-placeholder\">---</div>\n }\n @if (hasValueChangingToNext(field.path, objIndex) && isChangesMode()) {\n <div class=\"__change-indicator\">\n <i class=\"fa-light fa-arrow-right\"></i>\n </div>\n }\n </td>\n }\n </tr>\n }\n </tbody>\n </table>\n </div>\n</div>\n<!--\n #endregion\n-->\n", styles: [".axp-compare-view{display:flex;height:100%;width:100%;flex-direction:column;border-radius:.375rem;border-width:1px;--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow);background-color:rgb(var(--ax-sys-color-lightest-surface));color:rgb(var(--ax-sys-color-on-lightest-surface));border-color:rgb(var(--ax-sys-color-border-lightest-surface));position:relative}.axp-compare-view .__filter-controls{flex-shrink:0;border-bottom-width:1px;padding:1rem;background-color:rgb(var(--ax-sys-color-light-surface));color:rgb(var(--ax-sys-color-on-light-surface));border-color:rgb(var(--ax-sys-color-border-light-surface))}.axp-compare-view .__filter-controls .__show-changes-toggle{font-size:.875rem;line-height:1.25rem}.axp-compare-view .__table-container{flex:1 1 0%;overflow:auto;position:relative}.axp-compare-view .__table{width:100%;border-collapse:separate;border-spacing:0;table-layout:fixed}.axp-compare-view .__table .__thead{position:-webkit-sticky;position:sticky;top:0;z-index:20}.axp-compare-view .__table .__thead .__header-row .__field-header{width:14rem;border-bottom-width:1px;border-right-width:1px;padding:.75rem 1rem;text-align:left;font-weight:700;background-color:rgb(var(--ax-sys-color-lighter-surface));color:rgb(var(--ax-sys-color-on-lighter-surface));border-color:rgb(var(--ax-sys-color-border-lighter-surface));position:-webkit-sticky;position:sticky;left:0;z-index:25}.axp-compare-view .__table .__thead .__header-row .__object-header{position:relative;border-bottom-width:1px;padding:.75rem 1rem;text-align:center;background-color:rgb(var(--ax-sys-color-lighter-surface));color:rgb(var(--ax-sys-color-on-lighter-surface));border-color:rgb(var(--ax-sys-color-border-lighter-surface));min-width:250px;width:250px}.axp-compare-view .__table .__thead .__header-row .__object-header .__object-title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.875rem;line-height:1.25rem;font-weight:600}.axp-compare-view .__table .__thead .__header-row .__object-header .__object-description{margin-top:.25rem;font-size:.75rem;line-height:1rem;opacity:.75}.axp-compare-view .__table .__thead .__header-row .__object-header .__remove-object-button{display:flex;width:1.5rem;height:1.5rem;cursor:pointer;align-items:center;justify-content:center;border-radius:9999px;--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-light-surface),var(--tw-bg-opacity, 1));font-size:.875rem;line-height:1.25rem;position:absolute;top:50%;inset-inline-end:0px;--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.axp-compare-view .__table .__thead .__header-row .__object-header .__remove-object-button:hover{--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-danger-100),var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-danger-600),var(--tw-text-opacity, 1))}.axp-compare-view .__table .__tbody .__row{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s;animation-duration:.2s}.axp-compare-view .__table .__tbody .__row.__row--odd{background-color:rgb(var(--ax-sys-color-lightest-surface));color:rgb(var(--ax-sys-color-on-lightest-surface));border-color:rgb(var(--ax-sys-color-border-lightest-surface))}.axp-compare-view .__table .__tbody .__row.__row--has-differences{border-left-width:4px;--tw-border-opacity: 1;border-left-color:rgba(var(--ax-sys-color-warning-500),var(--tw-border-opacity, 1))}.axp-compare-view .__table .__tbody .__row.__row--has-differences .__field-cell{background-color:rgba(var(--ax-sys-color-warning-500),var(--tw-bg-opacity, 1));--tw-bg-opacity: .05}.axp-compare-view .__table .__tbody .__row.__row--has-equal-values{border-left-width:4px;--tw-border-opacity: 1;border-left-color:rgba(var(--ax-sys-color-success-500),var(--tw-border-opacity, 1))}.axp-compare-view .__table .__tbody .__row.__row--has-equal-values .__field-cell{background-color:rgba(var(--ax-sys-color-success-500),var(--tw-bg-opacity, 1));--tw-bg-opacity: .05}.axp-compare-view .__table .__tbody .__row .__field-cell{width:14rem;border-bottom-width:1px;border-right-width:1px;padding:.75rem 1rem;vertical-align:top;background-color:rgb(var(--ax-sys-color-lightest-surface));color:rgb(var(--ax-sys-color-on-lightest-surface));border-color:rgb(var(--ax-sys-color-border-lightest-surface));position:-webkit-sticky;position:sticky;left:0;z-index:15}.axp-compare-view .__table .__tbody .__row .__field-cell .__field-content{display:flex;flex-direction:column;gap:.25rem}.axp-compare-view .__table .__tbody .__row .__field-cell .__field-content .__field-title{font-weight:500}.axp-compare-view .__table .__tbody .__row .__field-cell .__field-content .__field-description{font-size:.75rem;line-height:1rem;opacity:.75}.axp-compare-view .__table .__tbody .__row .__object-cell{border-bottom-width:1px;padding:.75rem 1rem;text-align:center;vertical-align:middle;position:relative}.axp-compare-view .__table .__tbody .__row .__object-cell.__cell--changed .__object-content{border-width:1px;border-style:dashed;--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-warning-200),var(--tw-border-opacity, 1));padding:.5rem}.axp-compare-view .__table .__tbody .__row .__object-cell .__object-content{position:relative;display:flex;align-items:center;justify-content:center}.axp-compare-view .__table .__tbody .__row .__object-cell .__change-indicator{position:absolute;inset-inline-end:-.25rem;top:50%;--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));line-height:1rem;--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-warning-500),var(--tw-text-opacity, 1));font-size:.875rem}.axp-compare-view .__table .__tbody .__row .__object-cell .__object-placeholder{opacity:.75}.axp-compare-view .__table .__tbody .__row.__row--has-differences .__field-cell{border-inline-start-width:4px;--tw-border-opacity: 1;border-inline-start-color:rgba(var(--ax-sys-color-warning-500),var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-warning-50),var(--tw-bg-opacity, 1))}.axp-compare-view .__table .__tbody .__row.__row--has-differences .__field-cell:is(.ax-dark *){--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-warning-900),var(--tw-bg-opacity, 1))}.axp-compare-view .__table .__tbody .__row.__row--has-equal-values .__field-cell{border-inline-start-width:4px;--tw-border-opacity: 1;border-inline-start-color:rgba(var(--ax-sys-color-success-500),var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-success-50),var(--tw-bg-opacity, 1))}.axp-compare-view .__table .__tbody .__row.__row--has-equal-values .__field-cell:is(.ax-dark *){--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-success-900),var(--tw-bg-opacity, 1))}\n"], dependencies: [{ kind: "ngmodule", type:
802
1167
  // Angular
803
1168
  CommonModule }, { kind: "ngmodule", type:
804
1169
  // ACoreX
805
- AXFormModule }, { kind: "ngmodule", type: AXTextBoxModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "ngmodule", type: AXLabelModule }, { kind: "component", type: i1.AXLabelComponent, selector: "ax-label", inputs: ["required", "for"], outputs: ["requiredChange"] }, { kind: "ngmodule", type: AXCheckBoxModule }, { kind: "component", type: i2$1.AXCheckBoxComponent, selector: "ax-check-box", inputs: ["disabled", "tabIndex", "readonly", "color", "value", "name", "id", "checked", "isLoading", "indeterminate"], outputs: ["onBlur", "onFocus", "valueChange", "onValueChanged"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type:
1170
+ AXFormModule }, { kind: "ngmodule", type: AXTextBoxModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "ngmodule", type: AXLabelModule }, { kind: "component", type: i3$2.AXLabelComponent, selector: "ax-label", inputs: ["required", "for"], outputs: ["requiredChange"] }, { kind: "ngmodule", type: AXCheckBoxModule }, { kind: "component", type: i2$3.AXCheckBoxComponent, selector: "ax-check-box", inputs: ["disabled", "tabIndex", "readonly", "color", "value", "name", "id", "isLoading", "indeterminate"], outputs: ["onBlur", "onFocus", "valueChange", "onValueChanged"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type:
806
1171
  // Platform
807
- AXPLayoutBuilderModule }, { kind: "component", type: i3$2.AXPWidgetContainerComponent, selector: "axp-widgets-container", inputs: ["context", "functions"], outputs: ["onContextChanged"] }, { kind: "directive", type: i3$2.AXPWidgetRendererDirective, selector: "[axp-widget-renderer]", inputs: ["parentNode", "index", "mode", "node"], outputs: ["onOptionsChanged", "onValueChanged"], exportAs: ["widgetRenderer"] }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }, { kind: "pipe", type: i2.AXTranslatorPipe, name: "translate" }], encapsulation: i0.ViewEncapsulation.None }); }
1172
+ AXPLayoutBuilderModule }, { kind: "component", type: i3$3.AXPWidgetContainerComponent, selector: "axp-widgets-container", inputs: ["context", "functions"], outputs: ["onContextChanged"] }, { kind: "directive", type: i3$3.AXPWidgetRendererDirective, selector: "[axp-widget-renderer]", inputs: ["parentNode", "index", "mode", "node"], outputs: ["onOptionsChanged", "onValueChanged"], exportAs: ["widgetRenderer"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }], encapsulation: i0.ViewEncapsulation.None }); }
808
1173
  }
809
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPCompareViewComponent, decorators: [{
1174
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPCompareViewComponent, decorators: [{
810
1175
  type: Component,
811
1176
  args: [{ selector: 'axp-compare-view', imports: [
812
1177
  // Angular
@@ -820,14 +1185,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
820
1185
  AXTranslationModule,
821
1186
  // Platform
822
1187
  AXPLayoutBuilderModule
823
- ], encapsulation: ViewEncapsulation.None, providers: [], template: "<!--\n #region ---- Compare View Table Layout ----\n-->\n<div class=\"axp-compare-view\">\n <div class=\"__table-container\">\n <table class=\"__table\">\n <thead class=\"__thead\">\n <tr class=\"__header-row\">\n <th class=\"__field-header\">\n <ax-check-box [value]=\"showOnlyChanges()\" (valueChange)=\"toggleShowOnlyChanges()\"\n class=\"__show-changes-toggle\">\n <ax-label>\n {{ 'compare-view.show-only-differences' | translate: { scope: 'common' } | async }}\n </ax-label>\n </ax-check-box>\n </th>\n @for (obj of remainingObjects(); track obj.id) {\n <th class=\"__object-header\" [attr.data-id]=\"obj.id\">\n <div class=\"__object-title\" [title]=\"obj.description\">\n <span>{{ obj.title | translate | async }}</span>\n @if (remainingObjects().length > 2) {\n <span class=\"__remove-object-button\" (click)=\"removeObject(obj.id)\">\n <i class=\"fa-light fa-times\"></i>\n </span>\n }\n </div>\n </th>\n }\n </tr>\n </thead>\n <tbody class=\"__tbody\">\n @for (field of filteredFields(); track field.path; let i = $index) {\n <tr class=\"__row\" [class.__row--odd]=\"i % 2 === 1\" [class.__row--has-differences]=\"hasUnequalValues(field.path)\"\n [class.__row--has-equal-values]=\"hasEqualValues(field.path)\">\n <td class=\"__field-cell\">\n <div class=\"__field-content\">\n <div class=\"__field-title\">\n {{ field.title | translate | async }}\n </div>\n @if (field.description) {\n <div class=\"__field-description\">{{ field.description }}</div>\n }\n </div>\n </td>\n @for (obj of remainingObjects(); track obj.id; let objIndex = $index) {\n <td class=\"__object-cell\" [attr.data-id]=\"obj.id\"\n [class.__cell--changed]=\"hasValueChangedFromPrevious(field.path, objIndex) && isChangesMode()\">\n @if (obj.context[field.path] !== undefined) {\n <div class=\"__object-content\">\n <axp-widgets-container [context]=\"obj.context\">\n <ng-container axp-widget-renderer [node]=\"field.widget\" [mode]=\"'view'\"></ng-container>\n </axp-widgets-container>\n </div>\n } @else {\n <div class=\"__object-placeholder\">---</div>\n }\n @if (hasValueChangingToNext(field.path, objIndex) && isChangesMode()) {\n <div class=\"__change-indicator\">\n <i class=\"fa-light fa-arrow-right\"></i>\n </div>\n }\n </td>\n }\n </tr>\n }\n </tbody>\n </table>\n </div>\n</div>\n<!--\n #endregion\n-->", styles: [".axp-compare-view{display:flex;height:100%;width:100%;flex-direction:column;border-radius:.375rem;border-width:1px;--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow);background-color:rgb(var(--ax-sys-color-lightest-surface));color:rgb(var(--ax-sys-color-on-lightest-surface));border-color:rgb(var(--ax-sys-color-border-lightest-surface));position:relative}.axp-compare-view .__filter-controls{flex-shrink:0;border-bottom-width:1px;padding:1rem;background-color:rgb(var(--ax-sys-color-light-surface));color:rgb(var(--ax-sys-color-on-light-surface));border-color:rgb(var(--ax-sys-color-border-light-surface))}.axp-compare-view .__filter-controls .__show-changes-toggle{font-size:.875rem;line-height:1.25rem}.axp-compare-view .__table-container{flex:1 1 0%;overflow:auto;position:relative}.axp-compare-view .__table{width:100%;border-collapse:separate;border-spacing:0;table-layout:fixed}.axp-compare-view .__table .__thead{position:-webkit-sticky;position:sticky;top:0;z-index:20}.axp-compare-view .__table .__thead .__header-row .__field-header{width:14rem;border-bottom-width:1px;border-right-width:1px;padding:.75rem 1rem;text-align:left;font-weight:700;background-color:rgb(var(--ax-sys-color-lighter-surface));color:rgb(var(--ax-sys-color-on-lighter-surface));border-color:rgb(var(--ax-sys-color-border-lighter-surface));position:-webkit-sticky;position:sticky;left:0;z-index:25}.axp-compare-view .__table .__thead .__header-row .__object-header{position:relative;border-bottom-width:1px;padding:.75rem 1rem;text-align:center;background-color:rgb(var(--ax-sys-color-lighter-surface));color:rgb(var(--ax-sys-color-on-lighter-surface));border-color:rgb(var(--ax-sys-color-border-lighter-surface));min-width:250px;width:250px}.axp-compare-view .__table .__thead .__header-row .__object-header .__object-title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.875rem;line-height:1.25rem;font-weight:600}.axp-compare-view .__table .__thead .__header-row .__object-header .__object-description{margin-top:.25rem;font-size:.75rem;line-height:1rem;opacity:.75}.axp-compare-view .__table .__thead .__header-row .__object-header .__remove-object-button{display:flex;width:1.5rem;height:1.5rem;cursor:pointer;align-items:center;justify-content:center;border-radius:9999px;--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-light-surface),var(--tw-bg-opacity, 1));font-size:.875rem;line-height:1.25rem;position:absolute;top:50%;inset-inline-end:0px;--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.axp-compare-view .__table .__thead .__header-row .__object-header .__remove-object-button:hover{--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-danger-100),var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-danger-600),var(--tw-text-opacity, 1))}.axp-compare-view .__table .__tbody .__row{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s;animation-duration:.2s}.axp-compare-view .__table .__tbody .__row.__row--odd{background-color:rgb(var(--ax-sys-color-lightest-surface));color:rgb(var(--ax-sys-color-on-lightest-surface));border-color:rgb(var(--ax-sys-color-border-lightest-surface))}.axp-compare-view .__table .__tbody .__row.__row--has-differences{border-left-width:4px;--tw-border-opacity: 1;border-left-color:rgba(var(--ax-sys-color-warning-500),var(--tw-border-opacity, 1))}.axp-compare-view .__table .__tbody .__row.__row--has-differences .__field-cell{background-color:rgba(var(--ax-sys-color-warning-500),var(--tw-bg-opacity, 1));--tw-bg-opacity: .05}.axp-compare-view .__table .__tbody .__row.__row--has-equal-values{border-left-width:4px;--tw-border-opacity: 1;border-left-color:rgba(var(--ax-sys-color-success-500),var(--tw-border-opacity, 1))}.axp-compare-view .__table .__tbody .__row.__row--has-equal-values .__field-cell{background-color:rgba(var(--ax-sys-color-success-500),var(--tw-bg-opacity, 1));--tw-bg-opacity: .05}.axp-compare-view .__table .__tbody .__row .__field-cell{width:14rem;border-bottom-width:1px;border-right-width:1px;padding:.75rem 1rem;vertical-align:top;background-color:rgb(var(--ax-sys-color-lightest-surface));color:rgb(var(--ax-sys-color-on-lightest-surface));border-color:rgb(var(--ax-sys-color-border-lightest-surface));position:-webkit-sticky;position:sticky;left:0;z-index:15}.axp-compare-view .__table .__tbody .__row .__field-cell .__field-content{display:flex;flex-direction:column;gap:.25rem}.axp-compare-view .__table .__tbody .__row .__field-cell .__field-content .__field-title{font-weight:500}.axp-compare-view .__table .__tbody .__row .__field-cell .__field-content .__field-description{font-size:.75rem;line-height:1rem;opacity:.75}.axp-compare-view .__table .__tbody .__row .__object-cell{border-bottom-width:1px;padding:.75rem 1rem;text-align:center;vertical-align:middle;position:relative}.axp-compare-view .__table .__tbody .__row .__object-cell.__cell--changed .__object-content{border-width:1px;border-style:dashed;--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-warning-200),var(--tw-border-opacity, 1));padding:.5rem}.axp-compare-view .__table .__tbody .__row .__object-cell .__object-content{position:relative;display:flex;align-items:center;justify-content:center}.axp-compare-view .__table .__tbody .__row .__object-cell .__change-indicator{position:absolute;inset-inline-end:-.25rem;top:50%;--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));line-height:1rem;--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-warning-500),var(--tw-text-opacity, 1));font-size:.875rem}.axp-compare-view .__table .__tbody .__row .__object-cell .__object-placeholder{opacity:.75}.axp-compare-view .__table .__tbody .__row.__row--has-differences .__field-cell{border-inline-start-width:4px;--tw-border-opacity: 1;border-inline-start-color:rgba(var(--ax-sys-color-warning-500),var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-warning-50),var(--tw-bg-opacity, 1))}.axp-compare-view .__table .__tbody .__row.__row--has-differences .__field-cell:is(.ax-dark *){--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-warning-900),var(--tw-bg-opacity, 1))}.axp-compare-view .__table .__tbody .__row.__row--has-equal-values .__field-cell{border-inline-start-width:4px;--tw-border-opacity: 1;border-inline-start-color:rgba(var(--ax-sys-color-success-500),var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-success-50),var(--tw-bg-opacity, 1))}.axp-compare-view .__table .__tbody .__row.__row--has-equal-values .__field-cell:is(.ax-dark *){--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-success-900),var(--tw-bg-opacity, 1))}\n"] }]
1188
+ ], encapsulation: ViewEncapsulation.None, providers: [], template: "<!--\n #region ---- Compare View Table Layout ----\n-->\n<div class=\"axp-compare-view\">\n <div class=\"__table-container\">\n <table class=\"__table\">\n <thead class=\"__thead\">\n <tr class=\"__header-row\">\n <th class=\"__field-header\">\n <ax-check-box\n [value]=\"showOnlyChanges()\"\n (valueChange)=\"toggleShowOnlyChanges()\"\n class=\"__show-changes-toggle\"\n >\n <ax-label>\n {{ '@activity-log:compare-view.show-only-differences' | translate | async }}\n </ax-label>\n </ax-check-box>\n </th>\n @for (obj of remainingObjects(); track obj.id) {\n <th class=\"__object-header\" [attr.data-id]=\"obj.id\">\n <div class=\"__object-title\" [title]=\"obj.description\">\n <span>{{ obj.title | translate | async }}</span>\n @if (remainingObjects().length > 2) {\n <span class=\"__remove-object-button\" (click)=\"removeObject(obj.id)\">\n <i class=\"fa-light fa-times\"></i>\n </span>\n }\n </div>\n </th>\n }\n </tr>\n </thead>\n <tbody class=\"__tbody\">\n @for (field of filteredFields(); track field.path; let i = $index) {\n <tr\n class=\"__row\"\n [class.__row--odd]=\"i % 2 === 1\"\n [class.__row--has-differences]=\"hasUnequalValues(field.path)\"\n [class.__row--has-equal-values]=\"hasEqualValues(field.path)\"\n >\n <td class=\"__field-cell\">\n <div class=\"__field-content\">\n <div class=\"__field-title\">\n {{ field.title | translate | async }}\n </div>\n @if (field.description) {\n <div class=\"__field-description\">{{ field.description }}</div>\n }\n </div>\n </td>\n @for (obj of remainingObjects(); track obj.id; let objIndex = $index) {\n <td\n class=\"__object-cell\"\n [attr.data-id]=\"obj.id\"\n [class.__cell--changed]=\"hasValueChangedFromPrevious(field.path, objIndex) && isChangesMode()\"\n >\n @if (obj.context[field.path] !== undefined) {\n <div class=\"__object-content\">\n <axp-widgets-container [context]=\"obj.context\">\n <ng-container axp-widget-renderer [node]=\"field.widget\" [mode]=\"'view'\"></ng-container>\n </axp-widgets-container>\n </div>\n } @else {\n <div class=\"__object-placeholder\">---</div>\n }\n @if (hasValueChangingToNext(field.path, objIndex) && isChangesMode()) {\n <div class=\"__change-indicator\">\n <i class=\"fa-light fa-arrow-right\"></i>\n </div>\n }\n </td>\n }\n </tr>\n }\n </tbody>\n </table>\n </div>\n</div>\n<!--\n #endregion\n-->\n", styles: [".axp-compare-view{display:flex;height:100%;width:100%;flex-direction:column;border-radius:.375rem;border-width:1px;--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow);background-color:rgb(var(--ax-sys-color-lightest-surface));color:rgb(var(--ax-sys-color-on-lightest-surface));border-color:rgb(var(--ax-sys-color-border-lightest-surface));position:relative}.axp-compare-view .__filter-controls{flex-shrink:0;border-bottom-width:1px;padding:1rem;background-color:rgb(var(--ax-sys-color-light-surface));color:rgb(var(--ax-sys-color-on-light-surface));border-color:rgb(var(--ax-sys-color-border-light-surface))}.axp-compare-view .__filter-controls .__show-changes-toggle{font-size:.875rem;line-height:1.25rem}.axp-compare-view .__table-container{flex:1 1 0%;overflow:auto;position:relative}.axp-compare-view .__table{width:100%;border-collapse:separate;border-spacing:0;table-layout:fixed}.axp-compare-view .__table .__thead{position:-webkit-sticky;position:sticky;top:0;z-index:20}.axp-compare-view .__table .__thead .__header-row .__field-header{width:14rem;border-bottom-width:1px;border-right-width:1px;padding:.75rem 1rem;text-align:left;font-weight:700;background-color:rgb(var(--ax-sys-color-lighter-surface));color:rgb(var(--ax-sys-color-on-lighter-surface));border-color:rgb(var(--ax-sys-color-border-lighter-surface));position:-webkit-sticky;position:sticky;left:0;z-index:25}.axp-compare-view .__table .__thead .__header-row .__object-header{position:relative;border-bottom-width:1px;padding:.75rem 1rem;text-align:center;background-color:rgb(var(--ax-sys-color-lighter-surface));color:rgb(var(--ax-sys-color-on-lighter-surface));border-color:rgb(var(--ax-sys-color-border-lighter-surface));min-width:250px;width:250px}.axp-compare-view .__table .__thead .__header-row .__object-header .__object-title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.875rem;line-height:1.25rem;font-weight:600}.axp-compare-view .__table .__thead .__header-row .__object-header .__object-description{margin-top:.25rem;font-size:.75rem;line-height:1rem;opacity:.75}.axp-compare-view .__table .__thead .__header-row .__object-header .__remove-object-button{display:flex;width:1.5rem;height:1.5rem;cursor:pointer;align-items:center;justify-content:center;border-radius:9999px;--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-light-surface),var(--tw-bg-opacity, 1));font-size:.875rem;line-height:1.25rem;position:absolute;top:50%;inset-inline-end:0px;--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.axp-compare-view .__table .__thead .__header-row .__object-header .__remove-object-button:hover{--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-danger-100),var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-danger-600),var(--tw-text-opacity, 1))}.axp-compare-view .__table .__tbody .__row{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s;animation-duration:.2s}.axp-compare-view .__table .__tbody .__row.__row--odd{background-color:rgb(var(--ax-sys-color-lightest-surface));color:rgb(var(--ax-sys-color-on-lightest-surface));border-color:rgb(var(--ax-sys-color-border-lightest-surface))}.axp-compare-view .__table .__tbody .__row.__row--has-differences{border-left-width:4px;--tw-border-opacity: 1;border-left-color:rgba(var(--ax-sys-color-warning-500),var(--tw-border-opacity, 1))}.axp-compare-view .__table .__tbody .__row.__row--has-differences .__field-cell{background-color:rgba(var(--ax-sys-color-warning-500),var(--tw-bg-opacity, 1));--tw-bg-opacity: .05}.axp-compare-view .__table .__tbody .__row.__row--has-equal-values{border-left-width:4px;--tw-border-opacity: 1;border-left-color:rgba(var(--ax-sys-color-success-500),var(--tw-border-opacity, 1))}.axp-compare-view .__table .__tbody .__row.__row--has-equal-values .__field-cell{background-color:rgba(var(--ax-sys-color-success-500),var(--tw-bg-opacity, 1));--tw-bg-opacity: .05}.axp-compare-view .__table .__tbody .__row .__field-cell{width:14rem;border-bottom-width:1px;border-right-width:1px;padding:.75rem 1rem;vertical-align:top;background-color:rgb(var(--ax-sys-color-lightest-surface));color:rgb(var(--ax-sys-color-on-lightest-surface));border-color:rgb(var(--ax-sys-color-border-lightest-surface));position:-webkit-sticky;position:sticky;left:0;z-index:15}.axp-compare-view .__table .__tbody .__row .__field-cell .__field-content{display:flex;flex-direction:column;gap:.25rem}.axp-compare-view .__table .__tbody .__row .__field-cell .__field-content .__field-title{font-weight:500}.axp-compare-view .__table .__tbody .__row .__field-cell .__field-content .__field-description{font-size:.75rem;line-height:1rem;opacity:.75}.axp-compare-view .__table .__tbody .__row .__object-cell{border-bottom-width:1px;padding:.75rem 1rem;text-align:center;vertical-align:middle;position:relative}.axp-compare-view .__table .__tbody .__row .__object-cell.__cell--changed .__object-content{border-width:1px;border-style:dashed;--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-warning-200),var(--tw-border-opacity, 1));padding:.5rem}.axp-compare-view .__table .__tbody .__row .__object-cell .__object-content{position:relative;display:flex;align-items:center;justify-content:center}.axp-compare-view .__table .__tbody .__row .__object-cell .__change-indicator{position:absolute;inset-inline-end:-.25rem;top:50%;--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));line-height:1rem;--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-warning-500),var(--tw-text-opacity, 1));font-size:.875rem}.axp-compare-view .__table .__tbody .__row .__object-cell .__object-placeholder{opacity:.75}.axp-compare-view .__table .__tbody .__row.__row--has-differences .__field-cell{border-inline-start-width:4px;--tw-border-opacity: 1;border-inline-start-color:rgba(var(--ax-sys-color-warning-500),var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-warning-50),var(--tw-bg-opacity, 1))}.axp-compare-view .__table .__tbody .__row.__row--has-differences .__field-cell:is(.ax-dark *){--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-warning-900),var(--tw-bg-opacity, 1))}.axp-compare-view .__table .__tbody .__row.__row--has-equal-values .__field-cell{border-inline-start-width:4px;--tw-border-opacity: 1;border-inline-start-color:rgba(var(--ax-sys-color-success-500),var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-success-50),var(--tw-bg-opacity, 1))}.axp-compare-view .__table .__tbody .__row.__row--has-equal-values .__field-cell:is(.ax-dark *){--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-success-900),var(--tw-bg-opacity, 1))}\n"] }]
824
1189
  }] });
825
1190
 
826
1191
  class AXPComponentSlot {
827
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPComponentSlot, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
828
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.1.6", type: AXPComponentSlot, isStandalone: true, ngImport: i0 }); }
1192
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPComponentSlot, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1193
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.1.8", type: AXPComponentSlot, isStandalone: true, ngImport: i0 }); }
829
1194
  }
830
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPComponentSlot, decorators: [{
1195
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPComponentSlot, decorators: [{
831
1196
  type: Directive
832
1197
  }] });
833
1198
 
@@ -847,10 +1212,10 @@ class AXPComponentSlotRegistryService {
847
1212
  get(slotName) {
848
1213
  return this.registry.get(slotName) || [];
849
1214
  }
850
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPComponentSlotRegistryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
851
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPComponentSlotRegistryService, providedIn: 'root' }); }
1215
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPComponentSlotRegistryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1216
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPComponentSlotRegistryService, providedIn: 'root' }); }
852
1217
  }
853
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPComponentSlotRegistryService, decorators: [{
1218
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPComponentSlotRegistryService, decorators: [{
854
1219
  type: Injectable,
855
1220
  args: [{
856
1221
  providedIn: 'root'
@@ -922,9 +1287,9 @@ class AXPComponentSlotDirective {
922
1287
  }
923
1288
  // load options
924
1289
  if (typeof config.options === 'function') {
925
- runInInjectionContext(this.injector, () => {
1290
+ await runInInjectionContext(this.injector, async () => {
926
1291
  const fun = config.options;
927
- options = fun();
1292
+ options = await fun();
928
1293
  });
929
1294
  }
930
1295
  else if (config.options) {
@@ -949,10 +1314,10 @@ class AXPComponentSlotDirective {
949
1314
  return condition(this.contextStore.data());
950
1315
  //return condition(this.context());
951
1316
  }
952
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPComponentSlotDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
953
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.1.6", 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 }); }
1317
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPComponentSlotDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1318
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.1.8", 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 }); }
954
1319
  }
955
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPComponentSlotDirective, decorators: [{
1320
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPComponentSlotDirective, decorators: [{
956
1321
  type: Directive,
957
1322
  args: [{
958
1323
  selector: 'axp-component-slot',
@@ -1012,11 +1377,11 @@ class AXPComponentSlotModule {
1012
1377
  f();
1013
1378
  });
1014
1379
  }
1015
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPComponentSlotModule, deps: [{ token: 'AXPComponentSlotModuleFactory', optional: true }], target: i0.ɵɵFactoryTarget.NgModule }); }
1016
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.1.6", ngImport: i0, type: AXPComponentSlotModule, declarations: [AXPComponentSlotDirective], exports: [AXPComponentSlotDirective] }); }
1017
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPComponentSlotModule }); }
1380
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPComponentSlotModule, deps: [{ token: 'AXPComponentSlotModuleFactory', optional: true }], target: i0.ɵɵFactoryTarget.NgModule }); }
1381
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.1.8", ngImport: i0, type: AXPComponentSlotModule, declarations: [AXPComponentSlotDirective], exports: [AXPComponentSlotDirective] }); }
1382
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPComponentSlotModule }); }
1018
1383
  }
1019
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPComponentSlotModule, decorators: [{
1384
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPComponentSlotModule, decorators: [{
1020
1385
  type: NgModule,
1021
1386
  args: [{
1022
1387
  declarations: [AXPComponentSlotDirective],
@@ -1029,8 +1394,269 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
1029
1394
  args: ['AXPComponentSlotModuleFactory']
1030
1395
  }] }] });
1031
1396
 
1397
+ //#endregion
1398
+ class AXPDataSelectorComponent extends AXBasePageComponent {
1399
+ constructor() {
1400
+ super(...arguments);
1401
+ //#region ---- Properties ----
1402
+ this.config = signal({
1403
+ title: '',
1404
+ dataSource: null,
1405
+ columns: [],
1406
+ selectionMode: 'single',
1407
+ searchFields: [],
1408
+ parentField: undefined,
1409
+ allowCreate: false
1410
+ }, ...(ngDevMode ? [{ debugName: "config" }] : []));
1411
+ this.searchTerm = '';
1412
+ this.grid = viewChild('grid', ...(ngDevMode ? [{ debugName: "grid" }] : []));
1413
+ this.initialSelectedItems = [];
1414
+ this.selectedItems = signal([], ...(ngDevMode ? [{ debugName: "selectedItems" }] : []));
1415
+ // Category Filter State
1416
+ this.activeCategoryFilter = signal(null, ...(ngDevMode ? [{ debugName: "activeCategoryFilter" }] : []));
1417
+ //#endregion
1418
+ //#region ---- Computed Properties ----
1419
+ this.allowSelect = computed(() => this.selectedItems().length > 0, ...(ngDevMode ? [{ debugName: "allowSelect" }] : []));
1420
+ this.hasSearch = computed(() => {
1421
+ const searchFields = this.config().searchFields;
1422
+ return searchFields && searchFields.length > 0;
1423
+ }, ...(ngDevMode ? [{ debugName: "hasSearch" }] : []));
1424
+ this.searchPlaceholder = computed(() => {
1425
+ const searchFields = this.config().searchFields;
1426
+ if (!searchFields || searchFields.length === 0) {
1427
+ return 'Search...';
1428
+ }
1429
+ return `Search in ${searchFields.join(', ')}...`;
1430
+ }, ...(ngDevMode ? [{ debugName: "searchPlaceholder" }] : []));
1431
+ // Category Tree Configuration
1432
+ this.categoryTreeConfig = computed(() => ({
1433
+ textField: 'title',
1434
+ valueField: 'id',
1435
+ showCheckbox: false,
1436
+ searchable: true,
1437
+ searchPlaceholder: '@general:terms.interface.category.search.placeholder',
1438
+ emptyStateTitle: '@general:terms.interface.category.search.no-records.title',
1439
+ emptyStateDescription: '@general:terms.interface.category.search.no-records.description',
1440
+ emptyStateIcon: 'fa-light fa-folder-open',
1441
+ }), ...(ngDevMode ? [{ debugName: "categoryTreeConfig" }] : []));
1442
+ // Category Tree Actions (no CRUD in filter mode)
1443
+ this.categoryTreeActions = computed(() => ({
1444
+ canCreate: false,
1445
+ canUpdate: false,
1446
+ canDelete: false,
1447
+ canCreateChild: false,
1448
+ }), ...(ngDevMode ? [{ debugName: "categoryTreeActions" }] : []));
1449
+ }
1450
+ //#endregion
1451
+ //#region ---- Lifecycle Methods ----
1452
+ ngOnInit() {
1453
+ // Set config from data passed by popup service
1454
+ // The config will be automatically set by AXBasePageComponent
1455
+ }
1456
+ ngAfterViewInit() {
1457
+ if (this.initialSelectedItems.length > 0 && this.grid()) {
1458
+ this.grid()?.selectRows(...this.initialSelectedItems);
1459
+ }
1460
+ if (this.searchTerm) {
1461
+ this.applySearchFilter(this.searchTerm);
1462
+ }
1463
+ else {
1464
+ this.applyFilterAndSort();
1465
+ }
1466
+ }
1467
+ //#endregion
1468
+ //#region ---- Event Handlers ----
1469
+ handleRowDbClick(e) {
1470
+ this.close({ items: [e.data] });
1471
+ }
1472
+ handleRowClick(e) {
1473
+ if (this.config().selectionMode === 'multiple') {
1474
+ this.selectedItems.set([...this.selectedItems(), e.data]);
1475
+ }
1476
+ else if (this.selectedItems().length > 0) {
1477
+ const selected = this.selectedItems().find((item) => item.id === e.data.id);
1478
+ if (selected) {
1479
+ this.selectedItems.set(this.selectedItems().filter((item) => item.id !== selected.id));
1480
+ }
1481
+ else {
1482
+ this.selectedItems.set([e.data]);
1483
+ }
1484
+ }
1485
+ else if (this.selectedItems().length === 0) {
1486
+ this.selectedItems.set([e.data]);
1487
+ }
1488
+ else {
1489
+ this.selectedItems.set([e.data]);
1490
+ }
1491
+ }
1492
+ async handleSelectedRowsChange(rows) {
1493
+ this.selectedItems.set(rows);
1494
+ }
1495
+ handleChangeSearchValue(e) {
1496
+ if (e.isUserInteraction) {
1497
+ this.applySearchFilter(e.value);
1498
+ }
1499
+ }
1500
+ async handleCreateNewClick() {
1501
+ this.close();
1502
+ // TODO: Implement create new functionality
1503
+ }
1504
+ handleCloseClick() {
1505
+ this.close();
1506
+ }
1507
+ handleSelectClick() {
1508
+ this.close({ items: this.selectedItems() });
1509
+ }
1510
+ async handleExpandRow(row) {
1511
+ if (this.grid()) {
1512
+ await this.grid().expandRow(row);
1513
+ }
1514
+ }
1515
+ // Category Filter Event Handlers
1516
+ handleCategoryFilterClick(node) {
1517
+ const categoryConfig = this.config().categoryFilter;
1518
+ // Get the filter value from the node
1519
+ const filterValue = node.id;
1520
+ // Store active filter state
1521
+ this.activeCategoryFilter.set({
1522
+ node,
1523
+ filterValue
1524
+ });
1525
+ // Apply filter to main data source
1526
+ this.applyCategoryFilter(filterValue, categoryConfig);
1527
+ }
1528
+ clearCategoryFilter() {
1529
+ this.activeCategoryFilter.set(null);
1530
+ this.config().dataSource.clearFilter();
1531
+ this.config().dataSource.refresh();
1532
+ }
1533
+ //#endregion
1534
+ //#region ---- Private Methods ----
1535
+ applySearchFilter(searchTerm) {
1536
+ const searchFields = this.config().searchFields;
1537
+ if (!searchFields || searchFields.length === 0) {
1538
+ return;
1539
+ }
1540
+ if (isEmpty(searchTerm) || isNil(searchTerm)) {
1541
+ this.config().dataSource.clearFilter();
1542
+ this.config().dataSource.refresh();
1543
+ return;
1544
+ }
1545
+ // Apply search filter to data source
1546
+ // This will be implemented based on the data source type
1547
+ this.config().dataSource.filter({
1548
+ field: 'title',
1549
+ value: searchTerm,
1550
+ operator: { type: 'contains' }
1551
+ });
1552
+ this.config().dataSource.refresh();
1553
+ }
1554
+ applyFilterAndSort() {
1555
+ // Apply any existing filters and sorting
1556
+ }
1557
+ applyCategoryFilter(filterValue, categoryConfig) {
1558
+ if (isNil(filterValue) || filterValue === 'root') {
1559
+ this.config().dataSource.clearFilter();
1560
+ this.config().dataSource.refresh();
1561
+ return;
1562
+ }
1563
+ const filter = {
1564
+ field: null,
1565
+ logic: 'and',
1566
+ operator: null,
1567
+ filters: [{
1568
+ field: categoryConfig.filterField,
1569
+ value: filterValue,
1570
+ operator: { type: 'contains' }
1571
+ }]
1572
+ };
1573
+ // Apply filter to data source (adds to existing filters)
1574
+ this.config().dataSource.filter(filter);
1575
+ this.config().dataSource.refresh();
1576
+ }
1577
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPDataSelectorComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1578
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.8", type: AXPDataSelectorComponent, isStandalone: true, selector: "axp-data-selector", viewQueries: [{ propertyName: "grid", first: true, predicate: ["grid"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"axp-data-selector\">\n <!-- Main Content Area -->\n <div class=\"axp-data-selector-content\" [class.with-category-filter]=\"config().categoryFilter?.enabled\">\n <!-- Category Filter Side Panel -->\n @if (config().categoryFilter?.enabled) {\n <div class=\"axp-category-filter-panel\" [style.width]=\"config().categoryFilter?.width || '300px'\">\n <axp-category-tree [dataSource]=\"config().categoryFilter!.dataSource\" [config]=\"categoryTreeConfig()\"\n [actions]=\"categoryTreeActions()\" (nodeClick)=\"handleCategoryFilterClick($event)\">\n </axp-category-tree>\n </div>\n }\n\n <!-- Main Data Area -->\n <div class=\"axp-main-data-area\">\n @if (hasSearch()) {\n <div class=\"ax-w-full ax-mb-2\">\n <ax-search-box [placeholder]=\"searchPlaceholder()\" [value]=\"searchTerm\"\n (onValueChanged)=\"handleChangeSearchValue($event)\" [axAutoFocus]=\"true\">\n <ax-clear-button></ax-clear-button>\n </ax-search-box>\n </div>\n }\n\n <ax-data-table #grid [showFooter]=\"false\" class=\"ax-h-[50vh]\" [paging]=\"true\"\n [loading]=\"{ enabled: true, animation: true }\" [dataSource]=\"config().dataSource\"\n [parentField]=\"config().parentField\" (selectedRowsChange)=\"handleSelectedRowsChange($event)\"\n (onRowClick)=\"handleRowClick($event)\" (onRowDbClick)=\"handleRowDbClick($event)\">\n @if (config().selectionMode === 'multiple') {\n <ax-select-column fixed=\"start\" [width]=\"'50px'\"></ax-select-column>\n }\n\n @for (col of config().columns; track col.name) {\n @if (col.visible) {\n <axp-widget-column-renderer [expandHandler]=\"$index === 0 && config().parentField ? true : false\"\n [caption]=\"col.title | translate | async\" [node]=\"{\n path: col.name,\n type: col.widget.type,\n options: col.widget.options,\n }\">\n </axp-widget-column-renderer>\n }\n }\n </ax-data-table>\n </div>\n </div>\n</div>\n\n<ax-footer>\n <ax-suffix>\n <ax-button look=\"solid\" [text]=\"('@general:actions.close.title' | translate | async)!\"\n (onClick)=\"handleCloseClick()\">\n </ax-button>\n <ax-button look=\"solid\" color=\"primary\" [text]=\"('@general:actions.select.title' | translate | async)!\"\n (onClick)=\"handleSelectClick()\" [disabled]=\"allowSelect() === false\">\n </ax-button>\n <!-- @if (config().allowCreate) {\n <ax-button\n look=\"solid\"\n color=\"primary\"\n [text]=\"'@general:actions.create.title' | translate | async\"\n (onClick)=\"handleCreateNewClick()\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-solid fa-add\"></ax-icon>\n </ax-prefix>\n </ax-button>\n } -->\n </ax-suffix>\n</ax-footer>", styles: [":host{display:block;height:100%}.ax-expand-handler{cursor:pointer;display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;margin-right:8px}.ax-expand-handler:hover{opacity:.8}.ax-expand-handler.ax-invisible{visibility:hidden}.ax-h-\\[50vh\\]{height:50vh}.ax-overflow-hidden{overflow:hidden}.ax-flex{display:flex}.ax-flex-col{flex-direction:column}.ax-gap-4{gap:1rem}.ax-p-4{padding:1rem}.ax-w-full{width:100%}.axp-data-selector{display:flex;flex-direction:column;height:100%;overflow:hidden}.axp-data-selector-header{display:flex;justify-content:space-between;align-items:center;padding:1rem;border-bottom:1px solid var(--border-color);background:var(--surface-color);flex-shrink:0}.axp-data-selector-header h3{margin:0;font-size:1.25rem;font-weight:600;color:var(--text-color)}.axp-data-selector-content{display:flex;flex:1;overflow:hidden}.axp-data-selector-content.with-category-filter .axp-main-data-area{flex:1;overflow:hidden}.axp-data-selector .axp-category-filter-panel{border-right:1px solid var(--border-color);padding:1rem;overflow-y:auto;background:var(--surface-color);flex-shrink:0}.axp-data-selector .axp-main-data-area{flex:1;overflow:hidden;padding:1rem;display:flex;flex-direction:column;gap:1rem}.axp-data-selector .axp-main-data-area .ax-data-table{flex:1;min-height:0}.axp-data-selector .axp-main-data-area .ax-search-box{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXCommonModule }, { kind: "directive", type: i1$2.AXAutoFocusDirective, selector: "[axAutoFocus]", inputs: ["axAutoFocus", "axAutoFocusTime"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i3.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXFormModule }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorClearButtonComponent, selector: "ax-clear-button", inputs: ["icon"] }, { kind: "component", type: i2$1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXDropdownButtonModule }, { kind: "ngmodule", type: AXDataTableModule }, { kind: "component", type: i4$2.AXDataTableComponent, selector: "ax-data-table", inputs: ["dataSource", "selectedRows", "parentField", "rowTemplate", "emptyTemplate", "noDataTemplate", "alternative", "showHeader", "fixedHeader", "showFooter", "fixedFooter", "itemHeight", "allowReordering", "paging", "fetchDataMode", "loading", "focusedRow"], outputs: ["selectedRowsChange", "focusedRowChange", "onRowClick", "onRowDbClick", "onColumnsOrderChanged", "onColumnSizeChanged", "onPageChanged"] }, { kind: "component", type: i4$2.AXRowSelectColumnComponent, selector: "ax-select-column", inputs: ["width", "caption", "fixed"] }, { kind: "ngmodule", type: AXSearchBoxModule }, { kind: "component", type: i4$1.AXSearchBoxComponent, selector: "ax-search-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "value", "state", "name", "id", "look", "class", "delayTime", "type"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "ngmodule", type: AXPLayoutBuilderModule }, { kind: "component", type: i3$3.AXPWidgetColumnRendererComponent, selector: "axp-widget-column-renderer", inputs: ["caption", "customExpandIcon", "customCollapseIcon", "customWidth", "node", "footerTemplate", "expandHandler", "cellTemplate", "headerTemplate"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "component", type: AXPCategoryTreeComponent, selector: "axp-category-tree", inputs: ["dataSource", "config", "actions", "events"], outputs: ["nodeClick", "nodeSelect", "nodeCreate", "nodeUpdate", "nodeDelete", "searchChange", "collapseChange"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1579
+ }
1580
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPDataSelectorComponent, decorators: [{
1581
+ type: Component,
1582
+ args: [{ selector: 'axp-data-selector', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
1583
+ CommonModule,
1584
+ AXCommonModule,
1585
+ AXButtonModule,
1586
+ AXFormModule,
1587
+ AXDecoratorModule,
1588
+ AXDropdownButtonModule,
1589
+ AXDataTableModule,
1590
+ AXSearchBoxModule,
1591
+ AXPLayoutBuilderModule,
1592
+ AXTranslationModule,
1593
+ AXBadgeModule,
1594
+ AXPCategoryTreeComponent,
1595
+ ], inputs: [], template: "<div class=\"axp-data-selector\">\n <!-- Main Content Area -->\n <div class=\"axp-data-selector-content\" [class.with-category-filter]=\"config().categoryFilter?.enabled\">\n <!-- Category Filter Side Panel -->\n @if (config().categoryFilter?.enabled) {\n <div class=\"axp-category-filter-panel\" [style.width]=\"config().categoryFilter?.width || '300px'\">\n <axp-category-tree [dataSource]=\"config().categoryFilter!.dataSource\" [config]=\"categoryTreeConfig()\"\n [actions]=\"categoryTreeActions()\" (nodeClick)=\"handleCategoryFilterClick($event)\">\n </axp-category-tree>\n </div>\n }\n\n <!-- Main Data Area -->\n <div class=\"axp-main-data-area\">\n @if (hasSearch()) {\n <div class=\"ax-w-full ax-mb-2\">\n <ax-search-box [placeholder]=\"searchPlaceholder()\" [value]=\"searchTerm\"\n (onValueChanged)=\"handleChangeSearchValue($event)\" [axAutoFocus]=\"true\">\n <ax-clear-button></ax-clear-button>\n </ax-search-box>\n </div>\n }\n\n <ax-data-table #grid [showFooter]=\"false\" class=\"ax-h-[50vh]\" [paging]=\"true\"\n [loading]=\"{ enabled: true, animation: true }\" [dataSource]=\"config().dataSource\"\n [parentField]=\"config().parentField\" (selectedRowsChange)=\"handleSelectedRowsChange($event)\"\n (onRowClick)=\"handleRowClick($event)\" (onRowDbClick)=\"handleRowDbClick($event)\">\n @if (config().selectionMode === 'multiple') {\n <ax-select-column fixed=\"start\" [width]=\"'50px'\"></ax-select-column>\n }\n\n @for (col of config().columns; track col.name) {\n @if (col.visible) {\n <axp-widget-column-renderer [expandHandler]=\"$index === 0 && config().parentField ? true : false\"\n [caption]=\"col.title | translate | async\" [node]=\"{\n path: col.name,\n type: col.widget.type,\n options: col.widget.options,\n }\">\n </axp-widget-column-renderer>\n }\n }\n </ax-data-table>\n </div>\n </div>\n</div>\n\n<ax-footer>\n <ax-suffix>\n <ax-button look=\"solid\" [text]=\"('@general:actions.close.title' | translate | async)!\"\n (onClick)=\"handleCloseClick()\">\n </ax-button>\n <ax-button look=\"solid\" color=\"primary\" [text]=\"('@general:actions.select.title' | translate | async)!\"\n (onClick)=\"handleSelectClick()\" [disabled]=\"allowSelect() === false\">\n </ax-button>\n <!-- @if (config().allowCreate) {\n <ax-button\n look=\"solid\"\n color=\"primary\"\n [text]=\"'@general:actions.create.title' | translate | async\"\n (onClick)=\"handleCreateNewClick()\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-solid fa-add\"></ax-icon>\n </ax-prefix>\n </ax-button>\n } -->\n </ax-suffix>\n</ax-footer>", styles: [":host{display:block;height:100%}.ax-expand-handler{cursor:pointer;display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;margin-right:8px}.ax-expand-handler:hover{opacity:.8}.ax-expand-handler.ax-invisible{visibility:hidden}.ax-h-\\[50vh\\]{height:50vh}.ax-overflow-hidden{overflow:hidden}.ax-flex{display:flex}.ax-flex-col{flex-direction:column}.ax-gap-4{gap:1rem}.ax-p-4{padding:1rem}.ax-w-full{width:100%}.axp-data-selector{display:flex;flex-direction:column;height:100%;overflow:hidden}.axp-data-selector-header{display:flex;justify-content:space-between;align-items:center;padding:1rem;border-bottom:1px solid var(--border-color);background:var(--surface-color);flex-shrink:0}.axp-data-selector-header h3{margin:0;font-size:1.25rem;font-weight:600;color:var(--text-color)}.axp-data-selector-content{display:flex;flex:1;overflow:hidden}.axp-data-selector-content.with-category-filter .axp-main-data-area{flex:1;overflow:hidden}.axp-data-selector .axp-category-filter-panel{border-right:1px solid var(--border-color);padding:1rem;overflow-y:auto;background:var(--surface-color);flex-shrink:0}.axp-data-selector .axp-main-data-area{flex:1;overflow:hidden;padding:1rem;display:flex;flex-direction:column;gap:1rem}.axp-data-selector .axp-main-data-area .ax-data-table{flex:1;min-height:0}.axp-data-selector .axp-main-data-area .ax-search-box{width:100%}\n"] }]
1596
+ }] });
1597
+
1598
+ var dataSelector_component = /*#__PURE__*/Object.freeze({
1599
+ __proto__: null,
1600
+ AXPDataSelectorComponent: AXPDataSelectorComponent
1601
+ });
1602
+
1603
+ class AXPDataSelectorService {
1604
+ constructor() {
1605
+ //#region ---- Services & Dependencies ----
1606
+ this.popupService = inject(AXPopupService);
1607
+ }
1608
+ //#endregion
1609
+ //#region ---- Public Methods ----
1610
+ /**
1611
+ * Open data selector popup
1612
+ */
1613
+ async open(config) {
1614
+ const component = await Promise.resolve().then(function () { return dataSelector_component; }).then(c => c.AXPDataSelectorComponent);
1615
+ const result = await this.popupService.open(component, {
1616
+ title: config.title,
1617
+ size: config.categoryFilter?.enabled ?
1618
+ 'lg'
1619
+ : (config.columns.length > 3 ? 'lg' : 'md'),
1620
+ data: {
1621
+ config: signal(config)
1622
+ }
1623
+ });
1624
+ return result.data || null;
1625
+ }
1626
+ /**
1627
+ * Open data selector with category filter
1628
+ */
1629
+ async openWithCategoryFilter(config, categoryFilterConfig) {
1630
+ const enhancedConfig = {
1631
+ ...config,
1632
+ categoryFilter: {
1633
+ enabled: true,
1634
+ ...categoryFilterConfig
1635
+ }
1636
+ };
1637
+ return this.open(enhancedConfig);
1638
+ }
1639
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPDataSelectorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1640
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPDataSelectorService, providedIn: 'root' }); }
1641
+ }
1642
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPDataSelectorService, decorators: [{
1643
+ type: Injectable,
1644
+ args: [{
1645
+ providedIn: 'root'
1646
+ }]
1647
+ }] });
1648
+
1032
1649
  class AXPDynamicFormComponent {
1033
1650
  constructor() {
1651
+ this.evaluatorService = inject(AXPExpressionEvaluatorService);
1652
+ /**
1653
+ * Tracks the latest scheduled evaluation to ensure last-write-wins for async evaluate
1654
+ */
1655
+ this.evaluationRunId = 0;
1656
+ /**
1657
+ * Memoization cache for resolveParamLayout to keep stable object identities
1658
+ */
1659
+ this.layoutCache = new Map();
1034
1660
  //#region ---- Inputs ----
1035
1661
  /**
1036
1662
  * Form definition containing groups and fields
@@ -1041,9 +1667,17 @@ class AXPDynamicFormComponent {
1041
1667
  */
1042
1668
  this.context = input.required(...(ngDevMode ? [{ debugName: "context" }] : []));
1043
1669
  /**
1044
- * Layout style for the form (normal, compact, vertical, horizontal)
1670
+ * Form appearance and density styling (normal, compact, spacious)
1671
+ */
1672
+ this.layoutLook = input('normal', ...(ngDevMode ? [{ debugName: "layoutLook" }] : []));
1673
+ /**
1674
+ * Form layout direction and flow (vertical, horizontal, grid)
1675
+ */
1676
+ this.layoutDirection = input('vertical', ...(ngDevMode ? [{ debugName: "layoutDirection" }] : []));
1677
+ /**
1678
+ * Default form mode. Can be overridden by section/group and field.
1045
1679
  */
1046
- this.layoutStyle = input('normal', ...(ngDevMode ? [{ debugName: "layoutStyle" }] : []));
1680
+ this.mode = input('edit', ...(ngDevMode ? [{ debugName: "mode" }] : []));
1047
1681
  /**
1048
1682
  * Custom layout configuration for form fields
1049
1683
  */
@@ -1056,6 +1690,26 @@ class AXPDynamicFormComponent {
1056
1690
  xxl: { colSpan: 4 },
1057
1691
  },
1058
1692
  }, ...(ngDevMode ? [{ debugName: "layoutConfig" }] : []));
1693
+ this.evaluatedFormDefinition = signal(null, ...(ngDevMode ? [{ debugName: "evaluatedFormDefinition" }] : []));
1694
+ /**
1695
+ * Evaluate definition when inputs change with last-write-wins and deep-equality guard
1696
+ */
1697
+ this.eff = effect(() => {
1698
+ const formDef = this.formDefinition();
1699
+ const ctx = this.context();
1700
+ const runId = ++this.evaluationRunId;
1701
+ (async () => {
1702
+ const evaluated = await this.expressionEvaluator(formDef, ctx);
1703
+ // Ignore stale results
1704
+ if (runId !== this.evaluationRunId) {
1705
+ return;
1706
+ }
1707
+ const prev = this.evaluatedFormDefinition();
1708
+ if (!isEqual(prev, evaluated)) {
1709
+ this.evaluatedFormDefinition.set(evaluated);
1710
+ }
1711
+ })();
1712
+ }, ...(ngDevMode ? [{ debugName: "eff" }] : []));
1059
1713
  //#endregion
1060
1714
  //#region ---- Outputs ----
1061
1715
  /**
@@ -1085,17 +1739,31 @@ class AXPDynamicFormComponent {
1085
1739
  */
1086
1740
  this.computedLayout = computed(() => this.layoutConfig(), ...(ngDevMode ? [{ debugName: "computedLayout" }] : []));
1087
1741
  /**
1088
- * Computed form definition
1742
+ * Resolve effective mode with precedence: field > group > form
1089
1743
  */
1090
- this.computedFormDefinition = computed(() => this.formDefinition(), ...(ngDevMode ? [{ debugName: "computedFormDefinition" }] : []));
1744
+ this.resolveParamMode = (group, param) => {
1745
+ const fieldMode = param?.mode;
1746
+ const groupMode = group?.mode;
1747
+ const formMode = this.mode();
1748
+ console.log(fieldMode, groupMode, formMode);
1749
+ return (fieldMode || groupMode || formMode || 'edit');
1750
+ };
1091
1751
  /**
1092
- * Host classes based on layout style
1752
+ * Host classes based on layout look and direction
1093
1753
  */
1094
1754
  this.hostClasses = computed(() => {
1095
1755
  const classes = ['axp-dynamic-form'];
1096
- const style = this.layoutStyle();
1097
- if (style && style !== 'normal') {
1098
- classes.push(`--${style}`);
1756
+ const look = this.layoutLook();
1757
+ const direction = this.layoutDirection();
1758
+ const mode = this.mode();
1759
+ if (look && look !== 'normal') {
1760
+ classes.push(`--look-${look}`);
1761
+ }
1762
+ if (direction && direction !== 'vertical') {
1763
+ classes.push(`--direction-${direction}`);
1764
+ }
1765
+ if (mode && mode !== 'edit') {
1766
+ classes.push(`--mode-${mode}`);
1099
1767
  }
1100
1768
  return classes.join(' ');
1101
1769
  }, ...(ngDevMode ? [{ debugName: "hostClasses" }] : []));
@@ -1105,8 +1773,11 @@ class AXPDynamicFormComponent {
1105
1773
  * Effect to sync context changes
1106
1774
  */
1107
1775
  this.#contextSyncEffect = effect(() => {
1108
- const context = this.context();
1109
- this.internalContext.set(context);
1776
+ const ctx = this.context() ?? {};
1777
+ const prev = this.internalContext() ?? {};
1778
+ if (!isEqual(prev, ctx)) {
1779
+ this.internalContext.set(ctx);
1780
+ }
1110
1781
  }, ...(ngDevMode ? [{ debugName: "#contextSyncEffect" }] : []));
1111
1782
  /**
1112
1783
  * Effect to handle form status changes
@@ -1118,12 +1789,90 @@ class AXPDynamicFormComponent {
1118
1789
  this.container()?.builderService.setStatus(AXPPageStatus.Rendered);
1119
1790
  }
1120
1791
  }, ...(ngDevMode ? [{ debugName: "#formStatusEffect" }] : []));
1792
+ /**
1793
+ * Invalidate memoization cache when layout config or evaluated definition changes
1794
+ */
1795
+ this.#layoutCacheInvalidationEffect = effect(() => {
1796
+ // Depend on layout config and evaluated definition identity
1797
+ // Any structural change should flush the cache to ensure correctness
1798
+ const _layout = this.layoutConfig();
1799
+ const _evaluated = this.evaluatedFormDefinition();
1800
+ // Simple invalidation: clear cache when either changes
1801
+ this.layoutCache.clear();
1802
+ }, ...(ngDevMode ? [{ debugName: "#layoutCacheInvalidationEffect" }] : []));
1803
+ }
1804
+ //#endregion
1805
+ //#region ---- Evaluator ----
1806
+ async expressionEvaluator(expression, context) {
1807
+ const scope = {
1808
+ context: {
1809
+ eval: (path) => get(context, path),
1810
+ },
1811
+ };
1812
+ return await this.evaluatorService.evaluate(expression, scope);
1813
+ }
1814
+ /**
1815
+ * Resolve effective grid layout for a specific parameter, merging per-parameter override with form layout.
1816
+ */
1817
+ resolveParamLayout(param) {
1818
+ const base = this.layoutConfig();
1819
+ const override = param.layout;
1820
+ // Build a signature to memoize per param + current base layout snapshot + override
1821
+ const signature = JSON.stringify({
1822
+ path: param?.path,
1823
+ base,
1824
+ override,
1825
+ });
1826
+ const cacheKey = param?.path ?? JSON.stringify(param);
1827
+ const cached = this.layoutCache.get(cacheKey);
1828
+ if (cached && cached.signature === signature) {
1829
+ return cached.config;
1830
+ }
1831
+ if (override == null) {
1832
+ this.layoutCache.set(cacheKey, { signature, config: base });
1833
+ return base;
1834
+ }
1835
+ const normalize = (value, fallback) => typeof value === 'number' && value > 0 ? value : fallback;
1836
+ const toConfig = (o) => {
1837
+ if (typeof o === 'number') {
1838
+ const cfg = {
1839
+ positions: {
1840
+ default: { colSpan: o },
1841
+ md: { colSpan: o },
1842
+ lg: { colSpan: o },
1843
+ xl: { colSpan: o },
1844
+ xxl: { colSpan: o },
1845
+ },
1846
+ };
1847
+ return cfg;
1848
+ }
1849
+ // When parameter layout object is provided, do NOT fall back to form layout.
1850
+ // Use cascading values across breakpoints: default -> md -> lg -> xl -> xxl.
1851
+ const d = normalize(o.default, 12);
1852
+ const md = normalize(o.md, d);
1853
+ const lg = normalize(o.lg, md);
1854
+ const xl = normalize(o.xl, lg);
1855
+ const xxl = normalize(o.xxl, xl);
1856
+ const cfg = {
1857
+ positions: {
1858
+ default: { colSpan: d },
1859
+ md: { colSpan: md },
1860
+ lg: { colSpan: lg },
1861
+ xl: { colSpan: xl },
1862
+ xxl: { colSpan: xxl },
1863
+ },
1864
+ };
1865
+ return cfg;
1866
+ };
1867
+ const result = toConfig(override);
1868
+ this.layoutCache.set(cacheKey, { signature, config: result });
1869
+ return result;
1121
1870
  }
1122
1871
  //#endregion
1123
1872
  //#region ---- Lifecycle Methods ----
1124
1873
  ngOnInit() {
1125
1874
  // Initialize internal context with input context
1126
- this.internalContext.set(this.context());
1875
+ this.internalContext.set(this.context() ?? {});
1127
1876
  }
1128
1877
  //#endregion
1129
1878
  //#region ---- Effects ----
@@ -1135,6 +1884,10 @@ class AXPDynamicFormComponent {
1135
1884
  * Effect to handle form status changes
1136
1885
  */
1137
1886
  #formStatusEffect;
1887
+ /**
1888
+ * Invalidate memoization cache when layout config or evaluated definition changes
1889
+ */
1890
+ #layoutCacheInvalidationEffect;
1138
1891
  //#endregion
1139
1892
  //#region ---- Event Handlers ----
1140
1893
  /**
@@ -1145,9 +1898,20 @@ class AXPDynamicFormComponent {
1145
1898
  this.contextInitiated.emit(event.data);
1146
1899
  }
1147
1900
  else {
1148
- this.internalContext.set(event.data);
1149
- this.contextChange.emit(event.data);
1901
+ this.internalContext.set(event.data ?? {});
1902
+ this.contextChange.emit(this.internalContext());
1903
+ }
1904
+ }
1905
+ isRequired(param) {
1906
+ const validations = param.widget?.options?.['validations'];
1907
+ if (Array.isArray(validations)) {
1908
+ return validations.some((v) => v?.rule === 'required');
1909
+ }
1910
+ if (validations && typeof validations === 'object') {
1911
+ // Support object-shaped validations like { required: true }
1912
+ return Boolean(validations['required']);
1150
1913
  }
1914
+ return false;
1151
1915
  }
1152
1916
  //#endregion
1153
1917
  //#region ---- Public Methods ----
@@ -1181,14 +1945,14 @@ class AXPDynamicFormComponent {
1181
1945
  }
1182
1946
  return false;
1183
1947
  }
1184
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPDynamicFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1185
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", type: AXPDynamicFormComponent, isStandalone: true, selector: "axp-dynamic-form", inputs: { formDefinition: { classPropertyName: "formDefinition", publicName: "formDefinition", isSignal: true, isRequired: true, transformFunction: null }, context: { classPropertyName: "context", publicName: "context", isSignal: true, isRequired: true, transformFunction: null }, layoutStyle: { classPropertyName: "layoutStyle", publicName: "layoutStyle", isSignal: true, isRequired: false, transformFunction: null }, layoutConfig: { classPropertyName: "layoutConfig", publicName: "layoutConfig", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { contextChange: "contextChange", contextInitiated: "contextInitiated", validityChange: "validityChange" }, host: { properties: { "class": "hostClasses()" }, classAttribute: "axp-dynamic-form" }, viewQueries: [{ propertyName: "form", first: true, predicate: AXFormComponent, descendants: true, isSignal: true }, { propertyName: "container", first: true, predicate: AXPWidgetContainerComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<ax-form>\n <axp-widgets-container [context]=\"internalContext()\" (onContextChanged)=\"handleContextChanged($event)\">\n <axp-layout-sections>\n @if (computedFormDefinition()) {\n @for (group of computedFormDefinition().groups; track group.name) {\n <axp-layout-section>\n <axp-layout-header>\n <axp-layout-title>{{ group.title }}</axp-layout-title>\n @if (group.description) {\n <axp-layout-description>{{ group.description }}</axp-layout-description>\n }\n </axp-layout-header>\n <axp-layout-content>\n @for (param of group.parameters; track param.path) {\n <div class=\"__field-container\">\n <ax-form-field class=\"__field-input\" [gridLayout]=\"computedLayout()\">\n <ax-label>{{ param.title }}</ax-label>\n <ng-container axp-widget-renderer [node]=\"param.widget\" [mode]=\"'edit'\"></ng-container>\n <!-- @if (param.description) {\n <axp-layout-description>{{ param.description }}</axp-layout-description>\n } -->\n </ax-form-field>\n </div>\n }\n </axp-layout-content>\n </axp-layout-section>\n }\n } @else {\n <axp-layout-section>\n <axp-layout-content>\n <div class=\"__empty-state\">\n <axp-layout-description>No form definition provided</axp-layout-description>\n </div>\n </axp-layout-content>\n </axp-layout-section>\n }\n </axp-layout-sections>\n </axp-widgets-container>\n</ax-form>\n", styles: [".axp-dynamic-form{width:100%}.axp-dynamic-form axp-layout-section axp-layout-content{display:flex;width:100%;flex-direction:column}.axp-dynamic-form axp-layout-section axp-layout-content>:not([hidden])~:not([hidden]){--tw-divide-y-reverse: 0;border-top-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px * var(--tw-divide-y-reverse));border-style:dashed;--tw-divide-opacity: 1;border-color:rgba(var(--ax-sys-color-border-lightest-surface),var(--tw-divide-opacity, 1))}.axp-dynamic-form axp-layout-section axp-layout-content .__field-container{align-items:center;gap:1rem;padding:1rem}@media (min-width: 1024px){.axp-dynamic-form axp-layout-section axp-layout-content .__field-container{padding-left:1.5rem;padding-right:1.5rem}}@media (min-width: 1280px){.axp-dynamic-form axp-layout-section axp-layout-content .__field-container{padding-left:2rem;padding-right:2rem}}@media (min-width: 1536px){.axp-dynamic-form axp-layout-section axp-layout-content .__field-container{padding-left:2.5rem;padding-right:2.5rem}}.axp-dynamic-form axp-layout-section axp-layout-content .__field-container{display:grid;grid-template-columns:repeat(12,minmax(0,1fr))}.axp-dynamic-form axp-layout-section axp-layout-content .__field-container .__field-info{grid-column:span 12 / span 12}@media (min-width: 768px){.axp-dynamic-form axp-layout-section axp-layout-content .__field-container .__field-info{grid-column:span 4 / span 4}}@media (min-width: 1024px){.axp-dynamic-form axp-layout-section axp-layout-content .__field-container .__field-info{grid-column:span 4 / span 4}}@media (min-width: 1536px){.axp-dynamic-form axp-layout-section axp-layout-content .__field-container .__field-info{grid-column:span 3 / span 3}}.axp-dynamic-form axp-layout-section axp-layout-content .__field-container axp-layout-description{margin-top:.5rem!important;font-size:.75rem!important;line-height:1rem!important}.axp-dynamic-form.--compact axp-layout-section axp-layout-content>:not([hidden])~:not([hidden]){border-style:none}.axp-dynamic-form.--compact axp-layout-section axp-layout-content .__field-container{display:flex;flex-direction:column;gap:.25rem;padding:.25rem .5rem;margin-bottom:.5rem;border-width:0px}.axp-dynamic-form.--compact axp-layout-section axp-layout-content .__field-container .__field-info{margin-bottom:.125rem;width:100%}.axp-dynamic-form.--compact axp-layout-section axp-layout-content .__field-container .__field-info axp-layout-title{font-size:.875rem;line-height:1.25rem;font-weight:500}.axp-dynamic-form.--compact axp-layout-section axp-layout-content .__field-container .__field-input{width:100%}.axp-dynamic-form.--compact axp-layout-section axp-layout-content .__field-container axp-layout-description{margin-top:.125rem!important;font-size:.75rem!important;line-height:1rem!important;opacity:.75!important}.axp-dynamic-form.--compact axp-layout-section{margin-bottom:.75rem}.axp-dynamic-form.--compact axp-layout-section axp-layout-header{margin-bottom:.5rem;gap:0px;padding:.5rem}.axp-dynamic-form.--compact axp-layout-section axp-layout-header axp-layout-title{font-size:1rem;line-height:1.5rem;font-weight:600}.axp-dynamic-form.--compact axp-layout-section axp-layout-header axp-layout-description{margin-top:.25rem;font-size:.75rem;line-height:1rem;opacity:.75}.axp-dynamic-form.--vertical axp-layout-section axp-layout-content .__field-container{display:flex;flex-direction:column;align-items:flex-start;gap:.75rem}.axp-dynamic-form.--vertical axp-layout-section axp-layout-content .__field-container .__field-info{grid-column:span 12 / span 12;width:100%}.axp-dynamic-form.--vertical axp-layout-section axp-layout-content .__field-container .__field-input{grid-column:span 12 / span 12;width:100%}.axp-dynamic-form.--vertical axp-layout-section axp-layout-content .__field-container axp-layout-description{margin-top:.25rem!important;font-size:.875rem!important;line-height:1.25rem!important}.axp-dynamic-form.--horizontal axp-layout-section axp-layout-content>:not([hidden])~:not([hidden]){border-style:none}.axp-dynamic-form.--horizontal axp-layout-section axp-layout-content .__field-container{display:flex;flex-direction:row;align-items:center;gap:1rem;padding-top:.75rem;padding-bottom:.75rem}.axp-dynamic-form.--horizontal axp-layout-section axp-layout-content .__field-container .__field-info{width:12rem;flex-shrink:0}.axp-dynamic-form.--horizontal axp-layout-section axp-layout-content .__field-container .__field-info axp-layout-title{margin-bottom:.25rem;font-size:.875rem;line-height:1.25rem;font-weight:500}.axp-dynamic-form.--horizontal axp-layout-section axp-layout-content .__field-container .__field-input{flex:1 1 0%}.axp-dynamic-form.--horizontal axp-layout-section axp-layout-content .__field-container axp-layout-description{margin-top:.25rem!important;font-size:.75rem!important;line-height:1rem!important;opacity:.75!important}.axp-dynamic-form .__empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding-top:2rem;padding-bottom:2rem;text-align:center}.axp-dynamic-form .__empty-state .__message{font-size:.875rem;line-height:1.25rem;--tw-text-opacity: 1;color:rgb(107 114 128 / var(--tw-text-opacity, 1))}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type:
1948
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPDynamicFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1949
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.8", type: AXPDynamicFormComponent, isStandalone: true, selector: "axp-dynamic-form", inputs: { formDefinition: { classPropertyName: "formDefinition", publicName: "formDefinition", isSignal: true, isRequired: true, transformFunction: null }, context: { classPropertyName: "context", publicName: "context", isSignal: true, isRequired: true, transformFunction: null }, layoutLook: { classPropertyName: "layoutLook", publicName: "layoutLook", isSignal: true, isRequired: false, transformFunction: null }, layoutDirection: { classPropertyName: "layoutDirection", publicName: "layoutDirection", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, layoutConfig: { classPropertyName: "layoutConfig", publicName: "layoutConfig", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { contextChange: "contextChange", contextInitiated: "contextInitiated", validityChange: "validityChange" }, host: { properties: { "class": "hostClasses()" }, classAttribute: "axp-dynamic-form" }, viewQueries: [{ propertyName: "form", first: true, predicate: AXFormComponent, descendants: true, isSignal: true }, { propertyName: "container", first: true, predicate: AXPWidgetContainerComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<ax-form>\n <axp-widgets-container [context]=\"internalContext()\" (onContextChanged)=\"handleContextChanged($event)\">\n <axp-layout-sections>\n @for (group of evaluatedFormDefinition()?.groups; track group.name) {\n <axp-layout-section>\n @if (group.title || group.description) {\n <axp-layout-header>\n <axp-layout-title>{{ group.title! | translate | async }}</axp-layout-title>\n @if (group.description) {\n <axp-layout-description>{{ group.description! | translate | async }}</axp-layout-description>\n }\n </axp-layout-header>\n }\n <axp-layout-content>\n @if (layoutDirection() === 'grid') {\n <div class=\"__field-container\">\n @for (param of group.parameters; track param.path) {\n @if (param.widget.options?.['hidden'] !== true) {\n <ax-form-field class=\"__field-input\" [gridLayout]=\"resolveParamLayout(param)\">\n <ax-label [required]=\"isRequired(param)\">{{ param.title! | translate | async }}</ax-label>\n <ng-container\n axp-widget-renderer\n [node]=\"param.widget\"\n [mode]=\"resolveParamMode(group, param)\"\n ></ng-container>\n @if (param.description) {\n <axp-layout-description>{{ param.description! | translate | async }}</axp-layout-description>\n }\n </ax-form-field>\n }\n }\n </div>\n } @else {\n @for (param of group.parameters; track param.path) {\n @if (param.widget.options?.['hidden'] !== true) {\n <div class=\"__field-container\">\n <ax-form-field class=\"__field-input\" [gridLayout]=\"resolveParamLayout(param)\">\n <ax-label [required]=\"isRequired(param)\">{{ param.title! | translate | async }}</ax-label>\n <ng-container\n axp-widget-renderer\n [node]=\"param.widget\"\n [mode]=\"resolveParamMode(group, param)\"\n ></ng-container>\n @if (param.description) {\n <axp-layout-description>{{ param.description! | translate | async }}</axp-layout-description>\n }\n </ax-form-field>\n </div>\n }\n }\n }\n </axp-layout-content>\n </axp-layout-section>\n } @empty {\n <axp-layout-section>\n <axp-layout-content>\n <axp-state-message\n icon=\"fa-light fa-clipboard-list\"\n [title]=\"'@general:no-form-definition.title'\"\n [description]=\"'@general:no-form-definition.description'\"\n >\n </axp-state-message>\n </axp-layout-content>\n </axp-layout-section>\n }\n </axp-layout-sections>\n </axp-widgets-container>\n</ax-form>\n", styles: ["axp-dynamic-form{width:100%}axp-dynamic-form axp-layout-section axp-layout-content{display:flex;width:100%;flex-direction:column}axp-dynamic-form axp-layout-section axp-layout-content>:not([hidden])~:not([hidden]){--tw-divide-y-reverse: 0;border-top-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px * var(--tw-divide-y-reverse));border-style:dashed;--tw-divide-opacity: 1;border-color:rgba(var(--ax-sys-color-border-lightest-surface),var(--tw-divide-opacity, 1))}axp-dynamic-form axp-layout-section axp-layout-content .__field-container{align-items:center;gap:1rem;padding:1rem}@media (min-width: 1024px){axp-dynamic-form axp-layout-section axp-layout-content .__field-container{padding-left:1.5rem;padding-right:1.5rem}}@media (min-width: 1280px){axp-dynamic-form axp-layout-section axp-layout-content .__field-container{padding-left:2rem;padding-right:2rem}}@media (min-width: 1536px){axp-dynamic-form axp-layout-section axp-layout-content .__field-container{padding-left:2.5rem;padding-right:2.5rem}}axp-dynamic-form axp-layout-section axp-layout-content .__field-container{display:grid;grid-template-columns:repeat(12,minmax(0,1fr))}axp-dynamic-form axp-layout-section axp-layout-content .__field-container .__field-info{grid-column:span 12 / span 12}@media (min-width: 768px){axp-dynamic-form axp-layout-section axp-layout-content .__field-container .__field-info{grid-column:span 4 / span 4}}@media (min-width: 1024px){axp-dynamic-form axp-layout-section axp-layout-content .__field-container .__field-info{grid-column:span 4 / span 4}}@media (min-width: 1536px){axp-dynamic-form axp-layout-section axp-layout-content .__field-container .__field-info{grid-column:span 3 / span 3}}axp-dynamic-form axp-layout-section axp-layout-content .__field-container axp-layout-description{margin-top:.5rem!important;font-size:.75rem!important;line-height:1rem!important}axp-dynamic-form.--look-compact axp-layout-section axp-layout-content>:not([hidden])~:not([hidden]){border-style:none}axp-dynamic-form.--look-compact axp-layout-section axp-layout-content .__field-container{display:flex;flex-direction:column;gap:.25rem;padding:.25rem .5rem;margin-bottom:.5rem;border-width:0px}axp-dynamic-form.--look-compact axp-layout-section axp-layout-content .__field-container .__field-info{margin-bottom:.125rem;width:100%}axp-dynamic-form.--look-compact axp-layout-section axp-layout-content .__field-container .__field-info axp-layout-title{font-size:.875rem;line-height:1.25rem;font-weight:500}axp-dynamic-form.--look-compact axp-layout-section axp-layout-content .__field-container .__field-input{width:100%}axp-dynamic-form.--look-compact axp-layout-section axp-layout-content .__field-container axp-layout-description{margin-top:.125rem!important;font-size:.75rem!important;line-height:1rem!important;opacity:.75!important}axp-dynamic-form.--look-compact axp-layout-section{margin-bottom:.75rem}axp-dynamic-form.--look-compact axp-layout-section axp-layout-header{margin-bottom:.5rem;gap:0px;padding:.5rem}axp-dynamic-form.--look-compact axp-layout-section axp-layout-header axp-layout-title{font-size:1rem;line-height:1.5rem;font-weight:600}axp-dynamic-form.--look-compact axp-layout-section axp-layout-header axp-layout-description{margin-top:.25rem;font-size:.75rem;line-height:1rem;opacity:.75}axp-dynamic-form.--look-borderless axp-layout-section{border-width:0px!important;--tw-shadow: 0 0 #0000 !important;--tw-shadow-colored: 0 0 #0000 !important;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)!important}axp-dynamic-form.--look-borderless axp-layout-section axp-layout-content>:not([hidden])~:not([hidden]){border-style:none}axp-dynamic-form.--look-borderless axp-layout-section axp-layout-content .__field-container{display:flex;flex-direction:column;gap:.25rem;padding:.25rem .5rem;margin-bottom:.5rem;border-width:0px}axp-dynamic-form.--look-borderless axp-layout-section axp-layout-content .__field-container .__field-info{margin-bottom:.125rem;width:100%}axp-dynamic-form.--look-borderless axp-layout-section axp-layout-content .__field-container .__field-info axp-layout-title{font-size:.875rem;line-height:1.25rem;font-weight:500}axp-dynamic-form.--look-borderless axp-layout-section axp-layout-content .__field-container .__field-input{width:100%}axp-dynamic-form.--look-borderless axp-layout-section axp-layout-content .__field-container axp-layout-description{margin-top:.125rem!important;font-size:.75rem!important;line-height:1rem!important;opacity:.75!important}axp-dynamic-form.--direction-vertical axp-layout-section axp-layout-content .__field-container{display:flex;flex-direction:column;align-items:flex-start;gap:.75rem}axp-dynamic-form.--direction-vertical axp-layout-section axp-layout-content .__field-container .__field-info{grid-column:span 12 / span 12;width:100%}axp-dynamic-form.--direction-vertical axp-layout-section axp-layout-content .__field-container .__field-input{grid-column:span 12 / span 12;width:100%}axp-dynamic-form.--direction-vertical axp-layout-section axp-layout-content .__field-container axp-layout-description{margin-top:.25rem!important;font-size:.875rem!important;line-height:1.25rem!important}axp-dynamic-form.--direction-horizontal axp-layout-section axp-layout-content>:not([hidden])~:not([hidden]){border-style:none}axp-dynamic-form.--direction-horizontal axp-layout-section axp-layout-content .__field-container{display:flex;flex-direction:row;align-items:center;gap:1rem;padding-top:.75rem;padding-bottom:.75rem}axp-dynamic-form.--direction-horizontal axp-layout-section axp-layout-content .__field-container .__field-info{width:12rem;flex-shrink:0}axp-dynamic-form.--direction-horizontal axp-layout-section axp-layout-content .__field-container .__field-info axp-layout-title{margin-bottom:.25rem;font-size:.875rem;line-height:1.25rem;font-weight:500}axp-dynamic-form.--direction-horizontal axp-layout-section axp-layout-content .__field-container .__field-input{flex:1 1 0%}axp-dynamic-form.--direction-horizontal axp-layout-section axp-layout-content .__field-container axp-layout-description{margin-top:.25rem!important;font-size:.75rem!important;line-height:1rem!important;opacity:.75!important}axp-dynamic-form.--direction-grid axp-layout-section axp-layout-content .__field-container{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:1rem;padding:1rem}axp-dynamic-form.--direction-grid axp-layout-section axp-layout-content .__field-container .__field-info{grid-column:span 12 / span 12}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type:
1186
1950
  // ACoreX
1187
- AXFormModule }, { kind: "component", type: i1$1.AXFormFieldComponent, selector: "ax-form-field", inputs: ["labelMode"] }, { kind: "component", type: i1$1.AXFormComponent, selector: "ax-form", inputs: ["labelMode", "look", "messageStyle", "updateOn"], outputs: ["onValidate", "updateOnChange"] }, { kind: "ngmodule", type: AXValidationModule }, { kind: "ngmodule", type:
1951
+ AXFormModule }, { kind: "component", type: i2$4.AXFormFieldComponent, selector: "ax-form-field", inputs: ["labelMode"] }, { kind: "component", type: i2$4.AXFormComponent, selector: "ax-form", inputs: ["labelMode", "look", "messageStyle", "updateOn"], outputs: ["onValidate", "updateOnChange"] }, { kind: "ngmodule", type: AXValidationModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type:
1188
1952
  // Platform
1189
- AXPLayoutBuilderModule }, { kind: "component", type: i3$2.AXPWidgetContainerComponent, selector: "axp-widgets-container", inputs: ["context", "functions"], outputs: ["onContextChanged"] }, { kind: "directive", type: i3$2.AXPWidgetRendererDirective, selector: "[axp-widget-renderer]", inputs: ["parentNode", "index", "mode", "node"], outputs: ["onOptionsChanged", "onValueChanged"], exportAs: ["widgetRenderer"] }, { kind: "component", type: AXPThemeLayoutBlockComponent, selector: "\n\n axp-page-content, \n axp-page-footer-container,\n axp-page-footer,\n axp-page-header,\n axp-page-header-container,\n axp-page-toolbar,\n\n axp-layout-content, \n axp-layout-page-content, \n\n axp-layout-sections,\n axp-layout-body,\n axp-layout-page-body,\n axp-layout-prefix,\n axp-layout-suffix,\n axp-layout-title-bar,\n axp-layout-title, \n axp-layout-title-actions, \n axp-layout-nav-button, \n axp-layout-description, \n axp-layout-breadcrumbs,\n axp-layout-list-action,\n " }, { kind: "component", type: AXPThemeLayoutHeaderComponent, selector: "axp-layout-header" }, { kind: "component", type: AXPThemeLayoutSectionComponent, selector: "axp-layout-section" }, { kind: "directive", type: AXPGridLayoutDirective, selector: "[gridLayout]", inputs: ["gridLayout"] }, { kind: "component", type: AXLabelComponent, selector: "ax-label", inputs: ["required", "for"], outputs: ["requiredChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
1953
+ AXPLayoutBuilderModule }, { kind: "component", type: i3$3.AXPWidgetContainerComponent, selector: "axp-widgets-container", inputs: ["context", "functions"], outputs: ["onContextChanged"] }, { kind: "directive", type: i3$3.AXPWidgetRendererDirective, selector: "[axp-widget-renderer]", inputs: ["parentNode", "index", "mode", "node"], outputs: ["onOptionsChanged", "onValueChanged"], exportAs: ["widgetRenderer"] }, { kind: "component", type: AXPThemeLayoutBlockComponent, selector: "\n\n axp-page-content, \n axp-page-footer-container,\n axp-page-footer,\n axp-page-header,\n axp-page-header-container,\n axp-page-toolbar,\n\n axp-layout-content, \n axp-layout-page-content, \n\n axp-layout-sections,\n axp-layout-body,\n axp-layout-page-body,\n axp-layout-prefix,\n axp-layout-suffix,\n axp-layout-title-bar,\n axp-layout-title, \n axp-layout-title-actions, \n axp-layout-nav-button, \n axp-layout-description, \n axp-layout-breadcrumbs,\n axp-layout-list-action,\n " }, { kind: "component", type: AXPThemeLayoutHeaderComponent, selector: "axp-layout-header" }, { kind: "component", type: AXPThemeLayoutSectionComponent, selector: "axp-layout-section" }, { kind: "directive", type: AXPGridLayoutDirective, selector: "[gridLayout]", inputs: ["gridLayout"] }, { kind: "component", type: AXLabelComponent, selector: "ax-label", inputs: ["required", "for"], outputs: ["requiredChange"] }, { kind: "component", type: AXPStateMessageComponent, selector: "axp-state-message", inputs: ["mode", "icon", "title", "description", "variant"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
1190
1954
  }
1191
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPDynamicFormComponent, decorators: [{
1955
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPDynamicFormComponent, decorators: [{
1192
1956
  type: Component,
1193
1957
  args: [{ standalone: true, selector: 'axp-dynamic-form', imports: [
1194
1958
  CommonModule,
@@ -1196,44 +1960,2168 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
1196
1960
  // ACoreX
1197
1961
  AXFormModule,
1198
1962
  AXValidationModule,
1963
+ AXTranslationModule,
1199
1964
  // Platform
1200
1965
  AXPLayoutBuilderModule,
1201
1966
  AXPThemeLayoutBlockComponent,
1202
1967
  AXPThemeLayoutHeaderComponent,
1203
1968
  AXPThemeLayoutSectionComponent,
1204
1969
  AXPGridLayoutDirective,
1205
- AXLabelComponent
1970
+ AXLabelComponent,
1971
+ AXPStateMessageComponent,
1206
1972
  ], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
1207
1973
  class: 'axp-dynamic-form',
1208
1974
  '[class]': 'hostClasses()',
1209
- }, template: "<ax-form>\n <axp-widgets-container [context]=\"internalContext()\" (onContextChanged)=\"handleContextChanged($event)\">\n <axp-layout-sections>\n @if (computedFormDefinition()) {\n @for (group of computedFormDefinition().groups; track group.name) {\n <axp-layout-section>\n <axp-layout-header>\n <axp-layout-title>{{ group.title }}</axp-layout-title>\n @if (group.description) {\n <axp-layout-description>{{ group.description }}</axp-layout-description>\n }\n </axp-layout-header>\n <axp-layout-content>\n @for (param of group.parameters; track param.path) {\n <div class=\"__field-container\">\n <ax-form-field class=\"__field-input\" [gridLayout]=\"computedLayout()\">\n <ax-label>{{ param.title }}</ax-label>\n <ng-container axp-widget-renderer [node]=\"param.widget\" [mode]=\"'edit'\"></ng-container>\n <!-- @if (param.description) {\n <axp-layout-description>{{ param.description }}</axp-layout-description>\n } -->\n </ax-form-field>\n </div>\n }\n </axp-layout-content>\n </axp-layout-section>\n }\n } @else {\n <axp-layout-section>\n <axp-layout-content>\n <div class=\"__empty-state\">\n <axp-layout-description>No form definition provided</axp-layout-description>\n </div>\n </axp-layout-content>\n </axp-layout-section>\n }\n </axp-layout-sections>\n </axp-widgets-container>\n</ax-form>\n", styles: [".axp-dynamic-form{width:100%}.axp-dynamic-form axp-layout-section axp-layout-content{display:flex;width:100%;flex-direction:column}.axp-dynamic-form axp-layout-section axp-layout-content>:not([hidden])~:not([hidden]){--tw-divide-y-reverse: 0;border-top-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px * var(--tw-divide-y-reverse));border-style:dashed;--tw-divide-opacity: 1;border-color:rgba(var(--ax-sys-color-border-lightest-surface),var(--tw-divide-opacity, 1))}.axp-dynamic-form axp-layout-section axp-layout-content .__field-container{align-items:center;gap:1rem;padding:1rem}@media (min-width: 1024px){.axp-dynamic-form axp-layout-section axp-layout-content .__field-container{padding-left:1.5rem;padding-right:1.5rem}}@media (min-width: 1280px){.axp-dynamic-form axp-layout-section axp-layout-content .__field-container{padding-left:2rem;padding-right:2rem}}@media (min-width: 1536px){.axp-dynamic-form axp-layout-section axp-layout-content .__field-container{padding-left:2.5rem;padding-right:2.5rem}}.axp-dynamic-form axp-layout-section axp-layout-content .__field-container{display:grid;grid-template-columns:repeat(12,minmax(0,1fr))}.axp-dynamic-form axp-layout-section axp-layout-content .__field-container .__field-info{grid-column:span 12 / span 12}@media (min-width: 768px){.axp-dynamic-form axp-layout-section axp-layout-content .__field-container .__field-info{grid-column:span 4 / span 4}}@media (min-width: 1024px){.axp-dynamic-form axp-layout-section axp-layout-content .__field-container .__field-info{grid-column:span 4 / span 4}}@media (min-width: 1536px){.axp-dynamic-form axp-layout-section axp-layout-content .__field-container .__field-info{grid-column:span 3 / span 3}}.axp-dynamic-form axp-layout-section axp-layout-content .__field-container axp-layout-description{margin-top:.5rem!important;font-size:.75rem!important;line-height:1rem!important}.axp-dynamic-form.--compact axp-layout-section axp-layout-content>:not([hidden])~:not([hidden]){border-style:none}.axp-dynamic-form.--compact axp-layout-section axp-layout-content .__field-container{display:flex;flex-direction:column;gap:.25rem;padding:.25rem .5rem;margin-bottom:.5rem;border-width:0px}.axp-dynamic-form.--compact axp-layout-section axp-layout-content .__field-container .__field-info{margin-bottom:.125rem;width:100%}.axp-dynamic-form.--compact axp-layout-section axp-layout-content .__field-container .__field-info axp-layout-title{font-size:.875rem;line-height:1.25rem;font-weight:500}.axp-dynamic-form.--compact axp-layout-section axp-layout-content .__field-container .__field-input{width:100%}.axp-dynamic-form.--compact axp-layout-section axp-layout-content .__field-container axp-layout-description{margin-top:.125rem!important;font-size:.75rem!important;line-height:1rem!important;opacity:.75!important}.axp-dynamic-form.--compact axp-layout-section{margin-bottom:.75rem}.axp-dynamic-form.--compact axp-layout-section axp-layout-header{margin-bottom:.5rem;gap:0px;padding:.5rem}.axp-dynamic-form.--compact axp-layout-section axp-layout-header axp-layout-title{font-size:1rem;line-height:1.5rem;font-weight:600}.axp-dynamic-form.--compact axp-layout-section axp-layout-header axp-layout-description{margin-top:.25rem;font-size:.75rem;line-height:1rem;opacity:.75}.axp-dynamic-form.--vertical axp-layout-section axp-layout-content .__field-container{display:flex;flex-direction:column;align-items:flex-start;gap:.75rem}.axp-dynamic-form.--vertical axp-layout-section axp-layout-content .__field-container .__field-info{grid-column:span 12 / span 12;width:100%}.axp-dynamic-form.--vertical axp-layout-section axp-layout-content .__field-container .__field-input{grid-column:span 12 / span 12;width:100%}.axp-dynamic-form.--vertical axp-layout-section axp-layout-content .__field-container axp-layout-description{margin-top:.25rem!important;font-size:.875rem!important;line-height:1.25rem!important}.axp-dynamic-form.--horizontal axp-layout-section axp-layout-content>:not([hidden])~:not([hidden]){border-style:none}.axp-dynamic-form.--horizontal axp-layout-section axp-layout-content .__field-container{display:flex;flex-direction:row;align-items:center;gap:1rem;padding-top:.75rem;padding-bottom:.75rem}.axp-dynamic-form.--horizontal axp-layout-section axp-layout-content .__field-container .__field-info{width:12rem;flex-shrink:0}.axp-dynamic-form.--horizontal axp-layout-section axp-layout-content .__field-container .__field-info axp-layout-title{margin-bottom:.25rem;font-size:.875rem;line-height:1.25rem;font-weight:500}.axp-dynamic-form.--horizontal axp-layout-section axp-layout-content .__field-container .__field-input{flex:1 1 0%}.axp-dynamic-form.--horizontal axp-layout-section axp-layout-content .__field-container axp-layout-description{margin-top:.25rem!important;font-size:.75rem!important;line-height:1rem!important;opacity:.75!important}.axp-dynamic-form .__empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding-top:2rem;padding-bottom:2rem;text-align:center}.axp-dynamic-form .__empty-state .__message{font-size:.875rem;line-height:1.25rem;--tw-text-opacity: 1;color:rgb(107 114 128 / var(--tw-text-opacity, 1))}\n"] }]
1975
+ }, template: "<ax-form>\n <axp-widgets-container [context]=\"internalContext()\" (onContextChanged)=\"handleContextChanged($event)\">\n <axp-layout-sections>\n @for (group of evaluatedFormDefinition()?.groups; track group.name) {\n <axp-layout-section>\n @if (group.title || group.description) {\n <axp-layout-header>\n <axp-layout-title>{{ group.title! | translate | async }}</axp-layout-title>\n @if (group.description) {\n <axp-layout-description>{{ group.description! | translate | async }}</axp-layout-description>\n }\n </axp-layout-header>\n }\n <axp-layout-content>\n @if (layoutDirection() === 'grid') {\n <div class=\"__field-container\">\n @for (param of group.parameters; track param.path) {\n @if (param.widget.options?.['hidden'] !== true) {\n <ax-form-field class=\"__field-input\" [gridLayout]=\"resolveParamLayout(param)\">\n <ax-label [required]=\"isRequired(param)\">{{ param.title! | translate | async }}</ax-label>\n <ng-container\n axp-widget-renderer\n [node]=\"param.widget\"\n [mode]=\"resolveParamMode(group, param)\"\n ></ng-container>\n @if (param.description) {\n <axp-layout-description>{{ param.description! | translate | async }}</axp-layout-description>\n }\n </ax-form-field>\n }\n }\n </div>\n } @else {\n @for (param of group.parameters; track param.path) {\n @if (param.widget.options?.['hidden'] !== true) {\n <div class=\"__field-container\">\n <ax-form-field class=\"__field-input\" [gridLayout]=\"resolveParamLayout(param)\">\n <ax-label [required]=\"isRequired(param)\">{{ param.title! | translate | async }}</ax-label>\n <ng-container\n axp-widget-renderer\n [node]=\"param.widget\"\n [mode]=\"resolveParamMode(group, param)\"\n ></ng-container>\n @if (param.description) {\n <axp-layout-description>{{ param.description! | translate | async }}</axp-layout-description>\n }\n </ax-form-field>\n </div>\n }\n }\n }\n </axp-layout-content>\n </axp-layout-section>\n } @empty {\n <axp-layout-section>\n <axp-layout-content>\n <axp-state-message\n icon=\"fa-light fa-clipboard-list\"\n [title]=\"'@general:no-form-definition.title'\"\n [description]=\"'@general:no-form-definition.description'\"\n >\n </axp-state-message>\n </axp-layout-content>\n </axp-layout-section>\n }\n </axp-layout-sections>\n </axp-widgets-container>\n</ax-form>\n", styles: ["axp-dynamic-form{width:100%}axp-dynamic-form axp-layout-section axp-layout-content{display:flex;width:100%;flex-direction:column}axp-dynamic-form axp-layout-section axp-layout-content>:not([hidden])~:not([hidden]){--tw-divide-y-reverse: 0;border-top-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px * var(--tw-divide-y-reverse));border-style:dashed;--tw-divide-opacity: 1;border-color:rgba(var(--ax-sys-color-border-lightest-surface),var(--tw-divide-opacity, 1))}axp-dynamic-form axp-layout-section axp-layout-content .__field-container{align-items:center;gap:1rem;padding:1rem}@media (min-width: 1024px){axp-dynamic-form axp-layout-section axp-layout-content .__field-container{padding-left:1.5rem;padding-right:1.5rem}}@media (min-width: 1280px){axp-dynamic-form axp-layout-section axp-layout-content .__field-container{padding-left:2rem;padding-right:2rem}}@media (min-width: 1536px){axp-dynamic-form axp-layout-section axp-layout-content .__field-container{padding-left:2.5rem;padding-right:2.5rem}}axp-dynamic-form axp-layout-section axp-layout-content .__field-container{display:grid;grid-template-columns:repeat(12,minmax(0,1fr))}axp-dynamic-form axp-layout-section axp-layout-content .__field-container .__field-info{grid-column:span 12 / span 12}@media (min-width: 768px){axp-dynamic-form axp-layout-section axp-layout-content .__field-container .__field-info{grid-column:span 4 / span 4}}@media (min-width: 1024px){axp-dynamic-form axp-layout-section axp-layout-content .__field-container .__field-info{grid-column:span 4 / span 4}}@media (min-width: 1536px){axp-dynamic-form axp-layout-section axp-layout-content .__field-container .__field-info{grid-column:span 3 / span 3}}axp-dynamic-form axp-layout-section axp-layout-content .__field-container axp-layout-description{margin-top:.5rem!important;font-size:.75rem!important;line-height:1rem!important}axp-dynamic-form.--look-compact axp-layout-section axp-layout-content>:not([hidden])~:not([hidden]){border-style:none}axp-dynamic-form.--look-compact axp-layout-section axp-layout-content .__field-container{display:flex;flex-direction:column;gap:.25rem;padding:.25rem .5rem;margin-bottom:.5rem;border-width:0px}axp-dynamic-form.--look-compact axp-layout-section axp-layout-content .__field-container .__field-info{margin-bottom:.125rem;width:100%}axp-dynamic-form.--look-compact axp-layout-section axp-layout-content .__field-container .__field-info axp-layout-title{font-size:.875rem;line-height:1.25rem;font-weight:500}axp-dynamic-form.--look-compact axp-layout-section axp-layout-content .__field-container .__field-input{width:100%}axp-dynamic-form.--look-compact axp-layout-section axp-layout-content .__field-container axp-layout-description{margin-top:.125rem!important;font-size:.75rem!important;line-height:1rem!important;opacity:.75!important}axp-dynamic-form.--look-compact axp-layout-section{margin-bottom:.75rem}axp-dynamic-form.--look-compact axp-layout-section axp-layout-header{margin-bottom:.5rem;gap:0px;padding:.5rem}axp-dynamic-form.--look-compact axp-layout-section axp-layout-header axp-layout-title{font-size:1rem;line-height:1.5rem;font-weight:600}axp-dynamic-form.--look-compact axp-layout-section axp-layout-header axp-layout-description{margin-top:.25rem;font-size:.75rem;line-height:1rem;opacity:.75}axp-dynamic-form.--look-borderless axp-layout-section{border-width:0px!important;--tw-shadow: 0 0 #0000 !important;--tw-shadow-colored: 0 0 #0000 !important;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)!important}axp-dynamic-form.--look-borderless axp-layout-section axp-layout-content>:not([hidden])~:not([hidden]){border-style:none}axp-dynamic-form.--look-borderless axp-layout-section axp-layout-content .__field-container{display:flex;flex-direction:column;gap:.25rem;padding:.25rem .5rem;margin-bottom:.5rem;border-width:0px}axp-dynamic-form.--look-borderless axp-layout-section axp-layout-content .__field-container .__field-info{margin-bottom:.125rem;width:100%}axp-dynamic-form.--look-borderless axp-layout-section axp-layout-content .__field-container .__field-info axp-layout-title{font-size:.875rem;line-height:1.25rem;font-weight:500}axp-dynamic-form.--look-borderless axp-layout-section axp-layout-content .__field-container .__field-input{width:100%}axp-dynamic-form.--look-borderless axp-layout-section axp-layout-content .__field-container axp-layout-description{margin-top:.125rem!important;font-size:.75rem!important;line-height:1rem!important;opacity:.75!important}axp-dynamic-form.--direction-vertical axp-layout-section axp-layout-content .__field-container{display:flex;flex-direction:column;align-items:flex-start;gap:.75rem}axp-dynamic-form.--direction-vertical axp-layout-section axp-layout-content .__field-container .__field-info{grid-column:span 12 / span 12;width:100%}axp-dynamic-form.--direction-vertical axp-layout-section axp-layout-content .__field-container .__field-input{grid-column:span 12 / span 12;width:100%}axp-dynamic-form.--direction-vertical axp-layout-section axp-layout-content .__field-container axp-layout-description{margin-top:.25rem!important;font-size:.875rem!important;line-height:1.25rem!important}axp-dynamic-form.--direction-horizontal axp-layout-section axp-layout-content>:not([hidden])~:not([hidden]){border-style:none}axp-dynamic-form.--direction-horizontal axp-layout-section axp-layout-content .__field-container{display:flex;flex-direction:row;align-items:center;gap:1rem;padding-top:.75rem;padding-bottom:.75rem}axp-dynamic-form.--direction-horizontal axp-layout-section axp-layout-content .__field-container .__field-info{width:12rem;flex-shrink:0}axp-dynamic-form.--direction-horizontal axp-layout-section axp-layout-content .__field-container .__field-info axp-layout-title{margin-bottom:.25rem;font-size:.875rem;line-height:1.25rem;font-weight:500}axp-dynamic-form.--direction-horizontal axp-layout-section axp-layout-content .__field-container .__field-input{flex:1 1 0%}axp-dynamic-form.--direction-horizontal axp-layout-section axp-layout-content .__field-container axp-layout-description{margin-top:.25rem!important;font-size:.75rem!important;line-height:1rem!important;opacity:.75!important}axp-dynamic-form.--direction-grid axp-layout-section axp-layout-content .__field-container{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:1rem;padding:1rem}axp-dynamic-form.--direction-grid axp-layout-section axp-layout-content .__field-container .__field-info{grid-column:span 12 / span 12}\n"] }]
1210
1976
  }] });
1211
1977
 
1212
- class AXPLayoutFiltersComponent {
1978
+ //#endregion
1979
+ class AXPDynamicFormStepperComponent {
1213
1980
  constructor() {
1214
- this.translate = inject(AXTranslationService);
1215
- this.calendarService = inject(AXCalendarService);
1216
- this.filterOperatorMiddleware = inject(AXPFilterOperatorMiddlewareService);
1217
- this.filtersDefinitions = input([], ...(ngDevMode ? [{ debugName: "filtersDefinitions" }] : []));
1218
- this.initialFilters = input([], ...(ngDevMode ? [{ debugName: "initialFilters" }] : []));
1219
- this.onFiltersChanged = output();
1220
- this.tagBox = viewChild('tagBox', ...(ngDevMode ? [{ debugName: "tagBox" }] : []));
1221
- this.selectedField = signal(null, ...(ngDevMode ? [{ debugName: "selectedField" }] : []));
1222
- this.selectedFilters = linkedSignal(() => this.convertQueriesToDefinitions(this.initialFilters()).map((i) => ({ ...i, readOnly: true })));
1223
- this.context = linkedSignal(() => this.convertQueriesToContext(this.initialFilters()));
1224
- this.activeFilter = signal(null, ...(ngDevMode ? [{ debugName: "activeFilter" }] : []));
1225
- this.asyncTags = signal([], ...(ngDevMode ? [{ debugName: "asyncTags" }] : []));
1226
- this.popover = viewChild('popover', ...(ngDevMode ? [{ debugName: "popover" }] : []));
1227
- this.inputValue = signal('', ...(ngDevMode ? [{ debugName: "inputValue" }] : []));
1228
- this.inlineFilters = () => {
1229
- return this.filtersDefinitions().filter((f) => f.filterType.inline &&
1230
- !this.filterOperatorMiddleware
1231
- .transformFilters(this.selectedFilters())
1232
- .some((sf) => sf.field === f.field &&
1233
- sf.operator?.type === (this.context()[sf.field]?.operation?.type || f.operator?.type)));
1234
- };
1981
+ //#region ---- Inputs ----
1982
+ /**
1983
+ * Stepper definition providing steps metadata and behavior configuration
1984
+ */
1985
+ this.definition = input.required(...(ngDevMode ? [{ debugName: "definition" }] : []));
1986
+ /**
1987
+ * Shared root context for all steps
1988
+ */
1989
+ this.context = input.required(...(ngDevMode ? [{ debugName: "context" }] : []));
1990
+ /**
1991
+ * Optional pass-through layout props for inner forms
1992
+ */
1993
+ this.layoutLook = input('normal', ...(ngDevMode ? [{ debugName: "layoutLook" }] : []));
1994
+ this.stepperDirection = input('horizontal', ...(ngDevMode ? [{ debugName: "stepperDirection" }] : []));
1995
+ this.layoutConfig = input(...(ngDevMode ? [undefined, { debugName: "layoutConfig" }] : []));
1996
+ /**
1997
+ * Optional guard that controls advancing to the next step (async only)
1998
+ */
1999
+ this.guardNext = input(...(ngDevMode ? [undefined, { debugName: "guardNext" }] : []));
2000
+ //#endregion
2001
+ //#region ---- Outputs ----
2002
+ /**
2003
+ * Emits when the shared root context changes
2004
+ */
2005
+ this.contextChange = output();
2006
+ /**
2007
+ * Emits when the active step changes
2008
+ */
2009
+ this.stepChange = output();
2010
+ /**
2011
+ * Emits after successful finish
2012
+ */
2013
+ this.finished = output();
2014
+ /**
2015
+ * Emits when cancelled by API
2016
+ */
2017
+ this.cancel = output();
2018
+ /**
2019
+ * Emits when navigation is blocked by validation or policy
2020
+ */
2021
+ this.navigationBlocked = output();
2022
+ //#endregion
2023
+ //#region ---- State ----
2024
+ /**
2025
+ * Internal reactive copy of the shared context
2026
+ */
2027
+ this.internalContext = signal({}, ...(ngDevMode ? [{ debugName: "internalContext" }] : []));
2028
+ /**
2029
+ * Active step index
2030
+ */
2031
+ this.currentStepIndex = signal(0, ...(ngDevMode ? [{ debugName: "currentStepIndex" }] : []));
2032
+ /**
2033
+ * Navigation lock while async guards are pending
2034
+ */
2035
+ this.navigationLocked = signal(false, ...(ngDevMode ? [{ debugName: "navigationLocked" }] : []));
2036
+ /**
2037
+ * Reference to underlying step wizard to sync visual navigation
2038
+ */
2039
+ this.wizard = viewChild(AXStepWizardComponent, ...(ngDevMode ? [{ debugName: "wizard" }] : []));
2040
+ /**
2041
+ * References to rendered dynamic forms (usually one active)
2042
+ */
2043
+ this.forms = viewChildren(AXPDynamicFormComponent, ...(ngDevMode ? [{ debugName: "forms" }] : []));
2044
+ //#endregion
2045
+ //#region ---- Computed Properties ----
2046
+ this.steps = computed(() => this.definition().steps ?? [], ...(ngDevMode ? [{ debugName: "steps" }] : []));
2047
+ this.stepCount = computed(() => this.steps().length, ...(ngDevMode ? [{ debugName: "stepCount" }] : []));
2048
+ this.currentStep = computed(() => this.steps()[this.currentStepIndex()] ?? undefined, ...(ngDevMode ? [{ debugName: "currentStep" }] : []));
2049
+ this.isFirstComputed = computed(() => this.currentStepIndex() === 0, ...(ngDevMode ? [{ debugName: "isFirstComputed" }] : []));
2050
+ this.isLastComputed = computed(() => this.currentStepIndex() === Math.max(0, this.stepCount() - 1), ...(ngDevMode ? [{ debugName: "isLastComputed" }] : []));
2051
+ /**
2052
+ * Non-undefined layout config for inner dynamic forms
2053
+ */
2054
+ this.effectiveLayoutConfig = computed(() => this.layoutConfig() ?? {
2055
+ positions: {
2056
+ default: { colSpan: 12 },
2057
+ md: { colSpan: 8 },
2058
+ lg: { colSpan: 6 },
2059
+ xl: { colSpan: 5 },
2060
+ xxl: { colSpan: 4 },
2061
+ },
2062
+ }, ...(ngDevMode ? [{ debugName: "effectiveLayoutConfig" }] : []));
2063
+ //#endregion
2064
+ //#region ---- Effects ----
2065
+ /**
2066
+ * Keep internal context in sync with input context
2067
+ */
2068
+ this.#contextSync = effect(() => {
2069
+ const ctx = this.context();
2070
+ this.internalContext.set(ctx ?? {});
2071
+ }, ...(ngDevMode ? [{ debugName: "#contextSync" }] : []));
2072
+ }
2073
+ //#endregion
2074
+ //#region ---- Effects ----
2075
+ /**
2076
+ * Keep internal context in sync with input context
2077
+ */
2078
+ #contextSync;
2079
+ //#endregion
2080
+ //#region ---- Public API ----
2081
+ /**
2082
+ * Returns the current step pointer
2083
+ */
2084
+ getCurrentStep() {
2085
+ const step = this.currentStep();
2086
+ return { index: this.currentStepIndex(), id: step?.id ?? '' };
2087
+ }
2088
+ /**
2089
+ * Public helpers for templates/consumers
2090
+ */
2091
+ isFirst() {
2092
+ return this.currentStepIndex() === 0;
2093
+ }
2094
+ isLast() {
2095
+ return this.currentStepIndex() === Math.max(0, this.stepCount() - 1);
2096
+ }
2097
+ /**
2098
+ * Returns the root context
2099
+ */
2100
+ getContext() {
2101
+ return this.internalContext();
2102
+ }
2103
+ /**
2104
+ * Replaces the root context programmatically
2105
+ */
2106
+ setContext(ctx) {
2107
+ this.internalContext.set(ctx ?? {});
2108
+ this.contextChange.emit(this.internalContext());
2109
+ }
2110
+ /**
2111
+ * Validates the current step.
2112
+ */
2113
+ async validateCurrentStep() {
2114
+ const instances = this.forms();
2115
+ if (!instances || instances.length === 0) {
2116
+ return true;
2117
+ }
2118
+ const index = this.currentStepIndex();
2119
+ const form = instances[index] ?? instances[0];
2120
+ if (form && typeof form.validate === 'function') {
2121
+ return await form.validate();
2122
+ }
2123
+ return true;
2124
+ }
2125
+ /**
2126
+ * Attempts to advance to the next step applying validation and guard
2127
+ */
2128
+ async next() {
2129
+ if (this.navigationLocked()) {
2130
+ return;
2131
+ }
2132
+ const valid = await this.validateCurrentStep();
2133
+ if (!valid) {
2134
+ const step = this.currentStep();
2135
+ if (step) {
2136
+ this.navigationBlocked.emit({ reason: 'invalid', stepId: step.id });
2137
+ }
2138
+ return;
2139
+ }
2140
+ const index = this.currentStepIndex();
2141
+ const step = this.steps()[index];
2142
+ if (!step) {
2143
+ return;
2144
+ }
2145
+ const event = { index, id: step.id, fullContext: this.internalContext() };
2146
+ const guard = this.guardNext();
2147
+ if (guard) {
2148
+ try {
2149
+ this.navigationLocked.set(true);
2150
+ const allowed = await guard(event);
2151
+ if (!allowed) {
2152
+ return;
2153
+ }
2154
+ }
2155
+ finally {
2156
+ this.navigationLocked.set(false);
2157
+ }
2158
+ }
2159
+ // Context is already synced through onStepContextChange
2160
+ this.contextChange.emit(this.internalContext());
2161
+ // Advance
2162
+ if (index < this.stepCount() - 1) {
2163
+ this.#activateStep(index + 1);
2164
+ // Sync visual wizard
2165
+ this.wizard()?.next();
2166
+ }
2167
+ }
2168
+ /**
2169
+ * Goes back to the previous step if possible
2170
+ */
2171
+ async previous() {
2172
+ if (this.navigationLocked()) {
2173
+ return;
2174
+ }
2175
+ const index = this.currentStepIndex();
2176
+ if (index <= 0) {
2177
+ return;
2178
+ }
2179
+ const current = this.steps()[index];
2180
+ if (current && current.canGoBack === false) {
2181
+ this.navigationBlocked.emit({ reason: 'cannot-go-back', stepId: current.id, targetIndex: index - 1 });
2182
+ return;
2183
+ }
2184
+ this.#activateStep(index - 1);
2185
+ // Sync visual wizard
2186
+ this.wizard()?.previous();
2187
+ }
2188
+ /**
2189
+ * Navigates to a specific step by id or index
2190
+ */
2191
+ async goTo(stepIdOrIndex) {
2192
+ if (typeof stepIdOrIndex === 'number') {
2193
+ await this.#attemptNavigateToIndex(stepIdOrIndex);
2194
+ return;
2195
+ }
2196
+ const idx = this.steps().findIndex((s) => s.id === stepIdOrIndex);
2197
+ if (idx >= 0) {
2198
+ await this.#attemptNavigateToIndex(idx);
2199
+ }
2200
+ }
2201
+ /**
2202
+ * Validates all steps and emits finished when successful
2203
+ */
2204
+ async finish() {
2205
+ // MVP: assume all steps valid
2206
+ this.finished.emit(this.internalContext());
2207
+ }
2208
+ /**
2209
+ * Emits cancel event without state changes
2210
+ */
2211
+ cancelFlow() {
2212
+ this.cancel.emit();
2213
+ }
2214
+ //#endregion
2215
+ //#region ---- Utilities ----
2216
+ #activateStep(index) {
2217
+ this.currentStepIndex.set(index);
2218
+ const step = this.steps()[index];
2219
+ if (step?.dataPath) {
2220
+ // Ensure the path exists for binding
2221
+ this.#ensurePath(step.dataPath);
2222
+ }
2223
+ if (step) {
2224
+ this.stepChange.emit({ index, id: step.id });
2225
+ }
2226
+ }
2227
+ /**
2228
+ * Attempts navigation to a specific index while enforcing linear/skip/back rules and validation.
2229
+ */
2230
+ async #attemptNavigateToIndex(targetIndex) {
2231
+ if (targetIndex < 0 || targetIndex >= this.stepCount()) {
2232
+ return;
2233
+ }
2234
+ const currentIndex = this.currentStepIndex();
2235
+ if (targetIndex === currentIndex) {
2236
+ return;
2237
+ }
2238
+ const steps = this.steps();
2239
+ const current = steps[currentIndex];
2240
+ const target = steps[targetIndex];
2241
+ if (!current || !target) {
2242
+ return;
2243
+ }
2244
+ // Moving backward: ensure all steps between have canGoBack !== false
2245
+ if (targetIndex < currentIndex) {
2246
+ for (let i = currentIndex; i > targetIndex; i--) {
2247
+ const step = steps[i];
2248
+ if (step && step.canGoBack === false) {
2249
+ this.navigationBlocked.emit({ reason: 'cannot-go-back', stepId: step.id, targetIndex });
2250
+ return;
2251
+ }
2252
+ }
2253
+ this.#activateStep(targetIndex);
2254
+ const w = this.wizard();
2255
+ if (w && typeof w.goStep === 'function') {
2256
+ w.goStep(targetIndex);
2257
+ }
2258
+ else {
2259
+ this.wizard()?.previous();
2260
+ }
2261
+ return;
2262
+ }
2263
+ // Moving forward: enforce linear and canSkip
2264
+ const isLinear = !!this.definition().linear;
2265
+ if (isLinear && targetIndex > currentIndex + 1) {
2266
+ this.navigationBlocked.emit({ reason: 'linear', stepId: current.id, targetIndex });
2267
+ return;
2268
+ }
2269
+ // Check skipped steps for canSkip
2270
+ for (let i = currentIndex + 1; i < targetIndex; i++) {
2271
+ const step = steps[i];
2272
+ if (step && step.canSkip !== true) {
2273
+ this.navigationBlocked.emit({ reason: 'cannot-skip', stepId: step.id, targetIndex });
2274
+ return;
2275
+ }
2276
+ }
2277
+ // Forward navigation should validate current step and pass guard
2278
+ const valid = await this.validateCurrentStep();
2279
+ if (!valid) {
2280
+ this.navigationBlocked.emit({ reason: 'invalid', stepId: current.id, targetIndex });
2281
+ return;
2282
+ }
2283
+ const guard = this.guardNext();
2284
+ if (guard) {
2285
+ try {
2286
+ this.navigationLocked.set(true);
2287
+ const allowed = await guard({ index: currentIndex, id: current.id, fullContext: this.internalContext() });
2288
+ if (!allowed) {
2289
+ return;
2290
+ }
2291
+ }
2292
+ finally {
2293
+ this.navigationLocked.set(false);
2294
+ }
2295
+ }
2296
+ this.#activateStep(targetIndex);
2297
+ const w = this.wizard();
2298
+ if (w && typeof w.goStep === 'function') {
2299
+ w.goStep(targetIndex);
2300
+ }
2301
+ else {
2302
+ this.wizard()?.next();
2303
+ }
2304
+ }
2305
+ #readStepSlice(path) {
2306
+ const root = this.internalContext();
2307
+ if (!path) {
2308
+ return { slice: root, exists: true };
2309
+ }
2310
+ const parts = path.split('.').filter(Boolean);
2311
+ let node = root;
2312
+ for (const key of parts) {
2313
+ if (node == null || typeof node !== 'object') {
2314
+ return { slice: undefined, exists: false };
2315
+ }
2316
+ node = node[key];
2317
+ }
2318
+ return { slice: node, exists: node !== undefined };
2319
+ }
2320
+ #writeStepSlice(path, value) {
2321
+ if (!path) {
2322
+ // Replace full root with value only if value is an object
2323
+ if (value && typeof value === 'object') {
2324
+ this.internalContext.set(value);
2325
+ }
2326
+ return;
2327
+ }
2328
+ const root = { ...this.internalContext() };
2329
+ const parts = path.split('.').filter(Boolean);
2330
+ let node = root;
2331
+ for (let i = 0; i < parts.length; i++) {
2332
+ const key = parts[i];
2333
+ if (i === parts.length - 1) {
2334
+ node[key] = value;
2335
+ }
2336
+ else {
2337
+ node[key] = node[key] && typeof node[key] === 'object' ? { ...node[key] } : {};
2338
+ node = node[key];
2339
+ }
2340
+ }
2341
+ this.internalContext.set(root);
2342
+ }
2343
+ #ensurePath(path) {
2344
+ const root = { ...this.internalContext() };
2345
+ const parts = path.split('.').filter(Boolean);
2346
+ let node = root;
2347
+ for (const key of parts) {
2348
+ if (!node[key] || typeof node[key] !== 'object') {
2349
+ node[key] = {};
2350
+ }
2351
+ node = node[key];
2352
+ }
2353
+ this.internalContext.set(root);
2354
+ }
2355
+ /**
2356
+ * Handle per-step context changes and keep internal root context in sync.
2357
+ */
2358
+ onStepContextChange(stepId, stepContext) {
2359
+ const step = this.steps().find((s) => s.id === stepId);
2360
+ if (!step) {
2361
+ return;
2362
+ }
2363
+ this.#writeStepSlice(step.dataPath, stepContext);
2364
+ this.contextChange.emit(this.internalContext());
2365
+ }
2366
+ /**
2367
+ * Exposes reading a step slice to the template
2368
+ */
2369
+ readStepSlice(path) {
2370
+ return this.#readStepSlice(path);
2371
+ }
2372
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPDynamicFormStepperComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2373
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.8", type: AXPDynamicFormStepperComponent, isStandalone: true, selector: "axp-dynamic-form-stepper", inputs: { definition: { classPropertyName: "definition", publicName: "definition", isSignal: true, isRequired: true, transformFunction: null }, context: { classPropertyName: "context", publicName: "context", isSignal: true, isRequired: true, transformFunction: null }, layoutLook: { classPropertyName: "layoutLook", publicName: "layoutLook", isSignal: true, isRequired: false, transformFunction: null }, stepperDirection: { classPropertyName: "stepperDirection", publicName: "stepperDirection", isSignal: true, isRequired: false, transformFunction: null }, layoutConfig: { classPropertyName: "layoutConfig", publicName: "layoutConfig", isSignal: true, isRequired: false, transformFunction: null }, guardNext: { classPropertyName: "guardNext", publicName: "guardNext", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { contextChange: "contextChange", stepChange: "stepChange", finished: "finished", cancel: "cancel", navigationBlocked: "navigationBlocked" }, host: { properties: { "class.--vertical": "stepperDirection() === 'vertical'" }, classAttribute: "axp-dynamic-form-stepper" }, viewQueries: [{ propertyName: "wizard", first: true, predicate: AXStepWizardComponent, descendants: true, isSignal: true }, { propertyName: "forms", predicate: AXPDynamicFormComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<ax-step-wizard\n class=\"ax-sticky ax-top-0 ax-z-10 ax-transition-all\"\n #sticky=\"axpSticky\"\n [axpSticky]=\"'ax-bg-lightest ax-shadow-md ax-pt-4'\"\n [stickyParent]=\"'.ax-popup-body-container'\"\n #wizard\n [content]=\"wizardContent\"\n [stickyOffset]=\"100\"\n [look]=\"'text-line'\"\n [orientation]=\"stepperDirection()\"\n>\n @for (step of steps(); track step.id) {\n <ax-step-wizard-item [label]=\"(step.title || '' | translate | async)!\" [id]=\"step.id\">\n @if (step.icon) {\n <ax-icon [class]=\"step.icon\"></ax-icon>\n }\n <ax-content>\n <axp-dynamic-form\n [formDefinition]=\"{ groups: step.groups }\"\n [context]=\"readStepSlice(step.dataPath).slice\"\n [layoutLook]=\"layoutLook()\"\n [layoutDirection]=\"step.formDirection || 'vertical'\"\n [layoutConfig]=\"effectiveLayoutConfig()\"\n (contextChange)=\"onStepContextChange(step.id, $event)\"\n ></axp-dynamic-form>\n </ax-content>\n </ax-step-wizard-item>\n }\n</ax-step-wizard>\n\n<ng-template [axStepWizardContent] #wizardContent=\"axStepWizardContent\"></ng-template>\n", styles: [".axp-dynamic-form-stepper.--vertical{display:flex;gap:1rem}.axp-dynamic-form-stepper.--vertical ax-step-wizard{width:unset}.axp-dynamic-form-stepper.--vertical ax-content{flex:1 1 auto}.axp-dynamic-form-stepper axp-layout-section{margin-bottom:.75rem}.axp-dynamic-form-stepper axp-layout-section axp-layout-header{margin-bottom:.5rem;gap:0px;padding:.5rem;padding:0}.axp-dynamic-form-stepper axp-layout-section axp-layout-header axp-layout-title{padding-bottom:1rem;font-size:1.25rem;line-height:1.75rem;font-weight:700}.axp-dynamic-form-stepper axp-layout-section axp-layout-header axp-layout-description{margin-top:.25rem;font-size:.75rem;line-height:1rem;opacity:.75}.axp-dynamic-form-stepper axp-layout-section axp-layout-section axp-layout-content{padding:0}.axp-dynamic-form-stepper axp-layout-section axp-layout-section axp-layout-content .__field-container{padding:0!important}.axp-dynamic-form-stepper ax-step-wizard{margin-bottom:2rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXStepWizardModule }, { kind: "component", type: i1$3.AXStepWizardComponent, selector: "ax-step-wizard", inputs: ["connector", "size", "look", "changeStep", "orientation", "content"], outputs: ["stepChanged"] }, { kind: "component", type: i1$3.AXStepWizardItemComponent, selector: "ax-step-wizard-item", inputs: ["disabled", "color", "step", "label", "description", "customTemplate", "active", "passed", "look", "state", "id"], outputs: ["activeChange", "passedChange", "lookChange", "stateChange"] }, { kind: "directive", type: i1$3.AXStepWizardContentDirective, selector: "[axStepWizardContent]", inputs: ["axStepWizardContent"], exportAs: ["axStepWizardContent"] }, { kind: "component", type: AXPDynamicFormComponent, selector: "axp-dynamic-form", inputs: ["formDefinition", "context", "layoutLook", "layoutDirection", "mode", "layoutConfig"], outputs: ["contextChange", "contextInitiated", "validityChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i2$1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "directive", type: AXPStickyDirective, selector: "[axpSticky]", inputs: ["axpSticky", "stickyOffset", "stickyParent", "stickyTarget"], outputs: ["isStickyChange"], exportAs: ["axpSticky"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
2374
+ }
2375
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPDynamicFormStepperComponent, decorators: [{
2376
+ type: Component,
2377
+ args: [{ standalone: true, selector: 'axp-dynamic-form-stepper', imports: [
2378
+ CommonModule,
2379
+ AXStepWizardModule,
2380
+ AXPDynamicFormComponent,
2381
+ AXDecoratorModule,
2382
+ AXTranslationModule,
2383
+ AXPStickyDirective,
2384
+ ], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
2385
+ class: 'axp-dynamic-form-stepper',
2386
+ '[class.--vertical]': "stepperDirection() === 'vertical'",
2387
+ }, template: "<ax-step-wizard\n class=\"ax-sticky ax-top-0 ax-z-10 ax-transition-all\"\n #sticky=\"axpSticky\"\n [axpSticky]=\"'ax-bg-lightest ax-shadow-md ax-pt-4'\"\n [stickyParent]=\"'.ax-popup-body-container'\"\n #wizard\n [content]=\"wizardContent\"\n [stickyOffset]=\"100\"\n [look]=\"'text-line'\"\n [orientation]=\"stepperDirection()\"\n>\n @for (step of steps(); track step.id) {\n <ax-step-wizard-item [label]=\"(step.title || '' | translate | async)!\" [id]=\"step.id\">\n @if (step.icon) {\n <ax-icon [class]=\"step.icon\"></ax-icon>\n }\n <ax-content>\n <axp-dynamic-form\n [formDefinition]=\"{ groups: step.groups }\"\n [context]=\"readStepSlice(step.dataPath).slice\"\n [layoutLook]=\"layoutLook()\"\n [layoutDirection]=\"step.formDirection || 'vertical'\"\n [layoutConfig]=\"effectiveLayoutConfig()\"\n (contextChange)=\"onStepContextChange(step.id, $event)\"\n ></axp-dynamic-form>\n </ax-content>\n </ax-step-wizard-item>\n }\n</ax-step-wizard>\n\n<ng-template [axStepWizardContent] #wizardContent=\"axStepWizardContent\"></ng-template>\n", styles: [".axp-dynamic-form-stepper.--vertical{display:flex;gap:1rem}.axp-dynamic-form-stepper.--vertical ax-step-wizard{width:unset}.axp-dynamic-form-stepper.--vertical ax-content{flex:1 1 auto}.axp-dynamic-form-stepper axp-layout-section{margin-bottom:.75rem}.axp-dynamic-form-stepper axp-layout-section axp-layout-header{margin-bottom:.5rem;gap:0px;padding:.5rem;padding:0}.axp-dynamic-form-stepper axp-layout-section axp-layout-header axp-layout-title{padding-bottom:1rem;font-size:1.25rem;line-height:1.75rem;font-weight:700}.axp-dynamic-form-stepper axp-layout-section axp-layout-header axp-layout-description{margin-top:.25rem;font-size:.75rem;line-height:1rem;opacity:.75}.axp-dynamic-form-stepper axp-layout-section axp-layout-section axp-layout-content{padding:0}.axp-dynamic-form-stepper axp-layout-section axp-layout-section axp-layout-content .__field-container{padding:0!important}.axp-dynamic-form-stepper ax-step-wizard{margin-bottom:2rem}\n"] }]
2388
+ }] });
2389
+
2390
+ class AXPDynamicDialogComponent extends AXBasePageComponent {
2391
+ constructor() {
2392
+ super(...arguments);
2393
+ this.dynamicForm = viewChild(AXPDynamicFormComponent, ...(ngDevMode ? [{ debugName: "dynamicForm" }] : []));
2394
+ this.stepper = viewChild(AXPDynamicFormStepperComponent, ...(ngDevMode ? [{ debugName: "stepper" }] : []));
2395
+ this.isSubmitting = signal(false, ...(ngDevMode ? [{ debugName: "isSubmitting" }] : []));
2396
+ this.previousContext = signal({}, ...(ngDevMode ? [{ debugName: "previousContext" }] : []));
2397
+ this.formData = signal({}, ...(ngDevMode ? [{ debugName: "formData" }] : []));
2398
+ // This will be set by the popup service automatically
2399
+ this.dialogResult = null;
2400
+ this.isSubmittingFromDialog = false;
2401
+ this.callBack = () => { };
2402
+ //#region ---- Computed Properties ----
2403
+ /**
2404
+ * Form context for widget container
2405
+ */
2406
+ this.formContext = computed(() => this.formData(), ...(ngDevMode ? [{ debugName: "formContext" }] : []));
2407
+ /**
2408
+ * Combined loading state from both signal and dialog
2409
+ */
2410
+ this.isFormLoading = computed(() => this.isSubmitting() || this.isSubmittingFromDialog, ...(ngDevMode ? [{ debugName: "isFormLoading" }] : []));
2411
+ this.defaultLayout = () => ({
2412
+ positions: {
2413
+ default: { colSpan: 12 },
2414
+ md: { colSpan: 8 },
2415
+ lg: { colSpan: 6 },
2416
+ xl: { colSpan: 5 },
2417
+ xxl: { colSpan: 4 },
2418
+ },
2419
+ });
2420
+ /**
2421
+ * Determine rendering mode and effective definitions
2422
+ */
2423
+ this.hasLegacyForm = computed(() => !!this.config.formDefinition, ...(ngDevMode ? [{ debugName: "hasLegacyForm" }] : []));
2424
+ this.providedDefinition = computed(() => this.config.definition, ...(ngDevMode ? [{ debugName: "providedDefinition" }] : []));
2425
+ this.providedMode = computed(() => this.config.mode || 'edit', ...(ngDevMode ? [{ debugName: "providedMode" }] : []));
2426
+ this.isStepperDefinition = computed(() => {
2427
+ const def = this.providedDefinition();
2428
+ return !!def && Array.isArray(def?.steps) && def.steps.length > 1;
2429
+ }, ...(ngDevMode ? [{ debugName: "isStepperDefinition" }] : []));
2430
+ this.shouldRenderForm = computed(() => {
2431
+ if (this.hasLegacyForm())
2432
+ return true;
2433
+ const def = this.providedDefinition();
2434
+ // Render form when definition is form-like or single/no step
2435
+ if (!def)
2436
+ return false;
2437
+ if (Array.isArray(def?.steps)) {
2438
+ return def.steps.length <= 1;
2439
+ }
2440
+ // No steps property -> treat as AXPDynamicFormDefinition
2441
+ return true;
2442
+ }, ...(ngDevMode ? [{ debugName: "shouldRenderForm" }] : []));
2443
+ this.effectiveFormDefinition = computed(() => {
2444
+ if (this.config.formDefinition)
2445
+ return this.config.formDefinition;
2446
+ const def = this.providedDefinition();
2447
+ if (!def)
2448
+ return undefined;
2449
+ if (Array.isArray(def?.steps)) {
2450
+ // Single-step stepper -> convert to form def
2451
+ const step = def.steps[0];
2452
+ return step ? { groups: step.groups } : undefined;
2453
+ }
2454
+ return def;
2455
+ }, ...(ngDevMode ? [{ debugName: "effectiveFormDefinition" }] : []));
2456
+ this.resolvedFormDefinition = computed(() => {
2457
+ return (this.effectiveFormDefinition() ?? { groups: [] });
2458
+ }, ...(ngDevMode ? [{ debugName: "resolvedFormDefinition" }] : []));
2459
+ this.effectiveLayoutLook = computed(() => this.config.layoutLook ?? 'borderless', ...(ngDevMode ? [{ debugName: "effectiveLayoutLook" }] : []));
2460
+ this.effectiveLayoutConfig = computed(() => this.config.layoutConfig ?? this.defaultLayout(), ...(ngDevMode ? [{ debugName: "effectiveLayoutConfig" }] : []));
2461
+ // Stepper-only
2462
+ this.stepperGuardNext = computed(() => this.config.stepper?.guardNext, ...(ngDevMode ? [{ debugName: "stepperGuardNext" }] : []));
2463
+ this.stepperDirection = computed(() => this.config.stepper?.stepperDirection ?? 'horizontal', ...(ngDevMode ? [{ debugName: "stepperDirection" }] : []));
2464
+ this.stepperDefinition = computed(() => {
2465
+ const def = this.providedDefinition();
2466
+ return (def ?? { steps: [] });
2467
+ }, ...(ngDevMode ? [{ debugName: "stepperDefinition" }] : []));
2468
+ this.stepperIsFirst = computed(() => this.stepper()?.isFirst() ?? true, ...(ngDevMode ? [{ debugName: "stepperIsFirst" }] : []));
2469
+ this.stepperIsLast = computed(() => this.stepper()?.isLast() ?? false, ...(ngDevMode ? [{ debugName: "stepperIsLast" }] : []));
2470
+ /**
2471
+ * Effective form direction when rendering dynamic-form (single-step or legacy form).
2472
+ * If a single-step definition is provided and that step specifies formDirection, use it.
2473
+ */
2474
+ this.effectiveFormDirection = computed(() => {
2475
+ if (this.hasLegacyForm()) {
2476
+ return 'vertical';
2477
+ }
2478
+ const def = this.providedDefinition();
2479
+ if (def && Array.isArray(def?.steps) && def.steps.length === 1) {
2480
+ return def.steps[0]?.formDirection ?? 'vertical';
2481
+ }
2482
+ return 'vertical';
2483
+ }, ...(ngDevMode ? [{ debugName: "effectiveFormDirection" }] : []));
2484
+ /**
2485
+ * Footer actions for dynamic button system
2486
+ */
2487
+ this.footerPrefixActions = computed(() => this.config.actions?.footer?.prefix || [], ...(ngDevMode ? [{ debugName: "footerPrefixActions" }] : []));
2488
+ this.footerSuffixActions = computed(() => this.config.actions?.footer?.suffix || [], ...(ngDevMode ? [{ debugName: "footerSuffixActions" }] : []));
2489
+ this.visibleFooterPrefixActions = computed(() => {
2490
+ const prefixFooterActions = this.footerPrefixActions();
2491
+ return prefixFooterActions.filter((action) => action.visible != false);
2492
+ }, ...(ngDevMode ? [{ debugName: "visibleFooterPrefixActions" }] : []));
2493
+ this.visibleFooterSuffixActions = computed(() => {
2494
+ const suffixFooterActions = this.footerSuffixActions();
2495
+ return suffixFooterActions.filter((action) => action.visible != false);
2496
+ }, ...(ngDevMode ? [{ debugName: "visibleFooterSuffixActions" }] : []));
2497
+ this.hasFooterActions = computed(() => {
2498
+ const prefixActions = this.visibleFooterPrefixActions();
2499
+ const suffixActions = this.visibleFooterSuffixActions();
2500
+ return prefixActions.length > 0 || suffixActions.length > 0;
2501
+ }, ...(ngDevMode ? [{ debugName: "hasFooterActions" }] : []));
2502
+ /** Stepper footer: choose a single confirm action from provided suffix actions (first visible). */
2503
+ this.confirmAction = computed(() => {
2504
+ const items = this.footerSuffixActions();
2505
+ return items.find((a) => a.visible !== false);
2506
+ }, ...(ngDevMode ? [{ debugName: "confirmAction" }] : []));
2507
+ this.confirmActionTitle = computed(() => this.confirmAction()?.title ?? 'Confirm', ...(ngDevMode ? [{ debugName: "confirmActionTitle" }] : []));
2508
+ }
2509
+ //#endregion
2510
+ //#region ---- Lifecycle Methods ----
2511
+ ngOnInit() {
2512
+ this.formData.set(this.config.context ?? {});
2513
+ }
2514
+ //#endregion
2515
+ //#region ---- Event Handlers ----
2516
+ handleContextInitiated(context) {
2517
+ this.previousContext.set(context);
2518
+ }
2519
+ handleContextChanged(context) {
2520
+ this.formData.set(context);
2521
+ }
2522
+ //#endregion
2523
+ //#region ---- Action Execution ----
2524
+ /**
2525
+ * Execute a dynamic action
2526
+ */
2527
+ async executeAction(action) {
2528
+ if (action.command) {
2529
+ // Execute the command if provided
2530
+ await this.executeCommand(action.command);
2531
+ }
2532
+ else {
2533
+ // Handle custom action logic here
2534
+ const result = {
2535
+ context: this.formData(),
2536
+ action: action.name || action.title,
2537
+ };
2538
+ this.close(result);
2539
+ }
2540
+ }
2541
+ /**
2542
+ * Execute a command
2543
+ */
2544
+ async executeCommand(command) {
2545
+ // Handle command execution logic here
2546
+ if (command.options?.['validate'] == true) {
2547
+ if (!(await this.isFormValid())) {
2548
+ return;
2549
+ }
2550
+ }
2551
+ //
2552
+ if (command.name == 'cancel') {
2553
+ this.close();
2554
+ }
2555
+ const result = {
2556
+ context: this.formData(),
2557
+ action: command.name,
2558
+ };
2559
+ // Store result in component property and popup data
2560
+ this.dialogResult = result;
2561
+ // Store in popup data for DialogRef access
2562
+ if (this.data) {
2563
+ this.data.context = result.context;
2564
+ this.data.action = result.action;
2565
+ }
2566
+ // Call the callback with DialogRef
2567
+ this.callBack({
2568
+ close: (result) => {
2569
+ this.close(result);
2570
+ },
2571
+ context: () => {
2572
+ return this.formData();
2573
+ },
2574
+ action: () => {
2575
+ return result.action;
2576
+ },
2577
+ setLoading: (loading) => {
2578
+ this.isSubmitting.set(loading);
2579
+ },
2580
+ });
2581
+ }
2582
+ //#endregion
2583
+ //#region ---- Public Methods ----
2584
+ /**
2585
+ * Check if form is valid
2586
+ */
2587
+ async isFormValid() {
2588
+ if (this.isStepperDefinition()) {
2589
+ return (await this.stepper()?.validateCurrentStep()) ?? false;
2590
+ }
2591
+ return (await this.dynamicForm()?.validate()) ?? false;
2592
+ }
2593
+ /** Stepper navigation handlers */
2594
+ goPrev() {
2595
+ this.stepper()?.previous();
2596
+ }
2597
+ goNext() {
2598
+ this.stepper()?.next();
2599
+ }
2600
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPDynamicDialogComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
2601
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.8", type: AXPDynamicDialogComponent, isStandalone: true, selector: "axp-dynamic-dialog", inputs: { config: "config" }, viewQueries: [{ propertyName: "dynamicForm", first: true, predicate: AXPDynamicFormComponent, descendants: true, isSignal: true }, { propertyName: "stepper", first: true, predicate: AXPDynamicFormStepperComponent, descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "@if (shouldRenderForm()) {\n <div class=\"ax-p-4\">\n <axp-dynamic-form\n [formDefinition]=\"resolvedFormDefinition()\"\n [context]=\"formContext()\"\n [mode]=\"providedMode()\"\n [layoutConfig]=\"effectiveLayoutConfig()\"\n [layoutLook]=\"effectiveLayoutLook()\"\n [layoutDirection]=\"effectiveFormDirection()\"\n (contextChange)=\"handleContextChanged($event)\"\n (contextInitiated)=\"handleContextInitiated($event)\"\n >\n </axp-dynamic-form>\n </div>\n\n <ax-footer>\n <ax-prefix>\n <ng-container *ngTemplateOutlet=\"footerPrefixActions\"></ng-container>\n </ax-prefix>\n <ax-suffix>\n <ng-container *ngTemplateOutlet=\"footerSuffixActions\"></ng-container>\n </ax-suffix>\n </ax-footer>\n} @else {\n <div class=\"ax-p-4\">\n <axp-dynamic-form-stepper\n #stepperRef\n [definition]=\"stepperDefinition()\"\n [context]=\"formContext()\"\n [layoutLook]=\"effectiveLayoutLook()\"\n [layoutConfig]=\"effectiveLayoutConfig()\"\n [stepperDirection]=\"stepperDirection()\"\n [guardNext]=\"stepperGuardNext()\"\n (contextChange)=\"handleContextChanged($event)\"\n >\n </axp-dynamic-form-stepper>\n </div>\n\n <ax-footer>\n <ax-prefix>\n <ax-button\n [disabled]=\"stepperIsFirst()\"\n [text]=\"'@general:actions.previous.title' | translate | async\"\n [look]=\"'outline'\"\n (onClick)=\"goPrev()\"\n ></ax-button>\n </ax-prefix>\n <ax-suffix>\n @if (!stepperIsLast()) {\n <ax-button\n [text]=\"'@general:actions.next.title' | translate | async\"\n [color]=\"'primary'\"\n (onClick)=\"goNext()\"\n ></ax-button>\n } @else {\n <ax-suffix>\n <ng-container *ngTemplateOutlet=\"footerSuffixActions\"></ng-container>\n </ax-suffix>\n }\n </ax-suffix>\n </ax-footer>\n}\n<!-- Footer Prefix Actions -->\n<ng-template #footerPrefixActions>\n @for (action of visibleFooterPrefixActions(); track $index) {\n <ax-button\n [disabled]=\"action.disabled || isFormLoading()\"\n [text]=\"(action.title | translate | async)!\"\n [look]=\"'outline'\"\n [color]=\"action.color\"\n (onClick)=\"executeAction(action)\"\n >\n @if (isFormLoading() && action.command?.name != 'cancel') {\n <ax-loading></ax-loading>\n }\n <ax-prefix>\n <i class=\"{{ action.icon }}\"></i>\n </ax-prefix>\n </ax-button>\n }\n</ng-template>\n\n<!-- Footer Suffix Actions -->\n<ng-template #footerSuffixActions>\n @for (action of visibleFooterSuffixActions(); track $index) {\n @if (action?.items && (action?.items?.length ?? 0) > 0) {\n <ax-dropdown-button\n [disabled]=\"action.disabled || isSubmitting()\"\n [text]=\"(action.title | translate | async)!\"\n [look]=\"'solid'\"\n [color]=\"action.color\"\n (onClick)=\"executeAction(action)\"\n >\n @if (action.icon) {\n <ax-prefix>\n <ax-icon icon=\"{{ action.icon }}\"></ax-icon>\n </ax-prefix>\n }\n <ax-button-item-list>\n @for (sub of action?.items; track $index) {\n <ax-button-item\n [text]=\"(sub.title | translate | async)!\"\n [color]=\"sub.color\"\n [disabled]=\"sub.disabled\"\n (onClick)=\"executeAction(sub)\"\n >\n @if (sub.icon) {\n <ax-prefix>\n <ax-icon icon=\"{{ sub.icon }}\"></ax-icon>\n </ax-prefix>\n }\n </ax-button-item>\n @if (sub.break) {\n <ax-divider></ax-divider>\n }\n }\n </ax-button-item-list>\n </ax-dropdown-button>\n } @else {\n <ax-button\n [disabled]=\"action.disabled || isSubmitting()\"\n [text]=\"(action.title | translate | async)!\"\n [look]=\"'solid'\"\n [color]=\"action.color\"\n (onClick)=\"executeAction(action)\"\n >\n @if (action.icon) {\n <ax-prefix>\n <ax-icon icon=\"{{ action.icon }}\"></ax-icon>\n </ax-prefix>\n }\n </ax-button>\n }\n }\n</ng-template>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type:
2602
+ //
2603
+ AXFormModule }, { kind: "ngmodule", type: AXValidationModule }, { kind: "component", type: AXPDynamicFormComponent, selector: "axp-dynamic-form", inputs: ["formDefinition", "context", "layoutLook", "layoutDirection", "mode", "layoutConfig"], outputs: ["contextChange", "contextInitiated", "validityChange"] }, { kind: "component", type: AXPDynamicFormStepperComponent, selector: "axp-dynamic-form-stepper", inputs: ["definition", "context", "layoutLook", "stepperDirection", "layoutConfig", "guardNext"], outputs: ["contextChange", "stepChange", "finished", "cancel", "navigationBlocked"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i2$1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i3.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "component", type: i3.AXButtonItemComponent, selector: "ax-button-item", inputs: ["color", "disabled", "text", "selected", "divided", "data", "name"], outputs: ["onClick", "onFocus", "onBlur", "disabledChange"] }, { kind: "component", type: i3.AXButtonItemListComponent, selector: "ax-button-item-list", inputs: ["items"], outputs: ["onItemClick"] }, { kind: "ngmodule", type: AXDropdownButtonModule }, { kind: "component", type: i4$3.AXDropdownButtonComponent, selector: "ax-dropdown-button", inputs: ["disabled", "size", "color", "look", "text", "type", "mode"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "lookChange", "colorChange", "disabledChange"] }, { kind: "ngmodule", type: AXDropdownModule }, { kind: "ngmodule", type: AXLoadingModule }, { kind: "component", type: i5$1.AXLoadingComponent, selector: "ax-loading", inputs: ["visible", "type", "context"], outputs: ["visibleChange"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2604
+ }
2605
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPDynamicDialogComponent, decorators: [{
2606
+ type: Component,
2607
+ args: [{ selector: 'axp-dynamic-dialog', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
2608
+ CommonModule,
2609
+ //
2610
+ AXFormModule,
2611
+ AXValidationModule,
2612
+ AXPDynamicFormComponent,
2613
+ AXPDynamicFormStepperComponent,
2614
+ AXDecoratorModule,
2615
+ AXButtonModule,
2616
+ AXDropdownButtonModule,
2617
+ AXDropdownModule,
2618
+ AXLoadingModule,
2619
+ AXTranslationModule,
2620
+ ], template: "@if (shouldRenderForm()) {\n <div class=\"ax-p-4\">\n <axp-dynamic-form\n [formDefinition]=\"resolvedFormDefinition()\"\n [context]=\"formContext()\"\n [mode]=\"providedMode()\"\n [layoutConfig]=\"effectiveLayoutConfig()\"\n [layoutLook]=\"effectiveLayoutLook()\"\n [layoutDirection]=\"effectiveFormDirection()\"\n (contextChange)=\"handleContextChanged($event)\"\n (contextInitiated)=\"handleContextInitiated($event)\"\n >\n </axp-dynamic-form>\n </div>\n\n <ax-footer>\n <ax-prefix>\n <ng-container *ngTemplateOutlet=\"footerPrefixActions\"></ng-container>\n </ax-prefix>\n <ax-suffix>\n <ng-container *ngTemplateOutlet=\"footerSuffixActions\"></ng-container>\n </ax-suffix>\n </ax-footer>\n} @else {\n <div class=\"ax-p-4\">\n <axp-dynamic-form-stepper\n #stepperRef\n [definition]=\"stepperDefinition()\"\n [context]=\"formContext()\"\n [layoutLook]=\"effectiveLayoutLook()\"\n [layoutConfig]=\"effectiveLayoutConfig()\"\n [stepperDirection]=\"stepperDirection()\"\n [guardNext]=\"stepperGuardNext()\"\n (contextChange)=\"handleContextChanged($event)\"\n >\n </axp-dynamic-form-stepper>\n </div>\n\n <ax-footer>\n <ax-prefix>\n <ax-button\n [disabled]=\"stepperIsFirst()\"\n [text]=\"'@general:actions.previous.title' | translate | async\"\n [look]=\"'outline'\"\n (onClick)=\"goPrev()\"\n ></ax-button>\n </ax-prefix>\n <ax-suffix>\n @if (!stepperIsLast()) {\n <ax-button\n [text]=\"'@general:actions.next.title' | translate | async\"\n [color]=\"'primary'\"\n (onClick)=\"goNext()\"\n ></ax-button>\n } @else {\n <ax-suffix>\n <ng-container *ngTemplateOutlet=\"footerSuffixActions\"></ng-container>\n </ax-suffix>\n }\n </ax-suffix>\n </ax-footer>\n}\n<!-- Footer Prefix Actions -->\n<ng-template #footerPrefixActions>\n @for (action of visibleFooterPrefixActions(); track $index) {\n <ax-button\n [disabled]=\"action.disabled || isFormLoading()\"\n [text]=\"(action.title | translate | async)!\"\n [look]=\"'outline'\"\n [color]=\"action.color\"\n (onClick)=\"executeAction(action)\"\n >\n @if (isFormLoading() && action.command?.name != 'cancel') {\n <ax-loading></ax-loading>\n }\n <ax-prefix>\n <i class=\"{{ action.icon }}\"></i>\n </ax-prefix>\n </ax-button>\n }\n</ng-template>\n\n<!-- Footer Suffix Actions -->\n<ng-template #footerSuffixActions>\n @for (action of visibleFooterSuffixActions(); track $index) {\n @if (action?.items && (action?.items?.length ?? 0) > 0) {\n <ax-dropdown-button\n [disabled]=\"action.disabled || isSubmitting()\"\n [text]=\"(action.title | translate | async)!\"\n [look]=\"'solid'\"\n [color]=\"action.color\"\n (onClick)=\"executeAction(action)\"\n >\n @if (action.icon) {\n <ax-prefix>\n <ax-icon icon=\"{{ action.icon }}\"></ax-icon>\n </ax-prefix>\n }\n <ax-button-item-list>\n @for (sub of action?.items; track $index) {\n <ax-button-item\n [text]=\"(sub.title | translate | async)!\"\n [color]=\"sub.color\"\n [disabled]=\"sub.disabled\"\n (onClick)=\"executeAction(sub)\"\n >\n @if (sub.icon) {\n <ax-prefix>\n <ax-icon icon=\"{{ sub.icon }}\"></ax-icon>\n </ax-prefix>\n }\n </ax-button-item>\n @if (sub.break) {\n <ax-divider></ax-divider>\n }\n }\n </ax-button-item-list>\n </ax-dropdown-button>\n } @else {\n <ax-button\n [disabled]=\"action.disabled || isSubmitting()\"\n [text]=\"(action.title | translate | async)!\"\n [look]=\"'solid'\"\n [color]=\"action.color\"\n (onClick)=\"executeAction(action)\"\n >\n @if (action.icon) {\n <ax-prefix>\n <ax-icon icon=\"{{ action.icon }}\"></ax-icon>\n </ax-prefix>\n }\n </ax-button>\n }\n }\n</ng-template>\n" }]
2621
+ }], propDecorators: { config: [{
2622
+ type: Input,
2623
+ args: [{ required: true }]
2624
+ }] } });
2625
+
2626
+ var dynamicDialog_component = /*#__PURE__*/Object.freeze({
2627
+ __proto__: null,
2628
+ AXPDynamicDialogComponent: AXPDynamicDialogComponent
2629
+ });
2630
+
2631
+ class AXPDynamicDialogService {
2632
+ constructor() {
2633
+ this.popupService = inject(AXPopupService);
2634
+ }
2635
+ /**
2636
+ * Show a dynamic dialog with the given configuration
2637
+ * @param config Dialog configuration including fields, validation, and UI options
2638
+ * @returns Promise resolving to dialog reference for controlling the dialog
2639
+ */
2640
+ async showDialog(config) {
2641
+ const component = await Promise.resolve().then(function () { return dynamicDialog_component; }).then(c => c.AXPDynamicDialogComponent);
2642
+ return new Promise(async (resolve) => {
2643
+ // Open popup and wait for it to close
2644
+ await this.popupService.open(component, {
2645
+ title: config.title,
2646
+ size: config.size || 'md',
2647
+ closeButton: config.closeButton,
2648
+ closeOnBackdropClick: false,
2649
+ draggable: false,
2650
+ data: {
2651
+ config,
2652
+ dialogResult: null,
2653
+ isSubmittingFromDialog: false,
2654
+ callBack: (result) => {
2655
+ resolve(result);
2656
+ }
2657
+ }
2658
+ });
2659
+ });
2660
+ }
2661
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPDynamicDialogService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2662
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPDynamicDialogService, providedIn: 'root' }); }
2663
+ }
2664
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPDynamicDialogService, decorators: [{
2665
+ type: Injectable,
2666
+ args: [{
2667
+ providedIn: 'root'
2668
+ }]
2669
+ }] });
2670
+
2671
+ class AXPDynamicFormBuilderService {
2672
+ constructor() {
2673
+ //#region ---- Services & Dependencies ----
2674
+ this.dialogService = inject(AXPDynamicDialogService);
2675
+ }
2676
+ //#endregion
2677
+ //#region ---- Public Methods ----
2678
+ /**
2679
+ * Create a new form builder
2680
+ */
2681
+ form() {
2682
+ return new FormBuilder();
2683
+ }
2684
+ /**
2685
+ * Create a new dialog builder
2686
+ */
2687
+ dialog() {
2688
+ return new DialogBuilder(this.dialogService);
2689
+ }
2690
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPDynamicFormBuilderService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2691
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPDynamicFormBuilderService, providedIn: 'root' }); }
2692
+ }
2693
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPDynamicFormBuilderService, decorators: [{
2694
+ type: Injectable,
2695
+ args: [{
2696
+ providedIn: 'root',
2697
+ }]
2698
+ }] });
2699
+ //#region ---- Form Builder Implementation ----
2700
+ class FormBuilder {
2701
+ constructor() {
2702
+ this.state = {
2703
+ groups: [],
2704
+ layoutConfig: {
2705
+ positions: {
2706
+ default: { colSpan: 12 },
2707
+ md: { colSpan: 8 },
2708
+ lg: { colSpan: 6 },
2709
+ xl: { colSpan: 5 },
2710
+ xxl: { colSpan: 4 },
2711
+ },
2712
+ },
2713
+ look: 'normal',
2714
+ direction: 'vertical',
2715
+ };
2716
+ }
2717
+ group(name, delegate) {
2718
+ const groupBuilder = new GroupBuilder(this, name);
2719
+ if (delegate) {
2720
+ delegate(groupBuilder);
2721
+ }
2722
+ this.addGroup(groupBuilder.build());
2723
+ return this;
2724
+ }
2725
+ layout(config) {
2726
+ this.state.layoutConfig = { ...this.state.layoutConfig, ...config };
2727
+ return this;
2728
+ }
2729
+ look(look) {
2730
+ this.state.look = look;
2731
+ return this;
2732
+ }
2733
+ direction(direction) {
2734
+ this.state.direction = direction;
2735
+ return this;
2736
+ }
2737
+ mode(mode) {
2738
+ this.state.mode = mode;
2739
+ return this;
2740
+ }
2741
+ build() {
2742
+ return {
2743
+ groups: this.state.groups,
2744
+ mode: this.state.mode,
2745
+ };
2746
+ }
2747
+ addGroup(group) {
2748
+ this.state.groups.push(group);
2749
+ }
2750
+ }
2751
+ //#endregion
2752
+ //#region ---- Group Builder Implementation ----
2753
+ class GroupBuilder {
2754
+ constructor(formBuilder, name) {
2755
+ this.formBuilder = formBuilder;
2756
+ this.groupState = {
2757
+ name: '',
2758
+ title: '',
2759
+ description: '',
2760
+ parameters: [],
2761
+ };
2762
+ this.groupState.name = name;
2763
+ }
2764
+ title(title) {
2765
+ this.groupState.title = title;
2766
+ return this;
2767
+ }
2768
+ description(description) {
2769
+ this.groupState.description = description;
2770
+ return this;
2771
+ }
2772
+ mode(mode) {
2773
+ this.groupState.mode = mode;
2774
+ return this;
2775
+ }
2776
+ field(path, delegate) {
2777
+ const fieldBuilder = new FieldBuilder(this, path);
2778
+ if (delegate) {
2779
+ delegate(fieldBuilder);
2780
+ }
2781
+ this.addField(fieldBuilder.build());
2782
+ return this;
2783
+ }
2784
+ group(name, delegate) {
2785
+ const nestedGroupBuilder = new GroupBuilder(this.formBuilder, name);
2786
+ if (delegate) {
2787
+ delegate(nestedGroupBuilder);
2788
+ }
2789
+ this.addGroup(nestedGroupBuilder.build());
2790
+ return this;
2791
+ }
2792
+ build() {
2793
+ return {
2794
+ name: this.groupState.name,
2795
+ title: this.groupState.title,
2796
+ description: this.groupState.description,
2797
+ parameters: this.groupState.parameters,
2798
+ mode: this.groupState.mode,
2799
+ };
2800
+ }
2801
+ addField(field) {
2802
+ this.groupState.parameters.push(field);
2803
+ }
2804
+ addGroup(group) {
2805
+ // For nested groups, we add them to the parent form builder
2806
+ this.formBuilder['addGroup'](group);
2807
+ }
2808
+ }
2809
+ //#endregion
2810
+ //#region ---- Field Builder Implementation ----
2811
+ class FieldBuilder {
2812
+ constructor(groupBuilder, path) {
2813
+ this.groupBuilder = groupBuilder;
2814
+ this.fieldState = {
2815
+ path: '',
2816
+ title: '',
2817
+ description: '',
2818
+ defaultValue: undefined,
2819
+ hidden: undefined,
2820
+ readonly: undefined,
2821
+ disabled: undefined,
2822
+ widget: undefined,
2823
+ };
2824
+ this.fieldState.path = path;
2825
+ this.fieldState.title = path;
2826
+ }
2827
+ //#region ---- Utility Methods ----
2828
+ /**
2829
+ * Merge provided widget options with field-level options
2830
+ */
2831
+ mergeWithFieldOptions(options) {
2832
+ return {
2833
+ hidden: this.fieldState.hidden,
2834
+ readonly: this.fieldState.readonly,
2835
+ disabled: this.fieldState.disabled,
2836
+ ...options,
2837
+ };
2838
+ }
2839
+ //#endregion
2840
+ title(title) {
2841
+ this.fieldState.title = title;
2842
+ return this;
2843
+ }
2844
+ description(description) {
2845
+ this.fieldState.description = description;
2846
+ return this;
2847
+ }
2848
+ mode(mode) {
2849
+ this.fieldState.mode = mode;
2850
+ return this;
2851
+ }
2852
+ options(options) {
2853
+ this.fieldState.defaultValue = options['defaultValue'];
2854
+ this.fieldState.hidden = options['hidden'];
2855
+ this.fieldState.readonly = options['readonly'];
2856
+ this.fieldState.disabled = options['disabled'];
2857
+ return this;
2858
+ }
2859
+ layout(layout) {
2860
+ this.fieldState.layout = layout;
2861
+ return this;
2862
+ }
2863
+ textBox(options) {
2864
+ this.fieldState.widget = {
2865
+ type: 'text-editor',
2866
+ path: this.fieldState.path,
2867
+ defaultValue: this.fieldState.defaultValue,
2868
+ options: this.mergeWithFieldOptions(options),
2869
+ };
2870
+ return this;
2871
+ }
2872
+ largeTextBox(options) {
2873
+ this.fieldState.widget = {
2874
+ type: 'large-text-editor',
2875
+ path: this.fieldState.path,
2876
+ defaultValue: this.fieldState.defaultValue,
2877
+ options: this.mergeWithFieldOptions(options),
2878
+ };
2879
+ return this;
2880
+ }
2881
+ richText(options) {
2882
+ this.fieldState.widget = {
2883
+ type: 'rich-text-editor',
2884
+ path: this.fieldState.path,
2885
+ defaultValue: this.fieldState.defaultValue,
2886
+ options: this.mergeWithFieldOptions(options),
2887
+ };
2888
+ return this;
2889
+ }
2890
+ passwordBox(options) {
2891
+ this.fieldState.widget = {
2892
+ type: 'password-editor',
2893
+ path: this.fieldState.path,
2894
+ defaultValue: this.fieldState.defaultValue,
2895
+ options: this.mergeWithFieldOptions(options),
2896
+ };
2897
+ return this;
2898
+ }
2899
+ selectBox(options) {
2900
+ this.fieldState.widget = {
2901
+ type: 'select-editor',
2902
+ path: this.fieldState.path,
2903
+ defaultValue: this.fieldState.defaultValue,
2904
+ options: this.mergeWithFieldOptions(options),
2905
+ };
2906
+ return this;
2907
+ }
2908
+ selectionList(options) {
2909
+ this.fieldState.widget = {
2910
+ type: 'selection-list-editor',
2911
+ path: this.fieldState.path,
2912
+ defaultValue: this.fieldState.defaultValue,
2913
+ options: this.mergeWithFieldOptions(options),
2914
+ };
2915
+ return this;
2916
+ }
2917
+ lookupBox(options) {
2918
+ this.fieldState.widget = {
2919
+ type: 'lookup-editor',
2920
+ path: this.fieldState.path,
2921
+ defaultValue: this.fieldState.defaultValue,
2922
+ options: this.mergeWithFieldOptions(options),
2923
+ };
2924
+ return this;
2925
+ }
2926
+ numberBox(options) {
2927
+ this.fieldState.widget = {
2928
+ type: 'number-editor',
2929
+ path: this.fieldState.path,
2930
+ defaultValue: this.fieldState.defaultValue,
2931
+ options: this.mergeWithFieldOptions(options),
2932
+ };
2933
+ return this;
2934
+ }
2935
+ dateTimeBox(options) {
2936
+ this.fieldState.widget = {
2937
+ type: 'date-time-editor',
2938
+ path: this.fieldState.path,
2939
+ defaultValue: this.fieldState.defaultValue,
2940
+ options: this.mergeWithFieldOptions(options),
2941
+ };
2942
+ return this;
2943
+ }
2944
+ toggleSwitch(options) {
2945
+ this.fieldState.widget = {
2946
+ type: 'toggle-editor',
2947
+ path: this.fieldState.path,
2948
+ defaultValue: this.fieldState.defaultValue,
2949
+ options: this.mergeWithFieldOptions(options),
2950
+ };
2951
+ return this;
2952
+ }
2953
+ colorBox(options) {
2954
+ this.fieldState.widget = {
2955
+ type: 'color-editor',
2956
+ path: this.fieldState.path,
2957
+ defaultValue: this.fieldState.defaultValue,
2958
+ options: this.mergeWithFieldOptions(options),
2959
+ };
2960
+ return this;
2961
+ }
2962
+ widget(type, options) {
2963
+ this.fieldState.widget = {
2964
+ type,
2965
+ path: this.fieldState.path,
2966
+ defaultValue: this.fieldState.defaultValue,
2967
+ options: this.mergeWithFieldOptions(options),
2968
+ };
2969
+ return this;
2970
+ }
2971
+ build() {
2972
+ return {
2973
+ path: this.fieldState.path,
2974
+ title: this.fieldState.title,
2975
+ description: this.fieldState.description,
2976
+ widget: this.fieldState.widget,
2977
+ layout: this.fieldState.layout,
2978
+ mode: this.fieldState.mode,
2979
+ };
2980
+ }
2981
+ }
2982
+ //#endregion
2983
+ //#region ---- Dialog Builder Implementation ----
2984
+ class DialogBuilder extends FormBuilder {
2985
+ constructor(dialogService) {
2986
+ super();
2987
+ this.dialogService = dialogService;
2988
+ this.dialogState = {
2989
+ groups: [],
2990
+ steps: [],
2991
+ layoutConfig: {
2992
+ positions: {
2993
+ default: { colSpan: 12 },
2994
+ md: { colSpan: 8 },
2995
+ lg: { colSpan: 6 },
2996
+ xl: { colSpan: 5 },
2997
+ xxl: { colSpan: 4 },
2998
+ },
2999
+ },
3000
+ look: 'borderless',
3001
+ direction: 'vertical',
3002
+ mode: 'edit',
3003
+ closeButton: false,
3004
+ title: '',
3005
+ message: '',
3006
+ size: 'md',
3007
+ context: {},
3008
+ actions: {
3009
+ footer: {
3010
+ prefix: [],
3011
+ suffix: [],
3012
+ },
3013
+ },
3014
+ };
3015
+ }
3016
+ // Override to keep chaining within dialog context
3017
+ group(name, delegate) {
3018
+ super.group(name, delegate);
3019
+ return this;
3020
+ }
3021
+ step(id, delegate) {
3022
+ const builder = new StepBuilder(this, id);
3023
+ if (delegate) {
3024
+ delegate(builder);
3025
+ }
3026
+ this.dialogState.steps.push(builder.build());
3027
+ return this;
3028
+ }
3029
+ stepperDirection(direction) {
3030
+ this.dialogState.stepperDirection = direction;
3031
+ return this;
3032
+ }
3033
+ guardNext(guard) {
3034
+ this.dialogState.guardNext = guard;
3035
+ return this;
3036
+ }
3037
+ // Ensure dialog state mirrors form state and chaining type stays IDialogBuilder
3038
+ layout(config) {
3039
+ super.layout(config);
3040
+ this.dialogState.layoutConfig = { ...this.dialogState.layoutConfig, ...config };
3041
+ return this;
3042
+ }
3043
+ look(look) {
3044
+ super.look(look);
3045
+ this.dialogState.look = look;
3046
+ return this;
3047
+ }
3048
+ direction(direction) {
3049
+ super.direction(direction);
3050
+ this.dialogState.direction = direction;
3051
+ return this;
3052
+ }
3053
+ mode(mode) {
3054
+ console.log(mode);
3055
+ super.mode(mode);
3056
+ this.dialogState.mode = mode;
3057
+ return this;
3058
+ }
3059
+ closeButton(closeButton) {
3060
+ this.dialogState.closeButton = closeButton;
3061
+ return this;
3062
+ }
3063
+ title(title) {
3064
+ this.dialogState.title = title;
3065
+ return this;
3066
+ }
3067
+ message(message) {
3068
+ this.dialogState.message = message;
3069
+ return this;
3070
+ }
3071
+ size(size) {
3072
+ this.dialogState.size = size;
3073
+ return this;
3074
+ }
3075
+ context(context) {
3076
+ this.dialogState.context = context;
3077
+ return this;
3078
+ }
3079
+ actions(delegate) {
3080
+ const actionBuilder = new ActionBuilder(this);
3081
+ if (delegate) {
3082
+ delegate(actionBuilder);
3083
+ }
3084
+ return this;
3085
+ }
3086
+ async show() {
3087
+ const built = this.build();
3088
+ const hasSteps = this.dialogState.steps.length > 0;
3089
+ const config = {
3090
+ title: this.dialogState.title,
3091
+ message: this.dialogState.message,
3092
+ closeButton: this.dialogState.closeButton,
3093
+ definition: hasSteps
3094
+ ? {
3095
+ steps: this.dialogState.steps.map((s) => ({
3096
+ id: s.id,
3097
+ title: s.title,
3098
+ description: s.description,
3099
+ icon: s.icon,
3100
+ groups: s.groups,
3101
+ formDirection: s.formDirection,
3102
+ })),
3103
+ }
3104
+ : {
3105
+ steps: [
3106
+ {
3107
+ id: 'form',
3108
+ groups: built.groups,
3109
+ formDirection: this.dialogState.direction,
3110
+ },
3111
+ ],
3112
+ },
3113
+ context: this.dialogState.context,
3114
+ size: this.dialogState.size,
3115
+ actions: this.dialogState.actions,
3116
+ layoutConfig: this.dialogState.layoutConfig,
3117
+ layoutLook: this.dialogState.look,
3118
+ mode: this.dialogState.mode,
3119
+ stepper: hasSteps
3120
+ ? {
3121
+ guardNext: this.dialogState.guardNext,
3122
+ stepperDirection: this.dialogState.stepperDirection,
3123
+ }
3124
+ : undefined,
3125
+ };
3126
+ return await this.dialogService.showDialog(config);
3127
+ }
3128
+ }
3129
+ //#endregion
3130
+ //#region ---- Action Builder Implementation ----
3131
+ class ActionBuilder {
3132
+ constructor(dialogBuilder) {
3133
+ this.dialogBuilder = dialogBuilder;
3134
+ }
3135
+ cancel(text) {
3136
+ if (!this.dialogBuilder['dialogState'].actions.footer.suffix) {
3137
+ this.dialogBuilder['dialogState'].actions.footer.suffix = [];
3138
+ }
3139
+ this.dialogBuilder['dialogState'].actions.footer.suffix.push({
3140
+ title: text || '@general:actions.cancel.title',
3141
+ icon: 'fa-times',
3142
+ color: 'default',
3143
+ command: { name: 'cancel' },
3144
+ });
3145
+ return this;
3146
+ }
3147
+ submit(text) {
3148
+ if (!this.dialogBuilder['dialogState'].actions.footer.suffix) {
3149
+ this.dialogBuilder['dialogState'].actions.footer.suffix = [];
3150
+ }
3151
+ this.dialogBuilder['dialogState'].actions.footer.suffix.push({
3152
+ title: text || '@general:actions.submit.title',
3153
+ icon: 'fa-check',
3154
+ color: 'primary',
3155
+ command: { name: 'submit', options: { validate: true } },
3156
+ });
3157
+ return this;
3158
+ }
3159
+ custom(action) {
3160
+ if (!this.dialogBuilder['dialogState'].actions.footer.suffix) {
3161
+ this.dialogBuilder['dialogState'].actions.footer.suffix = [];
3162
+ }
3163
+ this.dialogBuilder['dialogState'].actions.footer.suffix.push(action);
3164
+ return this;
3165
+ }
3166
+ }
3167
+ // #region ---- Step Builder Implementation ----
3168
+ class StepBuilder {
3169
+ constructor(dialogBuilder, id) {
3170
+ this.dialogBuilder = dialogBuilder;
3171
+ this.stepState = {
3172
+ id: '',
3173
+ groups: [],
3174
+ };
3175
+ this.stepState.id = id;
3176
+ }
3177
+ title(title) {
3178
+ this.stepState.title = title;
3179
+ return this;
3180
+ }
3181
+ description(description) {
3182
+ this.stepState.description = description;
3183
+ return this;
3184
+ }
3185
+ icon(icon) {
3186
+ this.stepState.icon = icon;
3187
+ return this;
3188
+ }
3189
+ direction(direction) {
3190
+ this.stepState.formDirection = direction;
3191
+ return this;
3192
+ }
3193
+ group(name, delegate) {
3194
+ const groupBuilder = new GroupBuilder(this.dialogBuilder, name);
3195
+ if (delegate) {
3196
+ delegate(groupBuilder);
3197
+ }
3198
+ this.stepState.groups.push(groupBuilder.build());
3199
+ return this;
3200
+ }
3201
+ build() {
3202
+ return this.stepState;
3203
+ }
3204
+ }
3205
+
3206
+ //#endregion
3207
+
3208
+ //#region ---- Imports ----
3209
+ //#endregion
3210
+
3211
+ //#endregion
3212
+ //#region ---- Injection Tokens ----
3213
+ /**
3214
+ * Injection token to provide available extra property types.
3215
+ */
3216
+ const AXP_EXTRA_PROPERTY_TYPES = new InjectionToken('AXP_EXTRA_PROPERTY_TYPES');
3217
+ //#endregion
3218
+
3219
+ class AXPExtraPropertiesComponent {
3220
+ constructor() {
3221
+ //#region ---- Inputs ----
3222
+ this.items = input([], ...(ngDevMode ? [{ debugName: "items" }] : []));
3223
+ this.mode = input('edit', ...(ngDevMode ? [{ debugName: "mode" }] : []));
3224
+ //#endregion
3225
+ //#region ---- Outputs ----
3226
+ this.itemsChange = output();
3227
+ //#endregion
3228
+ //#region ---- Services & Dependencies ----
3229
+ this.providedTypes = inject(AXP_EXTRA_PROPERTY_TYPES, { optional: true }) ?? [];
3230
+ this.translationService = inject(AXTranslationService);
3231
+ //#endregion
3232
+ //#region ---- Class Properties ----
3233
+ this.newKey = signal('', ...(ngDevMode ? [{ debugName: "newKey" }] : []));
3234
+ this.newTitle = signal('', ...(ngDevMode ? [{ debugName: "newTitle" }] : []));
3235
+ this.newTypeId = signal('', ...(ngDevMode ? [{ debugName: "newTypeId" }] : []));
3236
+ this.newValue = signal(undefined, ...(ngDevMode ? [{ debugName: "newValue" }] : []));
3237
+ /** Local, ephemeral context for widget rendering */
3238
+ this.internalContext = signal({}, ...(ngDevMode ? [{ debugName: "internalContext" }] : []));
3239
+ this.lastTypeByKey = {};
3240
+ this.draftVersion = signal(0, ...(ngDevMode ? [{ debugName: "draftVersion" }] : []));
3241
+ this.draftKey = computed(() => `__draft__v${this.draftVersion()}`, ...(ngDevMode ? [{ debugName: "draftKey" }] : []));
3242
+ this.typeOptions = computed(() => this.providedTypes, ...(ngDevMode ? [{ debugName: "typeOptions" }] : []));
3243
+ this.presetTypes = computed(() => this.providedTypes.slice(0, 5), ...(ngDevMode ? [{ debugName: "presetTypes" }] : []));
3244
+ this.canAdd = computed(() => {
3245
+ const key = this.newKey()?.trim();
3246
+ const title = this.newTitle()?.trim();
3247
+ const typeId = this.newTypeId();
3248
+ const val = this.newValue();
3249
+ const hasValue = val !== undefined && val !== null && (typeof val !== 'string' || val.trim() !== '');
3250
+ if (!key || !title || !typeId || !hasValue)
3251
+ return false;
3252
+ return !this.items().some((i) => i.key === key);
3253
+ }, ...(ngDevMode ? [{ debugName: "canAdd" }] : []));
3254
+ //#endregion
3255
+ //#region ---- Effects ----
3256
+ /** Sync incoming items' values into internal context for rendering */
3257
+ this.syncContextFromItems = effect(() => {
3258
+ const items = this.items();
3259
+ const current = this.internalContext();
3260
+ const currentExtra = current['extra'] ?? {};
3261
+ const extra = { ...currentExtra };
3262
+ for (const it of items) {
3263
+ if (it.value !== undefined && it.value !== null) {
3264
+ extra[it.key] = it.value;
3265
+ }
3266
+ else if (Object.prototype.hasOwnProperty.call(extra, it.key)) {
3267
+ delete extra[it.key];
3268
+ }
3269
+ }
3270
+ const nextContext = { ...current, extra };
3271
+ if (!isEqual(nextContext, current)) {
3272
+ this.internalContext.set(nextContext);
3273
+ }
3274
+ }, ...(ngDevMode ? [{ debugName: "syncContextFromItems" }] : []));
3275
+ /**
3276
+ * Clear item values when their widget type changes to avoid incompatible stale values
3277
+ */
3278
+ this.clearValueOnTypeChange = effect(() => {
3279
+ const items = this.items();
3280
+ const changedKeys = new Set();
3281
+ for (const it of items) {
3282
+ const prevType = this.lastTypeByKey[it.key];
3283
+ if (prevType && prevType !== it.type) {
3284
+ changedKeys.add(it.key);
3285
+ }
3286
+ this.lastTypeByKey[it.key] = it.type;
3287
+ }
3288
+ if (changedKeys.size > 0) {
3289
+ const updated = items.map((it) => (changedKeys.has(it.key) ? { ...it, value: undefined } : it));
3290
+ // Reset cached default values for affected nodes
3291
+ changedKeys.forEach((k) => {
3292
+ const node = this.nodeCache[k];
3293
+ if (node) {
3294
+ node.defaultValue = undefined;
3295
+ }
3296
+ });
3297
+ this.itemsChange.emit(updated);
3298
+ }
3299
+ }, ...(ngDevMode ? [{ debugName: "clearValueOnTypeChange" }] : []));
3300
+ this.nodeCache = {};
3301
+ }
3302
+ //#endregion
3303
+ //#region ---- Event Handlers ----
3304
+ onContextChanged(event) {
3305
+ // Ignore initial bootstrapping to prevent cycles
3306
+ if (event.state === 'initiated')
3307
+ return;
3308
+ const data = (event.data ?? {});
3309
+ const extra = data['extra'] ?? {};
3310
+ // sync draft value
3311
+ const dk = this.draftKey();
3312
+ if (Object.prototype.hasOwnProperty.call(extra, dk)) {
3313
+ this.newValue.set(extra[dk]);
3314
+ }
3315
+ const nextItems = this.items().map((it) => ({ ...it, value: extra[it.key] }));
3316
+ if (!isEqual(nextItems, this.items())) {
3317
+ this.itemsChange.emit(nextItems);
3318
+ }
3319
+ }
3320
+ //#endregion
3321
+ //#region ---- Utility Methods ----
3322
+ handleAddItem() {
3323
+ if (!this.canAdd())
3324
+ return;
3325
+ const type = this.typeOptions().find((t) => t.id === this.newTypeId());
3326
+ const next = {
3327
+ key: this.newKey().trim(),
3328
+ title: this.newTitle().trim(),
3329
+ type: this.newTypeId(),
3330
+ value: this.newValue(),
3331
+ options: cloneDeep(type?.defaultOptions ?? {}),
3332
+ };
3333
+ const updated = [...this.items(), next];
3334
+ this.itemsChange.emit(updated);
3335
+ // reset inputs
3336
+ this.newKey.set('');
3337
+ this.newTitle.set('');
3338
+ this.newTypeId.set('');
3339
+ this.newValue.set(undefined);
3340
+ // clear draft from context
3341
+ const ctx = { ...this.internalContext() };
3342
+ const draftExtra = { ...(ctx['extra'] ?? {}) };
3343
+ const dk = this.draftKey();
3344
+ if (Object.prototype.hasOwnProperty.call(draftExtra, dk)) {
3345
+ delete draftExtra[dk];
3346
+ this.internalContext.set({ ...ctx, extra: draftExtra });
3347
+ }
3348
+ }
3349
+ handleRemoveItem(key) {
3350
+ const updated = this.items().filter((i) => i.key !== key);
3351
+ this.itemsChange.emit(updated);
3352
+ // prune context
3353
+ const ctx = { ...this.internalContext() };
3354
+ if (ctx['extra']) {
3355
+ const { [key]: _, ...rest } = ctx['extra'];
3356
+ this.internalContext.set({ ...ctx, ['extra']: rest });
3357
+ }
3358
+ }
3359
+ handleDrop(event) {
3360
+ const arr = [...this.items()];
3361
+ moveItemInArray(arr, event.previousIndex, event.currentIndex);
3362
+ this.itemsChange.emit(arr);
3363
+ }
3364
+ selectPreset(id) {
3365
+ this.newTypeId.set(id);
3366
+ }
3367
+ getNode(item) {
3368
+ const key = item.key;
3369
+ let node = this.nodeCache[key];
3370
+ if (!node) {
3371
+ node = {
3372
+ type: item.type,
3373
+ path: `extra.${item.key}`,
3374
+ options: item.options ?? {},
3375
+ defaultValue: item.value,
3376
+ };
3377
+ this.nodeCache[key] = node;
3378
+ }
3379
+ else {
3380
+ // Keep reference stable; update nested fields if essential changes happen
3381
+ node.type = item.type;
3382
+ node.options = item.options ?? node.options;
3383
+ // Do not overwrite defaultValue during editing to avoid resets
3384
+ }
3385
+ return node;
3386
+ }
3387
+ draftNode() {
3388
+ const typeId = this.newTypeId();
3389
+ const type = this.typeOptions().find((t) => t.id === typeId);
3390
+ let node = this.draftNodeCache;
3391
+ const resolvedType = typeId;
3392
+ if (!node || node.type !== resolvedType) {
3393
+ node = {
3394
+ type: resolvedType,
3395
+ path: `extra.${this.draftKey()}`,
3396
+ options: cloneDeep(type?.defaultOptions ?? {}),
3397
+ defaultValue: this.newValue(),
3398
+ };
3399
+ this.draftNodeCache = node;
3400
+ }
3401
+ else {
3402
+ node.options = cloneDeep(type?.defaultOptions ?? {});
3403
+ }
3404
+ return node;
3405
+ }
3406
+ //#region ---- Utility Helpers ----
3407
+ newTypeChanged(val) {
3408
+ this.newTypeId.set(val);
3409
+ // force draft widget re-render on type change
3410
+ this.draftNodeCache = undefined;
3411
+ // clear draft value from both signal and context to avoid type mismatch
3412
+ const prevDraftKey = this.draftKey();
3413
+ this.newValue.set(undefined);
3414
+ const ctx = { ...this.internalContext() };
3415
+ const draftExtra = { ...(ctx['extra'] ?? {}) };
3416
+ if (Object.prototype.hasOwnProperty.call(draftExtra, prevDraftKey)) {
3417
+ delete draftExtra[prevDraftKey];
3418
+ this.internalContext.set({ ...ctx, extra: draftExtra });
3419
+ }
3420
+ // bump draft version so new draft path is isolated from old widget emissions
3421
+ this.draftVersion.set(this.draftVersion() + 1);
3422
+ const t = this.typeOptions().find((x) => x.id === val);
3423
+ if (t) {
3424
+ const autoTitle = t.title ?? val;
3425
+ const autoKey = this.sanitizeKey(autoTitle);
3426
+ // Only auto-fill when empty
3427
+ if (!this.newTitle()?.trim())
3428
+ this.newTitle.set(autoTitle);
3429
+ // always derive key from title
3430
+ this.newKey.set(autoKey);
3431
+ }
3432
+ }
3433
+ ngOnInit() {
3434
+ // auto-select first item of type list
3435
+ const types = this.typeOptions();
3436
+ if (!this.newTypeId() && types && types.length > 0) {
3437
+ this.newTypeChanged(types[0].id);
3438
+ }
3439
+ }
3440
+ handleTitleChange(val) {
3441
+ this.newTitle.set(val);
3442
+ this.newKey.set(this.sanitizeKey(val));
3443
+ }
3444
+ sanitizeKey(input) {
3445
+ if (!input)
3446
+ return '';
3447
+ // Convert to camelCase, remove invalid chars, ensure starts with letter/_
3448
+ let k = camelCase(String(input));
3449
+ k = k.replace(/[^a-zA-Z0-9_]/g, '');
3450
+ if (!/^[a-zA-Z_]/.test(k))
3451
+ k = `_${k}`;
3452
+ // enforce uniqueness by suffixing if needed
3453
+ const exists = (candidate) => this.items().some((i) => i.key === candidate);
3454
+ if (!exists(k))
3455
+ return k;
3456
+ let i = 1;
3457
+ while (exists(`${k}${i}`))
3458
+ i++;
3459
+ return `${k}${i}`;
3460
+ }
3461
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPExtraPropertiesComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3462
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.8", type: AXPExtraPropertiesComponent, isStandalone: true, selector: "axp-extra-properties", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { itemsChange: "itemsChange" }, host: { classAttribute: "ax-block ax-flex-1" }, ngImport: i0, template: `
3463
+ <div class="ax-grid ax-grid-cols-12 ax-gap-4">
3464
+ <axp-widgets-container [context]="internalContext()" (onContextChanged)="onContextChanged($event)">
3465
+ <div cdkDropList (cdkDropListDropped)="handleDrop($event)" class="ax-col-span-12 ax-flex ax-flex-col ax-gap-3">
3466
+ @for(item of items(); track item.key){
3467
+ @if(mode()==='edit'){
3468
+ <div class="ax-grid ax-grid-cols-12 ax-gap-4 ax-items-center" cdkDrag [cdkDragDisabled]="false">
3469
+ <div class="ax-col-span-12 md:ax-col-span-3 ax-flex ax-items-center ax-gap-3">
3470
+ <ax-icon class="fa-solid fa-grip-dots-vertical ax-cursor-move ax-text-neutral-500" cdkDragHandle></ax-icon>
3471
+ <div>
3472
+ <div class="ax-font-semibold">{{item.title}}</div>
3473
+ </div>
3474
+ <!-- Small-screen delete aligned with title -->
3475
+ <ax-button class="ax-ml-auto md:ax-hidden" look="blank" color="danger" (onClick)="handleRemoveItem(item.key)">
3476
+ <ax-prefix><ax-icon class="fa-light fa-trash-can"></ax-icon></ax-prefix>
3477
+ </ax-button>
3478
+ </div>
3479
+ <div class="ax-col-span-12 md:ax-col-span-8">
3480
+ <ng-container
3481
+ axp-widget-renderer
3482
+ [node]="getNode(item)"
3483
+ [mode]="'edit'"
3484
+ ></ng-container>
3485
+ </div>
3486
+ <div class="ax-hidden md:ax-block md:ax-col-span-1 md:ax-justify-self-end">
3487
+ <ax-button look="blank" color="danger" (onClick)="handleRemoveItem(item.key)">
3488
+ <ax-prefix><ax-icon class="fa-light fa-trash-can"></ax-icon></ax-prefix>
3489
+ </ax-button>
3490
+ </div>
3491
+ </div>
3492
+ } @else {
3493
+ <div class="ax-grid ax-grid-cols-12 ax-gap-1">
3494
+ <div class="ax-font-semibold">{{item.title}}</div>
3495
+ <div class="ax-col-span-12 ax-text-muted">
3496
+ <ng-container
3497
+ axp-widget-renderer
3498
+ [node]="getNode(item)"
3499
+ [mode]="'view'"
3500
+ ></ng-container>
3501
+ </div>
3502
+ </div>
3503
+ }
3504
+ } @empty {
3505
+ <div class="ax-col-span-12 ax-text-sm ax-text-gray-400">
3506
+ {{ 'extra-properties:messages.no-extra-properties' | translate | async }}
3507
+ </div>
3508
+ }
3509
+ @if(mode()==='edit'){
3510
+ <div class="ax-grid ax-grid-cols-12 ax-gap-4 ax-items-end ax-mt-4 ax-border-t ax-border-dashed ax-pt-4">
3511
+ <!-- Type -->
3512
+ <ax-form-field class="ax-col-span-12 md:ax-col-span-6 lg:ax-col-span-3">
3513
+ <ax-label>{{ 'extra-properties:labels.type' | translate | async }}</ax-label>
3514
+ <ax-select-box
3515
+ [value]="newTypeId()"
3516
+ [dataSource]="typeOptions()"
3517
+ valueField="id"
3518
+ textField="title"
3519
+ (onValueChanged)="newTypeChanged($event.value)"
3520
+ ></ax-select-box>
3521
+ </ax-form-field>
3522
+ <!-- Title -->
3523
+ <ax-form-field class="ax-col-span-12 md:ax-col-span-6 lg:ax-col-span-5">
3524
+ <ax-label>{{ 'extra-properties:labels.title' | translate | async }}</ax-label>
3525
+ <ax-text-box [ngModel]="newTitle()" (onValueChanged)="handleTitleChange($event.value)"></ax-text-box>
3526
+ </ax-form-field>
3527
+ <!-- Value -->
3528
+ @if(newTypeId()){
3529
+ <ax-form-field class="ax-col-span-12 md:ax-col-span-6 lg:ax-col-span-4">
3530
+ <ax-label>{{ 'extra-properties:labels.value' | translate | async }}</ax-label>
3531
+ <div (keydown.enter)="handleAddItem()">
3532
+ <ng-container
3533
+ axp-widget-renderer
3534
+ [node]="draftNode()"
3535
+ [mode]="'edit'"
3536
+ ></ng-container>
3537
+ </div>
3538
+ </ax-form-field>
3539
+ }
3540
+ <!-- Add moved to bottom (same as before) -->
3541
+ <div class="ax-col-span-12 ax-flex ax-justify-end">
3542
+ <ax-button look="solid" (onClick)="handleAddItem()" [disabled]="!canAdd()" text="{{ 'extra-properties:actions.add-field' | translate | async }}">
3543
+ <ax-prefix><ax-icon class="fa-solid fa-add"></ax-icon></ax-prefix>
3544
+ </ax-button>
3545
+ </div>
3546
+ </div>
3547
+ }
3548
+ </div>
3549
+ </axp-widgets-container>
3550
+ </div>
3551
+
3552
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: AXFormModule }, { kind: "component", type: i2$4.AXFormFieldComponent, selector: "ax-form-field", inputs: ["labelMode"] }, { kind: "ngmodule", type: AXLabelModule }, { kind: "component", type: i3$2.AXLabelComponent, selector: "ax-label", inputs: ["required", "for"], outputs: ["requiredChange"] }, { kind: "ngmodule", type: AXTextBoxModule }, { kind: "component", type: i4$4.AXTextBoxComponent, selector: "ax-text-box", inputs: ["disabled", "tabIndex", "readonly", "value", "state", "name", "id", "placeholder", "maxLength", "allowNull", "type", "autoComplete", "look", "mask-options", "class"], outputs: ["onBlur", "onFocus", "valueChange", "stateChange", "onValueChanged", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "ngmodule", type: AXSelectBoxModule }, { kind: "component", type: i5$2.AXSelectBoxComponent, selector: "ax-select-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "minValue", "maxValue", "value", "state", "name", "id", "type", "look", "multiple", "valueField", "textField", "disabledField", "textTemplate", "selectedItems", "isItemTruncated", "showItemTooltip", "dataSource", "minRecordsForSearch", "caption", "itemTemplate", "selectedTemplate", "emptyTemplate", "loadingTemplate", "dropdownWidth", "searchBoxAutoFocus"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onOpened", "onClosed", "onItemSelected", "onItemClick"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i3.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i2$1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXPLayoutBuilderModule }, { kind: "component", type: i3$3.AXPWidgetContainerComponent, selector: "axp-widgets-container", inputs: ["context", "functions"], outputs: ["onContextChanged"] }, { kind: "directive", type: i3$3.AXPWidgetRendererDirective, selector: "[axp-widget-renderer]", inputs: ["parentNode", "index", "mode", "node"], outputs: ["onOptionsChanged", "onValueChanged"], exportAs: ["widgetRenderer"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i9.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i9.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i9.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3553
+ }
3554
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPExtraPropertiesComponent, decorators: [{
3555
+ type: Component,
3556
+ args: [{
3557
+ selector: 'axp-extra-properties',
3558
+ template: `
3559
+ <div class="ax-grid ax-grid-cols-12 ax-gap-4">
3560
+ <axp-widgets-container [context]="internalContext()" (onContextChanged)="onContextChanged($event)">
3561
+ <div cdkDropList (cdkDropListDropped)="handleDrop($event)" class="ax-col-span-12 ax-flex ax-flex-col ax-gap-3">
3562
+ @for(item of items(); track item.key){
3563
+ @if(mode()==='edit'){
3564
+ <div class="ax-grid ax-grid-cols-12 ax-gap-4 ax-items-center" cdkDrag [cdkDragDisabled]="false">
3565
+ <div class="ax-col-span-12 md:ax-col-span-3 ax-flex ax-items-center ax-gap-3">
3566
+ <ax-icon class="fa-solid fa-grip-dots-vertical ax-cursor-move ax-text-neutral-500" cdkDragHandle></ax-icon>
3567
+ <div>
3568
+ <div class="ax-font-semibold">{{item.title}}</div>
3569
+ </div>
3570
+ <!-- Small-screen delete aligned with title -->
3571
+ <ax-button class="ax-ml-auto md:ax-hidden" look="blank" color="danger" (onClick)="handleRemoveItem(item.key)">
3572
+ <ax-prefix><ax-icon class="fa-light fa-trash-can"></ax-icon></ax-prefix>
3573
+ </ax-button>
3574
+ </div>
3575
+ <div class="ax-col-span-12 md:ax-col-span-8">
3576
+ <ng-container
3577
+ axp-widget-renderer
3578
+ [node]="getNode(item)"
3579
+ [mode]="'edit'"
3580
+ ></ng-container>
3581
+ </div>
3582
+ <div class="ax-hidden md:ax-block md:ax-col-span-1 md:ax-justify-self-end">
3583
+ <ax-button look="blank" color="danger" (onClick)="handleRemoveItem(item.key)">
3584
+ <ax-prefix><ax-icon class="fa-light fa-trash-can"></ax-icon></ax-prefix>
3585
+ </ax-button>
3586
+ </div>
3587
+ </div>
3588
+ } @else {
3589
+ <div class="ax-grid ax-grid-cols-12 ax-gap-1">
3590
+ <div class="ax-font-semibold">{{item.title}}</div>
3591
+ <div class="ax-col-span-12 ax-text-muted">
3592
+ <ng-container
3593
+ axp-widget-renderer
3594
+ [node]="getNode(item)"
3595
+ [mode]="'view'"
3596
+ ></ng-container>
3597
+ </div>
3598
+ </div>
3599
+ }
3600
+ } @empty {
3601
+ <div class="ax-col-span-12 ax-text-sm ax-text-gray-400">
3602
+ {{ 'extra-properties:messages.no-extra-properties' | translate | async }}
3603
+ </div>
3604
+ }
3605
+ @if(mode()==='edit'){
3606
+ <div class="ax-grid ax-grid-cols-12 ax-gap-4 ax-items-end ax-mt-4 ax-border-t ax-border-dashed ax-pt-4">
3607
+ <!-- Type -->
3608
+ <ax-form-field class="ax-col-span-12 md:ax-col-span-6 lg:ax-col-span-3">
3609
+ <ax-label>{{ 'extra-properties:labels.type' | translate | async }}</ax-label>
3610
+ <ax-select-box
3611
+ [value]="newTypeId()"
3612
+ [dataSource]="typeOptions()"
3613
+ valueField="id"
3614
+ textField="title"
3615
+ (onValueChanged)="newTypeChanged($event.value)"
3616
+ ></ax-select-box>
3617
+ </ax-form-field>
3618
+ <!-- Title -->
3619
+ <ax-form-field class="ax-col-span-12 md:ax-col-span-6 lg:ax-col-span-5">
3620
+ <ax-label>{{ 'extra-properties:labels.title' | translate | async }}</ax-label>
3621
+ <ax-text-box [ngModel]="newTitle()" (onValueChanged)="handleTitleChange($event.value)"></ax-text-box>
3622
+ </ax-form-field>
3623
+ <!-- Value -->
3624
+ @if(newTypeId()){
3625
+ <ax-form-field class="ax-col-span-12 md:ax-col-span-6 lg:ax-col-span-4">
3626
+ <ax-label>{{ 'extra-properties:labels.value' | translate | async }}</ax-label>
3627
+ <div (keydown.enter)="handleAddItem()">
3628
+ <ng-container
3629
+ axp-widget-renderer
3630
+ [node]="draftNode()"
3631
+ [mode]="'edit'"
3632
+ ></ng-container>
3633
+ </div>
3634
+ </ax-form-field>
3635
+ }
3636
+ <!-- Add moved to bottom (same as before) -->
3637
+ <div class="ax-col-span-12 ax-flex ax-justify-end">
3638
+ <ax-button look="solid" (onClick)="handleAddItem()" [disabled]="!canAdd()" text="{{ 'extra-properties:actions.add-field' | translate | async }}">
3639
+ <ax-prefix><ax-icon class="fa-solid fa-add"></ax-icon></ax-prefix>
3640
+ </ax-button>
3641
+ </div>
3642
+ </div>
3643
+ }
3644
+ </div>
3645
+ </axp-widgets-container>
3646
+ </div>
3647
+
3648
+ `,
3649
+ changeDetection: ChangeDetectionStrategy.OnPush,
3650
+ imports: [
3651
+ CommonModule,
3652
+ FormsModule,
3653
+ AXFormModule,
3654
+ AXLabelModule,
3655
+ AXTextBoxModule,
3656
+ AXSelectBoxModule,
3657
+ AXButtonModule,
3658
+ AXDecoratorModule,
3659
+ AXPLayoutBuilderModule,
3660
+ DragDropModule,
3661
+ AXTranslationModule,
3662
+ //AXPGridLayoutDirective,
3663
+ ],
3664
+ standalone: true,
3665
+ host: {
3666
+ class: 'ax-block ax-flex-1',
3667
+ },
3668
+ }]
3669
+ }] });
3670
+
3671
+ class AXPWidgetPropertyViewerComponent {
3672
+ constructor() {
3673
+ this.widget = input.required(...(ngDevMode ? [{ debugName: "widget" }] : []));
3674
+ this.mode = input('simple', ...(ngDevMode ? [{ debugName: "mode" }] : []));
3675
+ this.widgetRegistryService = inject(AXPWidgetRegistryService);
3676
+ // Designer connector removed to avoid cross-entry circular dependency
3677
+ this.currentTabIndex = signal(0, ...(ngDevMode ? [{ debugName: "currentTabIndex" }] : []));
3678
+ this.config = signal(null, ...(ngDevMode ? [{ debugName: "config" }] : []));
3679
+ this.allPoperties = [];
3680
+ this.tabs = signal([], ...(ngDevMode ? [{ debugName: "tabs" }] : []));
3681
+ this.groups = computed(() => {
3682
+ return this.tabs().length ? this.tabs()[this.currentTabIndex()].groups : [];
3683
+ }, ...(ngDevMode ? [{ debugName: "groups" }] : []));
3684
+ this.groupCollapsedStates = new Map();
3685
+ this.onChanged = new EventEmitter();
3686
+ this.context = signal({}, ...(ngDevMode ? [{ debugName: "context" }] : []));
3687
+ this.initialContext = {};
3688
+ effect(() => {
3689
+ if (!this.widget())
3690
+ return;
3691
+ const config = this.widgetRegistryService.resolve(this.widget()?.type);
3692
+ if (config) {
3693
+ this.initialContext = {};
3694
+ this.config.set(config);
3695
+ this.fillTabs();
3696
+ }
3697
+ else {
3698
+ console.error(`Invalid widget name: ${this.widget()}`);
3699
+ }
3700
+ });
3701
+ }
3702
+ update(values) {
3703
+ this.context.set(merge(cloneDeep(this.context()), values));
3704
+ }
3705
+ fillTabs() {
3706
+ const tabs = [
3707
+ {
3708
+ name: 'general',
3709
+ title: 'General',
3710
+ groups: [],
3711
+ },
3712
+ ];
3713
+ Object.entries(this.config()?.components ?? {}).forEach((c) => {
3714
+ if (c[1].component != null && c[1].properties?.length) {
3715
+ tabs.push({ name: c[0], title: capitalize(c[0]), groups: [] });
3716
+ }
3717
+ });
3718
+ ///
3719
+ this.allPoperties = [];
3720
+ ///
3721
+ tabs.forEach((tab) => {
3722
+ const props = tab.name == 'general'
3723
+ ? (this.config()?.properties ?? [])
3724
+ : ((this.config()?.components)[tab.name]?.properties ?? []);
3725
+ //
3726
+ const visibleProps = props.filter((c) => c.visible != false);
3727
+ this.allPoperties.push(...props);
3728
+ tab.groups = unionBy(sortBy(visibleProps.map((pg) => ({
3729
+ isCollapsed: !!this.groupCollapsedStates.get(pg.group.name),
3730
+ name: pg.group.name,
3731
+ title: pg.group.title,
3732
+ props: sortBy(visibleProps.filter((p) => p.group.name == pg.group.name && pg.visible), ['order', 'title']),
3733
+ })), ['order', 'title']), 'name').filter((c) => c.props.length);
3734
+ });
3735
+ this.tabs.set(tabs.filter((c) => c.groups.length));
3736
+ //
3737
+ this.initialContext = this.allPoperties
3738
+ .filter((c) => (!isArray(c.schema.defaultValue) && !isNil(c.schema.defaultValue)) ||
3739
+ (isArray(c.schema.defaultValue) && !isEmpty(c.schema.defaultValue)))
3740
+ .reduce((acc, c) => {
3741
+ set(acc, c.schema.interface.path, c.schema.defaultValue);
3742
+ return acc;
3743
+ }, {});
3744
+ //
3745
+ untracked(() => {
3746
+ this.context.set(merge(cloneDeep(this.initialContext), this.widget()));
3747
+ this.onChanged.emit({ values: this.context(), mode: 'init' });
3748
+ });
3749
+ }
3750
+ handleContextChange(e) {
3751
+ untracked(() => {
3752
+ this.context.set(e.data);
3753
+ this.onChanged.emit({ values: this.context(), mode: e.state == 'initiated' ? 'init' : 'update' });
3754
+ });
3755
+ }
3756
+ handleTabChange(event) {
3757
+ const indx = event.index;
3758
+ if (this.currentTabIndex() != indx) {
3759
+ this.currentTabIndex.set(indx);
3760
+ }
3761
+ }
3762
+ handleCollapsedChange(group, collapsed) {
3763
+ this.groupCollapsedStates.set(group, collapsed);
3764
+ }
3765
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPWidgetPropertyViewerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3766
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.8", type: AXPWidgetPropertyViewerComponent, isStandalone: true, selector: "axp-widget-property-viewer", inputs: { widget: { classPropertyName: "widget", publicName: "widget", isSignal: true, isRequired: true, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onChanged: "onChanged" }, ngImport: i0, template: "<axp-widgets-container [context]=\"context()\" (onContextChanged)=\"handleContextChange($event)\">\n @if (mode() == 'advanced') {\n <div class=\"ax-flex ax-flex-col\">\n @if (tabs().length > 1) {\n <div class=\"ax-pb-2\">\n <ax-tabs look=\"default\" (onActiveTabChanged)=\"handleTabChange($event)\" [look]=\"'with-line'\">\n @for (tab of tabs(); track $index) {\n <ax-tab-item [text]=\"tab.title\" [key]=\"$index.toString()\" [active]=\"currentTabIndex() === $index\">\n </ax-tab-item>\n }\n </ax-tabs>\n </div>\n }\n <div class=\"ax-flex-1 ax-overflow-auto\">\n <ax-collapse-group class=\"ax-h-fit\" [look]=\"'flat'\">\n @for (group of groups(); track $index) {\n <ax-collapse\n class=\"!ax-mb-0\"\n [caption]=\"group.title\"\n [(isCollapsed)]=\"group.isCollapsed\"\n (isCollapsedChange)=\"handleCollapsedChange(group.name, $event)\"\n >\n <div class=\"ax-flex ax-flex-col\">\n @for (p of group.props; track $index) {\n <div class=\"ax-flex ax-flex-col ax-gap-1 ax-py-2\">\n <span class=\"ax-font-semibold\">{{ p.title }}</span>\n @if (p.schema.interface) {\n <ng-container axp-widget-renderer [node]=\"p.schema.interface\" [mode]=\"'edit'\"> </ng-container>\n }\n </div>\n }\n </div>\n </ax-collapse>\n }\n </ax-collapse-group>\n </div>\n </div>\n }\n <!-- Simple-->\n @else {\n <div class=\"ax-flex ax-flex-col ax-p-4 ax-gap-4\">\n <!-- groups -->\n @for (group of groups(); track $index) {\n <!-- props -->\n @for (p of group.props; track $index) {\n <div class=\"ax-flex ax-flex-col ax-gap-2\">\n <span class=\"ax-font-semibold\">{{ p.title | translate | async }}</span>\n @if (p.schema.interface) {\n <ng-container axp-widget-renderer [node]=\"p.schema.interface\" [mode]=\"'edit'\"> </ng-container>\n }\n </div>\n }\n }\n </div>\n }\n</axp-widgets-container>\n", styles: [":host ax-collapse .ax-collapse-header{font-weight:600}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXCollapseModule }, { kind: "component", type: i1$4.AXCollapseComponent, selector: "ax-collapse", inputs: ["disabled", "look", "isCollapsed", "showHeader", "caption", "icon", "isLoading", "headerTemplate"], outputs: ["onClick", "isCollapsedChange"] }, { kind: "component", type: i1$4.AXCollapseGroupComponent, selector: "ax-collapse-group", inputs: ["look", "accordion", "activeIndex"], outputs: ["accordionChange", "activeIndexChange"] }, { kind: "ngmodule", type: AXTabsModule }, { kind: "component", type: i2$5.AXTabsComponent, selector: "ax-tabs", inputs: ["look", "location", "fitParent", "minWidth", "content"], outputs: ["onActiveTabChanged"] }, { kind: "component", type: i2$5.AXTabItemComponent, selector: "ax-tab-item", inputs: ["disabled", "text", "key", "headerTemplate", "active"], outputs: ["disabledChange", "onClick", "onBlur", "onFocus", "activeChange"] }, { kind: "ngmodule", type: AXPLayoutBuilderModule }, { kind: "component", type: i3$3.AXPWidgetContainerComponent, selector: "axp-widgets-container", inputs: ["context", "functions"], outputs: ["onContextChanged"] }, { kind: "directive", type: i3$3.AXPWidgetRendererDirective, selector: "[axp-widget-renderer]", inputs: ["parentNode", "index", "mode", "node"], outputs: ["onOptionsChanged", "onValueChanged"], exportAs: ["widgetRenderer"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3767
+ }
3768
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPWidgetPropertyViewerComponent, decorators: [{
3769
+ type: Component,
3770
+ args: [{ selector: 'axp-widget-property-viewer', changeDetection: ChangeDetectionStrategy.OnPush, imports: [CommonModule, AXCollapseModule, AXTabsModule, AXPLayoutBuilderModule, AXTranslationModule], template: "<axp-widgets-container [context]=\"context()\" (onContextChanged)=\"handleContextChange($event)\">\n @if (mode() == 'advanced') {\n <div class=\"ax-flex ax-flex-col\">\n @if (tabs().length > 1) {\n <div class=\"ax-pb-2\">\n <ax-tabs look=\"default\" (onActiveTabChanged)=\"handleTabChange($event)\" [look]=\"'with-line'\">\n @for (tab of tabs(); track $index) {\n <ax-tab-item [text]=\"tab.title\" [key]=\"$index.toString()\" [active]=\"currentTabIndex() === $index\">\n </ax-tab-item>\n }\n </ax-tabs>\n </div>\n }\n <div class=\"ax-flex-1 ax-overflow-auto\">\n <ax-collapse-group class=\"ax-h-fit\" [look]=\"'flat'\">\n @for (group of groups(); track $index) {\n <ax-collapse\n class=\"!ax-mb-0\"\n [caption]=\"group.title\"\n [(isCollapsed)]=\"group.isCollapsed\"\n (isCollapsedChange)=\"handleCollapsedChange(group.name, $event)\"\n >\n <div class=\"ax-flex ax-flex-col\">\n @for (p of group.props; track $index) {\n <div class=\"ax-flex ax-flex-col ax-gap-1 ax-py-2\">\n <span class=\"ax-font-semibold\">{{ p.title }}</span>\n @if (p.schema.interface) {\n <ng-container axp-widget-renderer [node]=\"p.schema.interface\" [mode]=\"'edit'\"> </ng-container>\n }\n </div>\n }\n </div>\n </ax-collapse>\n }\n </ax-collapse-group>\n </div>\n </div>\n }\n <!-- Simple-->\n @else {\n <div class=\"ax-flex ax-flex-col ax-p-4 ax-gap-4\">\n <!-- groups -->\n @for (group of groups(); track $index) {\n <!-- props -->\n @for (p of group.props; track $index) {\n <div class=\"ax-flex ax-flex-col ax-gap-2\">\n <span class=\"ax-font-semibold\">{{ p.title | translate | async }}</span>\n @if (p.schema.interface) {\n <ng-container axp-widget-renderer [node]=\"p.schema.interface\" [mode]=\"'edit'\"> </ng-container>\n }\n </div>\n }\n }\n </div>\n }\n</axp-widgets-container>\n", styles: [":host ax-collapse .ax-collapse-header{font-weight:600}\n"] }]
3771
+ }], ctorParameters: () => [], propDecorators: { onChanged: [{
3772
+ type: Output
3773
+ }] } });
3774
+
3775
+ class AXPExtraPropertiesSchemaComponent {
3776
+ constructor() {
3777
+ //#region ---- Inputs ----
3778
+ this.schema = input([], ...(ngDevMode ? [{ debugName: "schema" }] : []));
3779
+ this.mode = input('edit', ...(ngDevMode ? [{ debugName: "mode" }] : []));
3780
+ //#endregion
3781
+ //#region ---- Outputs ----
3782
+ this.schemaChange = output();
3783
+ //#endregion
3784
+ //#region ---- Services & Dependencies ----
3785
+ this.providedTypes = inject(AXP_EXTRA_PROPERTY_TYPES, { optional: true }) ?? [];
3786
+ this.translationService = inject(AXTranslationService);
3787
+ //#endregion
3788
+ //#region ---- Class Properties ----
3789
+ this.newTitle = signal('', ...(ngDevMode ? [{ debugName: "newTitle" }] : []));
3790
+ this.newTypeId = signal('', ...(ngDevMode ? [{ debugName: "newTypeId" }] : []));
3791
+ this.typeOptions = computed(() => this.providedTypes, ...(ngDevMode ? [{ debugName: "typeOptions" }] : []));
3792
+ this.canAdd = computed(() => {
3793
+ const title = this.newTitle()?.trim();
3794
+ const typeId = this.newTypeId();
3795
+ const key = this.deriveKey(title);
3796
+ if (!key || !title || !typeId)
3797
+ return false;
3798
+ return !this.schema().some((i) => i.key === key);
3799
+ }, ...(ngDevMode ? [{ debugName: "canAdd" }] : []));
3800
+ // Selection state for right panel editor
3801
+ this.selectedKey = signal(null, ...(ngDevMode ? [{ debugName: "selectedKey" }] : []));
3802
+ this.selectedItem = computed(() => this.schema().find((i) => i.key === this.selectedKey()) ?? null, ...(ngDevMode ? [{ debugName: "selectedItem" }] : []));
3803
+ // Auto-select first item when schema changes or current selection removed
3804
+ effect(() => {
3805
+ const items = this.schema();
3806
+ const current = this.selectedKey();
3807
+ if (!items.length) {
3808
+ if (current !== null)
3809
+ this.selectedKey.set(null);
3810
+ return;
3811
+ }
3812
+ if (!current || !items.some((i) => i.key === current)) {
3813
+ this.selectedKey.set(items[0].key);
3814
+ }
3815
+ });
3816
+ }
3817
+ //#endregion
3818
+ //#region ---- Utility Methods ----
3819
+ handleAdd() {
3820
+ if (!this.canAdd())
3821
+ return;
3822
+ const type = this.typeOptions().find((t) => t.id === this.newTypeId());
3823
+ const title = this.newTitle().trim();
3824
+ const key = this.deriveKey(title);
3825
+ const next = {
3826
+ key,
3827
+ title,
3828
+ type: this.newTypeId(),
3829
+ options: cloneDeep(type?.defaultOptions ?? {}),
3830
+ };
3831
+ const updated = [...this.schema(), next];
3832
+ this.schemaChange.emit(updated);
3833
+ this.newTitle.set('');
3834
+ this.newTypeId.set('');
3835
+ // select newly added item
3836
+ this.selectedKey.set(key);
3837
+ }
3838
+ handleRemove(key) {
3839
+ const updated = this.schema().filter((i) => i.key !== key);
3840
+ this.schemaChange.emit(updated);
3841
+ if (this.selectedKey() === key) {
3842
+ this.selectedKey.set(updated.length ? updated[0].key : null);
3843
+ }
3844
+ }
3845
+ handleDrop(event) {
3846
+ const arr = [...this.schema()];
3847
+ moveItemInArray(arr, event.previousIndex, event.currentIndex);
3848
+ this.schemaChange.emit(arr);
3849
+ }
3850
+ handleUpdateTitle(key, title) {
3851
+ const updated = this.schema().map((it) => (it.key === key ? { ...it, title } : it));
3852
+ this.schemaChange.emit(updated);
3853
+ }
3854
+ handleUpdateType(key, typeId) {
3855
+ const type = this.typeOptions().find((t) => t.id === typeId);
3856
+ const updated = this.schema().map((it) => it.key === key ? { ...it, type: typeId, options: cloneDeep(type?.defaultOptions ?? {}) } : it);
3857
+ this.schemaChange.emit(updated);
3858
+ }
3859
+ newTypeChanged(val) {
3860
+ this.newTypeId.set(val);
3861
+ const t = this.typeOptions().find((x) => x.id === val);
3862
+ if (t) {
3863
+ const autoTitle = t.title ?? val;
3864
+ if (!this.newTitle()?.trim())
3865
+ this.newTitle.set(autoTitle);
3866
+ }
3867
+ }
3868
+ handleTitleChange(val) {
3869
+ this.newTitle.set(val);
3870
+ }
3871
+ handleSelect(key) {
3872
+ this.selectedKey.set(key);
3873
+ }
3874
+ handleViewerChanged(e) {
3875
+ // Ignore initial emissions to prevent change detection loops
3876
+ if (e?.mode === 'init')
3877
+ return;
3878
+ const key = this.selectedKey();
3879
+ if (!key)
3880
+ return;
3881
+ const nextOptions = e?.values?.options ?? {};
3882
+ const updated = this.schema().map((it) => (it.key === key ? { ...it, options: cloneDeep(nextOptions) } : it));
3883
+ this.schemaChange.emit(updated);
3884
+ }
3885
+ deriveKey(input) {
3886
+ if (!input)
3887
+ return '';
3888
+ let k = camelCase(String(input));
3889
+ k = k.replace(/[^a-zA-Z0-9_]/g, '');
3890
+ if (!/^[a-zA-Z_]/.test(k))
3891
+ k = `_${k}`;
3892
+ const exists = (candidate) => this.schema().some((i) => i.key === candidate);
3893
+ if (!exists(k))
3894
+ return k;
3895
+ let i = 1;
3896
+ while (exists(`${k}${i}`))
3897
+ i++;
3898
+ return `${k}${i}`;
3899
+ }
3900
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPExtraPropertiesSchemaComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3901
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.8", type: AXPExtraPropertiesSchemaComponent, isStandalone: true, selector: "axp-extra-properties-schema", inputs: { schema: { classPropertyName: "schema", publicName: "schema", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { schemaChange: "schemaChange" }, host: { classAttribute: "ax-flex ax-flex-1 ax-h-full ax-gap-4 ax-p-4" }, ngImport: i0, template: "<!-- Left Panel: list/manage properties -->\n<div class=\"ax-flex ax-flex-col ax-gap-3 ax-min-h-0 ax-h-full ax-w-2/3\">\n <div class=\"ax-overflow-y-auto ax-min-h-0 ax-h-full ax-pe-2 -ax-me-2\">\n <div cdkDropList (cdkDropListDropped)=\"handleDrop($event)\" class=\"ax-flex ax-flex-col ax-gap-3\">\n @for (item of schema(); track item.key) {\n @if (mode() === 'edit') {\n <div class=\"ax-grid ax-grid-cols-12 ax-gap-4 ax-items-center ax-rounded ax-border ax-p-3 ax-cursor-pointer ax-lightest-surface \"\n [class.!ax-lighter-surface]=\"item.key === selectedKey()\" (click)=\"handleSelect(item.key)\" cdkDrag\n [cdkDragDisabled]=\"false\">\n <div class=\"ax-col-span-12 md:ax-col-span-4 ax-flex ax-items-center ax-gap-3\">\n <ax-icon class=\"fa-solid fa-grip-dots-vertical ax-cursor-move ax-text-neutral-500\"\n cdkDragHandle></ax-icon>\n <div>\n <div class=\"ax-font-semibold\">{{ item.title }}</div>\n </div>\n </div>\n <div class=\"ax-col-span-12 md:ax-col-span-7 ax-grid ax-grid-cols-12 ax-gap-4 ax-items-center\">\n <ax-form-field class=\"ax-col-span-12 md:ax-col-span-6\">\n <ax-select-box [value]=\"item.type\" [dataSource]=\"typeOptions()\" valueField=\"id\"\n textField=\"title\"\n (onValueChanged)=\"handleUpdateType(item.key, $event.value)\"></ax-select-box>\n </ax-form-field>\n <ax-form-field class=\"ax-col-span-12 md:ax-col-span-6\">\n <ax-text-box [ngModel]=\"item.title\"\n (onValueChanged)=\"handleUpdateTitle(item.key, $event.value)\"></ax-text-box>\n </ax-form-field>\n </div>\n <div class=\"ax-hidden md:ax-block md:ax-col-span-1 md:ax-justify-self-end\">\n <ax-button look=\"blank\" color=\"danger\" (onClick)=\"handleRemove(item.key)\">\n <ax-prefix><ax-icon class=\"fa-light fa-trash-can\"></ax-icon></ax-prefix>\n </ax-button>\n </div>\n </div>\n } @else {\n <div class=\"ax-grid ax-grid-cols-12 ax-gap-1 ax-rounded ax-border ax-p-3\">\n <div class=\"ax-font-semibold\">{{ item.title }}</div>\n <div class=\"ax-col-span-12 ax-text-xs ax-text-muted\">{{ item.key }}</div>\n </div>\n }\n } @empty {\n <div class=\"ax-text-sm ax-text-gray-400\">{{ '@extra-properties:messages.no-schema-fields' | translate |\n async\n }}</div>\n }\n\n @if (mode() === 'edit') {\n <div class=\"ax-grid ax-grid-cols-12 ax-gap-4 ax-items-end ax-mt-4 ax-border-t ax-border-dashed ax-pt-4\">\n <!-- Type -->\n <ax-form-field class=\"ax-col-span-12 md:ax-col-span-6 lg:ax-col-span-6\">\n <ax-label>{{ '@extra-properties:labels.type' | translate | async }}</ax-label>\n <ax-select-box [ngModel]=\"newTypeId()\" [dataSource]=\"typeOptions()\" valueField=\"id\"\n textField=\"title\" (onValueChanged)=\"newTypeChanged($event.value)\"></ax-select-box>\n </ax-form-field>\n <!-- Title -->\n <ax-form-field class=\"ax-col-span-12 md:ax-col-span-6 lg:ax-col-span-6\">\n <ax-label>{{ '@extra-properties:labels.title' | translate | async }}</ax-label>\n <ax-text-box [ngModel]=\"newTitle()\"\n (onValueChanged)=\"handleTitleChange($event.value)\"></ax-text-box>\n </ax-form-field>\n <!-- Add -->\n <div class=\"ax-col-span-12 ax-flex ax-justify-end\">\n <ax-button look=\"solid\" (onClick)=\"handleAdd()\" [disabled]=\"!canAdd()\"\n text=\"{{ '@extra-properties:actions.add-field' | translate | async }}\">\n <ax-prefix><ax-icon class=\"fa-solid fa-add\"></ax-icon></ax-prefix>\n </ax-button>\n </div>\n </div>\n }\n </div>\n </div>\n</div>\n\n<!-- Right Panel: widget property viewer for selected item -->\n<div class=\"ax-w-1/3 ax-border ax-rounded ax-h-full ax-flex ax-flex-col ax-lightest-surface\">\n @if (mode() === 'edit' && selectedItem()) {\n <div class=\"ax-p-4 ax-font-semibold ax-border-b ax-lighter-surface\">\n {{selectedItem()?.title}}\n </div>\n <div class=\"ax-overflow-y-auto ax-flex-1\">\n <axp-widget-property-viewer [widget]=\"{ type: selectedItem()!.type, options: selectedItem()!.options }\"\n [mode]=\"'advanced'\" (onChanged)=\"handleViewerChanged($event)\" />\n </div>\n }\n @else {\n <div class=\"ax-text-sm ax-text-muted ax-p-4 ax-text-center\">{{ '@extra-properties:messages.select-field-to-edit' |\n translate | async }}</div>\n }\n</div>", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: AXFormModule }, { kind: "component", type: i2$4.AXFormFieldComponent, selector: "ax-form-field", inputs: ["labelMode"] }, { kind: "ngmodule", type: AXLabelModule }, { kind: "component", type: i3$2.AXLabelComponent, selector: "ax-label", inputs: ["required", "for"], outputs: ["requiredChange"] }, { kind: "ngmodule", type: AXTextBoxModule }, { kind: "component", type: i4$4.AXTextBoxComponent, selector: "ax-text-box", inputs: ["disabled", "tabIndex", "readonly", "value", "state", "name", "id", "placeholder", "maxLength", "allowNull", "type", "autoComplete", "look", "mask-options", "class"], outputs: ["onBlur", "onFocus", "valueChange", "stateChange", "onValueChanged", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "ngmodule", type: AXSelectBoxModule }, { kind: "component", type: i5$2.AXSelectBoxComponent, selector: "ax-select-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "minValue", "maxValue", "value", "state", "name", "id", "type", "look", "multiple", "valueField", "textField", "disabledField", "textTemplate", "selectedItems", "isItemTruncated", "showItemTooltip", "dataSource", "minRecordsForSearch", "caption", "itemTemplate", "selectedTemplate", "emptyTemplate", "loadingTemplate", "dropdownWidth", "searchBoxAutoFocus"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onOpened", "onClosed", "onItemSelected", "onItemClick"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i3.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i2$1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i9.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i9.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i9.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type: AXPWidgetPropertyViewerComponent, selector: "axp-widget-property-viewer", inputs: ["widget", "mode"], outputs: ["onChanged"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3902
+ }
3903
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPExtraPropertiesSchemaComponent, decorators: [{
3904
+ type: Component,
3905
+ args: [{ selector: 'axp-extra-properties-schema', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
3906
+ CommonModule,
3907
+ FormsModule,
3908
+ AXFormModule,
3909
+ AXLabelModule,
3910
+ AXTextBoxModule,
3911
+ AXSelectBoxModule,
3912
+ AXButtonModule,
3913
+ AXDecoratorModule,
3914
+ DragDropModule,
3915
+ AXTranslationModule,
3916
+ AXPWidgetPropertyViewerComponent,
3917
+ ], standalone: true, host: {
3918
+ class: 'ax-flex ax-flex-1 ax-h-full ax-gap-4 ax-p-4',
3919
+ }, template: "<!-- Left Panel: list/manage properties -->\n<div class=\"ax-flex ax-flex-col ax-gap-3 ax-min-h-0 ax-h-full ax-w-2/3\">\n <div class=\"ax-overflow-y-auto ax-min-h-0 ax-h-full ax-pe-2 -ax-me-2\">\n <div cdkDropList (cdkDropListDropped)=\"handleDrop($event)\" class=\"ax-flex ax-flex-col ax-gap-3\">\n @for (item of schema(); track item.key) {\n @if (mode() === 'edit') {\n <div class=\"ax-grid ax-grid-cols-12 ax-gap-4 ax-items-center ax-rounded ax-border ax-p-3 ax-cursor-pointer ax-lightest-surface \"\n [class.!ax-lighter-surface]=\"item.key === selectedKey()\" (click)=\"handleSelect(item.key)\" cdkDrag\n [cdkDragDisabled]=\"false\">\n <div class=\"ax-col-span-12 md:ax-col-span-4 ax-flex ax-items-center ax-gap-3\">\n <ax-icon class=\"fa-solid fa-grip-dots-vertical ax-cursor-move ax-text-neutral-500\"\n cdkDragHandle></ax-icon>\n <div>\n <div class=\"ax-font-semibold\">{{ item.title }}</div>\n </div>\n </div>\n <div class=\"ax-col-span-12 md:ax-col-span-7 ax-grid ax-grid-cols-12 ax-gap-4 ax-items-center\">\n <ax-form-field class=\"ax-col-span-12 md:ax-col-span-6\">\n <ax-select-box [value]=\"item.type\" [dataSource]=\"typeOptions()\" valueField=\"id\"\n textField=\"title\"\n (onValueChanged)=\"handleUpdateType(item.key, $event.value)\"></ax-select-box>\n </ax-form-field>\n <ax-form-field class=\"ax-col-span-12 md:ax-col-span-6\">\n <ax-text-box [ngModel]=\"item.title\"\n (onValueChanged)=\"handleUpdateTitle(item.key, $event.value)\"></ax-text-box>\n </ax-form-field>\n </div>\n <div class=\"ax-hidden md:ax-block md:ax-col-span-1 md:ax-justify-self-end\">\n <ax-button look=\"blank\" color=\"danger\" (onClick)=\"handleRemove(item.key)\">\n <ax-prefix><ax-icon class=\"fa-light fa-trash-can\"></ax-icon></ax-prefix>\n </ax-button>\n </div>\n </div>\n } @else {\n <div class=\"ax-grid ax-grid-cols-12 ax-gap-1 ax-rounded ax-border ax-p-3\">\n <div class=\"ax-font-semibold\">{{ item.title }}</div>\n <div class=\"ax-col-span-12 ax-text-xs ax-text-muted\">{{ item.key }}</div>\n </div>\n }\n } @empty {\n <div class=\"ax-text-sm ax-text-gray-400\">{{ '@extra-properties:messages.no-schema-fields' | translate |\n async\n }}</div>\n }\n\n @if (mode() === 'edit') {\n <div class=\"ax-grid ax-grid-cols-12 ax-gap-4 ax-items-end ax-mt-4 ax-border-t ax-border-dashed ax-pt-4\">\n <!-- Type -->\n <ax-form-field class=\"ax-col-span-12 md:ax-col-span-6 lg:ax-col-span-6\">\n <ax-label>{{ '@extra-properties:labels.type' | translate | async }}</ax-label>\n <ax-select-box [ngModel]=\"newTypeId()\" [dataSource]=\"typeOptions()\" valueField=\"id\"\n textField=\"title\" (onValueChanged)=\"newTypeChanged($event.value)\"></ax-select-box>\n </ax-form-field>\n <!-- Title -->\n <ax-form-field class=\"ax-col-span-12 md:ax-col-span-6 lg:ax-col-span-6\">\n <ax-label>{{ '@extra-properties:labels.title' | translate | async }}</ax-label>\n <ax-text-box [ngModel]=\"newTitle()\"\n (onValueChanged)=\"handleTitleChange($event.value)\"></ax-text-box>\n </ax-form-field>\n <!-- Add -->\n <div class=\"ax-col-span-12 ax-flex ax-justify-end\">\n <ax-button look=\"solid\" (onClick)=\"handleAdd()\" [disabled]=\"!canAdd()\"\n text=\"{{ '@extra-properties:actions.add-field' | translate | async }}\">\n <ax-prefix><ax-icon class=\"fa-solid fa-add\"></ax-icon></ax-prefix>\n </ax-button>\n </div>\n </div>\n }\n </div>\n </div>\n</div>\n\n<!-- Right Panel: widget property viewer for selected item -->\n<div class=\"ax-w-1/3 ax-border ax-rounded ax-h-full ax-flex ax-flex-col ax-lightest-surface\">\n @if (mode() === 'edit' && selectedItem()) {\n <div class=\"ax-p-4 ax-font-semibold ax-border-b ax-lighter-surface\">\n {{selectedItem()?.title}}\n </div>\n <div class=\"ax-overflow-y-auto ax-flex-1\">\n <axp-widget-property-viewer [widget]=\"{ type: selectedItem()!.type, options: selectedItem()!.options }\"\n [mode]=\"'advanced'\" (onChanged)=\"handleViewerChanged($event)\" />\n </div>\n }\n @else {\n <div class=\"ax-text-sm ax-text-muted ax-p-4 ax-text-center\">{{ '@extra-properties:messages.select-field-to-edit' |\n translate | async }}</div>\n }\n</div>" }]
3920
+ }], ctorParameters: () => [] });
3921
+
3922
+ class AXPExtraPropertiesValuesComponent {
3923
+ constructor() {
3924
+ //#region ---- Inputs ----
3925
+ this.schema = input([], ...(ngDevMode ? [{ debugName: "schema" }] : []));
3926
+ this.values = input({}, ...(ngDevMode ? [{ debugName: "values" }] : []));
3927
+ this.mode = input('edit', ...(ngDevMode ? [{ debugName: "mode" }] : []));
3928
+ //#endregion
3929
+ //#region ---- Outputs ----
3930
+ this.valuesChange = output();
3931
+ //#endregion
3932
+ //#region ---- Outputs ----
3933
+ this.isRequired = (item) => {
3934
+ return item.options?.['validations']?.['required'] ?? false;
3935
+ };
3936
+ //#endregion
3937
+ //#region ---- Class Properties ----
3938
+ this.internalContext = signal({}, ...(ngDevMode ? [{ debugName: "internalContext" }] : []));
3939
+ this.nodeCache = {};
3940
+ this.lastTypeByKey = {};
3941
+ //#endregion
3942
+ //#region ---- Effects ----
3943
+ this.syncContextFromInputs = effect(() => {
3944
+ const schema = this.schema();
3945
+ const vals = this.values();
3946
+ const current = this.internalContext();
3947
+ const currentExtra = current['extra'] ?? {};
3948
+ const extra = {};
3949
+ for (const s of schema) {
3950
+ const v = vals[s.key];
3951
+ if (v !== undefined && v !== null)
3952
+ extra[s.key] = v;
3953
+ }
3954
+ const nextContext = { ...current, extra };
3955
+ if (!isEqual(nextContext, current)) {
3956
+ this.internalContext.set(nextContext);
3957
+ }
3958
+ }, ...(ngDevMode ? [{ debugName: "syncContextFromInputs" }] : []));
3959
+ this.clearOnSchemaTypeChange = effect(() => {
3960
+ const schema = this.schema();
3961
+ const changedKeys = new Set();
3962
+ for (const s of schema) {
3963
+ const prev = this.lastTypeByKey[s.key];
3964
+ if (prev && prev !== s.type)
3965
+ changedKeys.add(s.key);
3966
+ this.lastTypeByKey[s.key] = s.type;
3967
+ }
3968
+ if (changedKeys.size > 0) {
3969
+ const next = { ...this.values() };
3970
+ changedKeys.forEach((k) => delete next[k]);
3971
+ // reset cached node defaults
3972
+ changedKeys.forEach((k) => {
3973
+ const node = this.nodeCache[k];
3974
+ if (node)
3975
+ node.defaultValue = undefined;
3976
+ });
3977
+ this.valuesChange.emit(next);
3978
+ }
3979
+ }, ...(ngDevMode ? [{ debugName: "clearOnSchemaTypeChange" }] : []));
3980
+ }
3981
+ //#endregion
3982
+ //#region ---- Event Handlers ----
3983
+ onContextChanged(event) {
3984
+ if (event.state === 'initiated')
3985
+ return;
3986
+ const data = (event.data ?? {});
3987
+ const extra = data['extra'] ?? {};
3988
+ const nextValues = {};
3989
+ for (const s of this.schema()) {
3990
+ if (Object.prototype.hasOwnProperty.call(extra, s.key)) {
3991
+ nextValues[s.key] = extra[s.key];
3992
+ }
3993
+ }
3994
+ const currentValues = this.values();
3995
+ if (!isEqual(currentValues, nextValues)) {
3996
+ this.valuesChange.emit(nextValues);
3997
+ }
3998
+ }
3999
+ //#endregion
4000
+ //#region ---- Utility Methods ----
4001
+ getNode(item) {
4002
+ const key = item.key;
4003
+ let node = this.nodeCache[key];
4004
+ if (!node) {
4005
+ node = {
4006
+ type: item.type,
4007
+ path: `extra.${item.key}`,
4008
+ options: item.options ?? {},
4009
+ defaultValue: this.values()[item.key],
4010
+ };
4011
+ this.nodeCache[key] = node;
4012
+ }
4013
+ else {
4014
+ // Keep reference stable; update nested fields if essential changes happen
4015
+ node.type = item.type;
4016
+ node.options = item.options ?? node.options;
4017
+ // Do not overwrite defaultValue during editing to avoid resets
4018
+ }
4019
+ return node;
4020
+ }
4021
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPExtraPropertiesValuesComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4022
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.8", type: AXPExtraPropertiesValuesComponent, isStandalone: true, selector: "axp-extra-properties-values", inputs: { schema: { classPropertyName: "schema", publicName: "schema", isSignal: true, isRequired: false, transformFunction: null }, values: { classPropertyName: "values", publicName: "values", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valuesChange: "valuesChange" }, host: { classAttribute: "ax-block ax-flex-1" }, ngImport: i0, template: `
4023
+ <div class="ax-grid ax-grid-cols-12 ax-gap-4">
4024
+ <axp-widgets-container [context]="internalContext()" (onContextChanged)="onContextChanged($event)">
4025
+ <div class="ax-col-span-12 ax-flex ax-flex-col ax-gap-3">
4026
+ @for(item of schema(); track item.key){
4027
+ @if(mode()==='edit'){
4028
+ <ax-form-field>
4029
+ <ax-label [required]="isRequired(item)">{{item.title}}</ax-label>
4030
+ <ng-container
4031
+ axp-widget-renderer
4032
+ [node]="getNode(item)"
4033
+ [mode]="'edit'"
4034
+ ></ng-container>
4035
+ </ax-form-field>
4036
+ } @else {
4037
+ <div class="ax-grid ax-grid-cols-12 ax-gap-1">
4038
+ <div class="ax-font-semibold">{{item.title}}</div>
4039
+ <div class="ax-col-span-12 ax-text-muted">
4040
+ <ng-container
4041
+ axp-widget-renderer
4042
+ [node]="getNode(item)"
4043
+ [mode]="'view'"
4044
+ ></ng-container>
4045
+ </div>
4046
+ </div>
4047
+ }
4048
+ }
4049
+ </div>
4050
+ </axp-widgets-container>
4051
+ </div>
4052
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXPLayoutBuilderModule }, { kind: "component", type: i3$3.AXPWidgetContainerComponent, selector: "axp-widgets-container", inputs: ["context", "functions"], outputs: ["onContextChanged"] }, { kind: "directive", type: i3$3.AXPWidgetRendererDirective, selector: "[axp-widget-renderer]", inputs: ["parentNode", "index", "mode", "node"], outputs: ["onOptionsChanged", "onValueChanged"], exportAs: ["widgetRenderer"] }, { kind: "ngmodule", type: AXFormModule }, { kind: "component", type: i2$4.AXFormFieldComponent, selector: "ax-form-field", inputs: ["labelMode"] }, { kind: "ngmodule", type: AXLabelModule }, { kind: "component", type: i3$2.AXLabelComponent, selector: "ax-label", inputs: ["required", "for"], outputs: ["requiredChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4053
+ }
4054
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPExtraPropertiesValuesComponent, decorators: [{
4055
+ type: Component,
4056
+ args: [{
4057
+ selector: 'axp-extra-properties-values',
4058
+ template: `
4059
+ <div class="ax-grid ax-grid-cols-12 ax-gap-4">
4060
+ <axp-widgets-container [context]="internalContext()" (onContextChanged)="onContextChanged($event)">
4061
+ <div class="ax-col-span-12 ax-flex ax-flex-col ax-gap-3">
4062
+ @for(item of schema(); track item.key){
4063
+ @if(mode()==='edit'){
4064
+ <ax-form-field>
4065
+ <ax-label [required]="isRequired(item)">{{item.title}}</ax-label>
4066
+ <ng-container
4067
+ axp-widget-renderer
4068
+ [node]="getNode(item)"
4069
+ [mode]="'edit'"
4070
+ ></ng-container>
4071
+ </ax-form-field>
4072
+ } @else {
4073
+ <div class="ax-grid ax-grid-cols-12 ax-gap-1">
4074
+ <div class="ax-font-semibold">{{item.title}}</div>
4075
+ <div class="ax-col-span-12 ax-text-muted">
4076
+ <ng-container
4077
+ axp-widget-renderer
4078
+ [node]="getNode(item)"
4079
+ [mode]="'view'"
4080
+ ></ng-container>
4081
+ </div>
4082
+ </div>
4083
+ }
4084
+ }
4085
+ </div>
4086
+ </axp-widgets-container>
4087
+ </div>
4088
+ `,
4089
+ changeDetection: ChangeDetectionStrategy.OnPush,
4090
+ imports: [CommonModule, AXPLayoutBuilderModule, AXFormModule, AXLabelModule],
4091
+ standalone: true,
4092
+ host: {
4093
+ class: 'ax-block ax-flex-1',
4094
+ },
4095
+ }]
4096
+ }] });
4097
+
4098
+ class AXPQueryFiltersComponent {
4099
+ constructor() {
4100
+ this.translate = inject(AXTranslationService);
4101
+ this.calendarService = inject(AXCalendarService);
4102
+ this.filterOperatorMiddleware = inject(AXPFilterOperatorMiddlewareService);
4103
+ this.filtersDefinitions = input([], ...(ngDevMode ? [{ debugName: "filtersDefinitions" }] : []));
4104
+ this.initialFilters = input([], ...(ngDevMode ? [{ debugName: "initialFilters" }] : []));
4105
+ this.onFiltersChanged = output();
4106
+ this.tagBox = viewChild('tagBox', ...(ngDevMode ? [{ debugName: "tagBox" }] : []));
4107
+ this.selectedField = signal(null, ...(ngDevMode ? [{ debugName: "selectedField" }] : []));
4108
+ this.selectedFilters = linkedSignal(() => this.convertQueriesToDefinitions(this.initialFilters()), {
4109
+ equal: isEqual,
4110
+ });
4111
+ this.context = linkedSignal(() => this.convertQueriesToContext(this.initialFilters()));
4112
+ this.activeFilter = signal(null, ...(ngDevMode ? [{ debugName: "activeFilter" }] : []));
4113
+ this.asyncTags = signal([], ...(ngDevMode ? [{ debugName: "asyncTags" }] : []));
4114
+ this.popover = viewChild('popover', ...(ngDevMode ? [{ debugName: "popover" }] : []));
4115
+ this.inputValue = signal('', ...(ngDevMode ? [{ debugName: "inputValue" }] : []));
4116
+ this.inlineFilters = () => {
4117
+ return this.filtersDefinitions().filter((f) => f.filterType.inline &&
4118
+ !this.filterOperatorMiddleware
4119
+ .transformFilters(this.selectedFilters())
4120
+ .some((sf) => sf.field === f.field &&
4121
+ sf.operator?.type === (this.context()[sf.field]?.operation?.type || f.operator?.type)));
4122
+ };
1235
4123
  this.getDisplayValue = async (filter, val) => {
1236
- if (filter.widget.type === 'select-editor' || filter.widget.type === 'select-filter') {
4124
+ if (filter.widget?.type === 'select-editor' || filter.widget?.type === 'select-filter') {
1237
4125
  const dataSource = filter.widget.options?.['dataSource'];
1238
4126
  const textField = filter.widget.options?.['textField'];
1239
4127
  const valueField = filter.widget.options?.['valueField'];
@@ -1284,6 +4172,7 @@ class AXPLayoutFiltersComponent {
1284
4172
  field: f.field,
1285
4173
  operator: context[f.field]?.operation,
1286
4174
  value: context[f.field]?.value,
4175
+ hidden: f.hidden,
1287
4176
  }));
1288
4177
  const newContext = {};
1289
4178
  convertedFilters.forEach((cf) => {
@@ -1308,7 +4197,7 @@ class AXPLayoutFiltersComponent {
1308
4197
  query: `${this.translate.translateSync(filter.title)} ${this.getActiveOperator(filter)} '${displayValue}'`,
1309
4198
  };
1310
4199
  })).then((results) => {
1311
- this.asyncTags.set(results);
4200
+ this.asyncTags.set(results.filter((r) => !r.hidden));
1312
4201
  });
1313
4202
  }, ...(ngDevMode ? [{ debugName: "#effect2" }] : []));
1314
4203
  }
@@ -1323,6 +4212,7 @@ class AXPLayoutFiltersComponent {
1323
4212
  title: definition?.title || '',
1324
4213
  widget: definition?.widget,
1325
4214
  filterType: definition?.filterType,
4215
+ hidden: q.hidden,
1326
4216
  };
1327
4217
  });
1328
4218
  }
@@ -1336,6 +4226,7 @@ class AXPLayoutFiltersComponent {
1336
4226
  this.tagBoxInput = this.tagBox()?.getHostElement().querySelector('input');
1337
4227
  }
1338
4228
  handleSelectField(field) {
4229
+ console.log(field);
1339
4230
  this.activeFilter.set(field);
1340
4231
  // this.inputValue.set('');
1341
4232
  this.tagBox()?.inputValue.set('');
@@ -1383,8 +4274,9 @@ class AXPLayoutFiltersComponent {
1383
4274
  #effect;
1384
4275
  handleSelectFilters(e) {
1385
4276
  if (e.value?.length < this.selectedFilters().length) {
4277
+ const hiddenFilters = this.selectedFilters().filter((f) => f.hidden);
1386
4278
  this.selectedFilters.update((prev) => {
1387
- return e.value;
4279
+ return hiddenFilters.concat(e.value);
1388
4280
  });
1389
4281
  }
1390
4282
  }
@@ -1431,12 +4323,12 @@ class AXPLayoutFiltersComponent {
1431
4323
  }
1432
4324
  }
1433
4325
  #effect2;
1434
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPLayoutFiltersComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1435
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", type: AXPLayoutFiltersComponent, isStandalone: true, selector: "axp-layout-filters", inputs: { filtersDefinitions: { classPropertyName: "filtersDefinitions", publicName: "filtersDefinitions", isSignal: true, isRequired: false, transformFunction: null }, initialFilters: { classPropertyName: "initialFilters", publicName: "initialFilters", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onFiltersChanged: "onFiltersChanged" }, viewQueries: [{ propertyName: "tagBox", first: true, predicate: ["tagBox"], descendants: true, isSignal: true }, { propertyName: "popover", first: true, predicate: ["popover"], descendants: true, isSignal: true }, { propertyName: "listItems", predicate: ["caseItem"], descendants: true }], ngImport: i0, template: "<div class=\"ax-flex ax-items-center ax-gap-2 ax-p-2\">\n <ax-button (keydown)=\"handleButtonKeyDown($event)\" (onClick)=\"popover.open()\" #filterButton [look]=\"'blank'\">\n <ax-icon class=\"far fa-bars-filter ax-cursor-pointer\"> </ax-icon>\n </ax-button>\n <ax-tag-box\n [ngModel]=\"asyncTags()\"\n (onValueChanged)=\"handleSelectFilters($event)\"\n [textField]=\"'query'\"\n [valueField]=\"'id'\"\n [readonly]=\"filtersDefinitions().length === 0\"\n [look]=\"'none'\"\n [readonlyField]=\"'readOnly'\"\n (onKeyDown)=\"handleKeyDown($event)\"\n [addOnEnter]=\"false\"\n [placeholder]=\"(filtersDefinitions().length === 0 ? 'filter.noRecords' : 'filter.title') | translate | async\"\n #tagBox\n ></ax-tag-box>\n</div>\n\n<ax-popover\n [offsetY]=\"activeFilter() ? -30 : 0\"\n [target]=\"tagBoxInput\"\n [openOn]=\"'toggle'\"\n (onOpened)=\"onPopoverOpened($event)\"\n [closeOn]=\"'clickOut'\"\n (onClosed)=\"handlePopoverClosed($event)\"\n [adaptivityEnabled]=\"true\"\n #popover\n>\n <div class=\"md:ax-min-w-72 ax-border ax-surface ax-w-full ax-rounded-md md:ax-max-h-96 md:ax-overflow-auto\">\n <axp-widgets-container [context]=\"context()\" (onContextChanged)=\"onContextChanged($event)\">\n @if (activeFilter()) {\n <div class=\"ax-flex ax-flex-col ax-lightest-surface ax-shadow-md\">\n <ax-header class=\"ax-border-b ax-border-light ax-px-4 ax-py-2\">{{\n activeFilter()?.title! | translate | async\n }}</ax-header>\n <ax-content class=\"ax-p-4\">\n <div class=\"ax-mb-2\">\n <ax-badge [text]=\"getActiveOperator(activeFilter())!\"></ax-badge>\n </div>\n <ng-container\n axp-widget-renderer\n [node]=\"{\n type: activeFilter()?.widget?.type || 'text-editor',\n path: activeFilter()?.field,\n options: activeFilter()?.widget?.options,\n }\"\n [mode]=\"'edit'\"\n >\n </ng-container>\n </ax-content>\n <ax-footer class=\"ax-border-t ax-flex ax-justify-end ax-border-light ax-w-full ax-px-4 ax-py-2\">\n <ax-button class=\"ax-xs\" [text]=\"'apply' | translate | async\" (onClick)=\"handleApplyFilter()\"></ax-button>\n </ax-footer>\n </div>\n } @else {\n <div axListNavigation #list=\"axListNavigation\" class=\"axp-list-items\">\n @if (tagBox.inputValue()) {\n @for (inlineFilter of inlineFilters(); track inlineFilter.field) {\n <div\n axListNavigationItem\n #caseItem=\"axListNavigationItem\"\n [class.axp-state-focused]=\"caseItem.isActive()\"\n tabindex=\"0\"\n (click)=\"handleSelectInlineFilter(inlineFilter)\"\n (keydown)=\"handleInlineFilterKeyDown($event, inlineFilter)\"\n >\n {{ inlineFilter.title | translate | async }} {{ getActiveOperator(inlineFilter) }} '{{\n tagBox.inputValue()\n }}'\n </div>\n }\n <span class=\"ax-w-full ax-border-t ax-border-light ax-my-1\"></span>\n }\n @for (field of filterFields(); track field.field) {\n <div\n axListNavigationItem\n #caseItem=\"axListNavigationItem\"\n [class.axp-state-focused]=\"caseItem.isActive()\"\n (click)=\"handleSelectField(field)\"\n (keydown)=\"handleFieldKeyDown($event, field)\"\n tabindex=\"0\"\n >\n <div class=\"ax-flex ax-items-end ax-gap-2\">\n <ax-icon class=\"ax-w-5\" [class]=\"'fa-light ' + field.icon\"> </ax-icon>\n {{ field.title | translate | async }}\n </div>\n </div>\n }\n </div>\n }\n </axp-widgets-container>\n </div>\n</ax-popover>\n", styles: ["axp-layout-filters{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i2$2.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i3.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i3.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: AXPopoverModule }, { kind: "component", type: i4$1.AXPopoverComponent, selector: "ax-popover", inputs: ["width", "disabled", "offsetX", "offsetY", "target", "placement", "content", "openOn", "closeOn", "hasBackdrop", "openAfter", "closeAfter", "backdropClass", "panelClass", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "ngmodule", type: AXSelectionListModule }, { kind: "ngmodule", type: AXTagBoxModule }, { kind: "component", type: i5$1.AXTagBoxComponent, selector: "ax-tag-box", inputs: ["disabled", "tabIndex", "readonly", "value", "state", "name", "id", "placeholder", "allowNull", "type", "look", "addOnComma", "addOnEnter", "valueField", "textField", "readonlyField", "allowDuplicateValues"], outputs: ["onBlur", "onFocus", "valueChange", "stateChange", "onValueChanged", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "ngmodule", type: AXPLayoutBuilderModule }, { kind: "component", type: i3$2.AXPWidgetContainerComponent, selector: "axp-widgets-container", inputs: ["context", "functions"], outputs: ["onContextChanged"] }, { kind: "directive", type: i3$2.AXPWidgetRendererDirective, selector: "[axp-widget-renderer]", inputs: ["parentNode", "index", "mode", "node"], outputs: ["onOptionsChanged", "onValueChanged"], exportAs: ["widgetRenderer"] }, { kind: "ngmodule", type: AXListNavigationModule }, { kind: "directive", type: i7.AXListNavigationDirective, selector: "[axListNavigation]", inputs: ["orientation"], outputs: ["onNavigationChanged", "onPressEnterOrSpace"], exportAs: ["axListNavigation"] }, { kind: "directive", type: i7.AXListNavigationItemDirective, selector: "[axListNavigationItem]", exportAs: ["axListNavigationItem"] }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "component", type: i8.AXBadgeComponent, selector: "ax-badge", inputs: ["color", "look", "text"] }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }, { kind: "pipe", type: i2.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
4326
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPQueryFiltersComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4327
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.8", type: AXPQueryFiltersComponent, isStandalone: true, selector: "axp-query-filters", inputs: { filtersDefinitions: { classPropertyName: "filtersDefinitions", publicName: "filtersDefinitions", isSignal: true, isRequired: false, transformFunction: null }, initialFilters: { classPropertyName: "initialFilters", publicName: "initialFilters", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onFiltersChanged: "onFiltersChanged" }, viewQueries: [{ propertyName: "tagBox", first: true, predicate: ["tagBox"], descendants: true, isSignal: true }, { propertyName: "popover", first: true, predicate: ["popover"], descendants: true, isSignal: true }, { propertyName: "listItems", predicate: ["caseItem"], descendants: true }], ngImport: i0, template: "<div class=\"ax-flex ax-items-center ax-gap-2 ax-p-2\">\n <ax-button (keydown)=\"handleButtonKeyDown($event)\" (onClick)=\"popover.open()\" #filterButton [look]=\"'blank'\">\n <ax-icon class=\"far fa-bars-filter ax-cursor-pointer\"> </ax-icon>\n </ax-button>\n <ax-tag-box\n [ngModel]=\"asyncTags()\"\n (onValueChanged)=\"handleSelectFilters($event)\"\n [textField]=\"'query'\"\n [valueField]=\"'id'\"\n [readonly]=\"filtersDefinitions().length === 0\"\n [look]=\"'none'\"\n [readonlyField]=\"'readOnly'\"\n (onKeyDown)=\"handleKeyDown($event)\"\n [addOnEnter]=\"false\"\n [placeholder]=\"\n (filtersDefinitions().length === 0\n ? '@general:terms.interface.filter.no-filter-definitions'\n : '@general:terms.interface.filter.placeholder'\n )\n | translate\n | async\n \"\n #tagBox\n ></ax-tag-box>\n</div>\n\n<ax-popover\n [offsetY]=\"activeFilter() ? -30 : 0\"\n [target]=\"tagBoxInput\"\n [openOn]=\"'toggle'\"\n (onOpened)=\"onPopoverOpened($event)\"\n [closeOn]=\"'clickOut'\"\n (onClosed)=\"handlePopoverClosed($event)\"\n [adaptivityEnabled]=\"true\"\n #popover\n>\n <div class=\"md:ax-min-w-72 ax-border ax-surface ax-w-full ax-rounded-md md:ax-max-h-96 md:ax-overflow-auto\">\n <axp-widgets-container [context]=\"context()\" (onContextChanged)=\"onContextChanged($event)\">\n @if (activeFilter()) {\n <div class=\"ax-flex ax-flex-col ax-lightest-surface ax-shadow-md\">\n <ax-header class=\"ax-border-b ax-border-light ax-px-4 ax-py-2\">{{\n activeFilter()?.title! | translate | async\n }}</ax-header>\n <ax-content class=\"ax-p-4\">\n <div class=\"ax-mb-2\">\n <ax-badge [text]=\"getActiveOperator(activeFilter())!\"></ax-badge>\n </div>\n <ng-container\n axp-widget-renderer\n [node]=\"{\n type: activeFilter()?.widget?.type || 'text-editor',\n path: activeFilter()?.field,\n options: activeFilter()?.widget?.options,\n }\"\n [mode]=\"'edit'\"\n >\n </ng-container>\n </ax-content>\n <ax-footer class=\"ax-border-t ax-flex ax-justify-end ax-border-light ax-w-full ax-px-4 ax-py-2\">\n <ax-button\n class=\"ax-xs\"\n [text]=\"'@general:actions.apply.title' | translate | async\"\n (onClick)=\"handleApplyFilter()\"\n ></ax-button>\n </ax-footer>\n </div>\n } @else {\n <div axListNavigation #list=\"axListNavigation\" class=\"axp-list-items\">\n @if (tagBox.inputValue()) {\n @for (inlineFilter of inlineFilters(); track inlineFilter.field) {\n <div\n axListNavigationItem\n #caseItem=\"axListNavigationItem\"\n [class.axp-state-focused]=\"caseItem.isActive()\"\n tabindex=\"0\"\n (click)=\"handleSelectInlineFilter(inlineFilter)\"\n (keydown)=\"handleInlineFilterKeyDown($event, inlineFilter)\"\n >\n {{ inlineFilter.title | translate | async }} {{ getActiveOperator(inlineFilter) }} '{{\n tagBox.inputValue()\n }}'\n </div>\n }\n <span class=\"ax-w-full ax-border-t ax-border-light ax-my-1\"></span>\n }\n @for (field of filterFields(); track field.field) {\n <div\n axListNavigationItem\n #caseItem=\"axListNavigationItem\"\n [class.axp-state-focused]=\"caseItem.isActive()\"\n (click)=\"handleSelectField(field)\"\n (keydown)=\"handleFieldKeyDown($event, field)\"\n tabindex=\"0\"\n >\n <div class=\"ax-flex ax-items-end ax-gap-2\">\n <ax-icon class=\"ax-w-5\" [class]=\"'fa-light ' + field.icon\"> </ax-icon>\n {{ field.title | translate | async }}\n </div>\n </div>\n }\n </div>\n }\n </axp-widgets-container>\n </div>\n</ax-popover>\n", styles: ["axp-query-filters{width:100%}.axp-list-items{display:flex;min-width:10rem;flex-direction:column;border-radius:.375rem;border-width:1px;padding-top:1rem;padding-bottom:1rem;--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow);background-color:rgb(var(--ax-sys-color-lightest-surface));color:rgb(var(--ax-sys-color-on-lightest-surface));border-color:rgb(var(--ax-sys-color-border-lightest-surface))}.axp-list-items>div{min-width:7rem;cursor:pointer;padding:.5rem 1rem;text-align:start}.axp-list-items>div:focus{outline:none}.axp-list-items>div.axp-state-focused,.axp-list-items>div:hover{background-color:rgb(var(--ax-sys-color-surface));color:rgb(var(--ax-sys-color-on-surface));border-color:rgb(var(--ax-sys-color-border-surface))}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i3.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i2$1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: AXPopoverModule }, { kind: "component", type: i4$5.AXPopoverComponent, selector: "ax-popover", inputs: ["width", "disabled", "offsetX", "offsetY", "target", "placement", "content", "openOn", "closeOn", "hasBackdrop", "openAfter", "closeAfter", "backdropClass", "panelClass", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "ngmodule", type: AXSelectionListModule }, { kind: "ngmodule", type: AXTagBoxModule }, { kind: "component", type: i5$3.AXTagBoxComponent, selector: "ax-tag-box", inputs: ["disabled", "tabIndex", "readonly", "value", "state", "name", "id", "placeholder", "allowNull", "type", "look", "addOnComma", "addOnEnter", "valueField", "textField", "readonlyField", "allowDuplicateValues"], outputs: ["onBlur", "onFocus", "valueChange", "stateChange", "onValueChanged", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "ngmodule", type: AXPLayoutBuilderModule }, { kind: "component", type: i3$3.AXPWidgetContainerComponent, selector: "axp-widgets-container", inputs: ["context", "functions"], outputs: ["onContextChanged"] }, { kind: "directive", type: i3$3.AXPWidgetRendererDirective, selector: "[axp-widget-renderer]", inputs: ["parentNode", "index", "mode", "node"], outputs: ["onOptionsChanged", "onValueChanged"], exportAs: ["widgetRenderer"] }, { kind: "ngmodule", type: AXListNavigationModule }, { kind: "directive", type: i7.AXListNavigationDirective, selector: "[axListNavigation]", inputs: ["orientation"], outputs: ["onNavigationChanged", "onPressEnterOrSpace"], exportAs: ["axListNavigation"] }, { kind: "directive", type: i7.AXListNavigationItemDirective, selector: "[axListNavigationItem]", exportAs: ["axListNavigationItem"] }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "component", type: i8.AXBadgeComponent, selector: "ax-badge", inputs: ["color", "look", "text"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
1436
4328
  }
1437
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPLayoutFiltersComponent, decorators: [{
4329
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPQueryFiltersComponent, decorators: [{
1438
4330
  type: Component,
1439
- args: [{ selector: 'axp-layout-filters', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [
4331
+ args: [{ selector: 'axp-query-filters', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [
1440
4332
  CommonModule,
1441
4333
  FormsModule,
1442
4334
  AXButtonModule,
@@ -1448,12 +4340,250 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
1448
4340
  AXPLayoutBuilderModule,
1449
4341
  AXListNavigationModule,
1450
4342
  AXBadgeModule,
1451
- ], template: "<div class=\"ax-flex ax-items-center ax-gap-2 ax-p-2\">\n <ax-button (keydown)=\"handleButtonKeyDown($event)\" (onClick)=\"popover.open()\" #filterButton [look]=\"'blank'\">\n <ax-icon class=\"far fa-bars-filter ax-cursor-pointer\"> </ax-icon>\n </ax-button>\n <ax-tag-box\n [ngModel]=\"asyncTags()\"\n (onValueChanged)=\"handleSelectFilters($event)\"\n [textField]=\"'query'\"\n [valueField]=\"'id'\"\n [readonly]=\"filtersDefinitions().length === 0\"\n [look]=\"'none'\"\n [readonlyField]=\"'readOnly'\"\n (onKeyDown)=\"handleKeyDown($event)\"\n [addOnEnter]=\"false\"\n [placeholder]=\"(filtersDefinitions().length === 0 ? 'filter.noRecords' : 'filter.title') | translate | async\"\n #tagBox\n ></ax-tag-box>\n</div>\n\n<ax-popover\n [offsetY]=\"activeFilter() ? -30 : 0\"\n [target]=\"tagBoxInput\"\n [openOn]=\"'toggle'\"\n (onOpened)=\"onPopoverOpened($event)\"\n [closeOn]=\"'clickOut'\"\n (onClosed)=\"handlePopoverClosed($event)\"\n [adaptivityEnabled]=\"true\"\n #popover\n>\n <div class=\"md:ax-min-w-72 ax-border ax-surface ax-w-full ax-rounded-md md:ax-max-h-96 md:ax-overflow-auto\">\n <axp-widgets-container [context]=\"context()\" (onContextChanged)=\"onContextChanged($event)\">\n @if (activeFilter()) {\n <div class=\"ax-flex ax-flex-col ax-lightest-surface ax-shadow-md\">\n <ax-header class=\"ax-border-b ax-border-light ax-px-4 ax-py-2\">{{\n activeFilter()?.title! | translate | async\n }}</ax-header>\n <ax-content class=\"ax-p-4\">\n <div class=\"ax-mb-2\">\n <ax-badge [text]=\"getActiveOperator(activeFilter())!\"></ax-badge>\n </div>\n <ng-container\n axp-widget-renderer\n [node]=\"{\n type: activeFilter()?.widget?.type || 'text-editor',\n path: activeFilter()?.field,\n options: activeFilter()?.widget?.options,\n }\"\n [mode]=\"'edit'\"\n >\n </ng-container>\n </ax-content>\n <ax-footer class=\"ax-border-t ax-flex ax-justify-end ax-border-light ax-w-full ax-px-4 ax-py-2\">\n <ax-button class=\"ax-xs\" [text]=\"'apply' | translate | async\" (onClick)=\"handleApplyFilter()\"></ax-button>\n </ax-footer>\n </div>\n } @else {\n <div axListNavigation #list=\"axListNavigation\" class=\"axp-list-items\">\n @if (tagBox.inputValue()) {\n @for (inlineFilter of inlineFilters(); track inlineFilter.field) {\n <div\n axListNavigationItem\n #caseItem=\"axListNavigationItem\"\n [class.axp-state-focused]=\"caseItem.isActive()\"\n tabindex=\"0\"\n (click)=\"handleSelectInlineFilter(inlineFilter)\"\n (keydown)=\"handleInlineFilterKeyDown($event, inlineFilter)\"\n >\n {{ inlineFilter.title | translate | async }} {{ getActiveOperator(inlineFilter) }} '{{\n tagBox.inputValue()\n }}'\n </div>\n }\n <span class=\"ax-w-full ax-border-t ax-border-light ax-my-1\"></span>\n }\n @for (field of filterFields(); track field.field) {\n <div\n axListNavigationItem\n #caseItem=\"axListNavigationItem\"\n [class.axp-state-focused]=\"caseItem.isActive()\"\n (click)=\"handleSelectField(field)\"\n (keydown)=\"handleFieldKeyDown($event, field)\"\n tabindex=\"0\"\n >\n <div class=\"ax-flex ax-items-end ax-gap-2\">\n <ax-icon class=\"ax-w-5\" [class]=\"'fa-light ' + field.icon\"> </ax-icon>\n {{ field.title | translate | async }}\n </div>\n </div>\n }\n </div>\n }\n </axp-widgets-container>\n </div>\n</ax-popover>\n", styles: ["axp-layout-filters{width:100%}\n"] }]
4343
+ ], template: "<div class=\"ax-flex ax-items-center ax-gap-2 ax-p-2\">\n <ax-button (keydown)=\"handleButtonKeyDown($event)\" (onClick)=\"popover.open()\" #filterButton [look]=\"'blank'\">\n <ax-icon class=\"far fa-bars-filter ax-cursor-pointer\"> </ax-icon>\n </ax-button>\n <ax-tag-box\n [ngModel]=\"asyncTags()\"\n (onValueChanged)=\"handleSelectFilters($event)\"\n [textField]=\"'query'\"\n [valueField]=\"'id'\"\n [readonly]=\"filtersDefinitions().length === 0\"\n [look]=\"'none'\"\n [readonlyField]=\"'readOnly'\"\n (onKeyDown)=\"handleKeyDown($event)\"\n [addOnEnter]=\"false\"\n [placeholder]=\"\n (filtersDefinitions().length === 0\n ? '@general:terms.interface.filter.no-filter-definitions'\n : '@general:terms.interface.filter.placeholder'\n )\n | translate\n | async\n \"\n #tagBox\n ></ax-tag-box>\n</div>\n\n<ax-popover\n [offsetY]=\"activeFilter() ? -30 : 0\"\n [target]=\"tagBoxInput\"\n [openOn]=\"'toggle'\"\n (onOpened)=\"onPopoverOpened($event)\"\n [closeOn]=\"'clickOut'\"\n (onClosed)=\"handlePopoverClosed($event)\"\n [adaptivityEnabled]=\"true\"\n #popover\n>\n <div class=\"md:ax-min-w-72 ax-border ax-surface ax-w-full ax-rounded-md md:ax-max-h-96 md:ax-overflow-auto\">\n <axp-widgets-container [context]=\"context()\" (onContextChanged)=\"onContextChanged($event)\">\n @if (activeFilter()) {\n <div class=\"ax-flex ax-flex-col ax-lightest-surface ax-shadow-md\">\n <ax-header class=\"ax-border-b ax-border-light ax-px-4 ax-py-2\">{{\n activeFilter()?.title! | translate | async\n }}</ax-header>\n <ax-content class=\"ax-p-4\">\n <div class=\"ax-mb-2\">\n <ax-badge [text]=\"getActiveOperator(activeFilter())!\"></ax-badge>\n </div>\n <ng-container\n axp-widget-renderer\n [node]=\"{\n type: activeFilter()?.widget?.type || 'text-editor',\n path: activeFilter()?.field,\n options: activeFilter()?.widget?.options,\n }\"\n [mode]=\"'edit'\"\n >\n </ng-container>\n </ax-content>\n <ax-footer class=\"ax-border-t ax-flex ax-justify-end ax-border-light ax-w-full ax-px-4 ax-py-2\">\n <ax-button\n class=\"ax-xs\"\n [text]=\"'@general:actions.apply.title' | translate | async\"\n (onClick)=\"handleApplyFilter()\"\n ></ax-button>\n </ax-footer>\n </div>\n } @else {\n <div axListNavigation #list=\"axListNavigation\" class=\"axp-list-items\">\n @if (tagBox.inputValue()) {\n @for (inlineFilter of inlineFilters(); track inlineFilter.field) {\n <div\n axListNavigationItem\n #caseItem=\"axListNavigationItem\"\n [class.axp-state-focused]=\"caseItem.isActive()\"\n tabindex=\"0\"\n (click)=\"handleSelectInlineFilter(inlineFilter)\"\n (keydown)=\"handleInlineFilterKeyDown($event, inlineFilter)\"\n >\n {{ inlineFilter.title | translate | async }} {{ getActiveOperator(inlineFilter) }} '{{\n tagBox.inputValue()\n }}'\n </div>\n }\n <span class=\"ax-w-full ax-border-t ax-border-light ax-my-1\"></span>\n }\n @for (field of filterFields(); track field.field) {\n <div\n axListNavigationItem\n #caseItem=\"axListNavigationItem\"\n [class.axp-state-focused]=\"caseItem.isActive()\"\n (click)=\"handleSelectField(field)\"\n (keydown)=\"handleFieldKeyDown($event, field)\"\n tabindex=\"0\"\n >\n <div class=\"ax-flex ax-items-end ax-gap-2\">\n <ax-icon class=\"ax-w-5\" [class]=\"'fa-light ' + field.icon\"> </ax-icon>\n {{ field.title | translate | async }}\n </div>\n </div>\n }\n </div>\n }\n </axp-widgets-container>\n </div>\n</ax-popover>\n", styles: ["axp-query-filters{width:100%}.axp-list-items{display:flex;min-width:10rem;flex-direction:column;border-radius:.375rem;border-width:1px;padding-top:1rem;padding-bottom:1rem;--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow);background-color:rgb(var(--ax-sys-color-lightest-surface));color:rgb(var(--ax-sys-color-on-lightest-surface));border-color:rgb(var(--ax-sys-color-border-lightest-surface))}.axp-list-items>div{min-width:7rem;cursor:pointer;padding:.5rem 1rem;text-align:start}.axp-list-items>div:focus{outline:none}.axp-list-items>div.axp-state-focused,.axp-list-items>div:hover{background-color:rgb(var(--ax-sys-color-surface));color:rgb(var(--ax-sys-color-on-surface));border-color:rgb(var(--ax-sys-color-border-surface))}\n"] }]
1452
4344
  }], propDecorators: { listItems: [{
1453
4345
  type: ViewChildren,
1454
4346
  args: ['caseItem']
1455
4347
  }] } });
1456
4348
 
4349
+ class AXPQuerySortsComponent {
4350
+ constructor() {
4351
+ this.sortDefinitions = model([], ...(ngDevMode ? [{ debugName: "sortDefinitions" }] : []));
4352
+ this.sortQueries = signal([], ...(ngDevMode ? [{ debugName: "sortQueries", equal: isEqual }] : [{
4353
+ equal: isEqual,
4354
+ }]));
4355
+ this.initialSortQueries = input([], ...(ngDevMode ? [{ debugName: "initialSortQueries" }] : []));
4356
+ this.sortQueriesChange = output();
4357
+ // Recompute merged sort queries whenever inputs change
4358
+ effect(() => {
4359
+ const initialQueries = this.initialSortQueries();
4360
+ const definitions = this.sortDefinitions();
4361
+ const existingQueriesMap = new Map(initialQueries.map((q) => [q.name, q]));
4362
+ const mergedQueries = definitions.map((def) => {
4363
+ const existingQuery = existingQueriesMap.get(def.name);
4364
+ return existingQuery ? { ...def, dir: existingQuery.dir } : { ...def };
4365
+ });
4366
+ this.sortQueries.set(mergedQueries);
4367
+ });
4368
+ effect(() => {
4369
+ this.sortQueriesChange.emit(this.sortQueries());
4370
+ });
4371
+ }
4372
+ drop(event) {
4373
+ const sd = this.sortDefinitions();
4374
+ moveItemInArray(sd, event.previousIndex, event.currentIndex);
4375
+ this.sortDefinitions.set([...sd]);
4376
+ // Reorder sortQueries based on new sortDefinitions order
4377
+ const sq = this.sortQueries();
4378
+ moveItemInArray(sq, event.previousIndex, event.currentIndex);
4379
+ this.sortQueries.set([...sq]);
4380
+ }
4381
+ getSortDirection(item) {
4382
+ return this.sortQueries().find((i) => i.name === item.name)?.dir;
4383
+ }
4384
+ changeItemSort(item) {
4385
+ const itemDirection = this.getSortDirection(item);
4386
+ const newDirection = itemDirection === 'asc' ? 'desc' : itemDirection === 'desc' ? undefined : 'asc';
4387
+ this.sortQueries.update((prev) => {
4388
+ return prev.map((field) => {
4389
+ if (field.name === item.name) {
4390
+ return { ...field, dir: newDirection };
4391
+ }
4392
+ return field;
4393
+ });
4394
+ });
4395
+ }
4396
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPQuerySortsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4397
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.8", type: AXPQuerySortsComponent, isStandalone: true, selector: "axp-query-sorts", inputs: { sortDefinitions: { classPropertyName: "sortDefinitions", publicName: "sortDefinitions", isSignal: true, isRequired: false, transformFunction: null }, initialSortQueries: { classPropertyName: "initialSortQueries", publicName: "initialSortQueries", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { sortDefinitions: "sortDefinitionsChange", sortQueriesChange: "sortQueriesChange" }, ngImport: i0, template: "<div class=\"ax-flex ax-flex-col ax-justify-center ax-gap-4 ax-select-none\">\n <div class=\"ax-flex ax-flex-col ax-gap-4 ax-select-none\" cdkDropList (cdkDropListDropped)=\"drop($event)\">\n <div class=\"ax-flex ax-flex-col ax-gap-3 ax-w-full ax-sorted-list ax-max-h-[calc(100vh-280px)] ax-overflow-auto\">\n @for (item of sortDefinitions(); track item.name) {\n <div class=\"ax-flex ax-py-1 ax-items-center ax-justify-between\" cdkDrag cdkDragBoundary=\".ax-sorted-list\">\n <div class=\"ax-flex ax-items-center ax-gap-3\" cdkDragHandle>\n <ax-icon class=\"fa-solid fa-grip-dots-vertical ax-cursor-move\"></ax-icon>\n <p class=\"ax-font-medium ax-text-sm\">{{ item.title | translate | async }}</p>\n </div>\n <ax-button [color]=\"'blank'\" class=\"ax-sm\" (click)=\"changeItemSort(item)\">\n <ax-icon\n [class.ax-text-primary]=\"getSortDirection(item) === 'asc'\"\n class=\"fa-solid fa-arrow-up-long ax-text-neutral-400\"\n ></ax-icon>\n <ax-icon\n [class.ax-text-primary]=\"getSortDirection(item) === 'desc'\"\n class=\"fa-solid fa-arrow-down-long ax-text-neutral-400\"\n ></ax-icon>\n </ax-button>\n </div>\n }\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "ngmodule", type: AXTabsModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i3.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
4398
+ }
4399
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPQuerySortsComponent, decorators: [{
4400
+ type: Component,
4401
+ args: [{ selector: 'axp-query-sorts', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [
4402
+ CdkDropList,
4403
+ CdkDrag,
4404
+ CdkDragHandle,
4405
+ AXTabsModule,
4406
+ AXTranslationModule,
4407
+ CommonModule,
4408
+ AXDecoratorModule,
4409
+ AXButtonModule,
4410
+ ], template: "<div class=\"ax-flex ax-flex-col ax-justify-center ax-gap-4 ax-select-none\">\n <div class=\"ax-flex ax-flex-col ax-gap-4 ax-select-none\" cdkDropList (cdkDropListDropped)=\"drop($event)\">\n <div class=\"ax-flex ax-flex-col ax-gap-3 ax-w-full ax-sorted-list ax-max-h-[calc(100vh-280px)] ax-overflow-auto\">\n @for (item of sortDefinitions(); track item.name) {\n <div class=\"ax-flex ax-py-1 ax-items-center ax-justify-between\" cdkDrag cdkDragBoundary=\".ax-sorted-list\">\n <div class=\"ax-flex ax-items-center ax-gap-3\" cdkDragHandle>\n <ax-icon class=\"fa-solid fa-grip-dots-vertical ax-cursor-move\"></ax-icon>\n <p class=\"ax-font-medium ax-text-sm\">{{ item.title | translate | async }}</p>\n </div>\n <ax-button [color]=\"'blank'\" class=\"ax-sm\" (click)=\"changeItemSort(item)\">\n <ax-icon\n [class.ax-text-primary]=\"getSortDirection(item) === 'asc'\"\n class=\"fa-solid fa-arrow-up-long ax-text-neutral-400\"\n ></ax-icon>\n <ax-icon\n [class.ax-text-primary]=\"getSortDirection(item) === 'desc'\"\n class=\"fa-solid fa-arrow-down-long ax-text-neutral-400\"\n ></ax-icon>\n </ax-button>\n </div>\n }\n </div>\n </div>\n</div>\n" }]
4411
+ }], ctorParameters: () => [] });
4412
+
4413
+ class AXPTemplateViewerComponent extends AXBasePageComponent {
4414
+ constructor() {
4415
+ super(...arguments);
4416
+ //#endregion
4417
+ //#region ---- Component State ----
4418
+ this.context = {};
4419
+ this.document = signal({ type: AXPWidgetsCatalog.document }, ...(ngDevMode ? [{ debugName: "document" }] : []));
4420
+ this.currentPageIndex = signal(0, ...(ngDevMode ? [{ debugName: "currentPageIndex" }] : []));
4421
+ this._config = signal(undefined, ...(ngDevMode ? [{ debugName: "_config" }] : []));
4422
+ this.currentPage = computed(() => {
4423
+ return (this.document().children?.[this.currentPageIndex()] ?? { type: AXPWidgetsCatalog.pageLayout });
4424
+ }, ...(ngDevMode ? [{ debugName: "currentPage" }] : []));
4425
+ }
4426
+ //#region ---- Input Properties ----
4427
+ set config(value) {
4428
+ this._config.set(value);
4429
+ }
4430
+ get config() {
4431
+ return this._config();
4432
+ }
4433
+ //#endregion
4434
+ //#region ---- Lifecycle Methods ----
4435
+ async ngOnInit() {
4436
+ super.ngOnInit();
4437
+ await this.loadTemplate();
4438
+ }
4439
+ //#endregion
4440
+ //#region ---- Template Loading ----
4441
+ async loadTemplate() {
4442
+ const config = this.config;
4443
+ if (!config)
4444
+ return;
4445
+ let templateData;
4446
+ if (typeof config.template === 'string') {
4447
+ try {
4448
+ templateData = JSON.parse(config.template);
4449
+ }
4450
+ catch (error) {
4451
+ console.error('Failed to parse template JSON:', error);
4452
+ return;
4453
+ }
4454
+ }
4455
+ else {
4456
+ templateData = config.template;
4457
+ }
4458
+ this.document.set(templateData);
4459
+ // Set initial context if provided
4460
+ if (config.context) {
4461
+ this.context = { ...config.context };
4462
+ }
4463
+ }
4464
+ //#endregion
4465
+ //#region ---- Event Handlers ----
4466
+ handleContextChanged(e) {
4467
+ this.context = e.data;
4468
+ }
4469
+ async handleSubmit(form) {
4470
+ const formResult = await form.validate();
4471
+ if (formResult.result) {
4472
+ this.close({
4473
+ context: this.context,
4474
+ cancelled: false,
4475
+ metadata: this.config?.metadata
4476
+ });
4477
+ }
4478
+ }
4479
+ handleCancel() {
4480
+ this.close({
4481
+ context: this.context,
4482
+ cancelled: true,
4483
+ metadata: this.config?.metadata
4484
+ });
4485
+ }
4486
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPTemplateViewerComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
4487
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.8", type: AXPTemplateViewerComponent, isStandalone: true, selector: "axp-template-viewer", inputs: { config: "config" }, usesInheritance: true, ngImport: i0, template: `
4488
+ <div class="ax-p-4 ax-min-h-64">
4489
+ <ax-form #form>
4490
+ <axp-widgets-container [context]="context" (onContextChanged)="handleContextChanged($event)" >
4491
+ <ng-container axp-widget-renderer [node]="currentPage()" [mode]="config?.readOnly ? 'view' : 'edit'"></ng-container>
4492
+ </axp-widgets-container>
4493
+ </ax-form>
4494
+ </div>
4495
+
4496
+ @if (config?.showActions !== false) {
4497
+ <ax-footer>
4498
+ <ax-suffix>
4499
+ <ax-button [text]="'@general:actions.cancel.title' | translate | async" (onClick)="handleCancel()"></ax-button>
4500
+ @if (!config?.readOnly) {
4501
+ <ax-button color="primary" [text]="'@general:actions.submit.title' | translate | async" (onClick)="handleSubmit(form)"></ax-button>
4502
+ }
4503
+ </ax-suffix>
4504
+ </ax-footer>
4505
+ }
4506
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXPLayoutBuilderModule }, { kind: "component", type: i3$3.AXPWidgetContainerComponent, selector: "axp-widgets-container", inputs: ["context", "functions"], outputs: ["onContextChanged"] }, { kind: "directive", type: i3$3.AXPWidgetRendererDirective, selector: "[axp-widget-renderer]", inputs: ["parentNode", "index", "mode", "node"], outputs: ["onOptionsChanged", "onValueChanged"], exportAs: ["widgetRenderer"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i3.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXFormModule }, { kind: "component", type: i2$4.AXFormComponent, selector: "ax-form", inputs: ["labelMode", "look", "messageStyle", "updateOn"], outputs: ["onValidate", "updateOnChange"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }], encapsulation: i0.ViewEncapsulation.None }); }
4507
+ }
4508
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPTemplateViewerComponent, decorators: [{
4509
+ type: Component,
4510
+ args: [{
4511
+ selector: 'axp-template-viewer',
4512
+ template: `
4513
+ <div class="ax-p-4 ax-min-h-64">
4514
+ <ax-form #form>
4515
+ <axp-widgets-container [context]="context" (onContextChanged)="handleContextChanged($event)" >
4516
+ <ng-container axp-widget-renderer [node]="currentPage()" [mode]="config?.readOnly ? 'view' : 'edit'"></ng-container>
4517
+ </axp-widgets-container>
4518
+ </ax-form>
4519
+ </div>
4520
+
4521
+ @if (config?.showActions !== false) {
4522
+ <ax-footer>
4523
+ <ax-suffix>
4524
+ <ax-button [text]="'@general:actions.cancel.title' | translate | async" (onClick)="handleCancel()"></ax-button>
4525
+ @if (!config?.readOnly) {
4526
+ <ax-button color="primary" [text]="'@general:actions.submit.title' | translate | async" (onClick)="handleSubmit(form)"></ax-button>
4527
+ }
4528
+ </ax-suffix>
4529
+ </ax-footer>
4530
+ }
4531
+ `,
4532
+ encapsulation: ViewEncapsulation.None,
4533
+ imports: [CommonModule, AXPLayoutBuilderModule, AXDecoratorModule, AXButtonModule, AXFormModule, AXTranslationModule]
4534
+ }]
4535
+ }], propDecorators: { config: [{
4536
+ type: Input
4537
+ }] } });
4538
+
4539
+ var templateViewer_component = /*#__PURE__*/Object.freeze({
4540
+ __proto__: null,
4541
+ AXPTemplateViewerComponent: AXPTemplateViewerComponent
4542
+ });
4543
+
4544
+ class AXPTemplateViewerService {
4545
+ constructor() {
4546
+ this.popupService = inject(AXPopupService);
4547
+ }
4548
+ /**
4549
+ * Show a template viewer dialog with the given configuration
4550
+ * @param config Template viewer configuration including template, title, and UI options
4551
+ * @returns Promise resolving to viewer result with form values and cancellation status
4552
+ */
4553
+ async showTemplate(config) {
4554
+ const component = await Promise.resolve().then(function () { return templateViewer_component; }).then(c => c.AXPTemplateViewerComponent);
4555
+ const result = await this.popupService.open(component, {
4556
+ title: config.title || 'Template Viewer',
4557
+ size: config.size || 'lg',
4558
+ closeButton: false,
4559
+ closeOnBackdropClick: false,
4560
+ draggable: false,
4561
+ data: { config }
4562
+ });
4563
+ return result?.data || { context: config.context, cancelled: true, metadata: config.metadata };
4564
+ }
4565
+ /**
4566
+ * Show a template viewer in read-only mode
4567
+ * @param config Template viewer configuration
4568
+ * @returns Promise resolving to viewer result
4569
+ */
4570
+ async showTemplateReadOnly(config) {
4571
+ return this.showTemplate({
4572
+ ...config,
4573
+ readOnly: true,
4574
+ showActions: false
4575
+ });
4576
+ }
4577
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPTemplateViewerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
4578
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPTemplateViewerService, providedIn: 'root' }); }
4579
+ }
4580
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPTemplateViewerService, decorators: [{
4581
+ type: Injectable,
4582
+ args: [{
4583
+ providedIn: 'root'
4584
+ }]
4585
+ }] });
4586
+
1457
4587
  const AXP_USER_AVATAR_PROVIDER = new InjectionToken('AXP_USER_AVATAR_PROVIDER', {
1458
4588
  providedIn: 'root',
1459
4589
  factory: () => {
@@ -1587,10 +4717,10 @@ class AXPUserAvatarService {
1587
4717
  throw error;
1588
4718
  }
1589
4719
  }
1590
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPUserAvatarService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1591
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPUserAvatarService, providedIn: 'root' }); }
4720
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPUserAvatarService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
4721
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPUserAvatarService, providedIn: 'root' }); }
1592
4722
  }
1593
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPUserAvatarService, decorators: [{
4723
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPUserAvatarService, decorators: [{
1594
4724
  type: Injectable,
1595
4725
  args: [{
1596
4726
  providedIn: 'root',
@@ -1680,10 +4810,10 @@ class AXPUserAvatarComponent {
1680
4810
  const idx = this.hashString(initials) % colors.length;
1681
4811
  return colors[idx];
1682
4812
  }
1683
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPUserAvatarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1684
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", type: AXPUserAvatarComponent, isStandalone: true, selector: "axp-user-avatar", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, userId: { classPropertyName: "userId", publicName: "userId", isSignal: true, isRequired: false, transformFunction: null } }, providers: [], ngImport: i0, template: "<ax-avatar #avatar [size]=\"size()\" class=\"ax-cursor-pointer\">\n @if(hasPicture()){\n <ax-image (onError)=\"onImageError($event)\" (onLoad)=\"onImageLoad($event)\" [src]=\"src()\"></ax-image>\n }@else{\n <ax-text class=\"ax-{{ avatarColor() }}-lightest \">\n <small class=\"ax-text-xs ax-font-semibold\">{{ avatarText() }}</small>\n </ax-text>\n }\n</ax-avatar>\n\n<!--\n\nax-primary-lightest\nax-warning-lightest\nax-success-lightest\nax-danger-lightest\nax-secondary-lightest\nax-accent1-lightest\nax-accent2-lightest\nax-accent3-lightest\n\n-->\n", styles: [""], dependencies: [{ kind: "ngmodule", type: AXAvatarModule }, { kind: "component", type: i1$3.AXAvatarComponent, selector: "ax-avatar", inputs: ["color", "size", "shape", "look"], outputs: ["sizeChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i3.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXImageModule }, { kind: "component", type: i3$3.AXImageComponent, selector: "ax-image", inputs: ["width", "height", "overlayMode", "src", "alt", "priority", "lazy"], outputs: ["onLoad", "onError"] }, { kind: "ngmodule", type: AXBadgeModule }], encapsulation: i0.ViewEncapsulation.None }); }
4813
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPUserAvatarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4814
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.8", type: AXPUserAvatarComponent, isStandalone: true, selector: "axp-user-avatar", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, userId: { classPropertyName: "userId", publicName: "userId", isSignal: true, isRequired: false, transformFunction: null } }, providers: [], ngImport: i0, template: "<ax-avatar #avatar [size]=\"size()\" class=\"ax-cursor-pointer\">\n @if(hasPicture()){\n <ax-image (onError)=\"onImageError($event)\" (onLoad)=\"onImageLoad($event)\" [src]=\"src()\"></ax-image>\n }@else{\n <ax-text class=\"ax-{{ avatarColor() }}-lightest \">\n <small class=\"ax-text-xs ax-font-semibold\">{{ avatarText() }}</small>\n </ax-text>\n }\n</ax-avatar>\n\n<!--\n\nax-primary-lightest\nax-warning-lightest\nax-success-lightest\nax-danger-lightest\nax-secondary-lightest\nax-accent1-lightest\nax-accent2-lightest\nax-accent3-lightest\n\n-->\n", styles: [""], dependencies: [{ kind: "ngmodule", type: AXAvatarModule }, { kind: "component", type: i1$5.AXAvatarComponent, selector: "ax-avatar", inputs: ["color", "size", "shape", "look"], outputs: ["sizeChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXImageModule }, { kind: "component", type: i3$4.AXImageComponent, selector: "ax-image", inputs: ["width", "height", "overlayMode", "src", "alt", "priority", "lazy"], outputs: ["onLoad", "onError"] }, { kind: "ngmodule", type: AXBadgeModule }], encapsulation: i0.ViewEncapsulation.None }); }
1685
4815
  }
1686
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPUserAvatarComponent, decorators: [{
4816
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPUserAvatarComponent, decorators: [{
1687
4817
  type: Component,
1688
4818
  args: [{ selector: 'axp-user-avatar', imports: [
1689
4819
  AXAvatarModule,
@@ -1693,6 +4823,46 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
1693
4823
  ], encapsulation: ViewEncapsulation.None, providers: [], template: "<ax-avatar #avatar [size]=\"size()\" class=\"ax-cursor-pointer\">\n @if(hasPicture()){\n <ax-image (onError)=\"onImageError($event)\" (onLoad)=\"onImageLoad($event)\" [src]=\"src()\"></ax-image>\n }@else{\n <ax-text class=\"ax-{{ avatarColor() }}-lightest \">\n <small class=\"ax-text-xs ax-font-semibold\">{{ avatarText() }}</small>\n </ax-text>\n }\n</ax-avatar>\n\n<!--\n\nax-primary-lightest\nax-warning-lightest\nax-success-lightest\nax-danger-lightest\nax-secondary-lightest\nax-accent1-lightest\nax-accent2-lightest\nax-accent3-lightest\n\n-->\n" }]
1694
4824
  }] });
1695
4825
 
4826
+ class AXPQueryViewsComponent {
4827
+ constructor() {
4828
+ this.popupService = inject(AXPopupService);
4829
+ this.translate = inject(AXTranslationService);
4830
+ this.tabs = viewChild('tabs', ...(ngDevMode ? [{ debugName: "tabs" }] : []));
4831
+ this.views = model([], ...(ngDevMode ? [{ debugName: "views" }] : []));
4832
+ this.selectedView = model.required(...(ngDevMode ? [{ debugName: "selectedView" }] : []));
4833
+ this.isMounted = signal(false, ...(ngDevMode ? [{ debugName: "isMounted" }] : []));
4834
+ this.#effect = effect(() => {
4835
+ if (!this.isMounted())
4836
+ return;
4837
+ const views = untracked(() => this.views());
4838
+ if (!views)
4839
+ return;
4840
+ const selectedTab = views.findIndex((v) => v.name == this.selectedView().name);
4841
+ untracked(() => {
4842
+ if (selectedTab != -1) {
4843
+ this.tabs()?.select(selectedTab);
4844
+ }
4845
+ });
4846
+ }, ...(ngDevMode ? [{ debugName: "#effect" }] : []));
4847
+ }
4848
+ ngAfterViewInit() {
4849
+ this.isMounted.set(true);
4850
+ }
4851
+ #effect;
4852
+ setView(view) {
4853
+ this.selectedView.set(view);
4854
+ }
4855
+ handleActiveChange(e) {
4856
+ console.log(e);
4857
+ }
4858
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPQueryViewsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4859
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.8", type: AXPQueryViewsComponent, isStandalone: true, selector: "axp-query-views", inputs: { views: { classPropertyName: "views", publicName: "views", isSignal: true, isRequired: false, transformFunction: null }, selectedView: { classPropertyName: "selectedView", publicName: "selectedView", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { views: "viewsChange", selectedView: "selectedViewChange" }, viewQueries: [{ propertyName: "tabs", first: true, predicate: ["tabs"], descendants: true, isSignal: true }], ngImport: i0, template: "<ax-tabs #tabs [look]=\"'with-line'\" class=\"ax-font-semibold\">\n @for (item of views(); track item.name) {\n <ax-tab-item (onClick)=\"setView(item)\" [key]=\"item.name\" [text]=\"(item.title | translate | async) || 'item.title'\">\n </ax-tab-item>\n }\n <!-- <ax-tab-item\n (onClick)=\"createNew()\"\n [key]=\"'create-new'\"\n [text]=\"('@general:actions.create.title' | translate | async) || 'Create New'\"\n >\n </ax-tab-item> -->\n</ax-tabs>\n", dependencies: [{ kind: "ngmodule", type: AXTabsModule }, { kind: "component", type: i2$5.AXTabsComponent, selector: "ax-tabs", inputs: ["look", "location", "fitParent", "minWidth", "content"], outputs: ["onActiveTabChanged"] }, { kind: "component", type: i2$5.AXTabItemComponent, selector: "ax-tab-item", inputs: ["disabled", "text", "key", "headerTemplate", "active"], outputs: ["disabledChange", "onClick", "onBlur", "onFocus", "activeChange"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: CommonModule }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
4860
+ }
4861
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPQueryViewsComponent, decorators: [{
4862
+ type: Component,
4863
+ args: [{ selector: 'axp-query-views', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [AXTabsModule, AXTranslationModule, CommonModule], template: "<ax-tabs #tabs [look]=\"'with-line'\" class=\"ax-font-semibold\">\n @for (item of views(); track item.name) {\n <ax-tab-item (onClick)=\"setView(item)\" [key]=\"item.name\" [text]=\"(item.title | translate | async) || 'item.title'\">\n </ax-tab-item>\n }\n <!-- <ax-tab-item\n (onClick)=\"createNew()\"\n [key]=\"'create-new'\"\n [text]=\"('@general:actions.create.title' | translate | async) || 'Create New'\"\n >\n </ax-tab-item> -->\n</ax-tabs>\n" }]
4864
+ }] });
4865
+
1696
4866
  /**
1697
4867
  * Generic widget item component for displaying selectable widgets with icons, titles, and descriptions.
1698
4868
  * Can be used across different modules for consistent widget display and interaction.
@@ -1739,10 +4909,10 @@ class AXPWidgetItemComponent {
1739
4909
  getIconClass() {
1740
4910
  return this.widget().icon || 'fa-light fa-document';
1741
4911
  }
1742
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPWidgetItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1743
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", type: AXPWidgetItemComponent, isStandalone: true, selector: "axp-widget-item", inputs: { widget: { classPropertyName: "widget", publicName: "widget", isSignal: true, isRequired: true, transformFunction: null }, isSelected: { classPropertyName: "isSelected", publicName: "isSelected", isSignal: true, isRequired: false, transformFunction: null }, showPinButton: { classPropertyName: "showPinButton", publicName: "showPinButton", isSignal: true, isRequired: false, transformFunction: null }, customClasses: { classPropertyName: "customClasses", publicName: "customClasses", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onWidgetClick: "onWidgetClick", onPinClick: "onPinClick" }, ngImport: i0, template: "<div (click)=\"handleClick($event)\"\n class=\"ax-py-2 ax-px-3 ax-rounded-md ax-flex ax-gap-3 ax-items-center ax-group hover:ax-bg-primary-lightest/65 hover:ax-text-primary-on-lightest ax-cursor-pointer ax-w-full\"\n [class.ax-bg-primary-lightest]=\"isSelected()\" [class.ax-text-primary-on-lightest]=\"isSelected()\"\n [class.ax-border-primary-lightest]=\"isSelected()\" [class]=\"customClasses()\">\n\n <!-- Widget Icon -->\n <div class=\"ax-min-w-10 ax-h-10 ax-flex ax-items-center ax-justify-center ax-rounded-md ax-border group-hover:ax-bg-primary-lighter group-hover:ax-text-primary-on-lighter group-hover:ax-border-primary-lighter\"\n [class.ax-bg-primary-light]=\"isSelected()\" [class.ax-text-primary-on-light]=\"isSelected()\"\n [class.ax-border-primary-light]=\"isSelected()\" [class.ax-surface]=\"!isSelected()\">\n <i [ngClass]=\"getIconClass()\" class=\"ax-text-lg\"></i>\n </div>\n\n <!-- Widget Content -->\n <div class=\"ax-flex ax-flex-col ax-gap-1 ax-flex-1 ax-w-[70%]\">\n <div class=\"ax-flex ax-items-center ax-justify-between ax-gap-2\">\n <!-- Widget Title -->\n <div class=\"ax-font-semibold ax-text-sm ax-truncate\" [title]=\"widget().title\">\n {{ widget().title }}\n </div>\n\n <!-- Pin Button -->\n @if (showPinButton()) {\n <div (click)=\"handlePinClick($event)\" class=\"ax-cursor-pointer\">\n @if (widget().isPinned) {\n <i class=\"fa-solid fa-thumbtack ax-text-sm ax-rotate-45\" title=\"Unpin\"></i>\n } @else {\n <i class=\"fa-light fa-thumbtack ax-text-sm ax-rotate-45 ax-invisible group-hover:ax-visible\"\n title=\"Pin\"></i>\n }\n </div>\n }\n </div>\n\n <!-- Widget Description -->\n @if (widget().description) {\n <span class=\"ax-text-xs ax-truncate\" [title]=\"widget().description\">\n {{ widget().description }}\n </span>\n }\n </div>\n</div>", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], encapsulation: i0.ViewEncapsulation.None }); }
4912
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPWidgetItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4913
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.8", type: AXPWidgetItemComponent, isStandalone: true, selector: "axp-widget-item", inputs: { widget: { classPropertyName: "widget", publicName: "widget", isSignal: true, isRequired: true, transformFunction: null }, isSelected: { classPropertyName: "isSelected", publicName: "isSelected", isSignal: true, isRequired: false, transformFunction: null }, showPinButton: { classPropertyName: "showPinButton", publicName: "showPinButton", isSignal: true, isRequired: false, transformFunction: null }, customClasses: { classPropertyName: "customClasses", publicName: "customClasses", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onWidgetClick: "onWidgetClick", onPinClick: "onPinClick" }, ngImport: i0, template: "<div (click)=\"handleClick($event)\"\n class=\"ax-py-2 ax-px-3 ax-rounded-md ax-flex ax-gap-3 ax-items-center ax-group hover:ax-bg-primary-lightest/65 hover:ax-text-primary-on-lightest ax-cursor-pointer ax-w-full\"\n [class.ax-bg-primary-lightest]=\"isSelected()\" [class.ax-text-primary-on-lightest]=\"isSelected()\"\n [class.ax-border-primary-lightest]=\"isSelected()\" [class]=\"customClasses()\">\n\n <!-- Widget Icon -->\n <div class=\"ax-min-w-10 ax-h-10 ax-flex ax-items-center ax-justify-center ax-rounded-md ax-border group-hover:ax-bg-primary-lighter group-hover:ax-text-primary-on-lighter group-hover:ax-border-primary-lighter\"\n [class.ax-bg-primary-light]=\"isSelected()\" [class.ax-text-primary-on-light]=\"isSelected()\"\n [class.ax-border-primary-light]=\"isSelected()\" [class.ax-surface]=\"!isSelected()\">\n <i [ngClass]=\"getIconClass()\" class=\"ax-text-lg\"></i>\n </div>\n\n <!-- Widget Content -->\n <div class=\"ax-flex ax-flex-col ax-gap-1 ax-flex-1 ax-w-[70%]\">\n <div class=\"ax-flex ax-items-center ax-justify-between ax-gap-2\">\n <!-- Widget Title -->\n <div class=\"ax-font-semibold ax-text-sm ax-truncate\" [title]=\"widget().title\">\n {{ widget().title }}\n </div>\n\n <!-- Pin Button -->\n @if (showPinButton()) {\n <div (click)=\"handlePinClick($event)\" class=\"ax-cursor-pointer\">\n @if (widget().isPinned) {\n <i class=\"fa-solid fa-thumbtack ax-text-sm ax-rotate-45\" title=\"Unpin\"></i>\n } @else {\n <i class=\"fa-light fa-thumbtack ax-text-sm ax-rotate-45 ax-invisible group-hover:ax-visible\"\n title=\"Pin\"></i>\n }\n </div>\n }\n </div>\n\n <!-- Widget Description -->\n @if (widget().description) {\n <span class=\"ax-text-xs ax-truncate\" [title]=\"widget().description\">\n {{ widget().description }}\n </span>\n }\n </div>\n</div>", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], encapsulation: i0.ViewEncapsulation.None }); }
1744
4914
  }
1745
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPWidgetItemComponent, decorators: [{
4915
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPWidgetItemComponent, decorators: [{
1746
4916
  type: Component,
1747
4917
  args: [{ selector: 'axp-widget-item', imports: [CommonModule], encapsulation: ViewEncapsulation.None, template: "<div (click)=\"handleClick($event)\"\n class=\"ax-py-2 ax-px-3 ax-rounded-md ax-flex ax-gap-3 ax-items-center ax-group hover:ax-bg-primary-lightest/65 hover:ax-text-primary-on-lightest ax-cursor-pointer ax-w-full\"\n [class.ax-bg-primary-lightest]=\"isSelected()\" [class.ax-text-primary-on-lightest]=\"isSelected()\"\n [class.ax-border-primary-lightest]=\"isSelected()\" [class]=\"customClasses()\">\n\n <!-- Widget Icon -->\n <div class=\"ax-min-w-10 ax-h-10 ax-flex ax-items-center ax-justify-center ax-rounded-md ax-border group-hover:ax-bg-primary-lighter group-hover:ax-text-primary-on-lighter group-hover:ax-border-primary-lighter\"\n [class.ax-bg-primary-light]=\"isSelected()\" [class.ax-text-primary-on-light]=\"isSelected()\"\n [class.ax-border-primary-light]=\"isSelected()\" [class.ax-surface]=\"!isSelected()\">\n <i [ngClass]=\"getIconClass()\" class=\"ax-text-lg\"></i>\n </div>\n\n <!-- Widget Content -->\n <div class=\"ax-flex ax-flex-col ax-gap-1 ax-flex-1 ax-w-[70%]\">\n <div class=\"ax-flex ax-items-center ax-justify-between ax-gap-2\">\n <!-- Widget Title -->\n <div class=\"ax-font-semibold ax-text-sm ax-truncate\" [title]=\"widget().title\">\n {{ widget().title }}\n </div>\n\n <!-- Pin Button -->\n @if (showPinButton()) {\n <div (click)=\"handlePinClick($event)\" class=\"ax-cursor-pointer\">\n @if (widget().isPinned) {\n <i class=\"fa-solid fa-thumbtack ax-text-sm ax-rotate-45\" title=\"Unpin\"></i>\n } @else {\n <i class=\"fa-light fa-thumbtack ax-text-sm ax-rotate-45 ax-invisible group-hover:ax-visible\"\n title=\"Pin\"></i>\n }\n </div>\n }\n </div>\n\n <!-- Widget Description -->\n @if (widget().description) {\n <span class=\"ax-text-xs ax-truncate\" [title]=\"widget().description\">\n {{ widget().description }}\n </span>\n }\n </div>\n</div>" }]
1748
4918
  }] });
@@ -1751,5 +4921,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
1751
4921
  * Generated bundle index. Do not edit.
1752
4922
  */
1753
4923
 
1754
- export { AXPActivityLogComponent, AXPCompareViewComponent, AXPComponentSlot, AXPComponentSlotDirective, AXPComponentSlotModule, AXPComponentSlotRegistryService, AXPDynamicFormComponent, AXPLayoutFiltersComponent, AXPMenuBadgeHelper, AXPTaskBadgeDirective, AXPTaskBadgeProvider, AXPTaskBadgeService, AXPThemeLayoutActionsComponent, AXPThemeLayoutBlockComponent, AXPThemeLayoutContainerComponent, AXPThemeLayoutEndSideComponent, AXPThemeLayoutFooterComponent, AXPThemeLayoutHeaderComponent, AXPThemeLayoutListComponent, AXPThemeLayoutListItemComponent, AXPThemeLayoutListItemsGroupComponent, AXPThemeLayoutPageHeaderComponent, AXPThemeLayoutPagePrimaryActionsComponent, AXPThemeLayoutPageSecondaryActionsComponent, AXPThemeLayoutSectionComponent, AXPThemeLayoutStartSideComponent, AXPThemeLayoutToolbarComponent, AXPUserAvatarComponent, AXPUserAvatarService, AXPWidgetItemComponent, AXP_TASK_BADGE_PROVIDERS, AXP_USER_AVATAR_PROVIDER };
4924
+ export { AXPActivityLogComponent, AXPCategoryTreeComponent, AXPCompareViewComponent, AXPComponentSlot, AXPComponentSlotDirective, AXPComponentSlotModule, AXPComponentSlotRegistryService, AXPDataSelectorComponent, AXPDataSelectorService, AXPDynamicDialogComponent, AXPDynamicDialogService, AXPDynamicFormBuilderService, AXPDynamicFormComponent, AXPDynamicFormStepperComponent, AXPExtraPropertiesComponent, AXPExtraPropertiesSchemaComponent, AXPExtraPropertiesValuesComponent, AXPMenuBadgeHelper, AXPQueryColumnsComponent, AXPQueryFiltersComponent, AXPQuerySortsComponent, AXPQueryViewsComponent, AXPStateMessageComponent, AXPTaskBadgeDirective, AXPTaskBadgeProvider, AXPTaskBadgeService, AXPTemplateViewerComponent, AXPTemplateViewerService, AXPThemeLayoutActionsComponent, AXPThemeLayoutBlockComponent, AXPThemeLayoutContainerComponent, AXPThemeLayoutEndSideComponent, AXPThemeLayoutFooterComponent, AXPThemeLayoutHeaderComponent, AXPThemeLayoutListComponent, AXPThemeLayoutListItemComponent, AXPThemeLayoutListItemsGroupComponent, AXPThemeLayoutPageHeaderComponent, AXPThemeLayoutPagePrimaryActionsComponent, AXPThemeLayoutPageSecondaryActionsComponent, AXPThemeLayoutSectionComponent, AXPThemeLayoutStartSideComponent, AXPThemeLayoutToolbarComponent, AXPUserAvatarComponent, AXPUserAvatarService, AXPWidgetItemComponent, AXPWidgetPropertyViewerComponent, AXP_EXTRA_PROPERTY_TYPES, AXP_TASK_BADGE_PROVIDERS, AXP_USER_AVATAR_PROVIDER };
1755
4925
  //# sourceMappingURL=acorex-platform-layout-components.mjs.map