@acorex/platform 20.3.0-next.7 → 20.3.0-next.9

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 (62) hide show
  1. package/common/index.d.ts +0 -2
  2. package/core/index.d.ts +386 -47
  3. package/fesm2022/acorex-platform-common.mjs +5 -10
  4. package/fesm2022/acorex-platform-common.mjs.map +1 -1
  5. package/fesm2022/acorex-platform-core.mjs +427 -125
  6. package/fesm2022/acorex-platform-core.mjs.map +1 -1
  7. package/fesm2022/acorex-platform-layout-builder.mjs +422 -26
  8. package/fesm2022/acorex-platform-layout-builder.mjs.map +1 -1
  9. package/fesm2022/acorex-platform-layout-components.mjs +1843 -111
  10. package/fesm2022/acorex-platform-layout-components.mjs.map +1 -1
  11. package/fesm2022/acorex-platform-layout-designer.mjs +19 -12
  12. package/fesm2022/acorex-platform-layout-designer.mjs.map +1 -1
  13. package/fesm2022/acorex-platform-layout-entity.mjs +463 -510
  14. package/fesm2022/acorex-platform-layout-entity.mjs.map +1 -1
  15. package/fesm2022/acorex-platform-layout-views.mjs +23 -15
  16. package/fesm2022/acorex-platform-layout-views.mjs.map +1 -1
  17. package/fesm2022/{acorex-platform-themes-default-entity-master-create-view.component-BXbkGGei.mjs → acorex-platform-themes-default-entity-master-create-view.component-Ct-ri59W.mjs} +3 -3
  18. package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-Ct-ri59W.mjs.map +1 -0
  19. package/fesm2022/{acorex-platform-themes-default-entity-master-list-view.component-gQIK6PIx.mjs → acorex-platform-themes-default-entity-master-list-view.component-7BB4LdjK.mjs} +9 -9
  20. package/fesm2022/acorex-platform-themes-default-entity-master-list-view.component-7BB4LdjK.mjs.map +1 -0
  21. package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-BDJR088o.mjs +101 -0
  22. package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-BDJR088o.mjs.map +1 -0
  23. package/fesm2022/acorex-platform-themes-default.mjs +8 -8
  24. package/fesm2022/acorex-platform-themes-default.mjs.map +1 -1
  25. package/fesm2022/{acorex-platform-themes-shared-icon-chooser-view.component-KpZWpnOJ.mjs → acorex-platform-themes-shared-icon-chooser-view.component-BgEh06Tn.mjs} +21 -11
  26. package/fesm2022/acorex-platform-themes-shared-icon-chooser-view.component-BgEh06Tn.mjs.map +1 -0
  27. package/fesm2022/{acorex-platform-themes-shared-settings.provider-CXiRmniv.mjs → acorex-platform-themes-shared-settings.provider-CLUKU4y0.mjs} +2 -2
  28. package/fesm2022/acorex-platform-themes-shared-settings.provider-CLUKU4y0.mjs.map +1 -0
  29. package/fesm2022/{acorex-platform-themes-shared-theme-color-chooser-column.component-BvOiVCgt.mjs → acorex-platform-themes-shared-theme-color-chooser-column.component-AeOQxjbS.mjs} +20 -5
  30. package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-column.component-AeOQxjbS.mjs.map +1 -0
  31. package/fesm2022/{acorex-platform-themes-shared-theme-color-chooser-view.component-BW0rfkjk.mjs → acorex-platform-themes-shared-theme-color-chooser-view.component-DEVzRd6-.mjs} +20 -5
  32. package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-view.component-DEVzRd6-.mjs.map +1 -0
  33. package/fesm2022/acorex-platform-themes-shared.mjs +205 -38
  34. package/fesm2022/acorex-platform-themes-shared.mjs.map +1 -1
  35. package/fesm2022/{acorex-platform-widgets-checkbox-widget-view.component-C-4bWr9G.mjs → acorex-platform-widgets-checkbox-widget-view.component-KYCQ2qTJ.mjs} +51 -35
  36. package/fesm2022/acorex-platform-widgets-checkbox-widget-view.component-KYCQ2qTJ.mjs.map +1 -0
  37. package/fesm2022/{acorex-platform-widgets-file-list-popup.component-rW2RD35f.mjs → acorex-platform-widgets-file-list-popup.component-Cmtq2bBV.mjs} +3 -3
  38. package/fesm2022/acorex-platform-widgets-file-list-popup.component-Cmtq2bBV.mjs.map +1 -0
  39. package/fesm2022/{acorex-platform-widgets-page-widget-designer.component-DNvnQ4Mc.mjs → acorex-platform-widgets-page-widget-designer.component-D8ivmxzT.mjs} +2 -2
  40. package/fesm2022/acorex-platform-widgets-page-widget-designer.component-D8ivmxzT.mjs.map +1 -0
  41. package/fesm2022/{acorex-platform-widgets-tabular-data-edit-popup.component-CPVRbE8B.mjs → acorex-platform-widgets-tabular-data-edit-popup.component-CMqq_iOj.mjs} +8 -8
  42. package/fesm2022/acorex-platform-widgets-tabular-data-edit-popup.component-CMqq_iOj.mjs.map +1 -0
  43. package/fesm2022/acorex-platform-widgets.mjs +4590 -5073
  44. package/fesm2022/acorex-platform-widgets.mjs.map +1 -1
  45. package/layout/builder/index.d.ts +62 -8
  46. package/layout/components/index.d.ts +780 -54
  47. package/layout/designer/index.d.ts +4 -2
  48. package/layout/entity/index.d.ts +53 -10
  49. package/package.json +9 -9
  50. package/widgets/index.d.ts +1441 -433
  51. package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-BXbkGGei.mjs.map +0 -1
  52. package/fesm2022/acorex-platform-themes-default-entity-master-list-view.component-gQIK6PIx.mjs.map +0 -1
  53. package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-Bp1JLsj1.mjs +0 -101
  54. package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-Bp1JLsj1.mjs.map +0 -1
  55. package/fesm2022/acorex-platform-themes-shared-icon-chooser-view.component-KpZWpnOJ.mjs.map +0 -1
  56. package/fesm2022/acorex-platform-themes-shared-settings.provider-CXiRmniv.mjs.map +0 -1
  57. package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-column.component-BvOiVCgt.mjs.map +0 -1
  58. package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-view.component-BW0rfkjk.mjs.map +0 -1
  59. package/fesm2022/acorex-platform-widgets-checkbox-widget-view.component-C-4bWr9G.mjs.map +0 -1
  60. package/fesm2022/acorex-platform-widgets-file-list-popup.component-rW2RD35f.mjs.map +0 -1
  61. package/fesm2022/acorex-platform-widgets-page-widget-designer.component-DNvnQ4Mc.mjs.map +0 -1
  62. package/fesm2022/acorex-platform-widgets-tabular-data-edit-popup.component-CPVRbE8B.mjs.map +0 -1
@@ -1,59 +1,70 @@
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 i7 from '@acorex/components/decorators';
5
+ import * as i2$1 from '@acorex/components/decorators';
5
6
  import { AXDecoratorModule } from '@acorex/components/decorators';
6
7
  import * as i5 from '@acorex/core/translation';
7
- import { AXTranslationService, AXTranslationModule } from '@acorex/core/translation';
8
- import * as i3 from '@acorex/components/skeleton';
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$1 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, model, Injector, ViewContainerRef, runInInjectionContext, Optional, Inject, NgModule, output, Input, EventEmitter, untracked, Output, linkedSignal, 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';
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';
23
30
  import * as i3$1 from '@acorex/components/switch';
24
31
  import { AXSwitchModule } from '@acorex/components/switch';
25
32
  import * as i9 from '@angular/cdk/drag-drop';
26
33
  import { moveItemInArray, CdkDropList, CdkDrag, CdkDragHandle, DragDropModule } from '@angular/cdk/drag-drop';
27
- import * as i1 from '@angular/forms';
34
+ import * as i1$1 from '@angular/forms';
28
35
  import { FormsModule } from '@angular/forms';
29
- import { cloneDeep, sortBy, isEqual, camelCase, merge, capitalize, unionBy, isArray, isNil, isEmpty, set } from 'lodash-es';
30
- import * as i2$1 from '@acorex/components/form';
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';
31
38
  import { AXFormModule, AXFormComponent } from '@acorex/components/form';
32
- import * as i4$1 from '@acorex/components/text-box';
39
+ import * as i4$4 from '@acorex/components/text-box';
33
40
  import { AXTextBoxModule } from '@acorex/components/text-box';
34
- import * as i2 from '@acorex/components/check-box';
41
+ import * as i2$3 from '@acorex/components/check-box';
35
42
  import { AXCheckBoxModule } from '@acorex/components/check-box';
36
43
  import * as i3$2 from '@acorex/components/label';
37
44
  import { AXLabelModule, AXLabelComponent } from '@acorex/components/label';
38
45
  import * as i3$3 from '@acorex/platform/layout/builder';
39
46
  import { AXPLayoutBuilderModule, AXPWidgetContainerComponent, AXPPageStatus, AXPWidgetRegistryService, AXPWidgetsCatalog } from '@acorex/platform/layout/builder';
40
- import { AXBasePageComponent } from '@acorex/components/page';
41
- import { AXValidationModule } from '@acorex/core/validation';
42
- import { AXPGridLayoutDirective, AXPFilterOperatorMiddlewareService, ALL_DEFAULT_OPERATORS } from '@acorex/platform/common';
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';
43
50
  import { AXDropdownButtonModule } from '@acorex/components/dropdown-button';
44
- import * as i3$4 from '@acorex/components/dropdown';
45
- import { AXDropdownModule } from '@acorex/components/dropdown';
46
- import { AXLoadingModule } from '@acorex/components/loading';
51
+ import { AXBasePageComponent } from '@acorex/components/page';
47
52
  import { AXPopupService } from '@acorex/components/popup';
53
+ import * as i5$1 from '@acorex/components/loading';
54
+ import { AXLoadingModule } from '@acorex/components/loading';
55
+ import { AXValidationModule } from '@acorex/core/validation';
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';
48
59
  import * as i5$2 from '@acorex/components/select-box';
49
60
  import { AXSelectBoxModule } from '@acorex/components/select-box';
50
- import * as i1$1 from '@acorex/components/collapse';
61
+ import * as i1$4 from '@acorex/components/collapse';
51
62
  import { AXCollapseModule } from '@acorex/components/collapse';
52
- import * as i2$3 from '@acorex/components/tabs';
63
+ import * as i2$5 from '@acorex/components/tabs';
53
64
  import { AXTabsModule } from '@acorex/components/tabs';
54
- import * as i7$1 from '@acorex/cdk/list-navigation';
65
+ import * as i7 from '@acorex/cdk/list-navigation';
55
66
  import { AXListNavigationModule } from '@acorex/cdk/list-navigation';
56
- import * as i4$2 from '@acorex/components/popover';
67
+ import * as i4$5 from '@acorex/components/popover';
57
68
  import { AXPopoverModule } from '@acorex/components/popover';
58
69
  import { AXSelectionListModule } from '@acorex/components/selection-list';
59
70
  import * as i5$3 from '@acorex/components/tag-box';
@@ -61,11 +72,33 @@ import { AXTagBoxModule } from '@acorex/components/tag-box';
61
72
  import { AXCalendarService } from '@acorex/core/date-time';
62
73
  import { BehaviorSubject, timer, Subject, takeUntil } from 'rxjs';
63
74
  import { tap } from 'rxjs/operators';
64
- import * as i1$2 from '@acorex/components/avatar';
75
+ import * as i1$5 from '@acorex/components/avatar';
65
76
  import { AXAvatarModule } from '@acorex/components/avatar';
66
- import * as i3$5 from '@acorex/components/image';
77
+ import * as i3$4 from '@acorex/components/image';
67
78
  import { AXImageModule } from '@acorex/components/image';
68
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
+
69
102
  //#region ---- Component Definition ----
70
103
  class AXPActivityLogComponent {
71
104
  //#endregion
@@ -196,7 +229,7 @@ class AXPActivityLogComponent {
196
229
  return currentIndex > 0; // Can compare if not the first activity
197
230
  }
198
231
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPActivityLogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
199
- 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\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: i7.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "directive", type: i5.AXTranslatorDirective, selector: "[translate]" }, { kind: "ngmodule", type: AXSkeletonModule }, { kind: "component", type: i3.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: i5.AXTranslatorPipe, name: "translate" }, { kind: "pipe", type: i5$1.AXFormatPipe, name: "format" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
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 }); }
200
233
  }
201
234
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPActivityLogComponent, decorators: [{
202
235
  type: Component,
@@ -210,7 +243,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImpor
210
243
  AXFormatModule,
211
244
  AXTagModule,
212
245
  AXAccordionCdkModule,
213
- ], 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"] }]
214
248
  }], ctorParameters: () => [] });
215
249
 
216
250
  const AXP_TASK_BADGE_PROVIDERS = new InjectionToken('AXP_TASK_BADGE_PROVIDERS');
@@ -701,6 +735,284 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImpor
701
735
  }]
702
736
  }] });
703
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
+
704
1016
  class AXPQueryColumnsComponent {
705
1017
  constructor() {
706
1018
  this.columns = model([], ...(ngDevMode ? [{ debugName: "columns" }] : []));
@@ -720,7 +1032,7 @@ class AXPQueryColumnsComponent {
720
1032
  this.columns.set(columns);
721
1033
  }
722
1034
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPQueryColumnsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
723
- 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.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.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: i7.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: i4.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }] }); }
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" }] }); }
724
1036
  }
725
1037
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPQueryColumnsComponent, decorators: [{
726
1038
  type: Component,
@@ -855,9 +1167,9 @@ class AXPCompareViewComponent {
855
1167
  // Angular
856
1168
  CommonModule }, { kind: "ngmodule", type:
857
1169
  // ACoreX
858
- 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.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:
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:
859
1171
  // Platform
860
- 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: i4.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.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 }); }
861
1173
  }
862
1174
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPCompareViewComponent, decorators: [{
863
1175
  type: Component,
@@ -1082,8 +1394,269 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImpor
1082
1394
  args: ['AXPComponentSlotModuleFactory']
1083
1395
  }] }] });
1084
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
+
1085
1649
  class AXPDynamicFormComponent {
1086
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();
1087
1660
  //#region ---- Inputs ----
1088
1661
  /**
1089
1662
  * Form definition containing groups and fields
@@ -1113,6 +1686,26 @@ class AXPDynamicFormComponent {
1113
1686
  xxl: { colSpan: 4 },
1114
1687
  },
1115
1688
  }, ...(ngDevMode ? [{ debugName: "layoutConfig" }] : []));
1689
+ this.evaluatedFormDefinition = signal(null, ...(ngDevMode ? [{ debugName: "evaluatedFormDefinition" }] : []));
1690
+ /**
1691
+ * Evaluate definition when inputs change with last-write-wins and deep-equality guard
1692
+ */
1693
+ this.eff = effect(() => {
1694
+ const formDef = this.formDefinition();
1695
+ const ctx = this.context();
1696
+ const runId = ++this.evaluationRunId;
1697
+ (async () => {
1698
+ const evaluated = await this.expressionEvaluator(formDef, ctx);
1699
+ // Ignore stale results
1700
+ if (runId !== this.evaluationRunId) {
1701
+ return;
1702
+ }
1703
+ const prev = this.evaluatedFormDefinition();
1704
+ if (!isEqual(prev, evaluated)) {
1705
+ this.evaluatedFormDefinition.set(evaluated);
1706
+ }
1707
+ })();
1708
+ }, ...(ngDevMode ? [{ debugName: "eff" }] : []));
1116
1709
  //#endregion
1117
1710
  //#region ---- Outputs ----
1118
1711
  /**
@@ -1162,8 +1755,11 @@ class AXPDynamicFormComponent {
1162
1755
  * Effect to sync context changes
1163
1756
  */
1164
1757
  this.#contextSyncEffect = effect(() => {
1165
- const context = this.context();
1166
- this.internalContext.set(context);
1758
+ const ctx = this.context();
1759
+ const prev = this.internalContext();
1760
+ if (!isEqual(prev, ctx)) {
1761
+ this.internalContext.set(ctx);
1762
+ }
1167
1763
  }, ...(ngDevMode ? [{ debugName: "#contextSyncEffect" }] : []));
1168
1764
  /**
1169
1765
  * Effect to handle form status changes
@@ -1175,6 +1771,84 @@ class AXPDynamicFormComponent {
1175
1771
  this.container()?.builderService.setStatus(AXPPageStatus.Rendered);
1176
1772
  }
1177
1773
  }, ...(ngDevMode ? [{ debugName: "#formStatusEffect" }] : []));
1774
+ /**
1775
+ * Invalidate memoization cache when layout config or evaluated definition changes
1776
+ */
1777
+ this.#layoutCacheInvalidationEffect = effect(() => {
1778
+ // Depend on layout config and evaluated definition identity
1779
+ // Any structural change should flush the cache to ensure correctness
1780
+ const _layout = this.layoutConfig();
1781
+ const _evaluated = this.evaluatedFormDefinition();
1782
+ // Simple invalidation: clear cache when either changes
1783
+ this.layoutCache.clear();
1784
+ }, ...(ngDevMode ? [{ debugName: "#layoutCacheInvalidationEffect" }] : []));
1785
+ }
1786
+ //#endregion
1787
+ //#region ---- Evaluator ----
1788
+ async expressionEvaluator(expression, context) {
1789
+ const scope = {
1790
+ context: {
1791
+ eval: (path) => get(context, path),
1792
+ },
1793
+ };
1794
+ return await this.evaluatorService.evaluate(expression, scope);
1795
+ }
1796
+ /**
1797
+ * Resolve effective grid layout for a specific parameter, merging per-parameter override with form layout.
1798
+ */
1799
+ resolveParamLayout(param) {
1800
+ const base = this.layoutConfig();
1801
+ const override = param.layout;
1802
+ // Build a signature to memoize per param + current base layout snapshot + override
1803
+ const signature = JSON.stringify({
1804
+ path: param?.path,
1805
+ base,
1806
+ override,
1807
+ });
1808
+ const cacheKey = param?.path ?? JSON.stringify(param);
1809
+ const cached = this.layoutCache.get(cacheKey);
1810
+ if (cached && cached.signature === signature) {
1811
+ return cached.config;
1812
+ }
1813
+ if (override == null) {
1814
+ this.layoutCache.set(cacheKey, { signature, config: base });
1815
+ return base;
1816
+ }
1817
+ const normalize = (value, fallback) => typeof value === 'number' && value > 0 ? value : fallback;
1818
+ const toConfig = (o) => {
1819
+ if (typeof o === 'number') {
1820
+ const cfg = {
1821
+ positions: {
1822
+ default: { colSpan: o },
1823
+ md: { colSpan: o },
1824
+ lg: { colSpan: o },
1825
+ xl: { colSpan: o },
1826
+ xxl: { colSpan: o },
1827
+ },
1828
+ };
1829
+ return cfg;
1830
+ }
1831
+ // When parameter layout object is provided, do NOT fall back to form layout.
1832
+ // Use cascading values across breakpoints: default -> md -> lg -> xl -> xxl.
1833
+ const d = normalize(o.default, 12);
1834
+ const md = normalize(o.md, d);
1835
+ const lg = normalize(o.lg, md);
1836
+ const xl = normalize(o.xl, lg);
1837
+ const xxl = normalize(o.xxl, xl);
1838
+ const cfg = {
1839
+ positions: {
1840
+ default: { colSpan: d },
1841
+ md: { colSpan: md },
1842
+ lg: { colSpan: lg },
1843
+ xl: { colSpan: xl },
1844
+ xxl: { colSpan: xxl },
1845
+ },
1846
+ };
1847
+ return cfg;
1848
+ };
1849
+ const result = toConfig(override);
1850
+ this.layoutCache.set(cacheKey, { signature, config: result });
1851
+ return result;
1178
1852
  }
1179
1853
  //#endregion
1180
1854
  //#region ---- Lifecycle Methods ----
@@ -1192,6 +1866,10 @@ class AXPDynamicFormComponent {
1192
1866
  * Effect to handle form status changes
1193
1867
  */
1194
1868
  #formStatusEffect;
1869
+ /**
1870
+ * Invalidate memoization cache when layout config or evaluated definition changes
1871
+ */
1872
+ #layoutCacheInvalidationEffect;
1195
1873
  //#endregion
1196
1874
  //#region ---- Event Handlers ----
1197
1875
  /**
@@ -1250,11 +1928,11 @@ class AXPDynamicFormComponent {
1250
1928
  return false;
1251
1929
  }
1252
1930
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPDynamicFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1253
- 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 }, 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 formDefinition().groups; track group.name) {\n <axp-layout-section>\n @if (group.title || group.description) {\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 }\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 [required]=\"isRequired(param)\">{{ param.title! | translate | async }}</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! | translate | async }}</axp-layout-description>\n }\n </ax-form-field>\n </div>\n }\n </axp-layout-content>\n </axp-layout-section>\n } @empty {\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.--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(1,minmax(0,1fr))}@media (min-width: 768px){.axp-dynamic-form.--direction-grid axp-layout-section axp-layout-content .__field-container{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (min-width: 1024px){.axp-dynamic-form.--direction-grid axp-layout-section axp-layout-content .__field-container{grid-template-columns:repeat(3,minmax(0,1fr))}}@media (min-width: 1280px){.axp-dynamic-form.--direction-grid axp-layout-section axp-layout-content .__field-container{grid-template-columns:repeat(4,minmax(0,1fr))}}.axp-dynamic-form.--direction-grid axp-layout-section axp-layout-content .__field-container{gap:1rem;padding:1rem}.axp-dynamic-form.--direction-grid axp-layout-section axp-layout-content .__field-container .__field-info{grid-column:1 / -1}.axp-dynamic-form.--direction-grid axp-layout-section axp-layout-content .__field-container .__field-input{grid-column:1 / -1}.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:
1931
+ 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 }, 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 axp-widget-renderer [node]=\"param.widget\" [mode]=\"'edit'\"></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 axp-widget-renderer [node]=\"param.widget\" [mode]=\"'edit'\"></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:
1254
1932
  // ACoreX
1255
- AXFormModule }, { kind: "component", type: i2$1.AXFormFieldComponent, selector: "ax-form-field", inputs: ["labelMode"] }, { kind: "component", type: i2$1.AXFormComponent, selector: "ax-form", inputs: ["labelMode", "look", "messageStyle", "updateOn"], outputs: ["onValidate", "updateOnChange"] }, { kind: "ngmodule", type: AXValidationModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type:
1933
+ 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:
1256
1934
  // Platform
1257
- 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: "pipe", type: i4.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
1935
+ 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 }); }
1258
1936
  }
1259
1937
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPDynamicFormComponent, decorators: [{
1260
1938
  type: Component,
@@ -1271,56 +1949,547 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImpor
1271
1949
  AXPThemeLayoutHeaderComponent,
1272
1950
  AXPThemeLayoutSectionComponent,
1273
1951
  AXPGridLayoutDirective,
1274
- AXLabelComponent
1952
+ AXLabelComponent,
1953
+ AXPStateMessageComponent,
1275
1954
  ], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
1276
1955
  class: 'axp-dynamic-form',
1277
1956
  '[class]': 'hostClasses()',
1278
- }, template: "<ax-form>\n <axp-widgets-container [context]=\"internalContext()\" (onContextChanged)=\"handleContextChanged($event)\">\n <axp-layout-sections>\n @for (group of formDefinition().groups; track group.name) {\n <axp-layout-section>\n @if (group.title || group.description) {\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 }\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 [required]=\"isRequired(param)\">{{ param.title! | translate | async }}</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! | translate | async }}</axp-layout-description>\n }\n </ax-form-field>\n </div>\n }\n </axp-layout-content>\n </axp-layout-section>\n } @empty {\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.--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(1,minmax(0,1fr))}@media (min-width: 768px){.axp-dynamic-form.--direction-grid axp-layout-section axp-layout-content .__field-container{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (min-width: 1024px){.axp-dynamic-form.--direction-grid axp-layout-section axp-layout-content .__field-container{grid-template-columns:repeat(3,minmax(0,1fr))}}@media (min-width: 1280px){.axp-dynamic-form.--direction-grid axp-layout-section axp-layout-content .__field-container{grid-template-columns:repeat(4,minmax(0,1fr))}}.axp-dynamic-form.--direction-grid axp-layout-section axp-layout-content .__field-container{gap:1rem;padding:1rem}.axp-dynamic-form.--direction-grid axp-layout-section axp-layout-content .__field-container .__field-info{grid-column:1 / -1}.axp-dynamic-form.--direction-grid axp-layout-section axp-layout-content .__field-container .__field-input{grid-column:1 / -1}.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"] }]
1957
+ }, 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 axp-widget-renderer [node]=\"param.widget\" [mode]=\"'edit'\"></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 axp-widget-renderer [node]=\"param.widget\" [mode]=\"'edit'\"></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"] }]
1279
1958
  }] });
1280
1959
 
1281
- class AXPDynamicDialogComponent extends AXBasePageComponent {
1960
+ //#endregion
1961
+ class AXPDynamicFormStepperComponent {
1282
1962
  constructor() {
1283
- super(...arguments);
1284
- this.dynamicForm = viewChild(AXPDynamicFormComponent, ...(ngDevMode ? [{ debugName: "dynamicForm" }] : []));
1285
- this.isSubmitting = signal(false, ...(ngDevMode ? [{ debugName: "isSubmitting" }] : []));
1286
- this.previousContext = signal({}, ...(ngDevMode ? [{ debugName: "previousContext" }] : []));
1287
- this.formData = signal({}, ...(ngDevMode ? [{ debugName: "formData" }] : []));
1288
- //#region ---- Computed Properties ----
1963
+ //#region ---- Inputs ----
1289
1964
  /**
1290
- * Form context for widget container
1965
+ * Stepper definition providing steps metadata and behavior configuration
1291
1966
  */
1292
- this.formContext = computed(() => this.formData(), ...(ngDevMode ? [{ debugName: "formContext" }] : []));
1293
- this.defaultLayout = () => ({
1294
- positions: {
1295
- default: { colSpan: 12 },
1296
- md: { colSpan: 8 },
1297
- lg: { colSpan: 6 },
1298
- xl: { colSpan: 5 },
1299
- xxl: { colSpan: 4 }
1300
- }
1301
- });
1967
+ this.definition = input.required(...(ngDevMode ? [{ debugName: "definition" }] : []));
1302
1968
  /**
1303
- * Footer actions for dynamic button system
1969
+ * Shared root context for all steps
1304
1970
  */
1305
- this.footerPrefixActions = computed(() => this.config.actions?.footer?.prefix || [], ...(ngDevMode ? [{ debugName: "footerPrefixActions" }] : []));
1306
- this.footerSuffixActions = computed(() => this.config.actions?.footer?.suffix || [], ...(ngDevMode ? [{ debugName: "footerSuffixActions" }] : []));
1307
- this.hasFooterActions = computed(() => {
1308
- const prefixActions = this.footerPrefixActions();
1309
- const suffixActions = this.footerSuffixActions();
1310
- return prefixActions.length > 0 || suffixActions.length > 0;
1311
- }, ...(ngDevMode ? [{ debugName: "hasFooterActions" }] : []));
1312
- this.hasVisibleFooterPrefixActions = computed(() => {
1313
- const prefixFooterActions = this.footerPrefixActions();
1314
- return prefixFooterActions.some((action) => action.visible != false);
1315
- }, ...(ngDevMode ? [{ debugName: "hasVisibleFooterPrefixActions" }] : []));
1316
- this.hasVisibleFooterSuffixActions = computed(() => {
1317
- const suffixFooterActions = this.footerSuffixActions();
1318
- return suffixFooterActions.some((action) => action.visible != false);
1319
- }, ...(ngDevMode ? [{ debugName: "hasVisibleFooterSuffixActions" }] : []));
1320
- }
1321
- //#endregion
1322
- //#region ---- Lifecycle Methods ----
1323
- ngOnInit() {
1971
+ this.context = input.required(...(ngDevMode ? [{ debugName: "context" }] : []));
1972
+ /**
1973
+ * Optional pass-through layout props for inner forms
1974
+ */
1975
+ this.layoutLook = input('normal', ...(ngDevMode ? [{ debugName: "layoutLook" }] : []));
1976
+ this.stepperDirection = input('horizontal', ...(ngDevMode ? [{ debugName: "stepperDirection" }] : []));
1977
+ this.layoutConfig = input(...(ngDevMode ? [undefined, { debugName: "layoutConfig" }] : []));
1978
+ /**
1979
+ * Optional guard that controls advancing to the next step (async only)
1980
+ */
1981
+ this.guardNext = input(...(ngDevMode ? [undefined, { debugName: "guardNext" }] : []));
1982
+ //#endregion
1983
+ //#region ---- Outputs ----
1984
+ /**
1985
+ * Emits when the shared root context changes
1986
+ */
1987
+ this.contextChange = output();
1988
+ /**
1989
+ * Emits when the active step changes
1990
+ */
1991
+ this.stepChange = output();
1992
+ /**
1993
+ * Emits after successful finish
1994
+ */
1995
+ this.finished = output();
1996
+ /**
1997
+ * Emits when cancelled by API
1998
+ */
1999
+ this.cancel = output();
2000
+ /**
2001
+ * Emits when navigation is blocked by validation or policy
2002
+ */
2003
+ this.navigationBlocked = output();
2004
+ //#endregion
2005
+ //#region ---- State ----
2006
+ /**
2007
+ * Internal reactive copy of the shared context
2008
+ */
2009
+ this.internalContext = signal({}, ...(ngDevMode ? [{ debugName: "internalContext" }] : []));
2010
+ /**
2011
+ * Active step index
2012
+ */
2013
+ this.currentStepIndex = signal(0, ...(ngDevMode ? [{ debugName: "currentStepIndex" }] : []));
2014
+ /**
2015
+ * Navigation lock while async guards are pending
2016
+ */
2017
+ this.navigationLocked = signal(false, ...(ngDevMode ? [{ debugName: "navigationLocked" }] : []));
2018
+ /**
2019
+ * Reference to underlying step wizard to sync visual navigation
2020
+ */
2021
+ this.wizard = viewChild(AXStepWizardComponent, ...(ngDevMode ? [{ debugName: "wizard" }] : []));
2022
+ /**
2023
+ * References to rendered dynamic forms (usually one active)
2024
+ */
2025
+ this.forms = viewChildren(AXPDynamicFormComponent, ...(ngDevMode ? [{ debugName: "forms" }] : []));
2026
+ //#endregion
2027
+ //#region ---- Computed Properties ----
2028
+ this.steps = computed(() => this.definition().steps ?? [], ...(ngDevMode ? [{ debugName: "steps" }] : []));
2029
+ this.stepCount = computed(() => this.steps().length, ...(ngDevMode ? [{ debugName: "stepCount" }] : []));
2030
+ this.currentStep = computed(() => this.steps()[this.currentStepIndex()] ?? undefined, ...(ngDevMode ? [{ debugName: "currentStep" }] : []));
2031
+ this.isFirstComputed = computed(() => this.currentStepIndex() === 0, ...(ngDevMode ? [{ debugName: "isFirstComputed" }] : []));
2032
+ this.isLastComputed = computed(() => this.currentStepIndex() === Math.max(0, this.stepCount() - 1), ...(ngDevMode ? [{ debugName: "isLastComputed" }] : []));
2033
+ /**
2034
+ * Non-undefined layout config for inner dynamic forms
2035
+ */
2036
+ this.effectiveLayoutConfig = computed(() => this.layoutConfig() ?? {
2037
+ positions: {
2038
+ default: { colSpan: 12 },
2039
+ md: { colSpan: 8 },
2040
+ lg: { colSpan: 6 },
2041
+ xl: { colSpan: 5 },
2042
+ xxl: { colSpan: 4 },
2043
+ },
2044
+ }, ...(ngDevMode ? [{ debugName: "effectiveLayoutConfig" }] : []));
2045
+ //#endregion
2046
+ //#region ---- Effects ----
2047
+ /**
2048
+ * Keep internal context in sync with input context
2049
+ */
2050
+ this.#contextSync = effect(() => {
2051
+ const ctx = this.context();
2052
+ this.internalContext.set(ctx ?? {});
2053
+ }, ...(ngDevMode ? [{ debugName: "#contextSync" }] : []));
2054
+ }
2055
+ //#endregion
2056
+ //#region ---- Effects ----
2057
+ /**
2058
+ * Keep internal context in sync with input context
2059
+ */
2060
+ #contextSync;
2061
+ //#endregion
2062
+ //#region ---- Public API ----
2063
+ /**
2064
+ * Returns the current step pointer
2065
+ */
2066
+ getCurrentStep() {
2067
+ const step = this.currentStep();
2068
+ return { index: this.currentStepIndex(), id: step?.id ?? '' };
2069
+ }
2070
+ /**
2071
+ * Public helpers for templates/consumers
2072
+ */
2073
+ isFirst() {
2074
+ return this.currentStepIndex() === 0;
2075
+ }
2076
+ isLast() {
2077
+ return this.currentStepIndex() === Math.max(0, this.stepCount() - 1);
2078
+ }
2079
+ /**
2080
+ * Returns the root context
2081
+ */
2082
+ getContext() {
2083
+ return this.internalContext();
2084
+ }
2085
+ /**
2086
+ * Replaces the root context programmatically
2087
+ */
2088
+ setContext(ctx) {
2089
+ this.internalContext.set(ctx ?? {});
2090
+ this.contextChange.emit(this.internalContext());
2091
+ }
2092
+ /**
2093
+ * Validates the current step.
2094
+ */
2095
+ async validateCurrentStep() {
2096
+ const instances = this.forms();
2097
+ if (!instances || instances.length === 0) {
2098
+ return true;
2099
+ }
2100
+ const index = this.currentStepIndex();
2101
+ const form = instances[index] ?? instances[0];
2102
+ if (form && typeof form.validate === 'function') {
2103
+ return await form.validate();
2104
+ }
2105
+ return true;
2106
+ }
2107
+ /**
2108
+ * Attempts to advance to the next step applying validation and guard
2109
+ */
2110
+ async next() {
2111
+ if (this.navigationLocked()) {
2112
+ return;
2113
+ }
2114
+ const valid = await this.validateCurrentStep();
2115
+ if (!valid) {
2116
+ const step = this.currentStep();
2117
+ if (step) {
2118
+ this.navigationBlocked.emit({ reason: 'invalid', stepId: step.id });
2119
+ }
2120
+ return;
2121
+ }
2122
+ const index = this.currentStepIndex();
2123
+ const step = this.steps()[index];
2124
+ if (!step) {
2125
+ return;
2126
+ }
2127
+ const event = { index, id: step.id, fullContext: this.internalContext() };
2128
+ const guard = this.guardNext();
2129
+ if (guard) {
2130
+ try {
2131
+ this.navigationLocked.set(true);
2132
+ const allowed = await guard(event);
2133
+ if (!allowed) {
2134
+ return;
2135
+ }
2136
+ }
2137
+ finally {
2138
+ this.navigationLocked.set(false);
2139
+ }
2140
+ }
2141
+ // Context is already synced through onStepContextChange
2142
+ this.contextChange.emit(this.internalContext());
2143
+ // Advance
2144
+ if (index < this.stepCount() - 1) {
2145
+ this.#activateStep(index + 1);
2146
+ // Sync visual wizard
2147
+ this.wizard()?.next();
2148
+ }
2149
+ }
2150
+ /**
2151
+ * Goes back to the previous step if possible
2152
+ */
2153
+ async previous() {
2154
+ if (this.navigationLocked()) {
2155
+ return;
2156
+ }
2157
+ const index = this.currentStepIndex();
2158
+ if (index <= 0) {
2159
+ return;
2160
+ }
2161
+ const current = this.steps()[index];
2162
+ if (current && current.canGoBack === false) {
2163
+ this.navigationBlocked.emit({ reason: 'cannot-go-back', stepId: current.id, targetIndex: index - 1 });
2164
+ return;
2165
+ }
2166
+ this.#activateStep(index - 1);
2167
+ // Sync visual wizard
2168
+ this.wizard()?.previous();
2169
+ }
2170
+ /**
2171
+ * Navigates to a specific step by id or index
2172
+ */
2173
+ async goTo(stepIdOrIndex) {
2174
+ if (typeof stepIdOrIndex === 'number') {
2175
+ await this.#attemptNavigateToIndex(stepIdOrIndex);
2176
+ return;
2177
+ }
2178
+ const idx = this.steps().findIndex((s) => s.id === stepIdOrIndex);
2179
+ if (idx >= 0) {
2180
+ await this.#attemptNavigateToIndex(idx);
2181
+ }
2182
+ }
2183
+ /**
2184
+ * Validates all steps and emits finished when successful
2185
+ */
2186
+ async finish() {
2187
+ // MVP: assume all steps valid
2188
+ this.finished.emit(this.internalContext());
2189
+ }
2190
+ /**
2191
+ * Emits cancel event without state changes
2192
+ */
2193
+ cancelFlow() {
2194
+ this.cancel.emit();
2195
+ }
2196
+ //#endregion
2197
+ //#region ---- Utilities ----
2198
+ #activateStep(index) {
2199
+ this.currentStepIndex.set(index);
2200
+ const step = this.steps()[index];
2201
+ if (step?.dataPath) {
2202
+ // Ensure the path exists for binding
2203
+ this.#ensurePath(step.dataPath);
2204
+ }
2205
+ if (step) {
2206
+ this.stepChange.emit({ index, id: step.id });
2207
+ }
2208
+ }
2209
+ /**
2210
+ * Attempts navigation to a specific index while enforcing linear/skip/back rules and validation.
2211
+ */
2212
+ async #attemptNavigateToIndex(targetIndex) {
2213
+ if (targetIndex < 0 || targetIndex >= this.stepCount()) {
2214
+ return;
2215
+ }
2216
+ const currentIndex = this.currentStepIndex();
2217
+ if (targetIndex === currentIndex) {
2218
+ return;
2219
+ }
2220
+ const steps = this.steps();
2221
+ const current = steps[currentIndex];
2222
+ const target = steps[targetIndex];
2223
+ if (!current || !target) {
2224
+ return;
2225
+ }
2226
+ // Moving backward: ensure all steps between have canGoBack !== false
2227
+ if (targetIndex < currentIndex) {
2228
+ for (let i = currentIndex; i > targetIndex; i--) {
2229
+ const step = steps[i];
2230
+ if (step && step.canGoBack === false) {
2231
+ this.navigationBlocked.emit({ reason: 'cannot-go-back', stepId: step.id, targetIndex });
2232
+ return;
2233
+ }
2234
+ }
2235
+ this.#activateStep(targetIndex);
2236
+ const w = this.wizard();
2237
+ if (w && typeof w.goStep === 'function') {
2238
+ w.goStep(targetIndex);
2239
+ }
2240
+ else {
2241
+ this.wizard()?.previous();
2242
+ }
2243
+ return;
2244
+ }
2245
+ // Moving forward: enforce linear and canSkip
2246
+ const isLinear = !!this.definition().linear;
2247
+ if (isLinear && targetIndex > currentIndex + 1) {
2248
+ this.navigationBlocked.emit({ reason: 'linear', stepId: current.id, targetIndex });
2249
+ return;
2250
+ }
2251
+ // Check skipped steps for canSkip
2252
+ for (let i = currentIndex + 1; i < targetIndex; i++) {
2253
+ const step = steps[i];
2254
+ if (step && step.canSkip !== true) {
2255
+ this.navigationBlocked.emit({ reason: 'cannot-skip', stepId: step.id, targetIndex });
2256
+ return;
2257
+ }
2258
+ }
2259
+ // Forward navigation should validate current step and pass guard
2260
+ const valid = await this.validateCurrentStep();
2261
+ if (!valid) {
2262
+ this.navigationBlocked.emit({ reason: 'invalid', stepId: current.id, targetIndex });
2263
+ return;
2264
+ }
2265
+ const guard = this.guardNext();
2266
+ if (guard) {
2267
+ try {
2268
+ this.navigationLocked.set(true);
2269
+ const allowed = await guard({ index: currentIndex, id: current.id, fullContext: this.internalContext() });
2270
+ if (!allowed) {
2271
+ return;
2272
+ }
2273
+ }
2274
+ finally {
2275
+ this.navigationLocked.set(false);
2276
+ }
2277
+ }
2278
+ this.#activateStep(targetIndex);
2279
+ const w = this.wizard();
2280
+ if (w && typeof w.goStep === 'function') {
2281
+ w.goStep(targetIndex);
2282
+ }
2283
+ else {
2284
+ this.wizard()?.next();
2285
+ }
2286
+ }
2287
+ #readStepSlice(path) {
2288
+ const root = this.internalContext();
2289
+ if (!path) {
2290
+ return { slice: root, exists: true };
2291
+ }
2292
+ const parts = path.split('.').filter(Boolean);
2293
+ let node = root;
2294
+ for (const key of parts) {
2295
+ if (node == null || typeof node !== 'object') {
2296
+ return { slice: undefined, exists: false };
2297
+ }
2298
+ node = node[key];
2299
+ }
2300
+ return { slice: node, exists: node !== undefined };
2301
+ }
2302
+ #writeStepSlice(path, value) {
2303
+ if (!path) {
2304
+ // Replace full root with value only if value is an object
2305
+ if (value && typeof value === 'object') {
2306
+ this.internalContext.set(value);
2307
+ }
2308
+ return;
2309
+ }
2310
+ const root = { ...this.internalContext() };
2311
+ const parts = path.split('.').filter(Boolean);
2312
+ let node = root;
2313
+ for (let i = 0; i < parts.length; i++) {
2314
+ const key = parts[i];
2315
+ if (i === parts.length - 1) {
2316
+ node[key] = value;
2317
+ }
2318
+ else {
2319
+ node[key] = node[key] && typeof node[key] === 'object' ? { ...node[key] } : {};
2320
+ node = node[key];
2321
+ }
2322
+ }
2323
+ this.internalContext.set(root);
2324
+ }
2325
+ #ensurePath(path) {
2326
+ const root = { ...this.internalContext() };
2327
+ const parts = path.split('.').filter(Boolean);
2328
+ let node = root;
2329
+ for (const key of parts) {
2330
+ if (!node[key] || typeof node[key] !== 'object') {
2331
+ node[key] = {};
2332
+ }
2333
+ node = node[key];
2334
+ }
2335
+ this.internalContext.set(root);
2336
+ }
2337
+ /**
2338
+ * Handle per-step context changes and keep internal root context in sync.
2339
+ */
2340
+ onStepContextChange(stepId, stepContext) {
2341
+ const step = this.steps().find((s) => s.id === stepId);
2342
+ if (!step) {
2343
+ return;
2344
+ }
2345
+ this.#writeStepSlice(step.dataPath, stepContext);
2346
+ this.contextChange.emit(this.internalContext());
2347
+ }
2348
+ /**
2349
+ * Exposes reading a step slice to the template
2350
+ */
2351
+ readStepSlice(path) {
2352
+ return this.#readStepSlice(path);
2353
+ }
2354
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPDynamicFormStepperComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2355
+ 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", "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 }); }
2356
+ }
2357
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPDynamicFormStepperComponent, decorators: [{
2358
+ type: Component,
2359
+ args: [{ standalone: true, selector: 'axp-dynamic-form-stepper', imports: [
2360
+ CommonModule,
2361
+ AXStepWizardModule,
2362
+ AXPDynamicFormComponent,
2363
+ AXDecoratorModule,
2364
+ AXTranslationModule,
2365
+ AXPStickyDirective,
2366
+ ], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
2367
+ class: 'axp-dynamic-form-stepper',
2368
+ '[class.--vertical]': "stepperDirection() === 'vertical'",
2369
+ }, 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"] }]
2370
+ }] });
2371
+
2372
+ class AXPDynamicDialogComponent extends AXBasePageComponent {
2373
+ constructor() {
2374
+ super(...arguments);
2375
+ this.dynamicForm = viewChild(AXPDynamicFormComponent, ...(ngDevMode ? [{ debugName: "dynamicForm" }] : []));
2376
+ this.stepper = viewChild(AXPDynamicFormStepperComponent, ...(ngDevMode ? [{ debugName: "stepper" }] : []));
2377
+ this.isSubmitting = signal(false, ...(ngDevMode ? [{ debugName: "isSubmitting" }] : []));
2378
+ this.previousContext = signal({}, ...(ngDevMode ? [{ debugName: "previousContext" }] : []));
2379
+ this.formData = signal({}, ...(ngDevMode ? [{ debugName: "formData" }] : []));
2380
+ // This will be set by the popup service automatically
2381
+ this.dialogResult = null;
2382
+ this.isSubmittingFromDialog = false;
2383
+ this.callBack = () => { };
2384
+ //#region ---- Computed Properties ----
2385
+ /**
2386
+ * Form context for widget container
2387
+ */
2388
+ this.formContext = computed(() => this.formData(), ...(ngDevMode ? [{ debugName: "formContext" }] : []));
2389
+ /**
2390
+ * Combined loading state from both signal and dialog
2391
+ */
2392
+ this.isFormLoading = computed(() => this.isSubmitting() || this.isSubmittingFromDialog, ...(ngDevMode ? [{ debugName: "isFormLoading" }] : []));
2393
+ this.defaultLayout = () => ({
2394
+ positions: {
2395
+ default: { colSpan: 12 },
2396
+ md: { colSpan: 8 },
2397
+ lg: { colSpan: 6 },
2398
+ xl: { colSpan: 5 },
2399
+ xxl: { colSpan: 4 },
2400
+ },
2401
+ });
2402
+ /**
2403
+ * Determine rendering mode and effective definitions
2404
+ */
2405
+ this.hasLegacyForm = computed(() => !!this.config.formDefinition, ...(ngDevMode ? [{ debugName: "hasLegacyForm" }] : []));
2406
+ this.providedDefinition = computed(() => this.config.definition, ...(ngDevMode ? [{ debugName: "providedDefinition" }] : []));
2407
+ this.isStepperDefinition = computed(() => {
2408
+ const def = this.providedDefinition();
2409
+ return !!def && Array.isArray(def?.steps) && def.steps.length > 1;
2410
+ }, ...(ngDevMode ? [{ debugName: "isStepperDefinition" }] : []));
2411
+ this.shouldRenderForm = computed(() => {
2412
+ if (this.hasLegacyForm())
2413
+ return true;
2414
+ const def = this.providedDefinition();
2415
+ // Render form when definition is form-like or single/no step
2416
+ if (!def)
2417
+ return false;
2418
+ if (Array.isArray(def?.steps)) {
2419
+ return def.steps.length <= 1;
2420
+ }
2421
+ // No steps property -> treat as AXPDynamicFormDefinition
2422
+ return true;
2423
+ }, ...(ngDevMode ? [{ debugName: "shouldRenderForm" }] : []));
2424
+ this.effectiveFormDefinition = computed(() => {
2425
+ if (this.config.formDefinition)
2426
+ return this.config.formDefinition;
2427
+ const def = this.providedDefinition();
2428
+ if (!def)
2429
+ return undefined;
2430
+ if (Array.isArray(def?.steps)) {
2431
+ // Single-step stepper -> convert to form def
2432
+ const step = def.steps[0];
2433
+ return step ? { groups: step.groups } : undefined;
2434
+ }
2435
+ return def;
2436
+ }, ...(ngDevMode ? [{ debugName: "effectiveFormDefinition" }] : []));
2437
+ this.resolvedFormDefinition = computed(() => {
2438
+ return (this.effectiveFormDefinition() ?? { groups: [] });
2439
+ }, ...(ngDevMode ? [{ debugName: "resolvedFormDefinition" }] : []));
2440
+ this.effectiveLayoutLook = computed(() => this.config.layoutLook ?? 'borderless', ...(ngDevMode ? [{ debugName: "effectiveLayoutLook" }] : []));
2441
+ this.effectiveLayoutConfig = computed(() => this.config.layoutConfig ?? this.defaultLayout(), ...(ngDevMode ? [{ debugName: "effectiveLayoutConfig" }] : []));
2442
+ // Stepper-only
2443
+ this.stepperGuardNext = computed(() => this.config.stepper?.guardNext, ...(ngDevMode ? [{ debugName: "stepperGuardNext" }] : []));
2444
+ this.stepperDirection = computed(() => this.config.stepper?.stepperDirection ?? 'horizontal', ...(ngDevMode ? [{ debugName: "stepperDirection" }] : []));
2445
+ this.stepperDefinition = computed(() => {
2446
+ const def = this.providedDefinition();
2447
+ return (def ?? { steps: [] });
2448
+ }, ...(ngDevMode ? [{ debugName: "stepperDefinition" }] : []));
2449
+ this.stepperIsFirst = computed(() => this.stepper()?.isFirst() ?? true, ...(ngDevMode ? [{ debugName: "stepperIsFirst" }] : []));
2450
+ this.stepperIsLast = computed(() => this.stepper()?.isLast() ?? false, ...(ngDevMode ? [{ debugName: "stepperIsLast" }] : []));
2451
+ /**
2452
+ * Effective form direction when rendering dynamic-form (single-step or legacy form).
2453
+ * If a single-step definition is provided and that step specifies formDirection, use it.
2454
+ */
2455
+ this.effectiveFormDirection = computed(() => {
2456
+ if (this.hasLegacyForm()) {
2457
+ return 'vertical';
2458
+ }
2459
+ const def = this.providedDefinition();
2460
+ if (def && Array.isArray(def?.steps) && def.steps.length === 1) {
2461
+ return def.steps[0]?.formDirection ?? 'vertical';
2462
+ }
2463
+ return 'vertical';
2464
+ }, ...(ngDevMode ? [{ debugName: "effectiveFormDirection" }] : []));
2465
+ /**
2466
+ * Footer actions for dynamic button system
2467
+ */
2468
+ this.footerPrefixActions = computed(() => this.config.actions?.footer?.prefix || [], ...(ngDevMode ? [{ debugName: "footerPrefixActions" }] : []));
2469
+ this.footerSuffixActions = computed(() => this.config.actions?.footer?.suffix || [], ...(ngDevMode ? [{ debugName: "footerSuffixActions" }] : []));
2470
+ this.visibleFooterPrefixActions = computed(() => {
2471
+ const prefixFooterActions = this.footerPrefixActions();
2472
+ return prefixFooterActions.filter((action) => action.visible != false);
2473
+ }, ...(ngDevMode ? [{ debugName: "visibleFooterPrefixActions" }] : []));
2474
+ this.visibleFooterSuffixActions = computed(() => {
2475
+ const suffixFooterActions = this.footerSuffixActions();
2476
+ return suffixFooterActions.filter((action) => action.visible != false);
2477
+ }, ...(ngDevMode ? [{ debugName: "visibleFooterSuffixActions" }] : []));
2478
+ this.hasFooterActions = computed(() => {
2479
+ const prefixActions = this.visibleFooterPrefixActions();
2480
+ const suffixActions = this.visibleFooterSuffixActions();
2481
+ return prefixActions.length > 0 || suffixActions.length > 0;
2482
+ }, ...(ngDevMode ? [{ debugName: "hasFooterActions" }] : []));
2483
+ /** Stepper footer: choose a single confirm action from provided suffix actions (first visible). */
2484
+ this.confirmAction = computed(() => {
2485
+ const items = this.footerSuffixActions();
2486
+ return items.find((a) => a.visible !== false);
2487
+ }, ...(ngDevMode ? [{ debugName: "confirmAction" }] : []));
2488
+ this.confirmActionTitle = computed(() => this.confirmAction()?.title ?? 'Confirm', ...(ngDevMode ? [{ debugName: "confirmActionTitle" }] : []));
2489
+ }
2490
+ //#endregion
2491
+ //#region ---- Lifecycle Methods ----
2492
+ ngOnInit() {
1324
2493
  this.formData.set(this.config.context ?? {});
1325
2494
  }
1326
2495
  //#endregion
@@ -1345,7 +2514,7 @@ class AXPDynamicDialogComponent extends AXBasePageComponent {
1345
2514
  // Handle custom action logic here
1346
2515
  const result = {
1347
2516
  context: this.formData(),
1348
- action: action.name || action.title
2517
+ action: action.name || action.title,
1349
2518
  };
1350
2519
  this.close(result);
1351
2520
  }
@@ -1355,18 +2524,41 @@ class AXPDynamicDialogComponent extends AXBasePageComponent {
1355
2524
  */
1356
2525
  async executeCommand(command) {
1357
2526
  // Handle command execution logic here
1358
- // This can be extended based on your command system
1359
- console.log('Executing command:', command);
1360
2527
  if (command.options?.['validate'] == true) {
1361
- if (!await this.isFormValid()) {
2528
+ if (!(await this.isFormValid())) {
1362
2529
  return;
1363
2530
  }
1364
2531
  }
2532
+ //
2533
+ if (command.name == 'cancel') {
2534
+ this.close();
2535
+ }
1365
2536
  const result = {
1366
2537
  context: this.formData(),
1367
- action: command.name
2538
+ action: command.name,
1368
2539
  };
1369
- this.close(result);
2540
+ // Store result in component property and popup data
2541
+ this.dialogResult = result;
2542
+ // Store in popup data for DialogRef access
2543
+ if (this.data) {
2544
+ this.data.context = result.context;
2545
+ this.data.action = result.action;
2546
+ }
2547
+ // Call the callback with DialogRef
2548
+ this.callBack({
2549
+ close: (result) => {
2550
+ this.close(result);
2551
+ },
2552
+ context: () => {
2553
+ return this.formData();
2554
+ },
2555
+ action: () => {
2556
+ return result.action;
2557
+ },
2558
+ setLoading: (loading) => {
2559
+ this.isSubmitting.set(loading);
2560
+ },
2561
+ });
1370
2562
  }
1371
2563
  //#endregion
1372
2564
  //#region ---- Public Methods ----
@@ -1374,25 +2566,39 @@ class AXPDynamicDialogComponent extends AXBasePageComponent {
1374
2566
  * Check if form is valid
1375
2567
  */
1376
2568
  async isFormValid() {
1377
- return await this.dynamicForm()?.validate() ?? false;
2569
+ if (this.isStepperDefinition()) {
2570
+ return (await this.stepper()?.validateCurrentStep()) ?? false;
2571
+ }
2572
+ return (await this.dynamicForm()?.validate()) ?? false;
2573
+ }
2574
+ /** Stepper navigation handlers */
2575
+ goPrev() {
2576
+ this.stepper()?.previous();
2577
+ }
2578
+ goNext() {
2579
+ this.stepper()?.next();
1378
2580
  }
1379
2581
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPDynamicDialogComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1380
- 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 }], usesInheritance: true, ngImport: i0, template: "<div class=\"ax-p-4\">\n <axp-dynamic-form\n [formDefinition]=\"config.formDefinition\"\n [context]=\"formContext()\"\n [layoutConfig]=\"config.layoutConfig || defaultLayout()\"\n [layoutLook]=\"'borderless'\"\n [layoutDirection]=\"'vertical'\"\n (contextChange)=\"handleContextChanged($event)\"\n (contextInitiated)=\"handleContextInitiated($event)\"\n >\n </axp-dynamic-form>\n</div>\n\n<ax-footer>\n <ax-prefix>\n <!-- Dynamic footer prefix actions -->\n @if (hasVisibleFooterPrefixActions()) {\n @for (action of footerPrefixActions(); track $index) {\n @if (action.visible != false) {\n <ax-button\n [disabled]=\"action.disabled || isSubmitting()\"\n [text]=\"(action.title | translate | async)!\"\n [look]=\"'outline'\"\n [color]=\"action.color\"\n (onClick)=\"executeAction(action)\"\n >\n <ax-prefix>\n <i class=\"{{ action.icon }}\"></i>\n </ax-prefix>\n @if (action?.items) {\n <ax-dropdown-panel #panel>\n <ax-button-item-list>\n @for (sub of action?.items; track $index) {\n @if (sub.visible != false) {\n <ax-button-item\n [text]=\"(sub.title | translate | async)!\"\n [color]=\"sub.color\"\n [disabled]=\"sub.disabled\"\n (onClick)=\"executeAction(sub)\"\n >\n <ax-prefix>\n <i class=\"fa-light {{ sub.icon }}\"></i>\n </ax-prefix>\n </ax-button-item>\n @if (sub.break) {\n <div class=\"ax-divider\"></div>\n }\n }\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n }\n </ax-button>\n }\n }\n }\n </ax-prefix>\n <ax-suffix>\n <!-- Dynamic footer suffix actions -->\n @if (hasFooterActions()) {\n <!-- Suffix actions -->\n @if (hasVisibleFooterSuffixActions()) {\n @for (action of footerSuffixActions(); track $index) {\n @if (action.visible != false) {\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 <ax-prefix>\n <i class=\"{{ action.icon }}\"></i>\n </ax-prefix>\n @if (action?.items) {\n <ax-dropdown-panel #panel>\n <ax-button-item-list>\n @for (sub of action?.items; track $index) {\n @if (sub.visible != false) {\n <ax-button-item\n [text]=\"(sub.title | translate | async)!\"\n [color]=\"sub.color\"\n [disabled]=\"sub.disabled\"\n (onClick)=\"executeAction(sub)\"\n >\n <ax-prefix>\n <i class=\"fa-light {{ sub.icon }}\"></i>\n </ax-prefix>\n </ax-button-item>\n @if (sub.break) {\n <div class=\"ax-divider\"></div>\n }\n }\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n }\n </ax-button>\n }\n }\n }\n }\n </ax-suffix>\n</ax-footer>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXFormModule }, { kind: "ngmodule", type: AXValidationModule }, { kind: "component", type: AXPDynamicFormComponent, selector: "axp-dynamic-form", inputs: ["formDefinition", "context", "layoutLook", "layoutDirection", "layoutConfig"], outputs: ["contextChange", "contextInitiated", "validityChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i7.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: 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: "component", type: i2$2.AXButtonItemComponent, selector: "ax-button-item", inputs: ["color", "disabled", "text", "selected", "divided", "data", "name"], outputs: ["onClick", "onFocus", "onBlur", "disabledChange"] }, { kind: "component", type: i2$2.AXButtonItemListComponent, selector: "ax-button-item-list", inputs: ["items"], outputs: ["onItemClick"] }, { kind: "ngmodule", type: AXDropdownButtonModule }, { kind: "ngmodule", type: AXDropdownModule }, { kind: "component", type: i3$4.AXDropdownPanelComponent, selector: "ax-dropdown-panel", inputs: ["isOpen", "fitParent", "dropdownWidth", "position", "placement", "_target", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "ngmodule", type: AXLoadingModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2582
+ 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 [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:
2583
+ //
2584
+ AXFormModule }, { kind: "ngmodule", type: AXValidationModule }, { kind: "component", type: AXPDynamicFormComponent, selector: "axp-dynamic-form", inputs: ["formDefinition", "context", "layoutLook", "layoutDirection", "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 }); }
1381
2585
  }
1382
2586
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPDynamicDialogComponent, decorators: [{
1383
2587
  type: Component,
1384
2588
  args: [{ selector: 'axp-dynamic-dialog', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
1385
2589
  CommonModule,
2590
+ //
1386
2591
  AXFormModule,
1387
2592
  AXValidationModule,
1388
2593
  AXPDynamicFormComponent,
2594
+ AXPDynamicFormStepperComponent,
1389
2595
  AXDecoratorModule,
1390
2596
  AXButtonModule,
1391
2597
  AXDropdownButtonModule,
1392
2598
  AXDropdownModule,
1393
2599
  AXLoadingModule,
1394
2600
  AXTranslationModule,
1395
- ], template: "<div class=\"ax-p-4\">\n <axp-dynamic-form\n [formDefinition]=\"config.formDefinition\"\n [context]=\"formContext()\"\n [layoutConfig]=\"config.layoutConfig || defaultLayout()\"\n [layoutLook]=\"'borderless'\"\n [layoutDirection]=\"'vertical'\"\n (contextChange)=\"handleContextChanged($event)\"\n (contextInitiated)=\"handleContextInitiated($event)\"\n >\n </axp-dynamic-form>\n</div>\n\n<ax-footer>\n <ax-prefix>\n <!-- Dynamic footer prefix actions -->\n @if (hasVisibleFooterPrefixActions()) {\n @for (action of footerPrefixActions(); track $index) {\n @if (action.visible != false) {\n <ax-button\n [disabled]=\"action.disabled || isSubmitting()\"\n [text]=\"(action.title | translate | async)!\"\n [look]=\"'outline'\"\n [color]=\"action.color\"\n (onClick)=\"executeAction(action)\"\n >\n <ax-prefix>\n <i class=\"{{ action.icon }}\"></i>\n </ax-prefix>\n @if (action?.items) {\n <ax-dropdown-panel #panel>\n <ax-button-item-list>\n @for (sub of action?.items; track $index) {\n @if (sub.visible != false) {\n <ax-button-item\n [text]=\"(sub.title | translate | async)!\"\n [color]=\"sub.color\"\n [disabled]=\"sub.disabled\"\n (onClick)=\"executeAction(sub)\"\n >\n <ax-prefix>\n <i class=\"fa-light {{ sub.icon }}\"></i>\n </ax-prefix>\n </ax-button-item>\n @if (sub.break) {\n <div class=\"ax-divider\"></div>\n }\n }\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n }\n </ax-button>\n }\n }\n }\n </ax-prefix>\n <ax-suffix>\n <!-- Dynamic footer suffix actions -->\n @if (hasFooterActions()) {\n <!-- Suffix actions -->\n @if (hasVisibleFooterSuffixActions()) {\n @for (action of footerSuffixActions(); track $index) {\n @if (action.visible != false) {\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 <ax-prefix>\n <i class=\"{{ action.icon }}\"></i>\n </ax-prefix>\n @if (action?.items) {\n <ax-dropdown-panel #panel>\n <ax-button-item-list>\n @for (sub of action?.items; track $index) {\n @if (sub.visible != false) {\n <ax-button-item\n [text]=\"(sub.title | translate | async)!\"\n [color]=\"sub.color\"\n [disabled]=\"sub.disabled\"\n (onClick)=\"executeAction(sub)\"\n >\n <ax-prefix>\n <i class=\"fa-light {{ sub.icon }}\"></i>\n </ax-prefix>\n </ax-button-item>\n @if (sub.break) {\n <div class=\"ax-divider\"></div>\n }\n }\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n }\n </ax-button>\n }\n }\n }\n }\n </ax-suffix>\n</ax-footer>\n" }]
2601
+ ], template: "@if (shouldRenderForm()) {\n <div class=\"ax-p-4\">\n <axp-dynamic-form\n [formDefinition]=\"resolvedFormDefinition()\"\n [context]=\"formContext()\"\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" }]
1396
2602
  }], propDecorators: { config: [{
1397
2603
  type: Input,
1398
2604
  args: [{ required: true }]
@@ -1410,19 +2616,28 @@ class AXPDynamicDialogService {
1410
2616
  /**
1411
2617
  * Show a dynamic dialog with the given configuration
1412
2618
  * @param config Dialog configuration including fields, validation, and UI options
1413
- * @returns Promise resolving to dialog result with form values and cancellation status
2619
+ * @returns Promise resolving to dialog reference for controlling the dialog
1414
2620
  */
1415
2621
  async showDialog(config) {
1416
2622
  const component = await Promise.resolve().then(function () { return dynamicDialog_component; }).then(c => c.AXPDynamicDialogComponent);
1417
- const result = await this.popupService.open(component, {
1418
- title: config.title,
1419
- size: config.size || 'md',
1420
- closeButton: false,
1421
- closeOnBackdropClick: false,
1422
- draggable: false,
1423
- data: { config }
2623
+ return new Promise(async (resolve) => {
2624
+ // Open popup and wait for it to close
2625
+ await this.popupService.open(component, {
2626
+ title: config.title,
2627
+ size: config.size || 'md',
2628
+ closeButton: config.closeButton,
2629
+ closeOnBackdropClick: false,
2630
+ draggable: false,
2631
+ data: {
2632
+ config,
2633
+ dialogResult: null,
2634
+ isSubmittingFromDialog: false,
2635
+ callBack: (result) => {
2636
+ resolve(result);
2637
+ }
2638
+ }
2639
+ });
1424
2640
  });
1425
- return result?.data || { context: config.context, cancelled: true };
1426
2641
  }
1427
2642
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPDynamicDialogService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1428
2643
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPDynamicDialogService, providedIn: 'root' }); }
@@ -1434,6 +2649,523 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImpor
1434
2649
  }]
1435
2650
  }] });
1436
2651
 
2652
+ class AXPDynamicFormBuilderService {
2653
+ constructor() {
2654
+ //#region ---- Services & Dependencies ----
2655
+ this.dialogService = inject(AXPDynamicDialogService);
2656
+ }
2657
+ //#endregion
2658
+ //#region ---- Public Methods ----
2659
+ /**
2660
+ * Create a new form builder
2661
+ */
2662
+ form() {
2663
+ return new FormBuilder();
2664
+ }
2665
+ /**
2666
+ * Create a new dialog builder
2667
+ */
2668
+ dialog() {
2669
+ return new DialogBuilder(this.dialogService);
2670
+ }
2671
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPDynamicFormBuilderService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2672
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPDynamicFormBuilderService, providedIn: 'root' }); }
2673
+ }
2674
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPDynamicFormBuilderService, decorators: [{
2675
+ type: Injectable,
2676
+ args: [{
2677
+ providedIn: 'root',
2678
+ }]
2679
+ }] });
2680
+ //#region ---- Form Builder Implementation ----
2681
+ class FormBuilder {
2682
+ constructor() {
2683
+ this.state = {
2684
+ groups: [],
2685
+ layoutConfig: {
2686
+ positions: {
2687
+ default: { colSpan: 12 },
2688
+ md: { colSpan: 8 },
2689
+ lg: { colSpan: 6 },
2690
+ xl: { colSpan: 5 },
2691
+ xxl: { colSpan: 4 },
2692
+ },
2693
+ },
2694
+ look: 'normal',
2695
+ direction: 'vertical',
2696
+ };
2697
+ }
2698
+ group(name, delegate) {
2699
+ const groupBuilder = new GroupBuilder(this, name);
2700
+ if (delegate) {
2701
+ delegate(groupBuilder);
2702
+ }
2703
+ this.addGroup(groupBuilder.build());
2704
+ return this;
2705
+ }
2706
+ layout(config) {
2707
+ this.state.layoutConfig = { ...this.state.layoutConfig, ...config };
2708
+ return this;
2709
+ }
2710
+ look(look) {
2711
+ this.state.look = look;
2712
+ return this;
2713
+ }
2714
+ direction(direction) {
2715
+ this.state.direction = direction;
2716
+ return this;
2717
+ }
2718
+ build() {
2719
+ return {
2720
+ groups: this.state.groups,
2721
+ };
2722
+ }
2723
+ addGroup(group) {
2724
+ this.state.groups.push(group);
2725
+ }
2726
+ }
2727
+ //#endregion
2728
+ //#region ---- Group Builder Implementation ----
2729
+ class GroupBuilder {
2730
+ constructor(formBuilder, name) {
2731
+ this.formBuilder = formBuilder;
2732
+ this.groupState = {
2733
+ name: '',
2734
+ title: '',
2735
+ description: '',
2736
+ parameters: [],
2737
+ };
2738
+ this.groupState.name = name;
2739
+ }
2740
+ title(title) {
2741
+ this.groupState.title = title;
2742
+ return this;
2743
+ }
2744
+ description(description) {
2745
+ this.groupState.description = description;
2746
+ return this;
2747
+ }
2748
+ field(path, delegate) {
2749
+ const fieldBuilder = new FieldBuilder(this, path);
2750
+ if (delegate) {
2751
+ delegate(fieldBuilder);
2752
+ }
2753
+ this.addField(fieldBuilder.build());
2754
+ return this;
2755
+ }
2756
+ group(name, delegate) {
2757
+ const nestedGroupBuilder = new GroupBuilder(this.formBuilder, name);
2758
+ if (delegate) {
2759
+ delegate(nestedGroupBuilder);
2760
+ }
2761
+ this.addGroup(nestedGroupBuilder.build());
2762
+ return this;
2763
+ }
2764
+ build() {
2765
+ return {
2766
+ name: this.groupState.name,
2767
+ title: this.groupState.title,
2768
+ description: this.groupState.description,
2769
+ parameters: this.groupState.parameters,
2770
+ };
2771
+ }
2772
+ addField(field) {
2773
+ this.groupState.parameters.push(field);
2774
+ }
2775
+ addGroup(group) {
2776
+ // For nested groups, we add them to the parent form builder
2777
+ this.formBuilder['addGroup'](group);
2778
+ }
2779
+ }
2780
+ //#endregion
2781
+ //#region ---- Field Builder Implementation ----
2782
+ class FieldBuilder {
2783
+ constructor(groupBuilder, path) {
2784
+ this.groupBuilder = groupBuilder;
2785
+ this.fieldState = {
2786
+ path: '',
2787
+ title: '',
2788
+ description: '',
2789
+ defaultValue: undefined,
2790
+ hidden: undefined,
2791
+ readonly: undefined,
2792
+ disabled: undefined,
2793
+ widget: undefined,
2794
+ };
2795
+ this.fieldState.path = path;
2796
+ this.fieldState.title = path;
2797
+ }
2798
+ //#region ---- Utility Methods ----
2799
+ /**
2800
+ * Merge provided widget options with field-level options
2801
+ */
2802
+ mergeWithFieldOptions(options) {
2803
+ return {
2804
+ hidden: this.fieldState.hidden,
2805
+ readonly: this.fieldState.readonly,
2806
+ disabled: this.fieldState.disabled,
2807
+ ...options,
2808
+ };
2809
+ }
2810
+ //#endregion
2811
+ title(title) {
2812
+ this.fieldState.title = title;
2813
+ return this;
2814
+ }
2815
+ description(description) {
2816
+ this.fieldState.description = description;
2817
+ return this;
2818
+ }
2819
+ options(options) {
2820
+ this.fieldState.defaultValue = options['defaultValue'];
2821
+ this.fieldState.hidden = options['hidden'];
2822
+ this.fieldState.readonly = options['readonly'];
2823
+ this.fieldState.disabled = options['disabled'];
2824
+ return this;
2825
+ }
2826
+ layout(layout) {
2827
+ this.fieldState.layout = layout;
2828
+ return this;
2829
+ }
2830
+ textBox(options) {
2831
+ this.fieldState.widget = {
2832
+ type: 'text-editor',
2833
+ path: this.fieldState.path,
2834
+ defaultValue: this.fieldState.defaultValue,
2835
+ options: this.mergeWithFieldOptions(options),
2836
+ };
2837
+ return this;
2838
+ }
2839
+ largeTextBox(options) {
2840
+ this.fieldState.widget = {
2841
+ type: 'large-text-editor',
2842
+ path: this.fieldState.path,
2843
+ defaultValue: this.fieldState.defaultValue,
2844
+ options: this.mergeWithFieldOptions(options),
2845
+ };
2846
+ return this;
2847
+ }
2848
+ richText(options) {
2849
+ this.fieldState.widget = {
2850
+ type: 'rich-text-editor',
2851
+ path: this.fieldState.path,
2852
+ defaultValue: this.fieldState.defaultValue,
2853
+ options: this.mergeWithFieldOptions(options),
2854
+ };
2855
+ return this;
2856
+ }
2857
+ passwordBox(options) {
2858
+ this.fieldState.widget = {
2859
+ type: 'password-editor',
2860
+ path: this.fieldState.path,
2861
+ defaultValue: this.fieldState.defaultValue,
2862
+ options: this.mergeWithFieldOptions(options),
2863
+ };
2864
+ return this;
2865
+ }
2866
+ selectBox(options) {
2867
+ this.fieldState.widget = {
2868
+ type: 'select-editor',
2869
+ path: this.fieldState.path,
2870
+ defaultValue: this.fieldState.defaultValue,
2871
+ options: this.mergeWithFieldOptions(options),
2872
+ };
2873
+ return this;
2874
+ }
2875
+ selectionList(options) {
2876
+ this.fieldState.widget = {
2877
+ type: 'selection-list-editor',
2878
+ path: this.fieldState.path,
2879
+ defaultValue: this.fieldState.defaultValue,
2880
+ options: this.mergeWithFieldOptions(options),
2881
+ };
2882
+ return this;
2883
+ }
2884
+ lookupBox(options) {
2885
+ this.fieldState.widget = {
2886
+ type: 'lookup-editor',
2887
+ path: this.fieldState.path,
2888
+ defaultValue: this.fieldState.defaultValue,
2889
+ options: this.mergeWithFieldOptions(options),
2890
+ };
2891
+ return this;
2892
+ }
2893
+ numberBox(options) {
2894
+ this.fieldState.widget = {
2895
+ type: 'number-editor',
2896
+ path: this.fieldState.path,
2897
+ defaultValue: this.fieldState.defaultValue,
2898
+ options: this.mergeWithFieldOptions(options),
2899
+ };
2900
+ return this;
2901
+ }
2902
+ dateTimeBox(options) {
2903
+ this.fieldState.widget = {
2904
+ type: 'date-time-editor',
2905
+ path: this.fieldState.path,
2906
+ defaultValue: this.fieldState.defaultValue,
2907
+ options: this.mergeWithFieldOptions(options),
2908
+ };
2909
+ return this;
2910
+ }
2911
+ toggleSwitch(options) {
2912
+ this.fieldState.widget = {
2913
+ type: 'toggle-editor',
2914
+ path: this.fieldState.path,
2915
+ defaultValue: this.fieldState.defaultValue,
2916
+ options: this.mergeWithFieldOptions(options),
2917
+ };
2918
+ return this;
2919
+ }
2920
+ colorBox(options) {
2921
+ this.fieldState.widget = {
2922
+ type: 'color-editor',
2923
+ path: this.fieldState.path,
2924
+ defaultValue: this.fieldState.defaultValue,
2925
+ options: this.mergeWithFieldOptions(options),
2926
+ };
2927
+ return this;
2928
+ }
2929
+ widget(type, options) {
2930
+ this.fieldState.widget = {
2931
+ type,
2932
+ path: this.fieldState.path,
2933
+ defaultValue: this.fieldState.defaultValue,
2934
+ options: this.mergeWithFieldOptions(options),
2935
+ };
2936
+ return this;
2937
+ }
2938
+ build() {
2939
+ return {
2940
+ path: this.fieldState.path,
2941
+ title: this.fieldState.title,
2942
+ description: this.fieldState.description,
2943
+ widget: this.fieldState.widget,
2944
+ layout: this.fieldState.layout,
2945
+ };
2946
+ }
2947
+ }
2948
+ //#endregion
2949
+ //#region ---- Dialog Builder Implementation ----
2950
+ class DialogBuilder extends FormBuilder {
2951
+ constructor(dialogService) {
2952
+ super();
2953
+ this.dialogService = dialogService;
2954
+ this.dialogState = {
2955
+ groups: [],
2956
+ steps: [],
2957
+ layoutConfig: {
2958
+ positions: {
2959
+ default: { colSpan: 12 },
2960
+ md: { colSpan: 8 },
2961
+ lg: { colSpan: 6 },
2962
+ xl: { colSpan: 5 },
2963
+ xxl: { colSpan: 4 },
2964
+ },
2965
+ },
2966
+ look: 'borderless',
2967
+ direction: 'vertical',
2968
+ closeButton: false,
2969
+ title: '',
2970
+ message: '',
2971
+ size: 'md',
2972
+ context: {},
2973
+ actions: {
2974
+ footer: {
2975
+ prefix: [],
2976
+ suffix: [],
2977
+ },
2978
+ },
2979
+ };
2980
+ }
2981
+ // Override to keep chaining within dialog context
2982
+ group(name, delegate) {
2983
+ super.group(name, delegate);
2984
+ return this;
2985
+ }
2986
+ step(id, delegate) {
2987
+ const builder = new StepBuilder(this, id);
2988
+ if (delegate) {
2989
+ delegate(builder);
2990
+ }
2991
+ this.dialogState.steps.push(builder.build());
2992
+ return this;
2993
+ }
2994
+ stepperDirection(direction) {
2995
+ this.dialogState.stepperDirection = direction;
2996
+ return this;
2997
+ }
2998
+ guardNext(guard) {
2999
+ this.dialogState.guardNext = guard;
3000
+ return this;
3001
+ }
3002
+ // Ensure dialog state mirrors form state and chaining type stays IDialogBuilder
3003
+ layout(config) {
3004
+ super.layout(config);
3005
+ this.dialogState.layoutConfig = { ...this.dialogState.layoutConfig, ...config };
3006
+ return this;
3007
+ }
3008
+ look(look) {
3009
+ super.look(look);
3010
+ this.dialogState.look = look;
3011
+ return this;
3012
+ }
3013
+ direction(direction) {
3014
+ super.direction(direction);
3015
+ this.dialogState.direction = direction;
3016
+ return this;
3017
+ }
3018
+ closeButton(closeButton) {
3019
+ this.dialogState.closeButton = closeButton;
3020
+ return this;
3021
+ }
3022
+ title(title) {
3023
+ this.dialogState.title = title;
3024
+ return this;
3025
+ }
3026
+ message(message) {
3027
+ this.dialogState.message = message;
3028
+ return this;
3029
+ }
3030
+ size(size) {
3031
+ this.dialogState.size = size;
3032
+ return this;
3033
+ }
3034
+ context(context) {
3035
+ this.dialogState.context = context;
3036
+ return this;
3037
+ }
3038
+ actions(delegate) {
3039
+ const actionBuilder = new ActionBuilder(this);
3040
+ if (delegate) {
3041
+ delegate(actionBuilder);
3042
+ }
3043
+ return this;
3044
+ }
3045
+ async show() {
3046
+ const built = this.build();
3047
+ const hasSteps = this.dialogState.steps.length > 0;
3048
+ const config = {
3049
+ title: this.dialogState.title,
3050
+ message: this.dialogState.message,
3051
+ closeButton: this.dialogState.closeButton,
3052
+ definition: hasSteps
3053
+ ? {
3054
+ steps: this.dialogState.steps.map((s) => ({
3055
+ id: s.id,
3056
+ title: s.title,
3057
+ description: s.description,
3058
+ icon: s.icon,
3059
+ groups: s.groups,
3060
+ formDirection: s.formDirection,
3061
+ })),
3062
+ }
3063
+ : {
3064
+ steps: [
3065
+ {
3066
+ id: 'form',
3067
+ groups: built.groups,
3068
+ formDirection: this.dialogState.direction,
3069
+ },
3070
+ ],
3071
+ },
3072
+ context: this.dialogState.context,
3073
+ size: this.dialogState.size,
3074
+ actions: this.dialogState.actions,
3075
+ layoutConfig: this.dialogState.layoutConfig,
3076
+ layoutLook: this.dialogState.look,
3077
+ stepper: hasSteps
3078
+ ? {
3079
+ guardNext: this.dialogState.guardNext,
3080
+ stepperDirection: this.dialogState.stepperDirection,
3081
+ }
3082
+ : undefined,
3083
+ };
3084
+ return await this.dialogService.showDialog(config);
3085
+ }
3086
+ }
3087
+ //#endregion
3088
+ //#region ---- Action Builder Implementation ----
3089
+ class ActionBuilder {
3090
+ constructor(dialogBuilder) {
3091
+ this.dialogBuilder = dialogBuilder;
3092
+ }
3093
+ cancel(text) {
3094
+ if (!this.dialogBuilder['dialogState'].actions.footer.suffix) {
3095
+ this.dialogBuilder['dialogState'].actions.footer.suffix = [];
3096
+ }
3097
+ this.dialogBuilder['dialogState'].actions.footer.suffix.push({
3098
+ title: text || '@general:actions.cancel.title',
3099
+ icon: 'fa-times',
3100
+ color: 'default',
3101
+ command: { name: 'cancel' },
3102
+ });
3103
+ return this;
3104
+ }
3105
+ submit(text) {
3106
+ if (!this.dialogBuilder['dialogState'].actions.footer.suffix) {
3107
+ this.dialogBuilder['dialogState'].actions.footer.suffix = [];
3108
+ }
3109
+ this.dialogBuilder['dialogState'].actions.footer.suffix.push({
3110
+ title: text || '@general:actions.submit.title',
3111
+ icon: 'fa-check',
3112
+ color: 'primary',
3113
+ command: { name: 'submit', options: { validate: true } },
3114
+ });
3115
+ return this;
3116
+ }
3117
+ custom(action) {
3118
+ if (!this.dialogBuilder['dialogState'].actions.footer.suffix) {
3119
+ this.dialogBuilder['dialogState'].actions.footer.suffix = [];
3120
+ }
3121
+ this.dialogBuilder['dialogState'].actions.footer.suffix.push(action);
3122
+ return this;
3123
+ }
3124
+ }
3125
+ // #region ---- Step Builder Implementation ----
3126
+ class StepBuilder {
3127
+ constructor(dialogBuilder, id) {
3128
+ this.dialogBuilder = dialogBuilder;
3129
+ this.stepState = {
3130
+ id: '',
3131
+ groups: [],
3132
+ };
3133
+ this.stepState.id = id;
3134
+ }
3135
+ title(title) {
3136
+ this.stepState.title = title;
3137
+ return this;
3138
+ }
3139
+ description(description) {
3140
+ this.stepState.description = description;
3141
+ return this;
3142
+ }
3143
+ icon(icon) {
3144
+ this.stepState.icon = icon;
3145
+ return this;
3146
+ }
3147
+ direction(direction) {
3148
+ this.stepState.formDirection = direction;
3149
+ return this;
3150
+ }
3151
+ group(name, delegate) {
3152
+ const groupBuilder = new GroupBuilder(this.dialogBuilder, name);
3153
+ if (delegate) {
3154
+ delegate(groupBuilder);
3155
+ }
3156
+ this.stepState.groups.push(groupBuilder.build());
3157
+ return this;
3158
+ }
3159
+ build() {
3160
+ return this.stepState;
3161
+ }
3162
+ }
3163
+
3164
+ //#endregion
3165
+
3166
+ //#region ---- Imports ----
3167
+ //#endregion
3168
+
1437
3169
  //#endregion
1438
3170
  //#region ---- Injection Tokens ----
1439
3171
  /**
@@ -1775,7 +3507,7 @@ class AXPExtraPropertiesComponent {
1775
3507
  </axp-widgets-container>
1776
3508
  </div>
1777
3509
 
1778
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: AXFormModule }, { kind: "component", type: i2$1.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$1.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: 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: i7.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i7.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: i4.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3510
+ `, 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 }); }
1779
3511
  }
1780
3512
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPExtraPropertiesComponent, decorators: [{
1781
3513
  type: Component,
@@ -1989,7 +3721,7 @@ class AXPWidgetPropertyViewerComponent {
1989
3721
  this.groupCollapsedStates.set(group, collapsed);
1990
3722
  }
1991
3723
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPWidgetPropertyViewerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1992
- 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$1.AXCollapseComponent, selector: "ax-collapse", inputs: ["disabled", "look", "isCollapsed", "showHeader", "caption", "icon", "isLoading", "headerTemplate"], outputs: ["onClick", "isCollapsedChange"] }, { kind: "component", type: i1$1.AXCollapseGroupComponent, selector: "ax-collapse-group", inputs: ["look", "accordion", "activeIndex"], outputs: ["accordionChange", "activeIndexChange"] }, { kind: "ngmodule", type: AXTabsModule }, { kind: "component", type: i2$3.AXTabsComponent, selector: "ax-tabs", inputs: ["look", "location", "fitParent", "minWidth", "content"], outputs: ["onActiveTabChanged"] }, { kind: "component", type: i2$3.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: i4.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3724
+ 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 }); }
1993
3725
  }
1994
3726
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPWidgetPropertyViewerComponent, decorators: [{
1995
3727
  type: Component,
@@ -2124,7 +3856,7 @@ class AXPExtraPropertiesSchemaComponent {
2124
3856
  return `${k}${i}`;
2125
3857
  }
2126
3858
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPExtraPropertiesSchemaComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2127
- 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.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: AXFormModule }, { kind: "component", type: i2$1.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$1.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: 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: i7.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i7.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: i4.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3859
+ 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 }); }
2128
3860
  }
2129
3861
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPExtraPropertiesSchemaComponent, decorators: [{
2130
3862
  type: Component,
@@ -2275,7 +4007,7 @@ class AXPExtraPropertiesValuesComponent {
2275
4007
  </div>
2276
4008
  </axp-widgets-container>
2277
4009
  </div>
2278
- `, 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$1.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 }); }
4010
+ `, 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 }); }
2279
4011
  }
2280
4012
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPExtraPropertiesValuesComponent, decorators: [{
2281
4013
  type: Component,
@@ -2550,7 +4282,7 @@ class AXPQueryFiltersComponent {
2550
4282
  }
2551
4283
  #effect2;
2552
4284
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPQueryFiltersComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2553
- 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]=\"(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-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.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.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: i7.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i7.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$2.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$1.AXListNavigationDirective, selector: "[axListNavigation]", inputs: ["orientation"], outputs: ["onNavigationChanged", "onPressEnterOrSpace"], exportAs: ["axListNavigation"] }, { kind: "directive", type: i7$1.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: i5.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
4285
+ 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 }); }
2554
4286
  }
2555
4287
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPQueryFiltersComponent, decorators: [{
2556
4288
  type: Component,
@@ -2566,7 +4298,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImpor
2566
4298
  AXPLayoutBuilderModule,
2567
4299
  AXListNavigationModule,
2568
4300
  AXBadgeModule,
2569
- ], 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-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"] }]
4301
+ ], 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"] }]
2570
4302
  }], propDecorators: { listItems: [{
2571
4303
  type: ViewChildren,
2572
4304
  args: ['caseItem']
@@ -2620,7 +4352,7 @@ class AXPQuerySortsComponent {
2620
4352
  });
2621
4353
  }
2622
4354
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPQuerySortsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2623
- 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: i7.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { 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: "pipe", type: i5.AXTranslatorPipe, name: "translate" }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
4355
+ 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 }); }
2624
4356
  }
2625
4357
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPQuerySortsComponent, decorators: [{
2626
4358
  type: Component,
@@ -2720,16 +4452,16 @@ class AXPTemplateViewerComponent extends AXBasePageComponent {
2720
4452
  </div>
2721
4453
 
2722
4454
  @if (config?.showActions !== false) {
2723
- <ax-footer *translate="let t">
4455
+ <ax-footer>
2724
4456
  <ax-suffix>
2725
- <ax-button [text]="t('cancel') | async" (onClick)="handleCancel()"></ax-button>
4457
+ <ax-button [text]="'@general:actions.cancel.title' | translate | async" (onClick)="handleCancel()"></ax-button>
2726
4458
  @if (!config?.readOnly) {
2727
- <ax-button color="primary" [text]="t('submit') | async" (onClick)="handleSubmit(form)"></ax-button>
4459
+ <ax-button color="primary" [text]="'@general:actions.submit.title' | translate | async" (onClick)="handleSubmit(form)"></ax-button>
2728
4460
  }
2729
4461
  </ax-suffix>
2730
4462
  </ax-footer>
2731
4463
  }
2732
- `, 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: i7.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: 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: AXFormModule }, { kind: "component", type: i2$1.AXFormComponent, selector: "ax-form", inputs: ["labelMode", "look", "messageStyle", "updateOn"], outputs: ["onValidate", "updateOnChange"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "directive", type: i5.AXTranslatorDirective, selector: "[translate]" }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }], encapsulation: i0.ViewEncapsulation.None }); }
4464
+ `, 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 }); }
2733
4465
  }
2734
4466
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPTemplateViewerComponent, decorators: [{
2735
4467
  type: Component,
@@ -2745,11 +4477,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImpor
2745
4477
  </div>
2746
4478
 
2747
4479
  @if (config?.showActions !== false) {
2748
- <ax-footer *translate="let t">
4480
+ <ax-footer>
2749
4481
  <ax-suffix>
2750
- <ax-button [text]="t('cancel') | async" (onClick)="handleCancel()"></ax-button>
4482
+ <ax-button [text]="'@general:actions.cancel.title' | translate | async" (onClick)="handleCancel()"></ax-button>
2751
4483
  @if (!config?.readOnly) {
2752
- <ax-button color="primary" [text]="t('submit') | async" (onClick)="handleSubmit(form)"></ax-button>
4484
+ <ax-button color="primary" [text]="'@general:actions.submit.title' | translate | async" (onClick)="handleSubmit(form)"></ax-button>
2753
4485
  }
2754
4486
  </ax-suffix>
2755
4487
  </ax-footer>
@@ -3037,7 +4769,7 @@ class AXPUserAvatarComponent {
3037
4769
  return colors[idx];
3038
4770
  }
3039
4771
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPUserAvatarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3040
- 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$2.AXAvatarComponent, selector: "ax-avatar", inputs: ["color", "size", "shape", "look"], outputs: ["sizeChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i7.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$5.AXImageComponent, selector: "ax-image", inputs: ["width", "height", "overlayMode", "src", "alt", "priority", "lazy"], outputs: ["onLoad", "onError"] }, { kind: "ngmodule", type: AXBadgeModule }], encapsulation: i0.ViewEncapsulation.None }); }
4772
+ 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 }); }
3041
4773
  }
3042
4774
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPUserAvatarComponent, decorators: [{
3043
4775
  type: Component,
@@ -3082,11 +4814,11 @@ class AXPQueryViewsComponent {
3082
4814
  console.log(e);
3083
4815
  }
3084
4816
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPQueryViewsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3085
- 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]=\"('view.createNew' | translate | async) || 'Create New'\"\n >\n </ax-tab-item> -->\n</ax-tabs>\n", dependencies: [{ kind: "ngmodule", type: AXTabsModule }, { kind: "component", type: i2$3.AXTabsComponent, selector: "ax-tabs", inputs: ["look", "location", "fitParent", "minWidth", "content"], outputs: ["onActiveTabChanged"] }, { kind: "component", type: i2$3.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: i4.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
4817
+ 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 }); }
3086
4818
  }
3087
4819
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPQueryViewsComponent, decorators: [{
3088
4820
  type: Component,
3089
- 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]=\"('view.createNew' | translate | async) || 'Create New'\"\n >\n </ax-tab-item> -->\n</ax-tabs>\n" }]
4821
+ 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" }]
3090
4822
  }] });
3091
4823
 
3092
4824
  /**
@@ -3136,7 +4868,7 @@ class AXPWidgetItemComponent {
3136
4868
  return this.widget().icon || 'fa-light fa-document';
3137
4869
  }
3138
4870
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPWidgetItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3139
- 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: i4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], encapsulation: i0.ViewEncapsulation.None }); }
4871
+ 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 }); }
3140
4872
  }
3141
4873
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPWidgetItemComponent, decorators: [{
3142
4874
  type: Component,
@@ -3147,5 +4879,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImpor
3147
4879
  * Generated bundle index. Do not edit.
3148
4880
  */
3149
4881
 
3150
- export { AXPActivityLogComponent, AXPCompareViewComponent, AXPComponentSlot, AXPComponentSlotDirective, AXPComponentSlotModule, AXPComponentSlotRegistryService, AXPDynamicDialogComponent, AXPDynamicDialogService, AXPDynamicFormComponent, AXPExtraPropertiesComponent, AXPExtraPropertiesSchemaComponent, AXPExtraPropertiesValuesComponent, AXPMenuBadgeHelper, AXPQueryColumnsComponent, AXPQueryFiltersComponent, AXPQuerySortsComponent, AXPQueryViewsComponent, 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 };
4882
+ 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 };
3151
4883
  //# sourceMappingURL=acorex-platform-layout-components.mjs.map