@acorex/platform 20.7.8 → 20.7.10

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 (28) hide show
  1. package/common/index.d.ts +26 -5
  2. package/core/index.d.ts +13 -7
  3. package/fesm2022/acorex-platform-common.mjs +5 -1
  4. package/fesm2022/acorex-platform-common.mjs.map +1 -1
  5. package/fesm2022/acorex-platform-core.mjs +20 -11
  6. package/fesm2022/acorex-platform-core.mjs.map +1 -1
  7. package/fesm2022/acorex-platform-layout-builder.mjs +31 -4
  8. package/fesm2022/acorex-platform-layout-builder.mjs.map +1 -1
  9. package/fesm2022/{acorex-platform-layout-components-binding-expression-editor-popup.component-ZnTG7wlJ.mjs → acorex-platform-layout-components-binding-expression-editor-popup.component-Cb6Lk4Ch.mjs} +5 -5
  10. package/fesm2022/{acorex-platform-layout-components-binding-expression-editor-popup.component-ZnTG7wlJ.mjs.map → acorex-platform-layout-components-binding-expression-editor-popup.component-Cb6Lk4Ch.mjs.map} +1 -1
  11. package/fesm2022/acorex-platform-layout-components.mjs +913 -36
  12. package/fesm2022/acorex-platform-layout-components.mjs.map +1 -1
  13. package/fesm2022/acorex-platform-layout-entity.mjs +471 -789
  14. package/fesm2022/acorex-platform-layout-entity.mjs.map +1 -1
  15. package/fesm2022/{acorex-platform-layout-widgets-repeater-widget-column.component-fcCirNxz.mjs → acorex-platform-layout-widgets-repeater-widget-column.component-DnhR00cH.mjs} +2 -2
  16. package/fesm2022/acorex-platform-layout-widgets-repeater-widget-column.component-DnhR00cH.mjs.map +1 -0
  17. package/fesm2022/acorex-platform-layout-widgets.mjs +219 -327
  18. package/fesm2022/acorex-platform-layout-widgets.mjs.map +1 -1
  19. package/fesm2022/{acorex-platform-themes-default-entity-master-list-view.component-DzWjSMSK.mjs → acorex-platform-themes-default-entity-master-list-view.component-HBr-ZTSt.mjs} +20 -5
  20. package/fesm2022/acorex-platform-themes-default-entity-master-list-view.component-HBr-ZTSt.mjs.map +1 -0
  21. package/fesm2022/acorex-platform-themes-default.mjs +2 -2
  22. package/layout/builder/index.d.ts +25 -14
  23. package/layout/components/index.d.ts +295 -2
  24. package/layout/entity/index.d.ts +59 -58
  25. package/layout/widgets/index.d.ts +38 -32
  26. package/package.json +5 -5
  27. package/fesm2022/acorex-platform-layout-widgets-repeater-widget-column.component-fcCirNxz.mjs.map +0 -1
  28. package/fesm2022/acorex-platform-themes-default-entity-master-list-view.component-DzWjSMSK.mjs.map +0 -1
@@ -1,6 +1,6 @@
1
- import * as i2$3 from '@acorex/components/button';
1
+ import * as i1$1 from '@acorex/components/button';
2
2
  import { AXButtonModule } from '@acorex/components/button';
3
- import * as i1$4 from '@acorex/cdk/common';
3
+ import * as i1$5 from '@acorex/cdk/common';
4
4
  import { AXCommonModule } from '@acorex/cdk/common';
5
5
  import * as i2$1 from '@acorex/components/decorators';
6
6
  import { AXDecoratorModule } from '@acorex/components/decorators';
@@ -13,13 +13,13 @@ import { AXFormatModule } from '@acorex/core/format';
13
13
  import { getSystemActions, AXPExpressionEvaluatorService, AXPContextStore, AXPColumnWidthService, AXPDataGenerator, AXPIconLogoConfig, AXPComponentLogoConfig, AXPImageUrlLogoConfig } from '@acorex/platform/core';
14
14
  import { AXPWorkflowService } from '@acorex/platform/workflow';
15
15
  import * as i1 from '@angular/common';
16
- import { CommonModule, NgTemplateOutlet } from '@angular/common';
16
+ import { CommonModule, NgTemplateOutlet, AsyncPipe } from '@angular/common';
17
17
  import * as i0 from '@angular/core';
18
18
  import { input, ChangeDetectionStrategy, ViewEncapsulation, Component, inject, signal, effect, InjectionToken, computed, Injectable, Directive, viewChild, contentChild, ElementRef, output, afterNextRender, model, Injector, ViewContainerRef, runInInjectionContext, Optional, Inject, NgModule, linkedSignal, untracked, HostListener, ViewChildren, Input, EventEmitter, Output } from '@angular/core';
19
19
  import { AXAccordionCdkModule } from '@acorex/cdk/accordion';
20
20
  import { AXTagModule } from '@acorex/components/tag';
21
21
  import { SIGNAL, signalSetFn } from '@angular/core/primitives/signals';
22
- import * as i1$1 from '@acorex/components/badge';
22
+ import * as i1$2 from '@acorex/components/badge';
23
23
  import { AXBadgeComponent, AXBadgeModule } from '@acorex/components/badge';
24
24
  import * as i6 from '@acorex/components/dropdown';
25
25
  import { AXDropdownModule } from '@acorex/components/dropdown';
@@ -27,20 +27,20 @@ import * as i5$1 from '@acorex/components/search-box';
27
27
  import { AXSearchBoxModule } from '@acorex/components/search-box';
28
28
  import * as i2$2 from '@acorex/components/tree-view-legacy';
29
29
  import { AXTreeViewLegacyModule } from '@acorex/components/tree-view-legacy';
30
- import * as i2$4 from '@acorex/components/popover';
30
+ import * as i2$3 from '@acorex/components/popover';
31
31
  import { AXPopoverModule } from '@acorex/components/popover';
32
32
  import * as i3 from '@acorex/components/switch';
33
33
  import { AXSwitchModule } from '@acorex/components/switch';
34
34
  import { moveItemInArray, CdkDropList, CdkDrag, CdkDragHandle } from '@angular/cdk/drag-drop';
35
- import * as i1$2 from '@angular/forms';
35
+ import * as i1$3 from '@angular/forms';
36
36
  import { FormsModule } from '@angular/forms';
37
37
  import { cloneDeep, sortBy, isNil, isEmpty, isEqual, get, set, merge, unionBy, isArray, capitalize } from 'lodash-es';
38
- import * as i2$6 from '@acorex/components/form';
38
+ import * as i2$5 from '@acorex/components/form';
39
39
  import { AXFormModule } from '@acorex/components/form';
40
40
  import { AXTextBoxModule } from '@acorex/components/text-box';
41
- import * as i2$5 from '@acorex/components/check-box';
41
+ import * as i2$4 from '@acorex/components/check-box';
42
42
  import { AXCheckBoxModule } from '@acorex/components/check-box';
43
- import * as i1$3 from '@acorex/components/label';
43
+ import * as i1$4 from '@acorex/components/label';
44
44
  import { AXLabelModule } from '@acorex/components/label';
45
45
  import * as i6$1 from '@acorex/platform/layout/widget-core';
46
46
  import { AXPWidgetCoreModule, AXPWidgetsCatalog, AXPWidgetRegistryService, AXPWidgetGroupEnum } from '@acorex/platform/layout/widget-core';
@@ -58,25 +58,28 @@ import * as i5$2 from '@acorex/components/tag-box';
58
58
  import { AXTagBoxModule } from '@acorex/components/tag-box';
59
59
  import { AXCalendarService } from '@acorex/core/date-time';
60
60
  import { AXPFilterOperatorMiddlewareService, AXPSettingsService, ALL_DEFAULT_OPERATORS, AXPFileStorageService } from '@acorex/platform/common';
61
- import * as i1$5 from '@acorex/components/image-editor';
61
+ import * as i1$6 from '@acorex/components/image-editor';
62
62
  import { AXImageEditorContainerComponent, AXImageEditorModule } from '@acorex/components/image-editor';
63
63
  import * as i3$1 from '@acorex/components/toolbar';
64
64
  import { AXToolBarModule } from '@acorex/components/toolbar';
65
- import * as i2$7 from '@acorex/components/image';
65
+ import { AXDialogService } from '@acorex/components/dialog';
66
+ import { AXToastService } from '@acorex/components/toast';
67
+ import { AXTreeViewComponent } from '@acorex/components/tree-view';
68
+ import { AXPLayoutBuilderService, AXPLayoutRendererComponent } from '@acorex/platform/layout/builder';
69
+ import { Subject, BehaviorSubject, timer, takeUntil } from 'rxjs';
70
+ import * as i2$6 from '@acorex/components/image';
66
71
  import { AXImageModule } from '@acorex/components/image';
67
72
  import { AXPlatform } from '@acorex/core/platform';
68
- import * as i2$8 from '@acorex/components/accordion';
73
+ import * as i2$7 from '@acorex/components/accordion';
69
74
  import { AXAccordionModule } from '@acorex/components/accordion';
70
75
  import { AXButtonGroupModule } from '@acorex/components/button-group';
71
76
  import * as i5$3 from '@acorex/components/tabs';
72
77
  import { AXTabsModule } from '@acorex/components/tabs';
73
- import { BehaviorSubject, timer, Subject, takeUntil } from 'rxjs';
74
78
  import { tap } from 'rxjs/operators';
75
- import * as i1$6 from '@acorex/components/avatar';
79
+ import * as i1$7 from '@acorex/components/avatar';
76
80
  import { AXAvatarModule } from '@acorex/components/avatar';
77
81
  import * as i3$2 from '@acorex/components/select-box';
78
82
  import { AXSelectBoxModule } from '@acorex/components/select-box';
79
- import { AXPLayoutBuilderService } from '@acorex/platform/layout/builder';
80
83
 
81
84
  //#endregion
82
85
  //#region ---- Component Definition ----
@@ -1023,7 +1026,7 @@ class AXPCategoryTreeComponent {
1023
1026
  this.isLoading.set(false);
1024
1027
  }
1025
1028
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPCategoryTreeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1026
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", 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-legacy\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-legacy>\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 @if (actions().canCreate) {\n <ax-button\n slot=\"actions\"\n (onClick)=\"handleCreateRootClick($event)\"\n look=\"solid\"\n color=\"primary\"\n [text]=\"((actions().createLabel || '@general:actions.add-new.title') | translate | async)!\"\n >\n <ax-icon class=\"fas fa-plus\"></ax-icon>\n </ax-button>\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 || '@general:actions.add-new-child.title') | translate | async)!\"\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 || '@general:actions.edit.title') | translate | async)!\"\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 || '@general:actions.delete.title') | translate | async)!\"\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: AXTreeViewLegacyModule }, { kind: "component", type: i2$2.AXTreeViewLegacyComponent, selector: "ax-tree-view-legacy", 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: i5$1.AXSearchBoxComponent, selector: "ax-search-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "value", "state", "name", "id", "look", "class", "delayTime", "type", "autoSearch"], 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: i2$3.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$3.AXButtonItemComponent, selector: "ax-button-item", inputs: ["color", "disabled", "text", "selected", "divided", "data", "name"], outputs: ["onClick", "onFocus", "onBlur", "disabledChange"] }, { kind: "component", type: i2$3.AXButtonItemListComponent, selector: "ax-button-item-list", inputs: ["items", "closeParentOnClick", "lockOnLoading"], 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 }); }
1029
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", 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-legacy\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-legacy>\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 @if (actions().canCreate) {\n <ax-button\n slot=\"actions\"\n (onClick)=\"handleCreateRootClick($event)\"\n look=\"solid\"\n color=\"primary\"\n [text]=\"((actions().createLabel || '@general:actions.add-new.title') | translate | async)!\"\n >\n <ax-icon class=\"fas fa-plus\"></ax-icon>\n </ax-button>\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 || '@general:actions.add-new-child.title') | translate | async)!\"\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 || '@general:actions.edit.title') | translate | async)!\"\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 || '@general:actions.delete.title') | translate | async)!\"\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: AXTreeViewLegacyModule }, { kind: "component", type: i2$2.AXTreeViewLegacyComponent, selector: "ax-tree-view-legacy", 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: i5$1.AXSearchBoxComponent, selector: "ax-search-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "value", "state", "name", "id", "look", "class", "delayTime", "type", "autoSearch"], 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: i1$1.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: i1$1.AXButtonItemComponent, selector: "ax-button-item", inputs: ["color", "disabled", "text", "selected", "divided", "data", "name"], outputs: ["onClick", "onFocus", "onBlur", "disabledChange"] }, { kind: "component", type: i1$1.AXButtonItemListComponent, selector: "ax-button-item-list", inputs: ["items", "closeParentOnClick", "lockOnLoading"], 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 }); }
1027
1030
  }
1028
1031
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPCategoryTreeComponent, decorators: [{
1029
1032
  type: Component,
@@ -1227,7 +1230,7 @@ class AXPColumnItemListComponent {
1227
1230
  </div>
1228
1231
  </div>
1229
1232
  </ax-popover>
1230
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: AXBadgeModule }, { kind: "component", type: i1$1.AXBadgeComponent, selector: "ax-badge", inputs: ["color", "look", "text"] }, { kind: "ngmodule", type: AXPopoverModule }, { kind: "component", type: i2$4.AXPopoverComponent, selector: "ax-popover", inputs: ["width", "disabled", "offsetX", "offsetY", "target", "placement", "content", "openOn", "closeOn", "hasBackdrop", "openAfter", "closeAfter", "repositionOnScroll", "backdropClass", "panelClass", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i2$3.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: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1233
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: AXBadgeModule }, { kind: "component", type: i1$2.AXBadgeComponent, selector: "ax-badge", inputs: ["color", "look", "text"] }, { kind: "ngmodule", type: AXPopoverModule }, { kind: "component", type: i2$3.AXPopoverComponent, selector: "ax-popover", inputs: ["width", "forceDisableActionSheetStyle", "disabled", "offsetX", "offsetY", "target", "placement", "content", "openOn", "closeOn", "hasBackdrop", "openAfter", "closeAfter", "repositionOnScroll", "backdropClass", "panelClass", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1$1.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: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1231
1234
  }
1232
1235
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPColumnItemListComponent, decorators: [{
1233
1236
  type: Component,
@@ -1309,7 +1312,7 @@ class AXPQueryColumnsComponent {
1309
1312
  this.columns.set(columns);
1310
1313
  }
1311
1314
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPQueryColumnsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1312
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", 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$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "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.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" }] }); }
1315
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", 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$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.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.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" }] }); }
1313
1316
  }
1314
1317
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPQueryColumnsComponent, decorators: [{
1315
1318
  type: Component,
@@ -1444,7 +1447,7 @@ class AXPCompareViewComponent {
1444
1447
  // Angular
1445
1448
  CommonModule }, { kind: "ngmodule", type:
1446
1449
  // ACoreX
1447
- AXFormModule }, { kind: "ngmodule", type: AXTextBoxModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "ngmodule", type: AXLabelModule }, { kind: "component", type: i1$3.AXLabelComponent, selector: "ax-label", inputs: ["required", "for"], outputs: ["requiredChange"] }, { kind: "ngmodule", type: AXCheckBoxModule }, { kind: "component", type: i2$5.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:
1450
+ AXFormModule }, { kind: "ngmodule", type: AXTextBoxModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "ngmodule", type: AXLabelModule }, { kind: "component", type: i1$4.AXLabelComponent, selector: "ax-label", inputs: ["required", "for"], outputs: ["requiredChange"] }, { kind: "ngmodule", type: AXCheckBoxModule }, { kind: "component", type: i2$4.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:
1448
1451
  // Platform
1449
1452
  AXPWidgetCoreModule }, { kind: "component", type: i6$1.AXPWidgetContainerComponent, selector: "axp-widgets-container", inputs: ["context", "functions"], outputs: ["onContextChanged"] }, { kind: "directive", type: i6$1.AXPWidgetRendererDirective, selector: "[axp-widget-renderer]", inputs: ["parentNode", "index", "mode", "node"], outputs: ["onOptionsChanged", "onValueChanged", "onLoad"], exportAs: ["widgetRenderer"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }], encapsulation: i0.ViewEncapsulation.None }); }
1450
1453
  }
@@ -2135,7 +2138,7 @@ class AXPDataSelectorComponent extends AXBasePageComponent {
2135
2138
  }
2136
2139
  }
2137
2140
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPDataSelectorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2138
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", 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]=\"searchPlaceholderText()\" [value]=\"searchTerm\"\n (onValueChanged)=\"handleChangeSearchValue($event)\" [axAutoFocus]=\"true\">\n <ax-clear-button></ax-clear-button>\n </ax-search-box>\n </div>\n }\n <!-- TODO: needs to show checkbox for single selection mode too -->\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\" [customWidth]=\"col.width || ''\" [node]=\"{\n path: col.dataPath || 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 @if (config().selectionMode === 'multiple' && selectedCount() > 0) {\n <ax-prefix>\n <div class=\"ax-flex ax-items-center ax-gap-2\">\n <ax-badge [text]=\"selectedCount().toString()\" color=\"primary\"></ax-badge>\n <span class=\"ax-text-base ax-font-medium ax-text-text-primary\">\n {{ '@general:terms.interface.items-selected' | translate | async }}\n </span>\n </div>\n </ax-prefix>\n }\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$4.AXAutoFocusDirective, selector: "[axAutoFocus]", inputs: ["axAutoFocus", "axAutoFocusTime"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i2$3.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$1.AXDataTableComponent, selector: "ax-data-table", inputs: ["dataSource", "selectedRows", "parentField", "rowDetailsTemplate", "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$1.AXRowSelectColumnComponent, selector: "ax-select-column", inputs: ["width", "caption", "fixed"] }, { kind: "ngmodule", type: AXSearchBoxModule }, { kind: "component", type: i5$1.AXSearchBoxComponent, selector: "ax-search-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "value", "state", "name", "id", "look", "class", "delayTime", "type", "autoSearch"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "ngmodule", type: AXPWidgetCoreModule }, { kind: "component", type: i6$1.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: i1$1.AXBadgeComponent, selector: "ax-badge", inputs: ["color", "look", "text"] }, { 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 }); }
2141
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", 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]=\"searchPlaceholderText()\" [value]=\"searchTerm\"\n (onValueChanged)=\"handleChangeSearchValue($event)\" [axAutoFocus]=\"true\">\n <ax-clear-button></ax-clear-button>\n </ax-search-box>\n </div>\n }\n <!-- TODO: needs to show checkbox for single selection mode too -->\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\" [customWidth]=\"col.width || ''\" [node]=\"{\n path: col.dataPath || 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 @if (config().selectionMode === 'multiple' && selectedCount() > 0) {\n <ax-prefix>\n <div class=\"ax-flex ax-items-center ax-gap-2\">\n <ax-badge [text]=\"selectedCount().toString()\" color=\"primary\"></ax-badge>\n <span class=\"ax-text-base ax-font-medium ax-text-text-primary\">\n {{ '@general:terms.interface.items-selected' | translate | async }}\n </span>\n </div>\n </ax-prefix>\n }\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$5.AXAutoFocusDirective, selector: "[axAutoFocus]", inputs: ["axAutoFocus", "axAutoFocusTime"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1$1.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$1.AXDataTableComponent, selector: "ax-data-table", inputs: ["dataSource", "selectedRows", "parentField", "rowDetailsTemplate", "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$1.AXRowSelectColumnComponent, selector: "ax-select-column", inputs: ["width", "caption", "fixed"] }, { kind: "ngmodule", type: AXSearchBoxModule }, { kind: "component", type: i5$1.AXSearchBoxComponent, selector: "ax-search-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "value", "state", "name", "id", "look", "class", "delayTime", "type", "autoSearch"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "ngmodule", type: AXPWidgetCoreModule }, { kind: "component", type: i6$1.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: i1$2.AXBadgeComponent, selector: "ax-badge", inputs: ["color", "look", "text"] }, { 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 }); }
2139
2142
  }
2140
2143
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPDataSelectorComponent, decorators: [{
2141
2144
  type: Component,
@@ -2684,7 +2687,7 @@ class AXPQueryFiltersComponent {
2684
2687
  }
2685
2688
  }
2686
2689
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPQueryFiltersComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2687
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", 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" }, host: { listeners: { "document:keydown": "handleKeyboardEvent($event)" } }, viewQueries: [{ propertyName: "tagBox", first: true, predicate: ["tagBox"], descendants: true, isSignal: true }, { propertyName: "widgetRenderer", first: true, predicate: ["widgetRenderer"], 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 #tagBoxComponent\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 [tagTemplate]=\"tagTemplate\"\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 >\n <ax-suffix class=\"ax-hidden md:ax-block\"><span class=\"ax-text-gray-500\">Ctrl+F</span></ax-suffix>\n </ax-tag-box>\n\n <ng-template #tagTemplate let-item let-index=\"index\">\n <div\n class=\"ax-inline-flex ax-items-center ax-gap-1.5 hover:ax-bg-darkest ax-cursor-pointer ax-rounded-md ax-px-3 ax-py-1 ax-text-sm ax-surface\"\n [class.!ax-bg-primary]=\"item.field === 'all'\"\n [class.!ax-text-white]=\"item.field === 'all'\"\n (click)=\"handleTagClick(item)\"\n >\n <span>{{ item.query }}</span>\n <button (click)=\"handleRemoveTag($event, index)\" type=\"button\">\n <ax-icon class=\"ax-icon ax-icon-close\"></ax-icon>\n </button>\n </div>\n </ng-template>\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\n class=\"md:ax-min-w-72 ax-border ax-surface ax-w-full ax-rounded-md md:ax-max-h-96 ax-max-w-80 md:ax-overflow-auto\"\n >\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\" (keydown.enter)=\"onEnterKeyPressed($event)\">\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())! | translate | async) || ''\"></ax-badge>\n </div>\n <ng-container\n #widgetRenderer=\"widgetRenderer\"\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$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i2$3.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: i2$4.AXPopoverComponent, selector: "ax-popover", inputs: ["width", "disabled", "offsetX", "offsetY", "target", "placement", "content", "openOn", "closeOn", "hasBackdrop", "openAfter", "closeAfter", "repositionOnScroll", "backdropClass", "panelClass", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "ngmodule", type: AXSelectionListModule }, { kind: "ngmodule", type: AXTagBoxModule }, { kind: "component", type: i5$2.AXTagBoxComponent, selector: "ax-tag-box", inputs: ["disabled", "tabIndex", "readonly", "value", "state", "name", "id", "placeholder", "allowNull", "type", "look", "addOnComma", "addOnEnter", "valueField", "textField", "readonlyField", "allowDuplicateValues", "tagTemplate"], outputs: ["onBlur", "onFocus", "valueChange", "stateChange", "onValueChanged", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress", "onTagClick", "onTagDblClick", "onTagContextMenu"] }, { kind: "ngmodule", type: AXPWidgetCoreModule }, { kind: "component", type: i6$1.AXPWidgetContainerComponent, selector: "axp-widgets-container", inputs: ["context", "functions"], outputs: ["onContextChanged"] }, { kind: "directive", type: i6$1.AXPWidgetRendererDirective, selector: "[axp-widget-renderer]", inputs: ["parentNode", "index", "mode", "node"], outputs: ["onOptionsChanged", "onValueChanged", "onLoad"], exportAs: ["widgetRenderer"] }, { kind: "ngmodule", type: AXListNavigationModule }, { kind: "directive", type: i7.AXListNavigationDirective, selector: "[axListNavigation]", inputs: ["orientation"], outputs: ["onNavigationChanged", "onKeypress"], exportAs: ["axListNavigation"] }, { kind: "directive", type: i7.AXListNavigationItemDirective, selector: "[axListNavigationItem]", outputs: ["onKeypress"], exportAs: ["axListNavigationItem"] }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "component", type: i1$1.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 }); }
2690
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", 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" }, host: { listeners: { "document:keydown": "handleKeyboardEvent($event)" } }, viewQueries: [{ propertyName: "tagBox", first: true, predicate: ["tagBox"], descendants: true, isSignal: true }, { propertyName: "widgetRenderer", first: true, predicate: ["widgetRenderer"], 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 #tagBoxComponent\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 [tagTemplate]=\"tagTemplate\"\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 >\n <ax-suffix class=\"ax-hidden md:ax-block\"><span class=\"ax-text-gray-500\">Ctrl+F</span></ax-suffix>\n </ax-tag-box>\n\n <ng-template #tagTemplate let-item let-index=\"index\">\n <div\n class=\"ax-inline-flex ax-items-center ax-gap-1.5 hover:ax-bg-darkest ax-cursor-pointer ax-rounded-md ax-px-3 ax-py-1 ax-text-sm ax-surface\"\n [class.!ax-bg-primary]=\"item.field === 'all'\"\n [class.!ax-text-white]=\"item.field === 'all'\"\n (click)=\"handleTagClick(item)\"\n >\n <span>{{ item.query }}</span>\n <button (click)=\"handleRemoveTag($event, index)\" type=\"button\">\n <ax-icon class=\"ax-icon ax-icon-close\"></ax-icon>\n </button>\n </div>\n </ng-template>\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\n class=\"md:ax-min-w-72 ax-border ax-surface ax-w-full ax-rounded-md md:ax-max-h-96 ax-max-w-80 md:ax-overflow-auto\"\n >\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\" (keydown.enter)=\"onEnterKeyPressed($event)\">\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())! | translate | async) || ''\"></ax-badge>\n </div>\n <ng-container\n #widgetRenderer=\"widgetRenderer\"\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$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1$1.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: i2$3.AXPopoverComponent, selector: "ax-popover", inputs: ["width", "forceDisableActionSheetStyle", "disabled", "offsetX", "offsetY", "target", "placement", "content", "openOn", "closeOn", "hasBackdrop", "openAfter", "closeAfter", "repositionOnScroll", "backdropClass", "panelClass", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "ngmodule", type: AXSelectionListModule }, { kind: "ngmodule", type: AXTagBoxModule }, { kind: "component", type: i5$2.AXTagBoxComponent, selector: "ax-tag-box", inputs: ["disabled", "tabIndex", "readonly", "value", "state", "name", "id", "placeholder", "allowNull", "type", "look", "addOnComma", "addOnEnter", "valueField", "textField", "readonlyField", "allowDuplicateValues", "tagTemplate"], outputs: ["onBlur", "onFocus", "valueChange", "stateChange", "onValueChanged", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress", "onTagClick", "onTagDblClick", "onTagContextMenu"] }, { kind: "ngmodule", type: AXPWidgetCoreModule }, { kind: "component", type: i6$1.AXPWidgetContainerComponent, selector: "axp-widgets-container", inputs: ["context", "functions"], outputs: ["onContextChanged"] }, { kind: "directive", type: i6$1.AXPWidgetRendererDirective, selector: "[axp-widget-renderer]", inputs: ["parentNode", "index", "mode", "node"], outputs: ["onOptionsChanged", "onValueChanged", "onLoad"], exportAs: ["widgetRenderer"] }, { kind: "ngmodule", type: AXListNavigationModule }, { kind: "directive", type: i7.AXListNavigationDirective, selector: "[axListNavigation]", inputs: ["orientation"], outputs: ["onNavigationChanged", "onKeypress"], exportAs: ["axListNavigation"] }, { kind: "directive", type: i7.AXListNavigationItemDirective, selector: "[axListNavigationItem]", outputs: ["onKeypress"], exportAs: ["axListNavigationItem"] }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "component", type: i1$2.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 }); }
2688
2691
  }
2689
2692
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPQueryFiltersComponent, decorators: [{
2690
2693
  type: Component,
@@ -2793,7 +2796,7 @@ class AXPImageEditorPopupComponent extends AXBasePageComponent {
2793
2796
  </ax-button>
2794
2797
  </ax-suffix>
2795
2798
  </ax-footer>
2796
- `, isInline: true, styles: ["::ng-deep ax-image-editor-view>canvas{height:65vh}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXImageEditorModule }, { kind: "component", type: i1$5.AXImageEditorViewComponent, selector: "ax-image-editor-view", inputs: ["showGrid", "src"] }, { kind: "component", type: i1$5.AXImageEditorContainerComponent, selector: "ax-image-editor-container", inputs: ["look", "disabled", "aspectRatio"], outputs: ["onValueChanged"] }, { kind: "component", type: i1$5.AXImageEditorHistoryComponent, selector: "ax-image-editor-history" }, { kind: "ngmodule", type: AXFormModule }, { kind: "component", type: i2$6.AXFormFieldComponent, selector: "ax-form-field", inputs: ["labelMode"] }, { kind: "component", type: i2$6.AXFormComponent, selector: "ax-form", inputs: ["disabled", "readonly", "labelMode", "look", "messageStyle", "updateOn", "inUserInteractionActive"], outputs: ["onValidate", "updateOnChange"] }, { kind: "ngmodule", type: AXToolBarModule }, { kind: "component", type: i3$1.AXToolBarComponent, selector: "ax-toolbar" }, { 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: i2$3.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: AXTranslationModule }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }] }); }
2799
+ `, isInline: true, styles: ["::ng-deep ax-image-editor-view>canvas{height:65vh}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXImageEditorModule }, { kind: "component", type: i1$6.AXImageEditorViewComponent, selector: "ax-image-editor-view", inputs: ["showGrid", "src"] }, { kind: "component", type: i1$6.AXImageEditorContainerComponent, selector: "ax-image-editor-container", inputs: ["look", "disabled", "aspectRatio"], outputs: ["onValueChanged"] }, { kind: "component", type: i1$6.AXImageEditorHistoryComponent, selector: "ax-image-editor-history" }, { kind: "ngmodule", type: AXFormModule }, { kind: "component", type: i2$5.AXFormFieldComponent, selector: "ax-form-field", inputs: ["labelMode"] }, { kind: "component", type: i2$5.AXFormComponent, selector: "ax-form", inputs: ["disabled", "readonly", "labelMode", "look", "messageStyle", "updateOn", "inUserInteractionActive"], outputs: ["onValidate", "updateOnChange"] }, { kind: "ngmodule", type: AXToolBarModule }, { kind: "component", type: i3$1.AXToolBarComponent, selector: "ax-toolbar" }, { 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: i1$1.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: AXTranslationModule }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }] }); }
2797
2800
  }
2798
2801
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPImageEditorPopupComponent, decorators: [{
2799
2802
  type: Component,
@@ -2874,6 +2877,407 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
2874
2877
  args: [{ providedIn: 'root' }]
2875
2878
  }] });
2876
2879
 
2880
+ //#region ---- Imports ----
2881
+ //#endregion
2882
+ //#region ---- Service Interface ----
2883
+ /**
2884
+ * Abstract service interface for menu customization operations.
2885
+ * Implement this interface and provide it via AXP_MENU_CUSTOMIZER_SERVICE token.
2886
+ */
2887
+ class AXPMenuCustomizerService {
2888
+ }
2889
+ /**
2890
+ * Injection token for menu customizer service
2891
+ */
2892
+ const AXP_MENU_CUSTOMIZER_SERVICE = new InjectionToken('AXP_MENU_CUSTOMIZER_SERVICE');
2893
+ //#endregion
2894
+
2895
+ //#region ---- Imports ----
2896
+ //#endregion
2897
+ //#region ---- Menu Customizer Component ----
2898
+ /**
2899
+ * Reusable menu customizer component that allows users to reorder, show/hide,
2900
+ * and manage menu items using a tree-like interface.
2901
+ * Can be used standalone or within popups/dialogs.
2902
+ *
2903
+ * Requires providing AXP_MENU_CUSTOMIZER_SERVICE with an implementation of AXPMenuCustomizerService.
2904
+ */
2905
+ class AXPMenuCustomizerComponent {
2906
+ constructor() {
2907
+ //#region ---- Dependencies ----
2908
+ this.menuCustomizerService = inject(AXP_MENU_CUSTOMIZER_SERVICE);
2909
+ this.layoutBuilder = inject(AXPLayoutBuilderService);
2910
+ this.dialogService = inject(AXDialogService);
2911
+ this.toastService = inject(AXToastService);
2912
+ this.translationService = inject(AXTranslationService);
2913
+ //#endregion
2914
+ //#region ---- Inputs & Outputs ----
2915
+ /** The scope key for loading/saving menu customizations (e.g., 'edition:{id}', 'tenant:{id}') */
2916
+ this.scopeKey = input.required(...(ngDevMode ? [{ debugName: "scopeKey" }] : []));
2917
+ /** Whether to show the toolbar with collapse/expand/reset actions */
2918
+ this.showToolbar = input(true, ...(ngDevMode ? [{ debugName: "showToolbar" }] : []));
2919
+ /** Whether to allow adding custom menu items */
2920
+ this.allowAddItems = input(true, ...(ngDevMode ? [{ debugName: "allowAddItems" }] : []));
2921
+ /** Drag behavior for the tree view: 'none' | 'move' | 'copy' */
2922
+ this.dragBehavior = input('both', ...(ngDevMode ? [{ debugName: "dragBehavior" }] : []));
2923
+ /** Drag area for the tree view: 'node' | 'handler' */
2924
+ this.dragArea = input('handler', ...(ngDevMode ? [{ debugName: "dragArea" }] : []));
2925
+ /** Emitted when changes are saved */
2926
+ this.saved = output();
2927
+ /** Emitted when the customizer is closed/cancelled */
2928
+ this.cancelled = output();
2929
+ //#endregion
2930
+ //#region ---- Component State ----
2931
+ this.tree = viewChild(AXTreeViewComponent, ...(ngDevMode ? [{ debugName: "tree" }] : []));
2932
+ this.treeNodes = signal([], ...(ngDevMode ? [{ debugName: "treeNodes" }] : []));
2933
+ this.isLoading = signal(false, ...(ngDevMode ? [{ debugName: "isLoading" }] : []));
2934
+ this.error = signal('', ...(ngDevMode ? [{ debugName: "error" }] : []));
2935
+ this.isSyncing = false;
2936
+ this.destroy$ = new Subject();
2937
+ }
2938
+ //#endregion
2939
+ //#region ---- Lifecycle ----
2940
+ async ngOnInit() {
2941
+ await this.loadMenuItems();
2942
+ }
2943
+ ngOnDestroy() {
2944
+ this.destroy$.next();
2945
+ this.destroy$.complete();
2946
+ }
2947
+ //#endregion
2948
+ //#region ---- Event Handlers ----
2949
+ /**
2950
+ * Handle before drop validation
2951
+ */
2952
+ async handleBeforeDrop(e) {
2953
+ const targetParent = e.currentParent?.['data'] || null;
2954
+ // Prevent dropping into items with paths (leaf nodes)
2955
+ if (targetParent?.menuItem?.path) {
2956
+ e.canceled = true;
2957
+ const message = await this.translationService.translateAsync('@platform-management:menu-management.messages.error.move');
2958
+ this.toastService.warning(message);
2959
+ return;
2960
+ }
2961
+ }
2962
+ /**
2963
+ * Handle after drop event to sync changes
2964
+ * The event contains information about the moved node and its new position
2965
+ */
2966
+ async handleAfterDrop(event) {
2967
+ await this.syncTreeChanges();
2968
+ }
2969
+ //#endregion
2970
+ //#region ---- Data Loading ----
2971
+ /**
2972
+ * Load menu tree for current scope
2973
+ */
2974
+ async loadMenuItems() {
2975
+ try {
2976
+ this.isLoading.set(true);
2977
+ this.error.set('');
2978
+ const treeNodes = await this.menuCustomizerService.getMenuTree(this.scopeKey());
2979
+ this.treeNodes.set(treeNodes);
2980
+ }
2981
+ catch (error) {
2982
+ this.error.set(error instanceof Error ? error.message : 'Failed to load menu items');
2983
+ const message = await this.translationService.translateAsync('@platform-management:menu-management.messages.error.load');
2984
+ this.toastService.danger(message);
2985
+ }
2986
+ finally {
2987
+ this.isLoading.set(false);
2988
+ }
2989
+ }
2990
+ /**
2991
+ * Sync tree changes to backend
2992
+ */
2993
+ async syncTreeChanges() {
2994
+ if (this.isSyncing) {
2995
+ return;
2996
+ }
2997
+ try {
2998
+ this.isSyncing = true;
2999
+ // Get nodes from signal - the tree component mutates the array in place
3000
+ // so this.treeNodes() will have the updated structure after drag-drop
3001
+ const nodes = this.treeNodes();
3002
+ if (!nodes || nodes.length === 0) {
3003
+ return;
3004
+ }
3005
+ await this.menuCustomizerService.syncTreeChanges(this.scopeKey(), nodes);
3006
+ const message = await this.translationService.translateAsync('@platform-management:menu-management.messages.success.reorder');
3007
+ this.toastService.success(message);
3008
+ }
3009
+ catch (error) {
3010
+ console.error('Failed to sync tree changes:', error);
3011
+ const message = await this.translationService.translateAsync('@platform-management:menu-management.messages.error.sync');
3012
+ this.toastService.danger(message);
3013
+ }
3014
+ finally {
3015
+ this.isSyncing = false;
3016
+ }
3017
+ }
3018
+ //#endregion
3019
+ //#region ---- Public Methods ----
3020
+ /**
3021
+ * Collapse all tree nodes
3022
+ */
3023
+ collapseAll() {
3024
+ this.tree()?.collapseAll();
3025
+ }
3026
+ /**
3027
+ * Expand all tree nodes
3028
+ */
3029
+ expandAll() {
3030
+ this.tree()?.expandAll();
3031
+ }
3032
+ /**
3033
+ * Reset all customizations
3034
+ */
3035
+ async resetCustomizations() {
3036
+ const title = await this.translationService.translateAsync('@platform-management:menu-management.actions.reset.confirm.title');
3037
+ const message = await this.translationService.translateAsync('@platform-management:menu-management.actions.reset.confirm.message');
3038
+ const confirmed = await this.dialogService.confirm(title, message);
3039
+ if (!confirmed)
3040
+ return;
3041
+ try {
3042
+ await this.menuCustomizerService.resetCustomizations(this.scopeKey());
3043
+ const successMessage = await this.translationService.translateAsync('@platform-management:menu-management.messages.success.reset');
3044
+ this.toastService.success(successMessage);
3045
+ }
3046
+ catch (error) {
3047
+ console.error('Failed to reset customizations:', error);
3048
+ const errorMessage = await this.translationService.translateAsync('@platform-management:menu-management.messages.error.reset');
3049
+ this.toastService.danger(errorMessage);
3050
+ }
3051
+ finally {
3052
+ await this.loadMenuItems();
3053
+ }
3054
+ }
3055
+ /**
3056
+ * Add new root menu item
3057
+ */
3058
+ async addRootMenuItem() {
3059
+ await this.showMenuItemDialog(null, null);
3060
+ }
3061
+ //#endregion
3062
+ //#region ---- Action Handlers ----
3063
+ /**
3064
+ * Handle menu item action
3065
+ */
3066
+ async onAction(action, nodeData) {
3067
+ switch (action) {
3068
+ case 'show':
3069
+ await this.showMenuItem(nodeData);
3070
+ break;
3071
+ case 'hide':
3072
+ await this.hideMenuItem(nodeData);
3073
+ break;
3074
+ case 'edit':
3075
+ await this.editMenuItem(nodeData);
3076
+ break;
3077
+ case 'delete':
3078
+ await this.deleteMenuItem(nodeData);
3079
+ break;
3080
+ case 'add-child':
3081
+ await this.addChildMenuItem(nodeData);
3082
+ break;
3083
+ }
3084
+ }
3085
+ /**
3086
+ * Add new child menu item
3087
+ */
3088
+ async addChildMenuItem(parentNodeData) {
3089
+ await this.showMenuItemDialog(null, parentNodeData.menuItem.name ?? null);
3090
+ }
3091
+ //#endregion
3092
+ //#region ---- Menu Item Actions ----
3093
+ /**
3094
+ * Show menu item
3095
+ */
3096
+ async showMenuItem(nodeData) {
3097
+ await this.executeMenuAction(() => this.menuCustomizerService.showMenuItem(this.scopeKey(), nodeData.menuItem.name), '@platform-management:menu-management.messages.success.show', '@platform-management:menu-management.messages.error.show');
3098
+ }
3099
+ /**
3100
+ * Hide menu item
3101
+ */
3102
+ async hideMenuItem(nodeData) {
3103
+ await this.executeMenuAction(() => this.menuCustomizerService.hideMenuItem(this.scopeKey(), nodeData.menuItem.name), '@platform-management:menu-management.messages.success.hide', '@platform-management:menu-management.messages.error.hide');
3104
+ }
3105
+ /**
3106
+ * Edit menu item
3107
+ */
3108
+ async editMenuItem(nodeData) {
3109
+ await this.showMenuItemDialog(nodeData);
3110
+ }
3111
+ /**
3112
+ * Delete custom menu item
3113
+ */
3114
+ async deleteMenuItem(nodeData) {
3115
+ const title = await this.translationService.translateAsync('@general:actions.delete.title');
3116
+ const message = await this.translationService.translateAsync('@platform-management:menu-management.actions.delete.confirm.message');
3117
+ const confirmed = await this.dialogService.confirm(title, message);
3118
+ if (!confirmed)
3119
+ return;
3120
+ try {
3121
+ const item = nodeData.menuItem;
3122
+ if (!item.name)
3123
+ return;
3124
+ await this.menuCustomizerService.deleteCustomMenuItem(this.scopeKey(), item.name);
3125
+ const successMessage = await this.translationService.translateAsync('@platform-management:menu-management.messages.success.delete');
3126
+ this.toastService.success(successMessage);
3127
+ await this.loadMenuItems();
3128
+ }
3129
+ catch (error) {
3130
+ const errorMessage = await this.translationService.translateAsync('@platform-management:menu-management.messages.error.delete');
3131
+ this.toastService.danger(errorMessage);
3132
+ }
3133
+ }
3134
+ //#endregion
3135
+ //#region ---- Dialog Helpers ----
3136
+ /**
3137
+ * Show menu item dialog (add/edit)
3138
+ */
3139
+ async showMenuItemDialog(nodeData, parentName = null) {
3140
+ const item = nodeData?.menuItem;
3141
+ const isEdit = !!item;
3142
+ const title = isEdit
3143
+ ? '@platform-management:menu-management.components.edit-dialog.title'
3144
+ : '@platform-management:menu-management.components.add-dialog.title';
3145
+ const context = {
3146
+ name: item?.name || '',
3147
+ text: item?.text || '',
3148
+ type: item?.type || 'menu',
3149
+ icon: item?.icon || '',
3150
+ path: item?.path || '',
3151
+ priority: item?.priority || 0,
3152
+ description: item?.description || '',
3153
+ };
3154
+ const dialogRef = await this.layoutBuilder
3155
+ .create()
3156
+ .dialog((dialog) => {
3157
+ dialog
3158
+ .setTitle(title)
3159
+ .setContext(context)
3160
+ .content((flex) => {
3161
+ flex
3162
+ .setDirection('column')
3163
+ .formField('@platform-management:menu-management.fields.name', (field) => {
3164
+ field.path('name');
3165
+ field.textBox({
3166
+ placeholder: '@platform-management:menu-management.fields.name',
3167
+ validations: [{ rule: 'required' }],
3168
+ disabled: isEdit && nodeData?.metadata?.isBuiltIn,
3169
+ });
3170
+ })
3171
+ .formField('@platform-management:menu-management.fields.text', (field) => {
3172
+ field.path('text');
3173
+ field.textBox({
3174
+ placeholder: '@platform-management:menu-management.fields.text',
3175
+ validations: [{ rule: 'required' }],
3176
+ });
3177
+ })
3178
+ .formField('@platform-management:menu-management.fields.icon', (field) => {
3179
+ field.path('icon');
3180
+ field.customWidget('icon-chooser', {});
3181
+ })
3182
+ .formField('@platform-management:menu-management.fields.path', (field) => {
3183
+ field.path('path');
3184
+ field.textBox({
3185
+ placeholder: '@platform-management:menu-management.fields.path',
3186
+ disabled: isEdit && nodeData?.metadata?.isBuiltIn,
3187
+ });
3188
+ })
3189
+ .formField('@platform-management:menu-management.fields.priority', (field) => {
3190
+ field.path('priority');
3191
+ field.numberBox({
3192
+ placeholder: '@platform-management:menu-management.fields.priority',
3193
+ step: 10,
3194
+ });
3195
+ })
3196
+ .formField('@platform-management:menu-management.fields.description', (field) => {
3197
+ field.path('description');
3198
+ field.largeTextBox({
3199
+ placeholder: '@platform-management:menu-management.fields.description',
3200
+ rows: 3,
3201
+ });
3202
+ });
3203
+ })
3204
+ .setActions((actions) => {
3205
+ actions.cancel('@general:actions.cancel.title').submit('@general:actions.save.title');
3206
+ });
3207
+ })
3208
+ .show();
3209
+ const action = dialogRef.action();
3210
+ if (action === 'cancel') {
3211
+ dialogRef.close();
3212
+ return;
3213
+ }
3214
+ const formData = dialogRef.context();
3215
+ try {
3216
+ if (isEdit && item?.name) {
3217
+ // Update existing item
3218
+ if (nodeData?.metadata?.isCustom) {
3219
+ await this.menuCustomizerService.updateCustomMenuItem(this.scopeKey(), item.name, formData);
3220
+ }
3221
+ else {
3222
+ await this.menuCustomizerService.updateMenuProperties(this.scopeKey(), item.name, formData);
3223
+ }
3224
+ }
3225
+ else {
3226
+ // Add new custom item
3227
+ const newItem = {
3228
+ name: formData.name,
3229
+ text: formData.text,
3230
+ icon: formData.icon,
3231
+ path: formData.path,
3232
+ priority: formData.priority,
3233
+ description: formData.description,
3234
+ };
3235
+ await this.menuCustomizerService.addCustomMenuItem(this.scopeKey(), newItem, parentName);
3236
+ }
3237
+ const successMessage = await this.translationService.translateAsync('@platform-management:menu-management.messages.success.save');
3238
+ this.toastService.success(successMessage);
3239
+ await this.loadMenuItems();
3240
+ dialogRef.close();
3241
+ }
3242
+ catch (error) {
3243
+ const errorMessage = await this.translationService.translateAsync('@platform-management:menu-management.messages.error.save');
3244
+ this.toastService.danger(errorMessage);
3245
+ }
3246
+ }
3247
+ /**
3248
+ * Execute a menu action with common error handling
3249
+ */
3250
+ async executeMenuAction(action, successMessageKey, errorMessageKey) {
3251
+ try {
3252
+ await action();
3253
+ const message = await this.translationService.translateAsync(successMessageKey);
3254
+ this.toastService.success(message);
3255
+ await this.loadMenuItems();
3256
+ }
3257
+ catch (error) {
3258
+ console.error('Menu action failed:', error);
3259
+ const message = await this.translationService.translateAsync(errorMessageKey);
3260
+ this.toastService.danger(message);
3261
+ }
3262
+ }
3263
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPMenuCustomizerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3264
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: AXPMenuCustomizerComponent, isStandalone: true, selector: "axp-menu-customizer", inputs: { scopeKey: { classPropertyName: "scopeKey", publicName: "scopeKey", isSignal: true, isRequired: true, transformFunction: null }, showToolbar: { classPropertyName: "showToolbar", publicName: "showToolbar", isSignal: true, isRequired: false, transformFunction: null }, allowAddItems: { classPropertyName: "allowAddItems", publicName: "allowAddItems", isSignal: true, isRequired: false, transformFunction: null }, dragBehavior: { classPropertyName: "dragBehavior", publicName: "dragBehavior", isSignal: true, isRequired: false, transformFunction: null }, dragArea: { classPropertyName: "dragArea", publicName: "dragArea", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { saved: "saved", cancelled: "cancelled" }, host: { classAttribute: "axp-menu-customizer" }, viewQueries: [{ propertyName: "tree", first: true, predicate: AXTreeViewComponent, descendants: true, isSignal: true }], ngImport: i0, template: "@if (isLoading()) {\n <!-- Loading State -->\n <axp-state-message\n mode=\"loading\"\n icon=\"fa-light fa-spinner-third fa-spin\"\n [title]=\"\n ('@platform-management:menu-management.components.menu-list.empty-states.loading.title' | translate | async)!\n \"\n [description]=\"\n ('@platform-management:menu-management.components.menu-list.empty-states.loading.description'\n | translate\n | async)!\n \"\n />\n} @else if (error()) {\n <!-- Error State -->\n <axp-state-message\n mode=\"error\"\n icon=\"fa-light fa-circle-exclamation\"\n [title]=\"\n ('@platform-management:menu-management.components.menu-list.empty-states.error.title' | translate | async)!\n \"\n [description]=\"\n ('@platform-management:menu-management.components.menu-list.empty-states.error.description' | translate | async)!\n \"\n >\n <ax-button\n slot=\"actions\"\n [text]=\"'@general:actions.retry.title' | translate | async\"\n [look]=\"'outline'\"\n [color]=\"'primary'\"\n (onClick)=\"loadMenuItems()\"\n >\n <i class=\"fa-light fa-rotate-left\"></i>\n </ax-button>\n </axp-state-message>\n} @else if (treeNodes().length === 0) {\n <!-- Empty State -->\n <axp-state-message\n mode=\"empty\"\n icon=\"fa-light fa-bars\"\n [title]=\"\n ('@platform-management:menu-management.components.menu-list.empty-states.no-data.title' | translate | async)!\n \"\n [description]=\"\n ('@platform-management:menu-management.components.menu-list.empty-states.no-data.description'\n | translate\n | async)!\n \"\n >\n @if (allowAddItems()) {\n <ax-button\n slot=\"actions\"\n [text]=\"'@platform-management:menu-management.actions.add-root.title' | translate | async\"\n [look]=\"'solid'\"\n [color]=\"'primary'\"\n (onClick)=\"addRootMenuItem()\"\n >\n <i class=\"fa-light fa-plus\"></i>\n </ax-button>\n }\n </axp-state-message>\n} @else {\n <!-- Toolbar -->\n @if (showToolbar()) {\n <div class=\"axp-menu-customizer__toolbar\">\n @if (allowAddItems()) {\n <ax-button\n [text]=\"'@platform-management:menu-management.actions.add-root.title' | translate | async\"\n [look]=\"'solid'\"\n [color]=\"'primary'\"\n (onClick)=\"addRootMenuItem()\"\n >\n <ax-prefix>\n <i class=\"fa-light fa-plus\"></i>\n </ax-prefix>\n </ax-button>\n }\n\n <div class=\"axp-menu-customizer__toolbar-spacer\"></div>\n\n <ax-button\n [text]=\"'@platform-management:menu-management.actions.collapse.title' | translate | async\"\n [look]=\"'outline'\"\n (onClick)=\"collapseAll()\"\n >\n <ax-prefix>\n <i class=\"fa-light fa-minus-square\"></i>\n </ax-prefix>\n </ax-button>\n\n <ax-button\n [text]=\"'@platform-management:menu-management.actions.expand.title' | translate | async\"\n [look]=\"'outline'\"\n (onClick)=\"expandAll()\"\n >\n <ax-prefix>\n <i class=\"fa-light fa-plus-square\"></i>\n </ax-prefix>\n </ax-button>\n\n <ax-button\n [text]=\"'@platform-management:menu-management.actions.reset.title' | translate | async\"\n [look]=\"'outline'\"\n [color]=\"'danger'\"\n (onClick)=\"resetCustomizations()\"\n >\n <ax-prefix>\n <i class=\"fa-light fa-rotate-left\"></i>\n </ax-prefix>\n </ax-button>\n </div>\n }\n\n <!-- Menu Tree Content -->\n <div class=\"axp-menu-customizer__container\">\n <div class=\"axp-menu-customizer__tree\">\n <ax-tree-view\n [(datasource)]=\"treeNodes\"\n [look]=\"'default'\"\n [nodeTemplate]=\"itemTemplate\"\n [selectMode]=\"'none'\"\n [showIcons]=\"false\"\n [showChildrenBadge]=\"false\"\n [dragBehavior]=\"dragBehavior()\"\n [dragArea]=\"dragArea()\"\n (onItemsChange)=\"handleAfterDrop($event)\"\n ></ax-tree-view>\n </div>\n </div>\n}\n\n<!-- Custom Item Template -->\n<ng-template #itemTemplate let-node=\"node\" let-level=\"level\">\n @let nodeData = node['data'];\n @let item = nodeData.menuItem;\n @let metadata = nodeData.metadata;\n <div\n class=\"axp-menu-customizer__item\"\n [class.axp-menu-customizer__item--hidden]=\"metadata.isHidden\"\n [class.axp-menu-customizer__item--custom]=\"metadata.isCustom\"\n [class.axp-menu-customizer__item--group]=\"item.type === 'group'\"\n >\n <!-- Icon (hidden for groups) -->\n @if (item.icon && item.type !== 'group') {\n <i class=\"axp-menu-customizer__item-icon\" [class]=\"item.icon\"></i>\n }\n\n <!-- Text or Info -->\n @if (item.type === 'group') {\n <!-- Group Heading -->\n <span class=\"axp-menu-customizer__item-group\">\n <i class=\"fa-light fa-layer-group\"></i>\n {{ item.text | translate | async }}\n </span>\n } @else if (item.type === 'break') {\n <!-- Divider -->\n <span class=\"axp-menu-customizer__item-divider\">\n <i class=\"fa-light fa-minus\"></i>\n {{ '@platform-management:menu-management.states.divider' | translate | async }}\n </span>\n } @else if (item.text) {\n <!-- Regular Menu Item -->\n <span class=\"axp-menu-customizer__item-text\">\n {{ item.text | translate | async }}\n </span>\n } @else if (item.path) {\n <!-- Path-only Item -->\n <span class=\"axp-menu-customizer__item-path\">\n <i class=\"fa-light fa-link\"></i>\n {{ item.path }}\n </span>\n }\n\n <!-- Menu Name/Key -->\n @if (item.name) {\n <code class=\"axp-menu-customizer__item-name\">{{ item.name }}</code>\n }\n\n <!-- Status Badges -->\n @if (metadata.isHidden) {\n <ax-badge\n [text]=\"('@platform-management:menu-management.states.hidden' | translate | async)!\"\n color=\"danger\"\n ></ax-badge>\n } @else if (metadata.isCustom) {\n <ax-badge\n [text]=\"('@platform-management:menu-management.states.custom' | translate | async)!\"\n color=\"success\"\n ></ax-badge>\n } @else if (metadata.isBuiltIn) {\n <ax-badge\n [text]=\"('@platform-management:menu-management.states.built-in' | translate | async)!\"\n color=\"primary\"\n ></ax-badge>\n }\n\n <!-- Actions Dropdown -->\n <ax-button class=\"axp-menu-customizer__item-actions\" [look]=\"'blank'\" [size]=\"'sm'\" [iconOnly]=\"true\">\n <ax-prefix>\n <i class=\"fa-light fa-ellipsis-vertical\"></i>\n </ax-prefix>\n\n <ax-dropdown-panel #panel>\n <ax-button-item-list>\n <!-- Edit (only for items with names) -->\n @if (item.name) {\n <ax-button-item\n [text]=\"('@general:actions.edit.title' | translate | async)!\"\n (onClick)=\"onAction('edit', nodeData); panel.close()\"\n >\n <ax-prefix>\n <i class=\"fa-light fa-edit\"></i>\n </ax-prefix>\n </ax-button-item>\n }\n\n <!-- Show/Hide (only for items with names) -->\n @if (item.name && metadata.isBuiltIn) {\n @if (metadata.isHidden) {\n <ax-button-item\n [text]=\"('@platform-management:menu-management.actions.show.title' | translate | async)!\"\n (onClick)=\"onAction('show', nodeData); panel.close()\"\n >\n <ax-prefix>\n <i class=\"fa-light fa-eye\"></i>\n </ax-prefix>\n </ax-button-item>\n } @else {\n <ax-button-item\n [text]=\"('@platform-management:menu-management.actions.hide.title' | translate | async)!\"\n (onClick)=\"onAction('hide', nodeData); panel.close()\"\n >\n <ax-prefix>\n <i class=\"fa-light fa-eye-slash\"></i>\n </ax-prefix>\n </ax-button-item>\n }\n }\n\n @if (!item.path && (item.type === 'menu' || !item.type) && allowAddItems()) {\n <!-- Add Child -->\n <ax-button-item\n [text]=\"('@platform-management:menu-management.actions.add-child.title' | translate | async)!\"\n (onClick)=\"onAction('add-child', nodeData); panel.close()\"\n >\n <ax-prefix>\n <i class=\"fa-light fa-plus\"></i>\n </ax-prefix>\n </ax-button-item>\n }\n\n <!-- Delete (only for custom items with names) -->\n @if (item.name && metadata.isCustom) {\n <ax-divider></ax-divider>\n <ax-button-item\n [color]=\"'danger'\"\n [text]=\"('@general:actions.delete.title' | translate | async)!\"\n (onClick)=\"onAction('delete', nodeData); panel.close()\"\n >\n <ax-prefix>\n <i class=\"fa-light fa-trash\"></i>\n </ax-prefix>\n </ax-button-item>\n }\n\n <!-- Info message for items without names -->\n @if (!item.name) {\n <ax-divider></ax-divider>\n <div class=\"ax-p-2 ax-text-xs ax-text-neutral-500 ax-italic\">\n {{ '@platform-management:menu-management.messages.info.no-name' | translate | async }}\n </div>\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-button>\n </div>\n</ng-template>\n", styles: [".axp-menu-customizer{display:flex;height:100%;flex-direction:column}.axp-menu-customizer__toolbar{display:flex;align-items:center;gap:.5rem;padding:1rem;border-bottom-width:1px;border-style:solid;--tw-border-opacity: 1;border-color:rgb(229 229 229 / var(--tw-border-opacity, 1))}.axp-menu-customizer__toolbar-spacer{flex:1 1 0%}.axp-menu-customizer__container{display:flex;flex:1 1 0%;flex-direction:column;gap:1rem;overflow:auto;padding:1rem}.axp-menu-customizer__tree{display:flex;flex-direction:column;gap:.5rem}.axp-menu-customizer__item{display:flex;flex:1 1 0%;align-items:center;gap:1rem;border-radius:.375rem;padding:.5rem;border-width:1px;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));transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.axp-menu-customizer__item: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-menu-customizer__item--hidden{opacity:.5}.axp-menu-customizer__item--custom{--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-primary-500),var(--tw-border-opacity, 1))}.axp-menu-customizer__item--group{padding-top:.75rem;padding-bottom:.75rem}.axp-menu-customizer__item-icon{display:flex;align-items:center;justify-content:center;height:1.5rem;width:1.5rem;--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-primary-500),var(--tw-text-opacity, 1))}.axp-menu-customizer__item-text{flex:1 1 0%;font-size:.875rem;line-height:1.25rem;font-weight:500}.axp-menu-customizer__item-group,.axp-menu-customizer__item-divider,.axp-menu-customizer__item-path{display:flex;flex:1 1 0%;align-items:center;gap:.5rem;font-size:.75rem;line-height:1rem;font-style:italic;--tw-text-opacity: 1;color:rgb(115 115 115 / var(--tw-text-opacity, 1))}.axp-menu-customizer__item-divider i,.axp-menu-customizer__item-path i{--tw-text-opacity: 1;color:rgb(163 163 163 / var(--tw-text-opacity, 1))}.axp-menu-customizer__item-name{display:flex;align-items:center;border-radius:.25rem;padding:.25rem .5rem;font-size:.75rem;line-height:1rem;--tw-bg-opacity: 1;background-color:rgb(245 245 245 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(64 64 64 / var(--tw-text-opacity, 1));font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-weight:400;border-width:1px;--tw-border-opacity: 1;border-color:rgb(229 229 229 / var(--tw-border-opacity, 1));white-space:nowrap;-webkit-user-select:all;user-select:all}.axp-menu-customizer__item-actions{margin-left:.5rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1$1.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: i1$1.AXButtonItemComponent, selector: "ax-button-item", inputs: ["color", "disabled", "text", "selected", "divided", "data", "name"], outputs: ["onClick", "onFocus", "onBlur", "disabledChange"] }, { kind: "component", type: i1$1.AXButtonItemListComponent, selector: "ax-button-item-list", inputs: ["items", "closeParentOnClick", "lockOnLoading"], outputs: ["onItemClick"] }, { 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: AXDropdownButtonModule }, { 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: "ngmodule", type: AXTranslationModule }, { kind: "component", type: AXTreeViewComponent, selector: "ax-tree-view", inputs: ["datasource", "selectMode", "selectionBehavior", "dragArea", "dragBehavior", "showIcons", "showChildrenBadge", "expandedIcon", "collapsedIcon", "indentSize", "look", "nodeTemplate", "idField", "titleField", "tooltipField", "iconField", "expandedField", "selectedField", "indeterminateField", "disabledField", "hiddenField", "childrenField", "childrenCountField", "dataField", "inheritDisabled", "expandOnDoubleClick", "doubleClickDuration", "tooltipDelay"], outputs: ["datasourceChange", "onBeforeDrop", "onNodeToggle", "onNodeSelect", "onNodeDoubleClick", "onNodeClick", "onSelectionChange", "onOrderChange", "onMoveChange", "onItemsChange"] }, { kind: "component", type: AXPStateMessageComponent, selector: "axp-state-message", inputs: ["mode", "icon", "title", "description", "variant"] }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "component", type: i1$2.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 }); }
3265
+ }
3266
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPMenuCustomizerComponent, decorators: [{
3267
+ type: Component,
3268
+ args: [{ selector: 'axp-menu-customizer', imports: [
3269
+ CommonModule,
3270
+ AXButtonModule,
3271
+ AXDecoratorModule,
3272
+ AXDropdownButtonModule,
3273
+ AXDropdownModule,
3274
+ AXTranslationModule,
3275
+ AXTreeViewComponent,
3276
+ AXPStateMessageComponent,
3277
+ AXBadgeModule,
3278
+ ], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: { class: 'axp-menu-customizer' }, template: "@if (isLoading()) {\n <!-- Loading State -->\n <axp-state-message\n mode=\"loading\"\n icon=\"fa-light fa-spinner-third fa-spin\"\n [title]=\"\n ('@platform-management:menu-management.components.menu-list.empty-states.loading.title' | translate | async)!\n \"\n [description]=\"\n ('@platform-management:menu-management.components.menu-list.empty-states.loading.description'\n | translate\n | async)!\n \"\n />\n} @else if (error()) {\n <!-- Error State -->\n <axp-state-message\n mode=\"error\"\n icon=\"fa-light fa-circle-exclamation\"\n [title]=\"\n ('@platform-management:menu-management.components.menu-list.empty-states.error.title' | translate | async)!\n \"\n [description]=\"\n ('@platform-management:menu-management.components.menu-list.empty-states.error.description' | translate | async)!\n \"\n >\n <ax-button\n slot=\"actions\"\n [text]=\"'@general:actions.retry.title' | translate | async\"\n [look]=\"'outline'\"\n [color]=\"'primary'\"\n (onClick)=\"loadMenuItems()\"\n >\n <i class=\"fa-light fa-rotate-left\"></i>\n </ax-button>\n </axp-state-message>\n} @else if (treeNodes().length === 0) {\n <!-- Empty State -->\n <axp-state-message\n mode=\"empty\"\n icon=\"fa-light fa-bars\"\n [title]=\"\n ('@platform-management:menu-management.components.menu-list.empty-states.no-data.title' | translate | async)!\n \"\n [description]=\"\n ('@platform-management:menu-management.components.menu-list.empty-states.no-data.description'\n | translate\n | async)!\n \"\n >\n @if (allowAddItems()) {\n <ax-button\n slot=\"actions\"\n [text]=\"'@platform-management:menu-management.actions.add-root.title' | translate | async\"\n [look]=\"'solid'\"\n [color]=\"'primary'\"\n (onClick)=\"addRootMenuItem()\"\n >\n <i class=\"fa-light fa-plus\"></i>\n </ax-button>\n }\n </axp-state-message>\n} @else {\n <!-- Toolbar -->\n @if (showToolbar()) {\n <div class=\"axp-menu-customizer__toolbar\">\n @if (allowAddItems()) {\n <ax-button\n [text]=\"'@platform-management:menu-management.actions.add-root.title' | translate | async\"\n [look]=\"'solid'\"\n [color]=\"'primary'\"\n (onClick)=\"addRootMenuItem()\"\n >\n <ax-prefix>\n <i class=\"fa-light fa-plus\"></i>\n </ax-prefix>\n </ax-button>\n }\n\n <div class=\"axp-menu-customizer__toolbar-spacer\"></div>\n\n <ax-button\n [text]=\"'@platform-management:menu-management.actions.collapse.title' | translate | async\"\n [look]=\"'outline'\"\n (onClick)=\"collapseAll()\"\n >\n <ax-prefix>\n <i class=\"fa-light fa-minus-square\"></i>\n </ax-prefix>\n </ax-button>\n\n <ax-button\n [text]=\"'@platform-management:menu-management.actions.expand.title' | translate | async\"\n [look]=\"'outline'\"\n (onClick)=\"expandAll()\"\n >\n <ax-prefix>\n <i class=\"fa-light fa-plus-square\"></i>\n </ax-prefix>\n </ax-button>\n\n <ax-button\n [text]=\"'@platform-management:menu-management.actions.reset.title' | translate | async\"\n [look]=\"'outline'\"\n [color]=\"'danger'\"\n (onClick)=\"resetCustomizations()\"\n >\n <ax-prefix>\n <i class=\"fa-light fa-rotate-left\"></i>\n </ax-prefix>\n </ax-button>\n </div>\n }\n\n <!-- Menu Tree Content -->\n <div class=\"axp-menu-customizer__container\">\n <div class=\"axp-menu-customizer__tree\">\n <ax-tree-view\n [(datasource)]=\"treeNodes\"\n [look]=\"'default'\"\n [nodeTemplate]=\"itemTemplate\"\n [selectMode]=\"'none'\"\n [showIcons]=\"false\"\n [showChildrenBadge]=\"false\"\n [dragBehavior]=\"dragBehavior()\"\n [dragArea]=\"dragArea()\"\n (onItemsChange)=\"handleAfterDrop($event)\"\n ></ax-tree-view>\n </div>\n </div>\n}\n\n<!-- Custom Item Template -->\n<ng-template #itemTemplate let-node=\"node\" let-level=\"level\">\n @let nodeData = node['data'];\n @let item = nodeData.menuItem;\n @let metadata = nodeData.metadata;\n <div\n class=\"axp-menu-customizer__item\"\n [class.axp-menu-customizer__item--hidden]=\"metadata.isHidden\"\n [class.axp-menu-customizer__item--custom]=\"metadata.isCustom\"\n [class.axp-menu-customizer__item--group]=\"item.type === 'group'\"\n >\n <!-- Icon (hidden for groups) -->\n @if (item.icon && item.type !== 'group') {\n <i class=\"axp-menu-customizer__item-icon\" [class]=\"item.icon\"></i>\n }\n\n <!-- Text or Info -->\n @if (item.type === 'group') {\n <!-- Group Heading -->\n <span class=\"axp-menu-customizer__item-group\">\n <i class=\"fa-light fa-layer-group\"></i>\n {{ item.text | translate | async }}\n </span>\n } @else if (item.type === 'break') {\n <!-- Divider -->\n <span class=\"axp-menu-customizer__item-divider\">\n <i class=\"fa-light fa-minus\"></i>\n {{ '@platform-management:menu-management.states.divider' | translate | async }}\n </span>\n } @else if (item.text) {\n <!-- Regular Menu Item -->\n <span class=\"axp-menu-customizer__item-text\">\n {{ item.text | translate | async }}\n </span>\n } @else if (item.path) {\n <!-- Path-only Item -->\n <span class=\"axp-menu-customizer__item-path\">\n <i class=\"fa-light fa-link\"></i>\n {{ item.path }}\n </span>\n }\n\n <!-- Menu Name/Key -->\n @if (item.name) {\n <code class=\"axp-menu-customizer__item-name\">{{ item.name }}</code>\n }\n\n <!-- Status Badges -->\n @if (metadata.isHidden) {\n <ax-badge\n [text]=\"('@platform-management:menu-management.states.hidden' | translate | async)!\"\n color=\"danger\"\n ></ax-badge>\n } @else if (metadata.isCustom) {\n <ax-badge\n [text]=\"('@platform-management:menu-management.states.custom' | translate | async)!\"\n color=\"success\"\n ></ax-badge>\n } @else if (metadata.isBuiltIn) {\n <ax-badge\n [text]=\"('@platform-management:menu-management.states.built-in' | translate | async)!\"\n color=\"primary\"\n ></ax-badge>\n }\n\n <!-- Actions Dropdown -->\n <ax-button class=\"axp-menu-customizer__item-actions\" [look]=\"'blank'\" [size]=\"'sm'\" [iconOnly]=\"true\">\n <ax-prefix>\n <i class=\"fa-light fa-ellipsis-vertical\"></i>\n </ax-prefix>\n\n <ax-dropdown-panel #panel>\n <ax-button-item-list>\n <!-- Edit (only for items with names) -->\n @if (item.name) {\n <ax-button-item\n [text]=\"('@general:actions.edit.title' | translate | async)!\"\n (onClick)=\"onAction('edit', nodeData); panel.close()\"\n >\n <ax-prefix>\n <i class=\"fa-light fa-edit\"></i>\n </ax-prefix>\n </ax-button-item>\n }\n\n <!-- Show/Hide (only for items with names) -->\n @if (item.name && metadata.isBuiltIn) {\n @if (metadata.isHidden) {\n <ax-button-item\n [text]=\"('@platform-management:menu-management.actions.show.title' | translate | async)!\"\n (onClick)=\"onAction('show', nodeData); panel.close()\"\n >\n <ax-prefix>\n <i class=\"fa-light fa-eye\"></i>\n </ax-prefix>\n </ax-button-item>\n } @else {\n <ax-button-item\n [text]=\"('@platform-management:menu-management.actions.hide.title' | translate | async)!\"\n (onClick)=\"onAction('hide', nodeData); panel.close()\"\n >\n <ax-prefix>\n <i class=\"fa-light fa-eye-slash\"></i>\n </ax-prefix>\n </ax-button-item>\n }\n }\n\n @if (!item.path && (item.type === 'menu' || !item.type) && allowAddItems()) {\n <!-- Add Child -->\n <ax-button-item\n [text]=\"('@platform-management:menu-management.actions.add-child.title' | translate | async)!\"\n (onClick)=\"onAction('add-child', nodeData); panel.close()\"\n >\n <ax-prefix>\n <i class=\"fa-light fa-plus\"></i>\n </ax-prefix>\n </ax-button-item>\n }\n\n <!-- Delete (only for custom items with names) -->\n @if (item.name && metadata.isCustom) {\n <ax-divider></ax-divider>\n <ax-button-item\n [color]=\"'danger'\"\n [text]=\"('@general:actions.delete.title' | translate | async)!\"\n (onClick)=\"onAction('delete', nodeData); panel.close()\"\n >\n <ax-prefix>\n <i class=\"fa-light fa-trash\"></i>\n </ax-prefix>\n </ax-button-item>\n }\n\n <!-- Info message for items without names -->\n @if (!item.name) {\n <ax-divider></ax-divider>\n <div class=\"ax-p-2 ax-text-xs ax-text-neutral-500 ax-italic\">\n {{ '@platform-management:menu-management.messages.info.no-name' | translate | async }}\n </div>\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-button>\n </div>\n</ng-template>\n", styles: [".axp-menu-customizer{display:flex;height:100%;flex-direction:column}.axp-menu-customizer__toolbar{display:flex;align-items:center;gap:.5rem;padding:1rem;border-bottom-width:1px;border-style:solid;--tw-border-opacity: 1;border-color:rgb(229 229 229 / var(--tw-border-opacity, 1))}.axp-menu-customizer__toolbar-spacer{flex:1 1 0%}.axp-menu-customizer__container{display:flex;flex:1 1 0%;flex-direction:column;gap:1rem;overflow:auto;padding:1rem}.axp-menu-customizer__tree{display:flex;flex-direction:column;gap:.5rem}.axp-menu-customizer__item{display:flex;flex:1 1 0%;align-items:center;gap:1rem;border-radius:.375rem;padding:.5rem;border-width:1px;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));transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.axp-menu-customizer__item: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-menu-customizer__item--hidden{opacity:.5}.axp-menu-customizer__item--custom{--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-primary-500),var(--tw-border-opacity, 1))}.axp-menu-customizer__item--group{padding-top:.75rem;padding-bottom:.75rem}.axp-menu-customizer__item-icon{display:flex;align-items:center;justify-content:center;height:1.5rem;width:1.5rem;--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-primary-500),var(--tw-text-opacity, 1))}.axp-menu-customizer__item-text{flex:1 1 0%;font-size:.875rem;line-height:1.25rem;font-weight:500}.axp-menu-customizer__item-group,.axp-menu-customizer__item-divider,.axp-menu-customizer__item-path{display:flex;flex:1 1 0%;align-items:center;gap:.5rem;font-size:.75rem;line-height:1rem;font-style:italic;--tw-text-opacity: 1;color:rgb(115 115 115 / var(--tw-text-opacity, 1))}.axp-menu-customizer__item-divider i,.axp-menu-customizer__item-path i{--tw-text-opacity: 1;color:rgb(163 163 163 / var(--tw-text-opacity, 1))}.axp-menu-customizer__item-name{display:flex;align-items:center;border-radius:.25rem;padding:.25rem .5rem;font-size:.75rem;line-height:1rem;--tw-bg-opacity: 1;background-color:rgb(245 245 245 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(64 64 64 / var(--tw-text-opacity, 1));font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-weight:400;border-width:1px;--tw-border-opacity: 1;border-color:rgb(229 229 229 / var(--tw-border-opacity, 1));white-space:nowrap;-webkit-user-select:all;user-select:all}.axp-menu-customizer__item-actions{margin-left:.5rem}\n"] }]
3279
+ }], propDecorators: { scopeKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "scopeKey", required: true }] }], showToolbar: [{ type: i0.Input, args: [{ isSignal: true, alias: "showToolbar", required: false }] }], allowAddItems: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowAddItems", required: false }] }], dragBehavior: [{ type: i0.Input, args: [{ isSignal: true, alias: "dragBehavior", required: false }] }], dragArea: [{ type: i0.Input, args: [{ isSignal: true, alias: "dragArea", required: false }] }], saved: [{ type: i0.Output, args: ["saved"] }], cancelled: [{ type: i0.Output, args: ["cancelled"] }], tree: [{ type: i0.ViewChild, args: [i0.forwardRef(() => AXTreeViewComponent), { isSignal: true }] }] } });
3280
+
2877
3281
  //#region ---- Component Definition ----
2878
3282
  class AXPSpreadsheetComponent {
2879
3283
  //#endregion
@@ -3457,7 +3861,7 @@ class AXPSpreadsheetComponent {
3457
3861
  }
3458
3862
  }
3459
3863
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPSpreadsheetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3460
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: AXPSpreadsheetComponent, isStandalone: true, selector: "axp-spreadsheet", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: true, transformFunction: null }, rowMode: { classPropertyName: "rowMode", publicName: "rowMode", isSignal: true, isRequired: false, transformFunction: null }, rowsInput: { classPropertyName: "rowsInput", publicName: "rowsInput", isSignal: true, isRequired: false, transformFunction: null }, rowsModel: { classPropertyName: "rowsModel", publicName: "rowsModel", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, emptyCellPlaceholder: { classPropertyName: "emptyCellPlaceholder", publicName: "emptyCellPlaceholder", isSignal: true, isRequired: false, transformFunction: null }, rowTitlePath: { classPropertyName: "rowTitlePath", publicName: "rowTitlePath", isSignal: true, isRequired: false, transformFunction: null }, rowDescriptionPath: { classPropertyName: "rowDescriptionPath", publicName: "rowDescriptionPath", isSignal: true, isRequired: false, transformFunction: null }, allowAddRows: { classPropertyName: "allowAddRows", publicName: "allowAddRows", isSignal: true, isRequired: false, transformFunction: null }, allowRemoveRows: { classPropertyName: "allowRemoveRows", publicName: "allowRemoveRows", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { rowsModel: "rowsModelChange", cellChange: "cellChange", rowChange: "rowChange", spreadsheetChange: "spreadsheetChange" }, host: { listeners: { "document:keydown": "handleKeyDown($event)" }, classAttribute: "axp-spreadsheet" }, ngImport: i0, template: "<!--\n #region ---- Spreadsheet Component Template ----\n-->\n<div class=\"__spreadsheet-container\" (click)=\"handleClickOutside($event)\">\n @if (isColumnsEmpty()) {\n <!-- Empty State: Columns are empty (regardless of rows) -->\n <div class=\"__empty-state\">\n <div class=\"__empty-icon\">\n <i class=\"fa-light fa-table-columns\"></i>\n </div>\n <div class=\"__empty-title\">{{ '@general:state-message.empty-columns.title' | translate | async }}</div>\n <div class=\"__empty-description\">{{ '@general:state-message.empty-columns.description' | translate | async }}\n </div>\n </div>\n } @else if (isEmpty()) {\n <!-- Empty State: Both columns and rows are empty -->\n <div class=\"__empty-state\">\n <div class=\"__empty-icon\">\n <i class=\"fa-light fa-table\"></i>\n </div>\n <div class=\"__empty-title\">{{ '@general:state-message.empty.title' | translate | async }}</div>\n <div class=\"__empty-description\">{{ '@general:state-message.empty.description' | translate | async }}</div>\n </div>\n } @else if (isRowsEmpty()) {\n <!-- Empty State: Only rows are empty - Show columns -->\n <div class=\"__table-wrapper\">\n <table class=\"__table\">\n <!-- Header Row -->\n <thead class=\"__thead\">\n <tr class=\"__header-row\">\n <!-- Corner cell (title) -->\n <th class=\"__corner-cell\">\n @if (title()) {\n <div class=\"__corner-title\">{{ title() | translate | async }}</div>\n }\n @if (rowMode() === 'dynamic' && allowAddRows() && !readonly()) {\n <div class=\"__corner-actions\">\n <ax-button look=\"blank\" color=\"primary\" (onClick)=\"handleAddRow()\"\n [attr.aria-label]=\"'Add Row'\">\n <ax-icon icon=\"far fa-plus\"></ax-icon>\n </ax-button>\n </div>\n }\n </th>\n\n <!-- Column headers -->\n @for (column of columns(); track column.name) {\n <th class=\"__column-header\" [style.width]=\"column.width\">\n <div class=\"__header-content\">\n <div class=\"__header-title\">{{ column.title | translate | async }}</div>\n </div>\n </th>\n }\n </tr>\n </thead>\n\n <!-- Empty State Row -->\n <tbody class=\"__tbody\">\n <tr class=\"__row __row--empty\">\n <td class=\"__row-header\" [attr.colspan]=\"columns().length + 1\">\n <div class=\"__empty-state-inline\">\n <div class=\"__empty-icon\">\n <i class=\"fa-light fa-list\"></i>\n </div>\n <div class=\"__empty-title\">{{ '@general:state-message.empty-rows.title' | translate | async\n }}\n </div>\n <div class=\"__empty-description\">{{ '@general:state-message.empty-rows.description' |\n translate |\n async }}</div>\n </div>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n } @else {\n <!-- Full Spreadsheet: Both columns and rows are available -->\n <div class=\"__table-wrapper\">\n <table class=\"__table\">\n <!-- Header Row -->\n <thead class=\"__thead\">\n <tr class=\"__header-row\">\n <!-- Corner cell (title) -->\n <th class=\"__corner-cell\">\n @if (title()) {\n <div class=\"__corner-title\">{{ title() | translate | async }}</div>\n }\n @if (rowMode() === 'dynamic' && allowAddRows() && !readonly()) {\n <div class=\"__corner-actions\">\n <ax-button look=\"blank\" color=\"primary\" (onClick)=\"handleAddRow()\"\n [attr.aria-label]=\"'Add Row'\">\n <ax-icon icon=\"far fa-plus\"></ax-icon>\n </ax-button>\n </div>\n }\n </th>\n\n <!-- Column headers -->\n @for (column of columns(); track column.name) {\n <th class=\"__column-header\" [style.width]=\"column.width\">\n <div class=\"__header-content\">\n <div class=\"__header-title\">{{ column.title | translate | async }}</div>\n </div>\n </th>\n }\n </tr>\n </thead>\n\n <!-- Body Rows -->\n <tbody class=\"__tbody\">\n <axp-widgets-container [context]=\"spreadsheetContext()\"\n (onContextChanged)=\"handleSpreadsheetContextChange($event)\">\n @for (rowItem of rowsWithIds(); track rowItem.rowId; let rowIndex = $index) {\n <tr class=\"__row\" [class.__row--odd]=\"rowIndex % 2 === 1\">\n <!-- Row header -->\n <td class=\"__row-header\">\n <div class=\"__header-content\">\n @if (rowTitlePath()) {\n <div class=\"__header-title\">{{ getRowTitle(rowItem.row, rowTitlePath()!) }}</div>\n }\n @if (rowDescriptionPath()) {\n <div class=\"__header-description\">{{ getRowDescription(rowItem.row,\n rowDescriptionPath()!) }}</div>\n }\n </div>\n @if (allowRemoveRows() && !readonly()) {\n <div class=\"__header-actions ax-xs ax-opacity-30 hover:ax-opacity-100\">\n <ax-button look=\"blank\" color=\"danger\"\n (onClick)=\"handleRemoveRow(rowItem.rowId, $event)\" [attr.aria-label]=\"'Remove Row'\">\n <ax-icon icon=\"far fa-times\"></ax-icon>\n </ax-button>\n </div>\n }\n </td>\n\n <!-- Spreadsheet cells -->\n @for (column of columns(); track column.name) {\n <td class=\"__cell\" [class.__cell--editing]=\"isCellEditing(rowItem.rowId, column.name)\"\n [class.__cell--readonly]=\"isColumnReadonly(column)\"\n (click)=\"$event.stopPropagation(); handleCellClick(rowItem.rowId, column.name, $event)\">\n @if (isCellEditing(rowItem.rowId, column.name) && !isColumnReadonly(column)) {\n <!-- Edit mode: Show widget in edit mode -->\n <div class=\"__cell-editor\" (blur)=\"handleCellBlur(rowItem.rowId, column.name)\"\n tabindex=\"-1\">\n <ng-container axp-widget-renderer [node]=\"getCellWidgetNode(column, rowIndex)\"\n [mode]=\"'edit'\"></ng-container>\n </div>\n <!-- Floating toolbar for commit/cancel -->\n <div class=\"__cell-toolbar ax-xs\" (click)=\"$event.stopPropagation()\"\n (mousedown)=\"$event.preventDefault(); $event.stopPropagation()\"\n (mouseup)=\"$event.stopPropagation()\" (focusin)=\"$event.stopPropagation()\">\n <ax-button look=\"blank\" color=\"success\" (onClick)=\"commitCellEdit()\"\n [attr.aria-label]=\"'Commit'\">\n <ax-icon icon=\"far fa-check\"></ax-icon>\n </ax-button>\n <ax-button look=\"blank\" color=\"danger\" (onClick)=\"cancelCellEdit()\"\n [attr.aria-label]=\"'Cancel'\">\n <ax-icon icon=\"far fa-times\"></ax-icon>\n </ax-button>\n </div>\n } @else {\n <!-- View mode: Show widget in view mode or placeholder -->\n <div class=\"__cell-value\">\n @if (getCellValue(rowIndex, column.name) !== null &&\n getCellValue(rowIndex, column.name) !== undefined) {\n <ng-container axp-widget-renderer [node]=\"getCellWidgetNode(column, rowIndex)\"\n [mode]=\"'view'\"></ng-container>\n } @else {\n <span class=\"__cell-placeholder\">{{ emptyCellPlaceholder() }}</span>\n }\n </div>\n }\n </td>\n }\n </tr>\n }\n </axp-widgets-container>\n </tbody>\n </table>\n </div>\n }\n</div>\n<!--\n #endregion\n-->", styles: [".axp-spreadsheet{display:flex;height:100%;width:100%;flex-direction:column}.axp-spreadsheet .__spreadsheet-container{position:relative;flex:1 1 0%;overflow:hidden;border-radius:.375rem;border-width:1px;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-spreadsheet .__empty-state{display:flex;min-height:200px;flex-direction:column;align-items:center;justify-content:center;padding:2rem;text-align:center}.axp-spreadsheet .__empty-state .__empty-icon{margin-bottom:1rem}.axp-spreadsheet .__empty-state .__empty-icon i{font-size:2.25rem;line-height:2.5rem;--tw-text-opacity: 1;color:rgb(163 163 163 / var(--tw-text-opacity, 1))}.axp-spreadsheet .__empty-state .__empty-title{margin-bottom:.5rem;font-size:1.125rem;line-height:1.75rem;font-weight:600;--tw-text-opacity: 1;color:rgb(38 38 38 / var(--tw-text-opacity, 1))}.axp-spreadsheet .__empty-state .__empty-description{font-size:.875rem;line-height:1.25rem;--tw-text-opacity: 1;color:rgb(82 82 82 / var(--tw-text-opacity, 1))}.axp-spreadsheet .__empty-state-inline{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:1.5rem;text-align:center}.axp-spreadsheet .__empty-state-inline .__empty-icon{margin-bottom:.75rem}.axp-spreadsheet .__empty-state-inline .__empty-icon i{font-size:1.5rem;line-height:2rem;--tw-text-opacity: 1;color:rgb(163 163 163 / var(--tw-text-opacity, 1))}.axp-spreadsheet .__empty-state-inline .__empty-title{margin-bottom:.25rem;font-size:1rem;line-height:1.5rem;font-weight:600;--tw-text-opacity: 1;color:rgb(38 38 38 / var(--tw-text-opacity, 1))}.axp-spreadsheet .__empty-state-inline .__empty-description{font-size:.75rem;line-height:1rem;--tw-text-opacity: 1;color:rgb(82 82 82 / var(--tw-text-opacity, 1))}.axp-spreadsheet .__table-wrapper{height:100%;width:100%;overflow-x:auto;overflow-y:auto;-webkit-overflow-scrolling:touch}.axp-spreadsheet .__table-wrapper::-webkit-scrollbar{height:8px;width:8px}.axp-spreadsheet .__table-wrapper::-webkit-scrollbar-track{--tw-bg-opacity: 1;background-color:rgb(245 245 245 / var(--tw-bg-opacity, 1))}.axp-spreadsheet .__table-wrapper::-webkit-scrollbar-thumb{border-radius:.25rem;--tw-bg-opacity: 1;background-color:rgb(163 163 163 / var(--tw-bg-opacity, 1))}.axp-spreadsheet .__table-wrapper::-webkit-scrollbar-thumb:hover{--tw-bg-opacity: 1;background-color:rgb(115 115 115 / var(--tw-bg-opacity, 1))}.axp-spreadsheet .__table{min-width:100%;border-collapse:separate;--tw-border-spacing-x: 0px;--tw-border-spacing-y: 0px;border-spacing:var(--tw-border-spacing-x) var(--tw-border-spacing-y)}.axp-spreadsheet .__table .__thead{position:sticky;top:0;z-index:2}.axp-spreadsheet .__table .__thead .__header-row .__corner-cell{position:relative;position:sticky;inset-inline-start:0px;width:200px;min-width:200px;border-width:1px;border-bottom-width:1px;padding:.5rem .75rem;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));z-index:3}.axp-spreadsheet .__table .__thead .__header-row .__corner-cell .__corner-title{text-align:center;font-size:.875rem;line-height:1.25rem;font-weight:600}.axp-spreadsheet .__table .__thead .__header-row .__corner-cell .__corner-actions{position:absolute;top:.25rem;inset-inline-end:.25rem}@media (max-width: 768px){.axp-spreadsheet .__table .__thead .__header-row .__corner-cell{width:200px;min-width:200px;padding:.375rem .5rem}}.axp-spreadsheet .__table .__thead .__header-row .__column-header{position:sticky;top:0;width:200px;min-width:200px;white-space:nowrap;border-bottom-width:1px;padding:.5rem .75rem;text-align:center;font-weight:600;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));z-index:2}.axp-spreadsheet .__table .__thead .__header-row .__column-header.__column-header--empty{width:300px;min-width:300px;white-space:normal}.axp-spreadsheet .__table .__thead .__header-row .__column-header .__header-content{display:flex;flex-direction:column;gap:.25rem}.axp-spreadsheet .__table .__thead .__header-row .__column-header .__header-content .__header-title{font-size:.875rem;line-height:1.25rem;font-weight:500}.axp-spreadsheet .__table .__thead .__header-row .__column-header .__header-content .__header-description{white-space:normal;overflow-wrap:break-word;font-size:.75rem;line-height:1rem;font-weight:400;opacity:.75}.axp-spreadsheet .__table .__thead .__header-row .__column-header .__header-actions{position:absolute;top:.25rem;inset-inline-end:.25rem}@media (max-width: 768px){.axp-spreadsheet .__table .__thead .__header-row .__column-header{width:120px;min-width:120px;padding:.375rem .5rem}.axp-spreadsheet .__table .__thead .__header-row .__column-header .__header-content .__header-title,.axp-spreadsheet .__table .__thead .__header-row .__column-header .__header-content .__header-description{font-size:.75rem;line-height:1rem}}.axp-spreadsheet .__table .__tbody .__row.__row--empty .__row-header{text-align:center}.axp-spreadsheet .__table .__tbody .__row .__row-header{position:relative;position:sticky;inset-inline-start:0px;width:200px;min-width:200px;border-width:1px;border-bottom-width:1px;padding:.5rem .75rem;vertical-align:top;font-weight:600;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));z-index:2}.axp-spreadsheet .__table .__tbody .__row .__row-header .__header-actions{position:absolute;top:.25rem;inset-inline-end:.25rem}.axp-spreadsheet .__table .__tbody .__row .__row-header .__header-content{display:flex;flex-direction:column;gap:.25rem}.axp-spreadsheet .__table .__tbody .__row .__row-header .__header-content .__header-title{font-size:.875rem;line-height:1.25rem;font-weight:500}.axp-spreadsheet .__table .__tbody .__row .__row-header .__header-content .__header-description{font-size:.75rem;line-height:1rem;font-weight:400;opacity:.75}@media (max-width: 768px){.axp-spreadsheet .__table .__tbody .__row .__row-header{width:200px;min-width:200px;padding:.375rem .5rem}.axp-spreadsheet .__table .__tbody .__row .__row-header .__header-content .__header-title,.axp-spreadsheet .__table .__tbody .__row .__row-header .__header-content .__header-description{font-size:.75rem;line-height:1rem}}.axp-spreadsheet .__table .__tbody .__row .__cell{position:relative;min-height:40px;width:200px;min-width:200px;cursor:pointer;border-bottom-width:1px;padding:.5rem .75rem;text-align:center;vertical-align:middle}.axp-spreadsheet .__table .__tbody .__row .__cell:before{content:\"\";pointer-events:none;position:absolute;inset:0;background-color:rgb(0 0 0 / var(--tw-bg-opacity, 1));--tw-bg-opacity: .05;opacity:0;transition-property:opacity;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1);animation-duration:.15s;animation-timing-function:cubic-bezier(.4,0,.2,1)}.axp-spreadsheet .__table .__tbody .__row .__cell:hover:not(.__cell--readonly):not(.__cell--editing):before{opacity:1}.axp-spreadsheet .__table .__tbody .__row .__cell.__cell--readonly{cursor:default}.axp-spreadsheet .__table .__tbody .__row .__cell.__cell--readonly:hover:before{opacity:0}.axp-spreadsheet .__table .__tbody .__row .__cell.__cell--empty{cursor:default}.axp-spreadsheet .__table .__tbody .__row .__cell.__cell--empty:hover:before{opacity:0}.axp-spreadsheet .__table .__tbody .__row .__cell.__cell--editing{position:relative;border-width:2px;--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-primary-500),var(--tw-border-opacity, 1));background-color:rgba(var(--ax-sys-color-primary-500),var(--tw-bg-opacity, 1));--tw-bg-opacity: .1;padding:1px}.axp-spreadsheet .__table .__tbody .__row .__cell.__cell--editing .__cell-editor{width:100%;padding:.5rem .75rem}.axp-spreadsheet .__table .__tbody .__row .__cell.__cell--editing .__cell-toolbar{position:absolute;bottom:-35px;inset-inline-end:0px;display:flex;gap:.125rem;white-space:nowrap;border-radius:.375rem;border-width:1px;padding:.25rem;--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));z-index:100}.axp-spreadsheet .__table .__tbody .__row .__cell .__cell-value{display:flex;min-height:1.25rem;align-items:center;justify-content:center;overflow-wrap:break-word;padding:.125rem;font-size:.875rem;line-height:1.25rem}.axp-spreadsheet .__table .__tbody .__row .__cell .__cell-placeholder{font-size:.875rem;line-height:1.25rem;--tw-text-opacity: 1;color:rgb(163 163 163 / var(--tw-text-opacity, 1))}.axp-spreadsheet .__table .__tbody .__row .__cell .__cell-editor{display:flex;width:100%;align-items:center;justify-content:center}@media (max-width: 768px){.axp-spreadsheet .__table .__tbody .__row .__cell{width:120px;min-width:120px;padding:.375rem .5rem}.axp-spreadsheet .__table .__tbody .__row .__cell .__cell-value{font-size:.75rem;line-height:1rem}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i2$3.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: "ngmodule", type: AXPWidgetCoreModule }, { kind: "component", type: i6$1.AXPWidgetContainerComponent, selector: "axp-widgets-container", inputs: ["context", "functions"], outputs: ["onContextChanged"] }, { kind: "directive", type: i6$1.AXPWidgetRendererDirective, selector: "[axp-widget-renderer]", inputs: ["parentNode", "index", "mode", "node"], outputs: ["onOptionsChanged", "onValueChanged", "onLoad"], exportAs: ["widgetRenderer"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
3864
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: AXPSpreadsheetComponent, isStandalone: true, selector: "axp-spreadsheet", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: true, transformFunction: null }, rowMode: { classPropertyName: "rowMode", publicName: "rowMode", isSignal: true, isRequired: false, transformFunction: null }, rowsInput: { classPropertyName: "rowsInput", publicName: "rowsInput", isSignal: true, isRequired: false, transformFunction: null }, rowsModel: { classPropertyName: "rowsModel", publicName: "rowsModel", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, emptyCellPlaceholder: { classPropertyName: "emptyCellPlaceholder", publicName: "emptyCellPlaceholder", isSignal: true, isRequired: false, transformFunction: null }, rowTitlePath: { classPropertyName: "rowTitlePath", publicName: "rowTitlePath", isSignal: true, isRequired: false, transformFunction: null }, rowDescriptionPath: { classPropertyName: "rowDescriptionPath", publicName: "rowDescriptionPath", isSignal: true, isRequired: false, transformFunction: null }, allowAddRows: { classPropertyName: "allowAddRows", publicName: "allowAddRows", isSignal: true, isRequired: false, transformFunction: null }, allowRemoveRows: { classPropertyName: "allowRemoveRows", publicName: "allowRemoveRows", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { rowsModel: "rowsModelChange", cellChange: "cellChange", rowChange: "rowChange", spreadsheetChange: "spreadsheetChange" }, host: { listeners: { "document:keydown": "handleKeyDown($event)" }, classAttribute: "axp-spreadsheet" }, ngImport: i0, template: "<!--\n #region ---- Spreadsheet Component Template ----\n-->\n<div class=\"__spreadsheet-container\" (click)=\"handleClickOutside($event)\">\n @if (isColumnsEmpty()) {\n <!-- Empty State: Columns are empty (regardless of rows) -->\n <div class=\"__empty-state\">\n <div class=\"__empty-icon\">\n <i class=\"fa-light fa-table-columns\"></i>\n </div>\n <div class=\"__empty-title\">{{ '@general:state-message.empty-columns.title' | translate | async }}</div>\n <div class=\"__empty-description\">{{ '@general:state-message.empty-columns.description' | translate | async }}\n </div>\n </div>\n } @else if (isEmpty()) {\n <!-- Empty State: Both columns and rows are empty -->\n <div class=\"__empty-state\">\n <div class=\"__empty-icon\">\n <i class=\"fa-light fa-table\"></i>\n </div>\n <div class=\"__empty-title\">{{ '@general:state-message.empty.title' | translate | async }}</div>\n <div class=\"__empty-description\">{{ '@general:state-message.empty.description' | translate | async }}</div>\n </div>\n } @else if (isRowsEmpty()) {\n <!-- Empty State: Only rows are empty - Show columns -->\n <div class=\"__table-wrapper\">\n <table class=\"__table\">\n <!-- Header Row -->\n <thead class=\"__thead\">\n <tr class=\"__header-row\">\n <!-- Corner cell (title) -->\n <th class=\"__corner-cell\">\n @if (title()) {\n <div class=\"__corner-title\">{{ title() | translate | async }}</div>\n }\n @if (rowMode() === 'dynamic' && allowAddRows() && !readonly()) {\n <div class=\"__corner-actions\">\n <ax-button look=\"blank\" color=\"primary\" (onClick)=\"handleAddRow()\"\n [attr.aria-label]=\"'Add Row'\">\n <ax-icon icon=\"far fa-plus\"></ax-icon>\n </ax-button>\n </div>\n }\n </th>\n\n <!-- Column headers -->\n @for (column of columns(); track column.name) {\n <th class=\"__column-header\" [style.width]=\"column.width\">\n <div class=\"__header-content\">\n <div class=\"__header-title\">{{ column.title | translate | async }}</div>\n </div>\n </th>\n }\n </tr>\n </thead>\n\n <!-- Empty State Row -->\n <tbody class=\"__tbody\">\n <tr class=\"__row __row--empty\">\n <td class=\"__row-header\" [attr.colspan]=\"columns().length + 1\">\n <div class=\"__empty-state-inline\">\n <div class=\"__empty-icon\">\n <i class=\"fa-light fa-list\"></i>\n </div>\n <div class=\"__empty-title\">{{ '@general:state-message.empty-rows.title' | translate | async\n }}\n </div>\n <div class=\"__empty-description\">{{ '@general:state-message.empty-rows.description' |\n translate |\n async }}</div>\n </div>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n } @else {\n <!-- Full Spreadsheet: Both columns and rows are available -->\n <div class=\"__table-wrapper\">\n <table class=\"__table\">\n <!-- Header Row -->\n <thead class=\"__thead\">\n <tr class=\"__header-row\">\n <!-- Corner cell (title) -->\n <th class=\"__corner-cell\">\n @if (title()) {\n <div class=\"__corner-title\">{{ title() | translate | async }}</div>\n }\n @if (rowMode() === 'dynamic' && allowAddRows() && !readonly()) {\n <div class=\"__corner-actions\">\n <ax-button look=\"blank\" color=\"primary\" (onClick)=\"handleAddRow()\"\n [attr.aria-label]=\"'Add Row'\">\n <ax-icon icon=\"far fa-plus\"></ax-icon>\n </ax-button>\n </div>\n }\n </th>\n\n <!-- Column headers -->\n @for (column of columns(); track column.name) {\n <th class=\"__column-header\" [style.width]=\"column.width\">\n <div class=\"__header-content\">\n <div class=\"__header-title\">{{ column.title | translate | async }}</div>\n </div>\n </th>\n }\n </tr>\n </thead>\n\n <!-- Body Rows -->\n <tbody class=\"__tbody\">\n <axp-widgets-container [context]=\"spreadsheetContext()\"\n (onContextChanged)=\"handleSpreadsheetContextChange($event)\">\n @for (rowItem of rowsWithIds(); track rowItem.rowId; let rowIndex = $index) {\n <tr class=\"__row\" [class.__row--odd]=\"rowIndex % 2 === 1\">\n <!-- Row header -->\n <td class=\"__row-header\">\n <div class=\"__header-content\">\n @if (rowTitlePath()) {\n <div class=\"__header-title\">{{ getRowTitle(rowItem.row, rowTitlePath()!) }}</div>\n }\n @if (rowDescriptionPath()) {\n <div class=\"__header-description\">{{ getRowDescription(rowItem.row,\n rowDescriptionPath()!) }}</div>\n }\n </div>\n @if (allowRemoveRows() && !readonly()) {\n <div class=\"__header-actions ax-xs ax-opacity-30 hover:ax-opacity-100\">\n <ax-button look=\"blank\" color=\"danger\"\n (onClick)=\"handleRemoveRow(rowItem.rowId, $event)\" [attr.aria-label]=\"'Remove Row'\">\n <ax-icon icon=\"far fa-times\"></ax-icon>\n </ax-button>\n </div>\n }\n </td>\n\n <!-- Spreadsheet cells -->\n @for (column of columns(); track column.name) {\n <td class=\"__cell\" [class.__cell--editing]=\"isCellEditing(rowItem.rowId, column.name)\"\n [class.__cell--readonly]=\"isColumnReadonly(column)\"\n (click)=\"$event.stopPropagation(); handleCellClick(rowItem.rowId, column.name, $event)\">\n @if (isCellEditing(rowItem.rowId, column.name) && !isColumnReadonly(column)) {\n <!-- Edit mode: Show widget in edit mode -->\n <div class=\"__cell-editor\" (blur)=\"handleCellBlur(rowItem.rowId, column.name)\"\n tabindex=\"-1\">\n <ng-container axp-widget-renderer [node]=\"getCellWidgetNode(column, rowIndex)\"\n [mode]=\"'edit'\"></ng-container>\n </div>\n <!-- Floating toolbar for commit/cancel -->\n <div class=\"__cell-toolbar ax-xs\" (click)=\"$event.stopPropagation()\"\n (mousedown)=\"$event.preventDefault(); $event.stopPropagation()\"\n (mouseup)=\"$event.stopPropagation()\" (focusin)=\"$event.stopPropagation()\">\n <ax-button look=\"blank\" color=\"success\" (onClick)=\"commitCellEdit()\"\n [attr.aria-label]=\"'Commit'\">\n <ax-icon icon=\"far fa-check\"></ax-icon>\n </ax-button>\n <ax-button look=\"blank\" color=\"danger\" (onClick)=\"cancelCellEdit()\"\n [attr.aria-label]=\"'Cancel'\">\n <ax-icon icon=\"far fa-times\"></ax-icon>\n </ax-button>\n </div>\n } @else {\n <!-- View mode: Show widget in view mode or placeholder -->\n <div class=\"__cell-value\">\n @if (getCellValue(rowIndex, column.name) !== null &&\n getCellValue(rowIndex, column.name) !== undefined) {\n <ng-container axp-widget-renderer [node]=\"getCellWidgetNode(column, rowIndex)\"\n [mode]=\"'view'\"></ng-container>\n } @else {\n <span class=\"__cell-placeholder\">{{ emptyCellPlaceholder() }}</span>\n }\n </div>\n }\n </td>\n }\n </tr>\n }\n </axp-widgets-container>\n </tbody>\n </table>\n </div>\n }\n</div>\n<!--\n #endregion\n-->", styles: [".axp-spreadsheet{display:flex;height:100%;width:100%;flex-direction:column}.axp-spreadsheet .__spreadsheet-container{position:relative;flex:1 1 0%;overflow:hidden;border-radius:.375rem;border-width:1px;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-spreadsheet .__empty-state{display:flex;min-height:200px;flex-direction:column;align-items:center;justify-content:center;padding:2rem;text-align:center}.axp-spreadsheet .__empty-state .__empty-icon{margin-bottom:1rem}.axp-spreadsheet .__empty-state .__empty-icon i{font-size:2.25rem;line-height:2.5rem;--tw-text-opacity: 1;color:rgb(163 163 163 / var(--tw-text-opacity, 1))}.axp-spreadsheet .__empty-state .__empty-title{margin-bottom:.5rem;font-size:1.125rem;line-height:1.75rem;font-weight:600;--tw-text-opacity: 1;color:rgb(38 38 38 / var(--tw-text-opacity, 1))}.axp-spreadsheet .__empty-state .__empty-description{font-size:.875rem;line-height:1.25rem;--tw-text-opacity: 1;color:rgb(82 82 82 / var(--tw-text-opacity, 1))}.axp-spreadsheet .__empty-state-inline{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:1.5rem;text-align:center}.axp-spreadsheet .__empty-state-inline .__empty-icon{margin-bottom:.75rem}.axp-spreadsheet .__empty-state-inline .__empty-icon i{font-size:1.5rem;line-height:2rem;--tw-text-opacity: 1;color:rgb(163 163 163 / var(--tw-text-opacity, 1))}.axp-spreadsheet .__empty-state-inline .__empty-title{margin-bottom:.25rem;font-size:1rem;line-height:1.5rem;font-weight:600;--tw-text-opacity: 1;color:rgb(38 38 38 / var(--tw-text-opacity, 1))}.axp-spreadsheet .__empty-state-inline .__empty-description{font-size:.75rem;line-height:1rem;--tw-text-opacity: 1;color:rgb(82 82 82 / var(--tw-text-opacity, 1))}.axp-spreadsheet .__table-wrapper{height:100%;width:100%;overflow-x:auto;overflow-y:auto;-webkit-overflow-scrolling:touch}.axp-spreadsheet .__table-wrapper::-webkit-scrollbar{height:8px;width:8px}.axp-spreadsheet .__table-wrapper::-webkit-scrollbar-track{--tw-bg-opacity: 1;background-color:rgb(245 245 245 / var(--tw-bg-opacity, 1))}.axp-spreadsheet .__table-wrapper::-webkit-scrollbar-thumb{border-radius:.25rem;--tw-bg-opacity: 1;background-color:rgb(163 163 163 / var(--tw-bg-opacity, 1))}.axp-spreadsheet .__table-wrapper::-webkit-scrollbar-thumb:hover{--tw-bg-opacity: 1;background-color:rgb(115 115 115 / var(--tw-bg-opacity, 1))}.axp-spreadsheet .__table{min-width:100%;border-collapse:separate;--tw-border-spacing-x: 0px;--tw-border-spacing-y: 0px;border-spacing:var(--tw-border-spacing-x) var(--tw-border-spacing-y)}.axp-spreadsheet .__table .__thead{position:sticky;top:0;z-index:2}.axp-spreadsheet .__table .__thead .__header-row .__corner-cell{position:relative;position:sticky;inset-inline-start:0px;width:200px;min-width:200px;border-width:1px;border-bottom-width:1px;padding:.5rem .75rem;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));z-index:3}.axp-spreadsheet .__table .__thead .__header-row .__corner-cell .__corner-title{text-align:center;font-size:.875rem;line-height:1.25rem;font-weight:600}.axp-spreadsheet .__table .__thead .__header-row .__corner-cell .__corner-actions{position:absolute;top:.25rem;inset-inline-end:.25rem}@media (max-width: 768px){.axp-spreadsheet .__table .__thead .__header-row .__corner-cell{width:200px;min-width:200px;padding:.375rem .5rem}}.axp-spreadsheet .__table .__thead .__header-row .__column-header{position:sticky;top:0;width:200px;min-width:200px;white-space:nowrap;border-bottom-width:1px;padding:.5rem .75rem;text-align:center;font-weight:600;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));z-index:2}.axp-spreadsheet .__table .__thead .__header-row .__column-header.__column-header--empty{width:300px;min-width:300px;white-space:normal}.axp-spreadsheet .__table .__thead .__header-row .__column-header .__header-content{display:flex;flex-direction:column;gap:.25rem}.axp-spreadsheet .__table .__thead .__header-row .__column-header .__header-content .__header-title{font-size:.875rem;line-height:1.25rem;font-weight:500}.axp-spreadsheet .__table .__thead .__header-row .__column-header .__header-content .__header-description{white-space:normal;overflow-wrap:break-word;font-size:.75rem;line-height:1rem;font-weight:400;opacity:.75}.axp-spreadsheet .__table .__thead .__header-row .__column-header .__header-actions{position:absolute;top:.25rem;inset-inline-end:.25rem}@media (max-width: 768px){.axp-spreadsheet .__table .__thead .__header-row .__column-header{width:120px;min-width:120px;padding:.375rem .5rem}.axp-spreadsheet .__table .__thead .__header-row .__column-header .__header-content .__header-title,.axp-spreadsheet .__table .__thead .__header-row .__column-header .__header-content .__header-description{font-size:.75rem;line-height:1rem}}.axp-spreadsheet .__table .__tbody .__row.__row--empty .__row-header{text-align:center}.axp-spreadsheet .__table .__tbody .__row .__row-header{position:relative;position:sticky;inset-inline-start:0px;width:200px;min-width:200px;border-width:1px;border-bottom-width:1px;padding:.5rem .75rem;vertical-align:top;font-weight:600;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));z-index:2}.axp-spreadsheet .__table .__tbody .__row .__row-header .__header-actions{position:absolute;top:.25rem;inset-inline-end:.25rem}.axp-spreadsheet .__table .__tbody .__row .__row-header .__header-content{display:flex;flex-direction:column;gap:.25rem}.axp-spreadsheet .__table .__tbody .__row .__row-header .__header-content .__header-title{font-size:.875rem;line-height:1.25rem;font-weight:500}.axp-spreadsheet .__table .__tbody .__row .__row-header .__header-content .__header-description{font-size:.75rem;line-height:1rem;font-weight:400;opacity:.75}@media (max-width: 768px){.axp-spreadsheet .__table .__tbody .__row .__row-header{width:200px;min-width:200px;padding:.375rem .5rem}.axp-spreadsheet .__table .__tbody .__row .__row-header .__header-content .__header-title,.axp-spreadsheet .__table .__tbody .__row .__row-header .__header-content .__header-description{font-size:.75rem;line-height:1rem}}.axp-spreadsheet .__table .__tbody .__row .__cell{position:relative;min-height:40px;width:200px;min-width:200px;cursor:pointer;border-bottom-width:1px;padding:.5rem .75rem;text-align:center;vertical-align:middle}.axp-spreadsheet .__table .__tbody .__row .__cell:before{content:\"\";pointer-events:none;position:absolute;inset:0;background-color:rgb(0 0 0 / var(--tw-bg-opacity, 1));--tw-bg-opacity: .05;opacity:0;transition-property:opacity;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1);animation-duration:.15s;animation-timing-function:cubic-bezier(.4,0,.2,1)}.axp-spreadsheet .__table .__tbody .__row .__cell:hover:not(.__cell--readonly):not(.__cell--editing):before{opacity:1}.axp-spreadsheet .__table .__tbody .__row .__cell.__cell--readonly{cursor:default}.axp-spreadsheet .__table .__tbody .__row .__cell.__cell--readonly:hover:before{opacity:0}.axp-spreadsheet .__table .__tbody .__row .__cell.__cell--empty{cursor:default}.axp-spreadsheet .__table .__tbody .__row .__cell.__cell--empty:hover:before{opacity:0}.axp-spreadsheet .__table .__tbody .__row .__cell.__cell--editing{position:relative;border-width:2px;--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-primary-500),var(--tw-border-opacity, 1));background-color:rgba(var(--ax-sys-color-primary-500),var(--tw-bg-opacity, 1));--tw-bg-opacity: .1;padding:1px}.axp-spreadsheet .__table .__tbody .__row .__cell.__cell--editing .__cell-editor{width:100%;padding:.5rem .75rem}.axp-spreadsheet .__table .__tbody .__row .__cell.__cell--editing .__cell-toolbar{position:absolute;bottom:-35px;inset-inline-end:0px;display:flex;gap:.125rem;white-space:nowrap;border-radius:.375rem;border-width:1px;padding:.25rem;--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));z-index:100}.axp-spreadsheet .__table .__tbody .__row .__cell .__cell-value{display:flex;min-height:1.25rem;align-items:center;justify-content:center;overflow-wrap:break-word;padding:.125rem;font-size:.875rem;line-height:1.25rem}.axp-spreadsheet .__table .__tbody .__row .__cell .__cell-placeholder{font-size:.875rem;line-height:1.25rem;--tw-text-opacity: 1;color:rgb(163 163 163 / var(--tw-text-opacity, 1))}.axp-spreadsheet .__table .__tbody .__row .__cell .__cell-editor{display:flex;width:100%;align-items:center;justify-content:center}@media (max-width: 768px){.axp-spreadsheet .__table .__tbody .__row .__cell{width:120px;min-width:120px;padding:.375rem .5rem}.axp-spreadsheet .__table .__tbody .__row .__cell .__cell-value{font-size:.75rem;line-height:1rem}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1$1.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: "ngmodule", type: AXPWidgetCoreModule }, { kind: "component", type: i6$1.AXPWidgetContainerComponent, selector: "axp-widgets-container", inputs: ["context", "functions"], outputs: ["onContextChanged"] }, { kind: "directive", type: i6$1.AXPWidgetRendererDirective, selector: "[axp-widget-renderer]", inputs: ["parentNode", "index", "mode", "node"], outputs: ["onOptionsChanged", "onValueChanged", "onLoad"], exportAs: ["widgetRenderer"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
3461
3865
  }
3462
3866
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPSpreadsheetComponent, decorators: [{
3463
3867
  type: Component,
@@ -3513,7 +3917,7 @@ class AXPLogoComponent {
3513
3917
  }
3514
3918
  }
3515
3919
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPLogoComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3516
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: AXPLogoComponent, isStandalone: true, selector: "axp-logo", inputs: { source: "source" }, host: { classAttribute: "ax-flex ax-justify-center" }, usesOnChanges: true, ngImport: i0, template: "@switch (logoType) { \n @case ('url') {\n <ax-image [width]=\"source.width\" [height]=\"source.height\" [src]=\"source.url\"></ax-image>\n } \n @case ('component') {\n <ng-container *ngComponentOutlet=\"source.component\"></ng-container>\n } \n @case ('icon') {\n <i [class]=\"source.icon\" [style.color]=\"source.color\"></i>\n } \n}\n\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"], exportAs: ["ngComponentOutlet"] }, { kind: "ngmodule", type: AXImageModule }, { kind: "component", type: i2$7.AXImageComponent, selector: "ax-image", inputs: ["width", "height", "overlayMode", "src", "alt", "priority", "lazy"], outputs: ["onLoad", "onError"] }, { kind: "ngmodule", type: AXDecoratorModule }] }); }
3920
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: AXPLogoComponent, isStandalone: true, selector: "axp-logo", inputs: { source: "source" }, host: { classAttribute: "ax-flex ax-justify-center" }, usesOnChanges: true, ngImport: i0, template: "@switch (logoType) { \n @case ('url') {\n <ax-image [width]=\"source.width\" [height]=\"source.height\" [src]=\"source.url\"></ax-image>\n } \n @case ('component') {\n <ng-container *ngComponentOutlet=\"source.component\"></ng-container>\n } \n @case ('icon') {\n <i [class]=\"source.icon\" [style.color]=\"source.color\"></i>\n } \n}\n\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"], exportAs: ["ngComponentOutlet"] }, { kind: "ngmodule", type: AXImageModule }, { kind: "component", type: i2$6.AXImageComponent, selector: "ax-image", inputs: ["width", "height", "overlayMode", "src", "alt", "priority", "lazy"], outputs: ["onLoad", "onError"] }, { kind: "ngmodule", type: AXDecoratorModule }] }); }
3517
3921
  }
3518
3922
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPLogoComponent, decorators: [{
3519
3923
  type: Component,
@@ -3729,7 +4133,7 @@ class AXPPropertyViewerComponent {
3729
4133
  const expressionPath = this.getExpressionPath(prop);
3730
4134
  const raw = get(this.context(), expressionPath);
3731
4135
  const currentValue = typeof raw === 'string' ? raw : '';
3732
- const { AXPBindingExpressionEditorPopupComponent } = await import('./acorex-platform-layout-components-binding-expression-editor-popup.component-ZnTG7wlJ.mjs');
4136
+ const { AXPBindingExpressionEditorPopupComponent } = await import('./acorex-platform-layout-components-binding-expression-editor-popup.component-Cb6Lk4Ch.mjs');
3733
4137
  const result = await this.popupService.open(AXPBindingExpressionEditorPopupComponent, {
3734
4138
  title: '@general:widgets.triggers.edit-binding-expression',
3735
4139
  size: 'lg',
@@ -3745,7 +4149,7 @@ class AXPPropertyViewerComponent {
3745
4149
  }
3746
4150
  }
3747
4151
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPPropertyViewerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3748
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: AXPPropertyViewerComponent, isStandalone: true, selector: "axp-property-viewer", inputs: { tabsInput: { classPropertyName: "tabsInput", publicName: "tabsInput", isSignal: true, isRequired: false, 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 <!-- #region Shared property row template (used in both advanced and simple modes) -->\n <ng-template #propertyRow let-prop=\"prop\" let-translateTitle=\"translateTitle\">\n <div class=\"ax-flex ax-flex-col ax-gap-2 ax-py-2\">\n <!-- Property header: title + value/expression toggle (when binding.enabled) -->\n <div class=\"ax-flex ax-items-center ax-gap-2 ax-w-full\">\n @if (prop.showLabel !== false) {\n @if (translateTitle) {\n <span class=\"ax-font-semibold ax-flex-1 ax-min-w-0\">{{ prop.title | translate | async }}</span>\n } @else {\n <span class=\"ax-font-semibold ax-flex-1 ax-min-w-0\">{{ prop.title }}</span>\n }\n }\n @if (prop.binding?.enabled) {\n <div class=\"ax-flex ax-gap-1 ax-shrink-0 ax-xs\">\n <ax-button [toggleable]=\"true\" [selected]=\"isExpressionMode(prop)\" look=\"twotone\"\n [color]=\"isExpressionMode(prop) ? 'primary' : 'default'\" class=\"ax-shrink-0\"\n [title]=\"(isExpressionMode(prop) ? '@general:terms.common.expression' : '@general:terms.common.value') | translate | async\"\n (selectedChange)=\"setExpressionMode(prop, $event)\">\n @if (isExpressionMode(prop)) {\n <ax-icon icon=\"fa-light fa-code\"></ax-icon>\n } @else {\n <ax-icon icon=\"fa-light fa-keyboard\"></ax-icon>\n }\n </ax-button>\n </div>\n }\n </div>\n <!-- Property content: Open Editor button (expression mode) or widget renderer (value mode) -->\n @if (prop.binding?.enabled && isExpressionMode(prop)) {\n <ax-button look=\"twotone\" color=\"primary\" size=\"sm\" class=\"ax-w-full\"\n [text]=\"'@general:widgets.triggers.open-editor' | translate | async\" (onClick)=\"openBindingEditor(prop)\"\n [title]=\"'@general:widgets.triggers.edit-binding-expression' | translate | async\">\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-code\"></ax-icon>\n </ax-prefix>\n </ax-button>\n } @else if (prop.schema.interface) {\n <ng-container axp-widget-renderer [node]=\"prop.schema.interface\" [mode]=\"'edit'\">\n </ng-container>\n }\n </div>\n </ng-template>\n <!-- #endregion -->\n\n <!-- #region Advanced mode: tabs + accordion groups -->\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-accordion-group [accordion]=\"false\" [look]=\"'flat'\">\n @for (group of groups(); track $index) {\n <ax-accordion-item class=\"!ax-mb-0\" [caption]=\"group.title\" [isCollapsed]=\"group.isCollapsed\"\n (isCollapsedChange)=\"handleCollapsedChange(group.name, $event)\">\n <div class=\"ax-flex ax-flex-col\">\n @for (p of group.props; track $index) {\n <ng-container *ngTemplateOutlet=\"propertyRow; context: { prop: p, translateTitle: false }\">\n </ng-container>\n }\n </div>\n </ax-accordion-item>\n }\n </ax-accordion-group>\n </div>\n </div>\n }\n <!-- #endregion -->\n\n <!-- #region Simple mode: flat list of properties with padding -->\n @else {\n <div class=\"ax-flex ax-flex-col ax-p-4 ax-gap-4\">\n @for (group of groups(); track $index) {\n @for (p of group.props; track $index) {\n <ng-container *ngTemplateOutlet=\"propertyRow; context: { prop: p, translateTitle: true }\">\n </ng-container>\n }\n }\n </div>\n }\n <!-- #endregion -->\n</axp-widgets-container>", styles: ["axp-property-viewer ax-accordion-item .ax-accordion-header{font-weight:600!important;border-bottom-width:1px!important;background-color:rgb(var(--ax-sys-color-lighter-surface))!important;color:rgb(var(--ax-sys-color-on-lighter-surface))!important;border-color:rgb(var(--ax-sys-color-border-lighter-surface))!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: AXAccordionModule }, { kind: "component", type: i2$8.AXAccordionItemComponent, selector: "ax-accordion-item", inputs: ["isCollapsed", "icon", "caption", "isLoading", "headerTemplate", "look", "disabled"], outputs: ["isCollapsedChange", "isLoadingChange", "onClick"] }, { kind: "component", type: i2$8.AXAccordionGroupComponent, selector: "ax-accordion-group", inputs: ["accordion", "activeIndex", "look", "collapsedOnItemClick"], outputs: ["activeIndexChange"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i2$3.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: AXButtonGroupModule }, { 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: AXTabsModule }, { kind: "component", type: i5$3.AXTabsComponent, selector: "ax-tabs", inputs: ["look", "location", "fitParent", "minWidth", "content"], outputs: ["onActiveTabChanged"] }, { kind: "component", type: i5$3.AXTabItemComponent, selector: "ax-tab-item", inputs: ["disabled", "text", "key", "headerTemplate", "active"], outputs: ["disabledChange", "onClick", "onBlur", "onFocus", "activeChange"] }, { kind: "ngmodule", type: AXPWidgetCoreModule }, { kind: "component", type: i6$1.AXPWidgetContainerComponent, selector: "axp-widgets-container", inputs: ["context", "functions"], outputs: ["onContextChanged"] }, { kind: "directive", type: i6$1.AXPWidgetRendererDirective, selector: "[axp-widget-renderer]", inputs: ["parentNode", "index", "mode", "node"], outputs: ["onOptionsChanged", "onValueChanged", "onLoad"], exportAs: ["widgetRenderer"] }, { 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 }); }
4152
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: AXPPropertyViewerComponent, isStandalone: true, selector: "axp-property-viewer", inputs: { tabsInput: { classPropertyName: "tabsInput", publicName: "tabsInput", isSignal: true, isRequired: false, 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 <!-- #region Shared property row template (used in both advanced and simple modes) -->\n <ng-template #propertyRow let-prop=\"prop\" let-translateTitle=\"translateTitle\">\n <div class=\"ax-flex ax-flex-col ax-gap-2 ax-py-2\">\n <!-- Property header: title + value/expression toggle (when binding.enabled) -->\n <div class=\"ax-flex ax-items-center ax-gap-2 ax-w-full\">\n @if (prop.showLabel !== false) {\n @if (translateTitle) {\n <span class=\"ax-font-semibold ax-flex-1 ax-min-w-0\">{{ prop.title | translate | async }}</span>\n } @else {\n <span class=\"ax-font-semibold ax-flex-1 ax-min-w-0\">{{ prop.title }}</span>\n }\n }\n @if (prop.binding?.enabled) {\n <div class=\"ax-flex ax-gap-1 ax-shrink-0 ax-xs\">\n <ax-button [toggleable]=\"true\" [selected]=\"isExpressionMode(prop)\" look=\"twotone\"\n [color]=\"isExpressionMode(prop) ? 'primary' : 'default'\" class=\"ax-shrink-0\"\n [title]=\"(isExpressionMode(prop) ? '@general:terms.common.expression' : '@general:terms.common.value') | translate | async\"\n (selectedChange)=\"setExpressionMode(prop, $event)\">\n @if (isExpressionMode(prop)) {\n <ax-icon icon=\"fa-light fa-code\"></ax-icon>\n } @else {\n <ax-icon icon=\"fa-light fa-keyboard\"></ax-icon>\n }\n </ax-button>\n </div>\n }\n </div>\n <!-- Property content: Open Editor button (expression mode) or widget renderer (value mode) -->\n @if (prop.binding?.enabled && isExpressionMode(prop)) {\n <ax-button look=\"twotone\" color=\"primary\" size=\"sm\" class=\"ax-w-full\"\n [text]=\"'@general:widgets.triggers.open-editor' | translate | async\" (onClick)=\"openBindingEditor(prop)\"\n [title]=\"'@general:widgets.triggers.edit-binding-expression' | translate | async\">\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-code\"></ax-icon>\n </ax-prefix>\n </ax-button>\n } @else if (prop.schema.interface) {\n <ng-container axp-widget-renderer [node]=\"prop.schema.interface\" [mode]=\"'edit'\">\n </ng-container>\n }\n </div>\n </ng-template>\n <!-- #endregion -->\n\n <!-- #region Advanced mode: tabs + accordion groups -->\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-accordion-group [accordion]=\"false\" [look]=\"'flat'\">\n @for (group of groups(); track $index) {\n <ax-accordion-item class=\"!ax-mb-0\" [caption]=\"group.title\" [isCollapsed]=\"group.isCollapsed\"\n (isCollapsedChange)=\"handleCollapsedChange(group.name, $event)\">\n <div class=\"ax-flex ax-flex-col\">\n @for (p of group.props; track $index) {\n <ng-container *ngTemplateOutlet=\"propertyRow; context: { prop: p, translateTitle: false }\">\n </ng-container>\n }\n </div>\n </ax-accordion-item>\n }\n </ax-accordion-group>\n </div>\n </div>\n }\n <!-- #endregion -->\n\n <!-- #region Simple mode: flat list of properties with padding -->\n @else {\n <div class=\"ax-flex ax-flex-col ax-p-4 ax-gap-4\">\n @for (group of groups(); track $index) {\n @for (p of group.props; track $index) {\n <ng-container *ngTemplateOutlet=\"propertyRow; context: { prop: p, translateTitle: true }\">\n </ng-container>\n }\n }\n </div>\n }\n <!-- #endregion -->\n</axp-widgets-container>", styles: ["axp-property-viewer ax-accordion-item .ax-accordion-header{font-weight:600!important;border-bottom-width:1px!important;background-color:rgb(var(--ax-sys-color-lighter-surface))!important;color:rgb(var(--ax-sys-color-on-lighter-surface))!important;border-color:rgb(var(--ax-sys-color-border-lighter-surface))!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: AXAccordionModule }, { kind: "component", type: i2$7.AXAccordionItemComponent, selector: "ax-accordion-item", inputs: ["isCollapsed", "icon", "caption", "isLoading", "headerTemplate", "look", "disabled"], outputs: ["isCollapsedChange", "isLoadingChange", "onClick"] }, { kind: "component", type: i2$7.AXAccordionGroupComponent, selector: "ax-accordion-group", inputs: ["accordion", "activeIndex", "look", "collapsedOnItemClick"], outputs: ["activeIndexChange"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1$1.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: AXButtonGroupModule }, { 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: AXTabsModule }, { kind: "component", type: i5$3.AXTabsComponent, selector: "ax-tabs", inputs: ["look", "location", "fitParent", "minWidth", "content"], outputs: ["onActiveTabChanged"] }, { kind: "component", type: i5$3.AXTabItemComponent, selector: "ax-tab-item", inputs: ["disabled", "text", "key", "headerTemplate", "active"], outputs: ["disabledChange", "onClick", "onBlur", "onFocus", "activeChange"] }, { kind: "ngmodule", type: AXPWidgetCoreModule }, { kind: "component", type: i6$1.AXPWidgetContainerComponent, selector: "axp-widgets-container", inputs: ["context", "functions"], outputs: ["onContextChanged"] }, { kind: "directive", type: i6$1.AXPWidgetRendererDirective, selector: "[axp-widget-renderer]", inputs: ["parentNode", "index", "mode", "node"], outputs: ["onOptionsChanged", "onValueChanged", "onLoad"], exportAs: ["widgetRenderer"] }, { 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 }); }
3749
4153
  }
3750
4154
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPPropertyViewerComponent, decorators: [{
3751
4155
  type: Component,
@@ -3823,7 +4227,7 @@ class AXPPropertyViewerPopupComponent extends AXBasePageComponent {
3823
4227
  ></ax-button>
3824
4228
  </ax-suffix>
3825
4229
  </ax-footer>
3826
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i2$3.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.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: "component", type: AXPPropertyViewerComponent, selector: "axp-property-viewer", inputs: ["tabsInput", "mode"], outputs: ["onChanged"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4230
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1$1.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.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: "component", type: AXPPropertyViewerComponent, selector: "axp-property-viewer", inputs: ["tabsInput", "mode"], outputs: ["onChanged"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3827
4231
  }
3828
4232
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPPropertyViewerPopupComponent, decorators: [{
3829
4233
  type: Component,
@@ -3945,7 +4349,7 @@ class AXPQuerySortsComponent {
3945
4349
  });
3946
4350
  }
3947
4351
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPQuerySortsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3948
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", 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: i2$3.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 }); }
4352
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", 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: i1$1.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 }); }
3949
4353
  }
3950
4354
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPQuerySortsComponent, decorators: [{
3951
4355
  type: Component,
@@ -4117,7 +4521,7 @@ class AXPStopwatchComponent {
4117
4521
  </div>
4118
4522
  }
4119
4523
  </div>
4120
- `, isInline: true, styles: [":host{display:inline-flex}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i2$3.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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4524
+ `, isInline: true, styles: [":host{display:inline-flex}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1$1.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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4121
4525
  }
4122
4526
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPStopwatchComponent, decorators: [{
4123
4527
  type: Component,
@@ -4166,6 +4570,457 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
4166
4570
  }, styles: [":host{display:inline-flex}\n"] }]
4167
4571
  }], ctorParameters: () => [], propDecorators: { mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], timeLimit: [{ type: i0.Input, args: [{ isSignal: true, alias: "timeLimit", required: false }] }], format: [{ type: i0.Input, args: [{ isSignal: true, alias: "format", required: false }] }], autoStart: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoStart", required: false }] }], showControls: [{ type: i0.Input, args: [{ isSignal: true, alias: "showControls", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }], timeUp: [{ type: i0.Output, args: ["timeUp"] }] } });
4168
4572
 
4573
+ /**
4574
+ * Builds the AXPWidgetNode tree for the table-columns-editor when using AXPLayoutRendererComponent.
4575
+ * Root: repeater-layout (path: 'columns') with add/remove controls.
4576
+ * Each row: form-field for name (text-editor), form-field for title (text-editor), form-field for widget (widget-field-configurator).
4577
+ */
4578
+ function buildTableColumnsEditorLayout() {
4579
+ return {
4580
+ type: 'repeater-layout',
4581
+ name: 'columns',
4582
+ path: 'columns',
4583
+ options: {
4584
+ hasControls: true,
4585
+ },
4586
+ children: [
4587
+ {
4588
+ type: 'form-field',
4589
+ name: 'name',
4590
+ options: {
4591
+ label: '@general:widgets.table-columns-editor.column-name',
4592
+ showLabel: true,
4593
+ },
4594
+ children: [
4595
+ {
4596
+ type: 'text-editor',
4597
+ path: 'name',
4598
+ name: 'name',
4599
+ options: { placeholder: 'name' },
4600
+ },
4601
+ ],
4602
+ },
4603
+ {
4604
+ type: 'form-field',
4605
+ name: 'title',
4606
+ options: {
4607
+ label: '@general:widgets.table-columns-editor.column-title',
4608
+ showLabel: true,
4609
+ },
4610
+ children: [
4611
+ {
4612
+ type: 'text-editor',
4613
+ path: 'title',
4614
+ name: 'title',
4615
+ options: { placeholder: 'Title' },
4616
+ },
4617
+ ],
4618
+ },
4619
+ {
4620
+ type: 'form-field',
4621
+ name: 'widget',
4622
+ options: {
4623
+ label: '@general:terms.widget',
4624
+ showLabel: true,
4625
+ },
4626
+ children: [
4627
+ {
4628
+ type: 'widget-field-configurator',
4629
+ path: 'widget',
4630
+ name: 'widget',
4631
+ options: {},
4632
+ },
4633
+ ],
4634
+ },
4635
+ ],
4636
+ };
4637
+ }
4638
+
4639
+ const DEFAULT_WIDGET = { type: 'text-box', options: {} };
4640
+ function normalizeColumn(row, index) {
4641
+ return {
4642
+ name: typeof row['name'] === 'string' ? row['name'] : (row['name'] != null ? String(row['name']) : `column_${index}`),
4643
+ title: typeof row['title'] === 'string' ? row['title'] : (row['title'] != null ? String(row['title']) : `Column ${index + 1}`),
4644
+ widget: row['widget'] != null && typeof row['widget'] === 'object' && 'type' in row['widget']
4645
+ ? row['widget']
4646
+ : { ...DEFAULT_WIDGET },
4647
+ };
4648
+ }
4649
+ function normalizeColumns(rows) {
4650
+ if (!Array.isArray(rows))
4651
+ return [];
4652
+ return rows.map((row, i) => normalizeColumn(typeof row === 'object' && row != null ? row : {}, i));
4653
+ }
4654
+ class AXPTableColumnsEditorComponent {
4655
+ constructor() {
4656
+ /** Layout tree: repeater (path: columns) with form-fields for name, title, widget. */
4657
+ this.columnsEditorLayout = signal(buildTableColumnsEditorLayout(), ...(ngDevMode ? [{ debugName: "columnsEditorLayout" }] : []));
4658
+ /** Two-way: list of column definitions (synced with editorContext.columns). */
4659
+ this.columns = model([], ...(ngDevMode ? [{ debugName: "columns" }] : []));
4660
+ /** Context for the layout renderer; must hold { columns: AXPTableColumnDefinition[] }. */
4661
+ this.editorContext = model({ columns: [] }, ...(ngDevMode ? [{ debugName: "editorContext" }] : []));
4662
+ afterNextRender(() => {
4663
+ const initial = this.columns();
4664
+ this.editorContext.set({ columns: initial?.length ? [...initial] : [] });
4665
+ });
4666
+ // Sync from parent columns into editor context (e.g. popup opened with initial columns).
4667
+ effect(() => {
4668
+ const cols = this.columns();
4669
+ const ctx = this.editorContext();
4670
+ if (!isEqual(ctx.columns, cols)) {
4671
+ this.editorContext.set({ columns: cols?.length ? [...cols] : [] });
4672
+ }
4673
+ });
4674
+ // Sync from layout renderer back to columns (user edited or repeater add/remove); normalize rows.
4675
+ effect(() => {
4676
+ const ctx = this.editorContext();
4677
+ const raw = ctx?.columns;
4678
+ const normalized = normalizeColumns(Array.isArray(raw) ? raw : []);
4679
+ const current = this.columns();
4680
+ if (!isEqual(current, normalized)) {
4681
+ this.columns.set(normalized);
4682
+ }
4683
+ });
4684
+ }
4685
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPTableColumnsEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4686
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.16", type: AXPTableColumnsEditorComponent, isStandalone: true, selector: "axp-table-columns-editor", inputs: { columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, editorContext: { classPropertyName: "editorContext", publicName: "editorContext", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { columns: "columnsChange", editorContext: "editorContextChange" }, ngImport: i0, template: `
4687
+ <div class="ax-flex ax-flex-col ax-flex-1 ax-min-h-0 ax-overflow-hidden">
4688
+ <div class="ax-flex-1 ax-min-h-0 ax-overflow-auto ax-p-2">
4689
+ <axp-layout-renderer
4690
+ [layout]="columnsEditorLayout()"
4691
+ [(context)]="editorContext"
4692
+ mode="edit"
4693
+ />
4694
+ </div>
4695
+ </div>
4696
+ `, isInline: true, dependencies: [{ kind: "component", type: AXPLayoutRendererComponent, selector: "axp-layout-renderer", inputs: ["layout", "context", "look", "mode"], outputs: ["contextChange", "contextInitiated", "validityChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4697
+ }
4698
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPTableColumnsEditorComponent, decorators: [{
4699
+ type: Component,
4700
+ args: [{
4701
+ selector: 'axp-table-columns-editor',
4702
+ standalone: true,
4703
+ changeDetection: ChangeDetectionStrategy.OnPush,
4704
+ imports: [AXPLayoutRendererComponent],
4705
+ template: `
4706
+ <div class="ax-flex ax-flex-col ax-flex-1 ax-min-h-0 ax-overflow-hidden">
4707
+ <div class="ax-flex-1 ax-min-h-0 ax-overflow-auto ax-p-2">
4708
+ <axp-layout-renderer
4709
+ [layout]="columnsEditorLayout()"
4710
+ [(context)]="editorContext"
4711
+ mode="edit"
4712
+ />
4713
+ </div>
4714
+ </div>
4715
+ `,
4716
+ }]
4717
+ }], ctorParameters: () => [], propDecorators: { columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }, { type: i0.Output, args: ["columnsChange"] }], editorContext: [{ type: i0.Input, args: [{ isSignal: true, alias: "editorContext", required: false }] }, { type: i0.Output, args: ["editorContextChange"] }] } });
4718
+
4719
+ const I18N$1 = {
4720
+ title: '@general:widgets.table-columns-editor.popup-title',
4721
+ cancel: '@general:actions.cancel.title',
4722
+ save: '@general:actions.save.title',
4723
+ };
4724
+ class AXPTableColumnsEditorPopupComponent extends AXBasePageComponent {
4725
+ constructor() {
4726
+ super();
4727
+ this.I18N = I18N$1;
4728
+ this.columns = input([], ...(ngDevMode ? [{ debugName: "columns" }] : []));
4729
+ this.localColumns = model([], ...(ngDevMode ? [{ debugName: "localColumns" }] : []));
4730
+ afterNextRender(() => {
4731
+ const initial = this.columns();
4732
+ this.localColumns.set(cloneDeep(initial?.length ? initial : []));
4733
+ });
4734
+ }
4735
+ handleCancel() {
4736
+ this.close();
4737
+ }
4738
+ handleSave() {
4739
+ this.close({ columns: this.localColumns() });
4740
+ }
4741
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPTableColumnsEditorPopupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4742
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.16", type: AXPTableColumnsEditorPopupComponent, isStandalone: true, selector: "axp-table-columns-editor-popup", inputs: { columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, localColumns: { classPropertyName: "localColumns", publicName: "localColumns", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { localColumns: "localColumnsChange" }, usesInheritance: true, ngImport: i0, template: `
4743
+ <div class="ax-flex ax-flex-col ax-flex-1 ax-min-h-0 ax-overflow-hidden">
4744
+ <div class="ax-flex-1 ax-min-h-0 ax-overflow-auto">
4745
+ <axp-table-columns-editor [(columns)]="localColumns" />
4746
+ </div>
4747
+ </div>
4748
+ <ax-footer>
4749
+ <ax-suffix>
4750
+ <ax-button
4751
+ look="solid"
4752
+ [text]="(I18N.cancel | translate | async) ?? ''"
4753
+ (onClick)="handleCancel()"
4754
+ ></ax-button>
4755
+ <ax-button
4756
+ look="solid"
4757
+ color="primary"
4758
+ [text]="(I18N.save | translate | async) ?? ''"
4759
+ (onClick)="handleSave()"
4760
+ ></ax-button>
4761
+ </ax-suffix>
4762
+ </ax-footer>
4763
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1$1.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.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: "component", type: AXPTableColumnsEditorComponent, selector: "axp-table-columns-editor", inputs: ["columns", "editorContext"], outputs: ["columnsChange", "editorContextChange"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4764
+ }
4765
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPTableColumnsEditorPopupComponent, decorators: [{
4766
+ type: Component,
4767
+ args: [{
4768
+ selector: 'axp-table-columns-editor-popup',
4769
+ standalone: true,
4770
+ changeDetection: ChangeDetectionStrategy.OnPush,
4771
+ imports: [AsyncPipe, AXButtonModule, AXDecoratorModule, AXTranslationModule, AXPTableColumnsEditorComponent],
4772
+ template: `
4773
+ <div class="ax-flex ax-flex-col ax-flex-1 ax-min-h-0 ax-overflow-hidden">
4774
+ <div class="ax-flex-1 ax-min-h-0 ax-overflow-auto">
4775
+ <axp-table-columns-editor [(columns)]="localColumns" />
4776
+ </div>
4777
+ </div>
4778
+ <ax-footer>
4779
+ <ax-suffix>
4780
+ <ax-button
4781
+ look="solid"
4782
+ [text]="(I18N.cancel | translate | async) ?? ''"
4783
+ (onClick)="handleCancel()"
4784
+ ></ax-button>
4785
+ <ax-button
4786
+ look="solid"
4787
+ color="primary"
4788
+ [text]="(I18N.save | translate | async) ?? ''"
4789
+ (onClick)="handleSave()"
4790
+ ></ax-button>
4791
+ </ax-suffix>
4792
+ </ax-footer>
4793
+ `,
4794
+ }]
4795
+ }], ctorParameters: () => [], propDecorators: { columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }], localColumns: [{ type: i0.Input, args: [{ isSignal: true, alias: "localColumns", required: false }] }, { type: i0.Output, args: ["localColumnsChange"] }] } });
4796
+
4797
+ var tableColumnsEditorPopup_component = /*#__PURE__*/Object.freeze({
4798
+ __proto__: null,
4799
+ AXPTableColumnsEditorPopupComponent: AXPTableColumnsEditorPopupComponent
4800
+ });
4801
+
4802
+ class AXPTableColumnsEditorService {
4803
+ constructor() {
4804
+ this.popupService = inject(AXPopupService);
4805
+ this.translationService = inject(AXTranslationService);
4806
+ }
4807
+ async open(options) {
4808
+ const component = await Promise.resolve().then(function () { return tableColumnsEditorPopup_component; }).then((m) => m.AXPTableColumnsEditorPopupComponent);
4809
+ const title = options?.title ??
4810
+ (await this.translationService.translateAsync('@general:widgets.table-columns-editor.popup-title'));
4811
+ const result = await this.popupService.open(component, {
4812
+ title,
4813
+ size: 'lg',
4814
+ data: {
4815
+ columns: options?.columns ?? [],
4816
+ },
4817
+ });
4818
+ const columns = result?.data?.columns;
4819
+ return Array.isArray(columns) ? columns : null;
4820
+ }
4821
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPTableColumnsEditorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
4822
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPTableColumnsEditorService, providedIn: 'root' }); }
4823
+ }
4824
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPTableColumnsEditorService, decorators: [{
4825
+ type: Injectable,
4826
+ args: [{ providedIn: 'root' }]
4827
+ }] });
4828
+
4829
+ /**
4830
+ * Builds spreadsheet column definitions from table column definitions.
4831
+ */
4832
+ function toSpreadsheetColumns(defs) {
4833
+ return defs.map((col) => ({
4834
+ name: col.name,
4835
+ title: col.title,
4836
+ path: col.name,
4837
+ widget: cloneDeep(col.widget),
4838
+ }));
4839
+ }
4840
+ class AXPTableDataEditorComponent {
4841
+ constructor() {
4842
+ this.columns = input.required(...(ngDevMode ? [{ debugName: "columns" }] : []));
4843
+ this.rowsModel = model([], ...(ngDevMode ? [{ debugName: "rowsModel" }] : []));
4844
+ this.spreadsheetColumns = computed(() => toSpreadsheetColumns(this.columns()), ...(ngDevMode ? [{ debugName: "spreadsheetColumns" }] : []));
4845
+ }
4846
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPTableDataEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4847
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: AXPTableDataEditorComponent, isStandalone: true, selector: "axp-table-data-editor", inputs: { columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: true, transformFunction: null }, rowsModel: { classPropertyName: "rowsModel", publicName: "rowsModel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { rowsModel: "rowsModelChange" }, ngImport: i0, template: `
4848
+ <div class="ax-flex ax-flex-col ax-flex-1 ax-min-h-0 ax-overflow-hidden">
4849
+ <div class="ax-flex-1 ax-min-h-0 ax-overflow-auto ax-p-2">
4850
+ @if (spreadsheetColumns().length > 0) {
4851
+ <axp-spreadsheet
4852
+ [title]="''"
4853
+ [columns]="spreadsheetColumns()"
4854
+ [(rowsModel)]="rowsModel"
4855
+ [rowMode]="'dynamic'"
4856
+ [readonly]="false"
4857
+ [allowAddRows]="true"
4858
+ [allowRemoveRows]="true"
4859
+ [emptyCellPlaceholder]="'–'"
4860
+ />
4861
+ } @else {
4862
+ <p class="ax-text-sm ax-text-neutral-500 ax-py-4">
4863
+ {{ ('@general:widgets.table-data-editor.define-columns-first' | translate | async) ?? 'Define columns first.' }}
4864
+ </p>
4865
+ }
4866
+ </div>
4867
+ </div>
4868
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: AXDecoratorModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type: AXPSpreadsheetComponent, selector: "axp-spreadsheet", inputs: ["title", "columns", "rowMode", "rowsInput", "rowsModel", "readonly", "emptyCellPlaceholder", "rowTitlePath", "rowDescriptionPath", "allowAddRows", "allowRemoveRows"], outputs: ["rowsModelChange", "cellChange", "rowChange", "spreadsheetChange"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4869
+ }
4870
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPTableDataEditorComponent, decorators: [{
4871
+ type: Component,
4872
+ args: [{
4873
+ selector: 'axp-table-data-editor',
4874
+ standalone: true,
4875
+ changeDetection: ChangeDetectionStrategy.OnPush,
4876
+ imports: [AsyncPipe, AXDecoratorModule, AXTranslationModule, AXPSpreadsheetComponent],
4877
+ template: `
4878
+ <div class="ax-flex ax-flex-col ax-flex-1 ax-min-h-0 ax-overflow-hidden">
4879
+ <div class="ax-flex-1 ax-min-h-0 ax-overflow-auto ax-p-2">
4880
+ @if (spreadsheetColumns().length > 0) {
4881
+ <axp-spreadsheet
4882
+ [title]="''"
4883
+ [columns]="spreadsheetColumns()"
4884
+ [(rowsModel)]="rowsModel"
4885
+ [rowMode]="'dynamic'"
4886
+ [readonly]="false"
4887
+ [allowAddRows]="true"
4888
+ [allowRemoveRows]="true"
4889
+ [emptyCellPlaceholder]="'–'"
4890
+ />
4891
+ } @else {
4892
+ <p class="ax-text-sm ax-text-neutral-500 ax-py-4">
4893
+ {{ ('@general:widgets.table-data-editor.define-columns-first' | translate | async) ?? 'Define columns first.' }}
4894
+ </p>
4895
+ }
4896
+ </div>
4897
+ </div>
4898
+ `,
4899
+ }]
4900
+ }], propDecorators: { columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: true }] }], rowsModel: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowsModel", required: false }] }, { type: i0.Output, args: ["rowsModelChange"] }] } });
4901
+
4902
+ const I18N = {
4903
+ title: '@general:widgets.table-data-editor.popup-title',
4904
+ cancel: '@general:actions.cancel.title',
4905
+ save: '@general:actions.save.title',
4906
+ };
4907
+ class AXPTableDataEditorPopupComponent extends AXBasePageComponent {
4908
+ constructor() {
4909
+ super();
4910
+ this.I18N = I18N;
4911
+ this.columns = input.required(...(ngDevMode ? [{ debugName: "columns" }] : []));
4912
+ this.rows = input([], ...(ngDevMode ? [{ debugName: "rows" }] : []));
4913
+ this.localRows = model([], ...(ngDevMode ? [{ debugName: "localRows" }] : []));
4914
+ afterNextRender(() => {
4915
+ const initial = this.rows();
4916
+ this.localRows.set(Array.isArray(initial) ? cloneDeep(initial) : []);
4917
+ });
4918
+ }
4919
+ handleCancel() {
4920
+ this.close();
4921
+ }
4922
+ handleSave() {
4923
+ const rows = this.localRows().map((row) => {
4924
+ const { _id, ...rest } = row;
4925
+ return rest;
4926
+ });
4927
+ this.close({ rows });
4928
+ }
4929
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPTableDataEditorPopupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4930
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.16", type: AXPTableDataEditorPopupComponent, isStandalone: true, selector: "axp-table-data-editor-popup", inputs: { columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: true, transformFunction: null }, rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, localRows: { classPropertyName: "localRows", publicName: "localRows", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { localRows: "localRowsChange" }, usesInheritance: true, ngImport: i0, template: `
4931
+ <div class="ax-flex ax-flex-col ax-flex-1 ax-min-h-0 ax-overflow-hidden">
4932
+ <div class="ax-flex-1 ax-min-h-0 ax-overflow-auto">
4933
+ <axp-table-data-editor
4934
+ [columns]="columns()"
4935
+ [(rowsModel)]="localRows"
4936
+ />
4937
+ </div>
4938
+ </div>
4939
+ <ax-footer>
4940
+ <ax-suffix>
4941
+ <ax-button
4942
+ look="solid"
4943
+ [text]="(I18N.cancel | translate | async) ?? ''"
4944
+ (onClick)="handleCancel()"
4945
+ ></ax-button>
4946
+ <ax-button
4947
+ look="solid"
4948
+ color="primary"
4949
+ [text]="(I18N.save | translate | async) ?? ''"
4950
+ (onClick)="handleSave()"
4951
+ ></ax-button>
4952
+ </ax-suffix>
4953
+ </ax-footer>
4954
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1$1.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.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: "component", type: AXPTableDataEditorComponent, selector: "axp-table-data-editor", inputs: ["columns", "rowsModel"], outputs: ["rowsModelChange"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4955
+ }
4956
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPTableDataEditorPopupComponent, decorators: [{
4957
+ type: Component,
4958
+ args: [{
4959
+ selector: 'axp-table-data-editor-popup',
4960
+ standalone: true,
4961
+ changeDetection: ChangeDetectionStrategy.OnPush,
4962
+ imports: [AsyncPipe, AXButtonModule, AXDecoratorModule, AXTranslationModule, AXPTableDataEditorComponent],
4963
+ template: `
4964
+ <div class="ax-flex ax-flex-col ax-flex-1 ax-min-h-0 ax-overflow-hidden">
4965
+ <div class="ax-flex-1 ax-min-h-0 ax-overflow-auto">
4966
+ <axp-table-data-editor
4967
+ [columns]="columns()"
4968
+ [(rowsModel)]="localRows"
4969
+ />
4970
+ </div>
4971
+ </div>
4972
+ <ax-footer>
4973
+ <ax-suffix>
4974
+ <ax-button
4975
+ look="solid"
4976
+ [text]="(I18N.cancel | translate | async) ?? ''"
4977
+ (onClick)="handleCancel()"
4978
+ ></ax-button>
4979
+ <ax-button
4980
+ look="solid"
4981
+ color="primary"
4982
+ [text]="(I18N.save | translate | async) ?? ''"
4983
+ (onClick)="handleSave()"
4984
+ ></ax-button>
4985
+ </ax-suffix>
4986
+ </ax-footer>
4987
+ `,
4988
+ }]
4989
+ }], ctorParameters: () => [], propDecorators: { columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: true }] }], rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: false }] }], localRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "localRows", required: false }] }, { type: i0.Output, args: ["localRowsChange"] }] } });
4990
+
4991
+ var tableDataEditorPopup_component = /*#__PURE__*/Object.freeze({
4992
+ __proto__: null,
4993
+ AXPTableDataEditorPopupComponent: AXPTableDataEditorPopupComponent
4994
+ });
4995
+
4996
+ class AXPTableDataEditorService {
4997
+ constructor() {
4998
+ this.popupService = inject(AXPopupService);
4999
+ this.translationService = inject(AXTranslationService);
5000
+ }
5001
+ async open(options) {
5002
+ const component = await Promise.resolve().then(function () { return tableDataEditorPopup_component; }).then((m) => m.AXPTableDataEditorPopupComponent);
5003
+ const title = options?.title ??
5004
+ (await this.translationService.translateAsync('@general:widgets.table-data-editor.popup-title'));
5005
+ const result = await this.popupService.open(component, {
5006
+ title,
5007
+ size: 'lg',
5008
+ data: {
5009
+ columns: options.columns ?? [],
5010
+ rows: options.rows ?? [],
5011
+ },
5012
+ });
5013
+ const rows = result?.data?.rows;
5014
+ return Array.isArray(rows) ? rows : null;
5015
+ }
5016
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPTableDataEditorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
5017
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPTableDataEditorService, providedIn: 'root' }); }
5018
+ }
5019
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPTableDataEditorService, decorators: [{
5020
+ type: Injectable,
5021
+ args: [{ providedIn: 'root' }]
5022
+ }] });
5023
+
4169
5024
  class AXPTemplateViewerComponent extends AXBasePageComponent {
4170
5025
  constructor() {
4171
5026
  super(...arguments);
@@ -4259,7 +5114,7 @@ class AXPTemplateViewerComponent extends AXBasePageComponent {
4259
5114
  </ax-suffix>
4260
5115
  </ax-footer>
4261
5116
  }
4262
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXPWidgetCoreModule }, { kind: "component", type: i6$1.AXPWidgetContainerComponent, selector: "axp-widgets-container", inputs: ["context", "functions"], outputs: ["onContextChanged"] }, { kind: "directive", type: i6$1.AXPWidgetRendererDirective, selector: "[axp-widget-renderer]", inputs: ["parentNode", "index", "mode", "node"], outputs: ["onOptionsChanged", "onValueChanged", "onLoad"], 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: i2$3.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$6.AXFormComponent, selector: "ax-form", inputs: ["disabled", "readonly", "labelMode", "look", "messageStyle", "updateOn", "inUserInteractionActive"], 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 }); }
5117
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXPWidgetCoreModule }, { kind: "component", type: i6$1.AXPWidgetContainerComponent, selector: "axp-widgets-container", inputs: ["context", "functions"], outputs: ["onContextChanged"] }, { kind: "directive", type: i6$1.AXPWidgetRendererDirective, selector: "[axp-widget-renderer]", inputs: ["parentNode", "index", "mode", "node"], outputs: ["onOptionsChanged", "onValueChanged", "onLoad"], 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: i1$1.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$5.AXFormComponent, selector: "ax-form", inputs: ["disabled", "readonly", "labelMode", "look", "messageStyle", "updateOn", "inUserInteractionActive"], 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 }); }
4263
5118
  }
4264
5119
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPTemplateViewerComponent, decorators: [{
4265
5120
  type: Component,
@@ -4550,7 +5405,7 @@ class AXPUserAvatarComponent {
4550
5405
  return colors[idx];
4551
5406
  }
4552
5407
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPUserAvatarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4553
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", 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 ax-relative\" [title]=\"this.src()\">\n @if(hasAvatar()){\n <ng-container>\n <ax-image (onError)=\"onImageError($event)\" (onLoad)=\"onImageLoad($event)\" [src]=\"src()\"\n [class.ax-opacity-0]=\"isLoading()\" class=\"ax-transition-opacity ax-duration-200\"></ax-image>\n @if(isLoading()){\n <!-- <ax-image [src]=\"src()\"></ax-image> -->\n <ax-icon icon=\"fa-solid fa-user fa-2x\" class=\"ax-text-3xl\"></ax-icon>\n }\n </ng-container>\n }@else{\n <ax-text class=\"ax-{{ avatarColor() }}-lightest \">\n <small class=\"ax-text-xs ax-font-semibold\">{{ avatarText() }}</small>\n </ax-text>\n <!-- TODO: Add initials if firstName and lastName are not available -->\n <!-- <ng-container>\n @if(firstName() && lastName())\n {\n <ax-text class=\"ax-{{ avatarColor() }}-lightest \">\n <small class=\"ax-text-xs ax-font-semibold\">{{ avatarText() }}</small>\n </ax-text>\n }\n @else {\n <ax-icon icon=\"fa-solid fa-user fa-2x\" class=\"ax-text-3xl\"></ax-icon>\n }\n </ng-container> -->\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-->", styles: [""], dependencies: [{ kind: "ngmodule", type: AXAvatarModule }, { kind: "component", type: i1$6.AXAvatarComponent, selector: "ax-avatar", inputs: ["color", "size", "shape", "look"], outputs: ["sizeChange"] }, { 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: AXImageModule }, { kind: "component", type: i2$7.AXImageComponent, selector: "ax-image", inputs: ["width", "height", "overlayMode", "src", "alt", "priority", "lazy"], outputs: ["onLoad", "onError"] }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "ngmodule", type: AXSkeletonModule }], encapsulation: i0.ViewEncapsulation.None }); }
5408
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", 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 ax-relative\" [title]=\"this.src()\">\n @if(hasAvatar()){\n <ng-container>\n <ax-image (onError)=\"onImageError($event)\" (onLoad)=\"onImageLoad($event)\" [src]=\"src()\"\n [class.ax-opacity-0]=\"isLoading()\" class=\"ax-transition-opacity ax-duration-200\"></ax-image>\n @if(isLoading()){\n <!-- <ax-image [src]=\"src()\"></ax-image> -->\n <ax-icon icon=\"fa-solid fa-user fa-2x\" class=\"ax-text-3xl\"></ax-icon>\n }\n </ng-container>\n }@else{\n <ax-text class=\"ax-{{ avatarColor() }}-lightest \">\n <small class=\"ax-text-xs ax-font-semibold\">{{ avatarText() }}</small>\n </ax-text>\n <!-- TODO: Add initials if firstName and lastName are not available -->\n <!-- <ng-container>\n @if(firstName() && lastName())\n {\n <ax-text class=\"ax-{{ avatarColor() }}-lightest \">\n <small class=\"ax-text-xs ax-font-semibold\">{{ avatarText() }}</small>\n </ax-text>\n }\n @else {\n <ax-icon icon=\"fa-solid fa-user fa-2x\" class=\"ax-text-3xl\"></ax-icon>\n }\n </ng-container> -->\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-->", styles: [""], dependencies: [{ kind: "ngmodule", type: AXAvatarModule }, { kind: "component", type: i1$7.AXAvatarComponent, selector: "ax-avatar", inputs: ["color", "size", "shape", "look"], outputs: ["sizeChange"] }, { 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: AXImageModule }, { kind: "component", type: i2$6.AXImageComponent, selector: "ax-image", inputs: ["width", "height", "overlayMode", "src", "alt", "priority", "lazy"], outputs: ["onLoad", "onError"] }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "ngmodule", type: AXSkeletonModule }], encapsulation: i0.ViewEncapsulation.None }); }
4554
5409
  }
4555
5410
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPUserAvatarComponent, decorators: [{
4556
5411
  type: Component,
@@ -4750,6 +5605,12 @@ class AXPWidgetFieldConfiguratorComponent {
4750
5605
  return;
4751
5606
  this.isEditMode.set(true);
4752
5607
  }
5608
+ /**
5609
+ * Exit edit mode when dropdown is closed (return to view mode)
5610
+ */
5611
+ exitEditMode() {
5612
+ this.isEditMode.set(false);
5613
+ }
4753
5614
  //#endregion
4754
5615
  //#region ---- Lifecycle ----
4755
5616
  constructor() {
@@ -4844,6 +5705,10 @@ class AXPWidgetFieldConfiguratorComponent {
4844
5705
  this.canPreview = computed(() => {
4845
5706
  return !!this.selectedWidgetType();
4846
5707
  }, ...(ngDevMode ? [{ debugName: "canPreview" }] : []));
5708
+ /**
5709
+ * Reference to the widget type select box (used to open dropdown when entering edit mode)
5710
+ */
5711
+ this.widgetSelectBox = viewChild('widgetSelectBox', ...(ngDevMode ? [{ debugName: "widgetSelectBox" }] : []));
4847
5712
  // Sync widget type to internal signal
4848
5713
  effect(() => {
4849
5714
  const widget = this.widget();
@@ -4855,6 +5720,18 @@ class AXPWidgetFieldConfiguratorComponent {
4855
5720
  }
4856
5721
  }
4857
5722
  });
5723
+ // Open select box dropdown when entering edit mode (after view has rendered)
5724
+ effect(() => {
5725
+ if (!this.isEditMode())
5726
+ return;
5727
+ const scheduleFocus = () => {
5728
+ setTimeout(() => {
5729
+ this.widgetSelectBox()?.focus();
5730
+ this.widgetSelectBox()?.open();
5731
+ }, 0);
5732
+ };
5733
+ scheduleFocus();
5734
+ });
4858
5735
  }
4859
5736
  //#endregion
4860
5737
  //#region ---- Event Handlers ----
@@ -4967,7 +5844,7 @@ class AXPWidgetFieldConfiguratorComponent {
4967
5844
  }
4968
5845
  }
4969
5846
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPWidgetFieldConfiguratorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4970
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: AXPWidgetFieldConfiguratorComponent, isStandalone: true, selector: "axp-widget-field-configurator", inputs: { widget: { classPropertyName: "widget", publicName: "widget", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, fieldName: { classPropertyName: "fieldName", publicName: "fieldName", isSignal: true, isRequired: false, transformFunction: null }, fieldTitle: { classPropertyName: "fieldTitle", publicName: "fieldTitle", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { widget: "widgetChange" }, ngImport: i0, template: "<!-- Widget Selector & Info Container -->\n<div class=\"__widget-container\">\n <!-- Edit Mode: Show Select Box -->\n @if (isEditMode()) {\n <div class=\"__widget-selector\">\n <ax-select-box [ngModel]=\"selectedWidgetType()\" [dataSource]=\"availableWidgets()\"\n [placeholder]=\"('@general:actions.select.title' | translate | async) ?? ''\" [readonly]=\"readonly()\"\n (onValueChanged)=\"onWidgetTypeChange($event)\" valueField=\"value\" textField=\"text\" [itemTemplate]=\"itemTemplate\"\n [selectedTemplate]=\"selectedTemplate\">\n <ax-search-box></ax-search-box>\n <ax-clear-button></ax-clear-button>\n </ax-select-box>\n </div>\n }\n\n <!-- View Mode: Show Widget Info -->\n @if (!isEditMode()) {\n @if (selectedWidgetType() && currentWidgetConfig(); as config) {\n <div class=\"__widget-info\">\n <!-- Widget Header (Clickable to Edit) -->\n <div class=\"__widget-header\" [class.__editable]=\"!readonly()\" (click)=\"enterEditMode()\">\n <div>\n @if (config.icon) {\n <i [class]=\"config.icon\"></i>\n }\n <div>\n <span>\n {{ config.title }}\n </span>\n @if (config.description) {\n <p>\n {{ config.description }}\n </p>\n }\n </div>\n </div>\n\n <!-- Action Buttons -->\n <div class=\"__action-buttons\" (click)=\"$event.stopPropagation()\">\n <!-- Configure Button -->\n @if (config.hasProperties) {\n <ax-button [disabled]=\"!canConfigure() || readonly()\"\n [title]=\"('@general:actions.configure.title' | translate | async) ?? ''\" look=\"blank\"\n [color]=\"isConfigured() ? 'primary' : 'default'\" size=\"sm\" (onClick)=\"openPropertyViewer()\">\n <ax-icon icon=\"fa-solid fa-cog\"></ax-icon>\n </ax-button>\n }\n <!-- Preview Button -->\n <ax-button [disabled]=\"!canPreview()\" [title]=\"('@general:actions.preview.title' | translate | async) ?? ''\"\n look=\"blank\" size=\"sm\" (onClick)=\"openPreview()\">\n <ax-icon icon=\"fa-solid fa-eye\"></ax-icon>\n </ax-button>\n </div>\n </div>\n\n <!-- No Configuration Needed State -->\n @if (!config.hasProperties) {\n <axp-state-message mode=\"info\" icon=\"fa-solid fa-info-circle\"\n [description]=\"'@general:widgets.widget-configurator.no-configuration-needed'\" variant=\"compact\">\n </axp-state-message>\n }\n </div>\n } @else {\n <!-- Empty State (Clickable to Edit) -->\n <div class=\"__widget-empty\" [class.__editable]=\"!readonly()\" (click)=\"enterEditMode()\">\n <i class=\"fa-solid fa-puzzle-piece\"></i>\n <span>\n {{ ('@general:widgets.widget-configurator.select-widget-type' | translate | async) ?? 'Select a widget type' }}\n </span>\n </div>\n }\n }\n\n <!-- Widget Item Template (Dropdown Items) -->\n <ng-template #itemTemplate let-context>\n @let item = context.data;\n <div class=\"__item-template ax-flex ax-w-full ax-items-center ax-gap-3 ax-p-2\">\n @if (item.icon) {\n <i [class]=\"item.icon + ' ax-text-base ax-w-5 ax-text-center'\"></i>\n }\n <div class=\"ax-flex ax-items-center ax-gap-2 ax-flex-1 ax-min-w-0\">\n <div class=\"ax-text-sm ax-font-medium\">\n {{ item.text }}\n </div>\n @if (item.description) {\n <div class=\"ax-text-xs ax-text-neutral-600\">\n {{ item.description }}\n </div>\n }\n </div>\n </div>\n </ng-template>\n\n <!-- Widget Selected Template (Selected Value Display) -->\n <ng-template #selectedTemplate let-item>\n <div class=\"__selected-template\">\n @if (item?.data?.icon) {\n <i [class]=\"item.data.icon\"></i>\n }\n <span>\n {{ item?.data?.text }}\n </span>\n </div>\n </ng-template>\n</div>", styles: ["axp-widget-field-configurator{display:flex;flex-direction:column}axp-widget-field-configurator .__widget-container{border-radius:.375rem;border-width:1px;padding:1rem;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));transition:all .2s ease}axp-widget-field-configurator .__widget-selector{display:flex;flex-direction:column}axp-widget-field-configurator .__widget-selector ax-select-box{width:100%}axp-widget-field-configurator .__widget-info{display:flex;flex-direction:column;gap:.75rem}axp-widget-field-configurator .__widget-info .__widget-header{display:flex;align-items:center;justify-content:space-between;gap:.75rem;padding:.375rem .5rem}axp-widget-field-configurator .__widget-info .__widget-header.__editable{cursor:pointer}axp-widget-field-configurator .__widget-info .__widget-header.__editable:hover{border-radius:.375rem;--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-lighter-surface),var(--tw-bg-opacity, 1))}axp-widget-field-configurator .__widget-info .__widget-header:not(.__editable){cursor:not-allowed}axp-widget-field-configurator .__widget-info .__widget-header>div:first-child{display:flex;flex:1 1 0%;align-items:center;gap:.5rem}axp-widget-field-configurator .__widget-info .__widget-header>div:first-child i{font-size:1rem;line-height:1.5rem;flex-shrink:0}axp-widget-field-configurator .__widget-info .__widget-header>div:first-child>div{display:flex;flex:1 1 0%;flex-direction:column;gap:.125rem}axp-widget-field-configurator .__widget-info .__widget-header>div:first-child>div>span{font-size:.875rem;line-height:1.25rem;font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}axp-widget-field-configurator .__widget-info .__widget-header>div:first-child>div>p{margin:0;font-size:.75rem;line-height:1rem;line-height:1.625;--tw-text-opacity: 1;color:rgb(82 82 82 / var(--tw-text-opacity, 1))}axp-widget-field-configurator .__widget-info .__description{line-height:1.5}axp-widget-field-configurator .__widget-info .__action-buttons{display:flex;align-items:center;gap:.25rem;flex-shrink:0}axp-widget-field-configurator .__widget-empty{display:flex;align-items:center;gap:.5rem;padding:.5rem}axp-widget-field-configurator .__widget-empty.__editable{cursor:pointer}axp-widget-field-configurator .__widget-empty.__editable:hover{border-radius:.375rem;--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-lighter-surface),var(--tw-bg-opacity, 1))}axp-widget-field-configurator .__widget-empty:not(.__editable){cursor:not-allowed}axp-widget-field-configurator .__widget-empty>i{font-size:1rem;line-height:1.5rem;--tw-text-opacity: 1;color:rgb(163 163 163 / var(--tw-text-opacity, 1))}axp-widget-field-configurator .__widget-empty>span{font-size:.875rem;line-height:1.25rem;--tw-text-opacity: 1;color:rgb(82 82 82 / var(--tw-text-opacity, 1))}axp-widget-field-configurator .__item-template>i{flex-shrink:0;display:inline-flex;align-items:center;justify-content:center}axp-widget-field-configurator .__item-template>div>div:first-child{flex-shrink:0}axp-widget-field-configurator .__item-template>div>div:last-child{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}axp-widget-field-configurator .__selected-template{display:flex;align-items:center;gap:.5rem}axp-widget-field-configurator .__selected-template>i{font-size:.875rem;line-height:1.25rem}axp-widget-field-configurator .__selected-template>span{font-size:.875rem;line-height:1.25rem;font-weight:500}axp-widget-field-configurator :host([readonly]){pointer-events:none;opacity:.7}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: AXFormModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i2$3.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: AXSelectBoxModule }, { kind: "component", type: i3$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", "itemHeight", "maxVisibleItems", "dataSource", "minRecordsForSearch", "caption", "itemTemplate", "selectedTemplate", "emptyTemplate", "loadingTemplate", "dropdownWidth", "searchBoxAutoFocus"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onOpened", "onClosed", "onItemSelected", "onItemClick"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i2$1.AXDecoratorClearButtonComponent, selector: "ax-clear-button", inputs: ["icon"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type: AXPStateMessageComponent, selector: "axp-state-message", inputs: ["mode", "icon", "title", "description", "variant"] }, { kind: "ngmodule", type: AXSearchBoxModule }, { kind: "component", type: i5$1.AXSearchBoxComponent, selector: "ax-search-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "value", "state", "name", "id", "look", "class", "delayTime", "type", "autoSearch"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
5847
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: AXPWidgetFieldConfiguratorComponent, isStandalone: true, selector: "axp-widget-field-configurator", inputs: { widget: { classPropertyName: "widget", publicName: "widget", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, fieldName: { classPropertyName: "fieldName", publicName: "fieldName", isSignal: true, isRequired: false, transformFunction: null }, fieldTitle: { classPropertyName: "fieldTitle", publicName: "fieldTitle", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { widget: "widgetChange" }, viewQueries: [{ propertyName: "widgetSelectBox", first: true, predicate: ["widgetSelectBox"], descendants: true, isSignal: true }], ngImport: i0, template: "<!-- Widget Selector & Info Container -->\n<div class=\"__widget-container\">\n <!-- Edit Mode: Show Select Box -->\n @if (isEditMode()) {\n <div class=\"__widget-selector\">\n <ax-select-box #widgetSelectBox [ngModel]=\"selectedWidgetType()\" [dataSource]=\"availableWidgets()\"\n [placeholder]=\"('@general:actions.select.title' | translate | async) ?? ''\" [readonly]=\"readonly()\"\n (onValueChanged)=\"onWidgetTypeChange($event)\" valueField=\"value\" textField=\"text\" [itemTemplate]=\"itemTemplate\"\n [selectedTemplate]=\"selectedTemplate\" (onClosed)=\"exitEditMode()\">\n <ax-search-box></ax-search-box>\n <ax-clear-button></ax-clear-button>\n </ax-select-box>\n </div>\n }\n\n <!-- View Mode: Show Widget Info -->\n @if (!isEditMode()) {\n @if (selectedWidgetType() && currentWidgetConfig(); as config) {\n <div class=\"__widget-info\">\n <!-- Widget Header (Clickable to Edit) -->\n <div class=\"__widget-header\" [class.__editable]=\"!readonly()\" (click)=\"enterEditMode()\">\n <div>\n @if (config.icon) {\n <i [class]=\"config.icon\"></i>\n }\n <div>\n <span>\n {{ config.title }}\n </span>\n @if (config.description) {\n <p>\n {{ config.description }}\n </p>\n }\n </div>\n </div>\n\n <!-- Action Buttons -->\n <div class=\"__action-buttons\" (click)=\"$event.stopPropagation()\">\n <!-- Configure Button -->\n @if (config.hasProperties) {\n <ax-button [disabled]=\"!canConfigure() || readonly()\"\n [title]=\"('@general:actions.configure.title' | translate | async) ?? ''\" look=\"blank\"\n [color]=\"isConfigured() ? 'primary' : 'default'\" size=\"sm\" (onClick)=\"openPropertyViewer()\">\n <ax-icon icon=\"fa-solid fa-cog\"></ax-icon>\n </ax-button>\n }\n <!-- Preview Button -->\n <ax-button [disabled]=\"!canPreview()\" [title]=\"('@general:actions.preview.title' | translate | async) ?? ''\"\n look=\"blank\" size=\"sm\" (onClick)=\"openPreview()\">\n <ax-icon icon=\"fa-solid fa-eye\"></ax-icon>\n </ax-button>\n </div>\n </div>\n\n <!-- No Configuration Needed State -->\n @if (!config.hasProperties) {\n <axp-state-message mode=\"info\" icon=\"fa-solid fa-info-circle\"\n [description]=\"'@general:widgets.widget-configurator.no-configuration-needed'\" variant=\"compact\">\n </axp-state-message>\n }\n </div>\n } @else {\n <!-- Empty State (Clickable to Edit) -->\n <div class=\"__widget-empty\" [class.__editable]=\"!readonly()\" (click)=\"enterEditMode()\">\n <i class=\"fa-solid fa-puzzle-piece\"></i>\n <span>\n {{ ('@general:widgets.widget-configurator.select-widget-type' | translate | async) ?? 'Select a widget type' }}\n </span>\n </div>\n }\n }\n\n <!-- Widget Item Template (Dropdown Items) -->\n <ng-template #itemTemplate let-context>\n @let item = context.data;\n <div class=\"__item-template ax-flex ax-w-full ax-items-center ax-gap-3 ax-p-2\">\n @if (item.icon) {\n <i [class]=\"item.icon + ' ax-text-base ax-w-5 ax-text-center'\"></i>\n }\n <div class=\"ax-flex ax-items-center ax-gap-2 ax-flex-1 ax-min-w-0\">\n <div class=\"ax-text-sm ax-font-medium\">\n {{ item.text }}\n </div>\n @if (item.description) {\n <div class=\"ax-text-xs ax-text-neutral-600\">\n {{ item.description }}\n </div>\n }\n </div>\n </div>\n </ng-template>\n\n <!-- Widget Selected Template (Selected Value Display) -->\n <ng-template #selectedTemplate let-item>\n <div class=\"__selected-template\">\n @if (item?.data?.icon) {\n <i [class]=\"item.data.icon\"></i>\n }\n <span>\n {{ item?.data?.text }}\n </span>\n </div>\n </ng-template>\n</div>", styles: ["axp-widget-field-configurator{display:flex;flex-direction:column}axp-widget-field-configurator .__widget-container{border-radius:.375rem;border-width:1px;padding:1rem;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));transition:all .2s ease}axp-widget-field-configurator .__widget-selector{display:flex;flex-direction:column}axp-widget-field-configurator .__widget-selector ax-select-box{width:100%}axp-widget-field-configurator .__widget-info{display:flex;flex-direction:column;gap:.75rem}axp-widget-field-configurator .__widget-info .__widget-header{display:flex;align-items:center;justify-content:space-between;gap:.75rem;padding:.375rem .5rem}axp-widget-field-configurator .__widget-info .__widget-header.__editable{cursor:pointer}axp-widget-field-configurator .__widget-info .__widget-header.__editable:hover{border-radius:.375rem;--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-lighter-surface),var(--tw-bg-opacity, 1))}axp-widget-field-configurator .__widget-info .__widget-header:not(.__editable){cursor:not-allowed}axp-widget-field-configurator .__widget-info .__widget-header>div:first-child{display:flex;flex:1 1 0%;align-items:center;gap:.5rem}axp-widget-field-configurator .__widget-info .__widget-header>div:first-child i{font-size:1rem;line-height:1.5rem;flex-shrink:0}axp-widget-field-configurator .__widget-info .__widget-header>div:first-child>div{display:flex;flex:1 1 0%;flex-direction:column;gap:.125rem}axp-widget-field-configurator .__widget-info .__widget-header>div:first-child>div>span{font-size:.875rem;line-height:1.25rem;font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}axp-widget-field-configurator .__widget-info .__widget-header>div:first-child>div>p{margin:0;font-size:.75rem;line-height:1rem;line-height:1.625;--tw-text-opacity: 1;color:rgb(82 82 82 / var(--tw-text-opacity, 1))}axp-widget-field-configurator .__widget-info .__description{line-height:1.5}axp-widget-field-configurator .__widget-info .__action-buttons{display:flex;align-items:center;gap:.25rem;flex-shrink:0}axp-widget-field-configurator .__widget-empty{display:flex;align-items:center;gap:.5rem;padding:.5rem}axp-widget-field-configurator .__widget-empty.__editable{cursor:pointer}axp-widget-field-configurator .__widget-empty.__editable:hover{border-radius:.375rem;--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-lighter-surface),var(--tw-bg-opacity, 1))}axp-widget-field-configurator .__widget-empty:not(.__editable){cursor:not-allowed}axp-widget-field-configurator .__widget-empty>i{font-size:1rem;line-height:1.5rem;--tw-text-opacity: 1;color:rgb(163 163 163 / var(--tw-text-opacity, 1))}axp-widget-field-configurator .__widget-empty>span{font-size:.875rem;line-height:1.25rem;--tw-text-opacity: 1;color:rgb(82 82 82 / var(--tw-text-opacity, 1))}axp-widget-field-configurator .__item-template>i{flex-shrink:0;display:inline-flex;align-items:center;justify-content:center}axp-widget-field-configurator .__item-template>div>div:first-child{flex-shrink:0}axp-widget-field-configurator .__item-template>div>div:last-child{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}axp-widget-field-configurator .__selected-template{display:flex;align-items:center;gap:.5rem}axp-widget-field-configurator .__selected-template>i{font-size:.875rem;line-height:1.25rem}axp-widget-field-configurator .__selected-template>span{font-size:.875rem;line-height:1.25rem;font-weight:500}axp-widget-field-configurator :host([readonly]){pointer-events:none;opacity:.7}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: AXFormModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1$1.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: AXSelectBoxModule }, { kind: "component", type: i3$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", "itemHeight", "maxVisibleItems", "dataSource", "minRecordsForSearch", "caption", "itemTemplate", "selectedTemplate", "emptyTemplate", "loadingTemplate", "dropdownWidth", "searchBoxAutoFocus"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onOpened", "onClosed", "onItemSelected", "onItemClick"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i2$1.AXDecoratorClearButtonComponent, selector: "ax-clear-button", inputs: ["icon"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type: AXPStateMessageComponent, selector: "axp-state-message", inputs: ["mode", "icon", "title", "description", "variant"] }, { kind: "ngmodule", type: AXSearchBoxModule }, { kind: "component", type: i5$1.AXSearchBoxComponent, selector: "ax-search-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "value", "state", "name", "id", "look", "class", "delayTime", "type", "autoSearch"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
4971
5848
  }
4972
5849
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPWidgetFieldConfiguratorComponent, decorators: [{
4973
5850
  type: Component,
@@ -4981,8 +5858,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
4981
5858
  AXTranslationModule,
4982
5859
  AXPStateMessageComponent,
4983
5860
  AXSearchBoxModule,
4984
- ], template: "<!-- Widget Selector & Info Container -->\n<div class=\"__widget-container\">\n <!-- Edit Mode: Show Select Box -->\n @if (isEditMode()) {\n <div class=\"__widget-selector\">\n <ax-select-box [ngModel]=\"selectedWidgetType()\" [dataSource]=\"availableWidgets()\"\n [placeholder]=\"('@general:actions.select.title' | translate | async) ?? ''\" [readonly]=\"readonly()\"\n (onValueChanged)=\"onWidgetTypeChange($event)\" valueField=\"value\" textField=\"text\" [itemTemplate]=\"itemTemplate\"\n [selectedTemplate]=\"selectedTemplate\">\n <ax-search-box></ax-search-box>\n <ax-clear-button></ax-clear-button>\n </ax-select-box>\n </div>\n }\n\n <!-- View Mode: Show Widget Info -->\n @if (!isEditMode()) {\n @if (selectedWidgetType() && currentWidgetConfig(); as config) {\n <div class=\"__widget-info\">\n <!-- Widget Header (Clickable to Edit) -->\n <div class=\"__widget-header\" [class.__editable]=\"!readonly()\" (click)=\"enterEditMode()\">\n <div>\n @if (config.icon) {\n <i [class]=\"config.icon\"></i>\n }\n <div>\n <span>\n {{ config.title }}\n </span>\n @if (config.description) {\n <p>\n {{ config.description }}\n </p>\n }\n </div>\n </div>\n\n <!-- Action Buttons -->\n <div class=\"__action-buttons\" (click)=\"$event.stopPropagation()\">\n <!-- Configure Button -->\n @if (config.hasProperties) {\n <ax-button [disabled]=\"!canConfigure() || readonly()\"\n [title]=\"('@general:actions.configure.title' | translate | async) ?? ''\" look=\"blank\"\n [color]=\"isConfigured() ? 'primary' : 'default'\" size=\"sm\" (onClick)=\"openPropertyViewer()\">\n <ax-icon icon=\"fa-solid fa-cog\"></ax-icon>\n </ax-button>\n }\n <!-- Preview Button -->\n <ax-button [disabled]=\"!canPreview()\" [title]=\"('@general:actions.preview.title' | translate | async) ?? ''\"\n look=\"blank\" size=\"sm\" (onClick)=\"openPreview()\">\n <ax-icon icon=\"fa-solid fa-eye\"></ax-icon>\n </ax-button>\n </div>\n </div>\n\n <!-- No Configuration Needed State -->\n @if (!config.hasProperties) {\n <axp-state-message mode=\"info\" icon=\"fa-solid fa-info-circle\"\n [description]=\"'@general:widgets.widget-configurator.no-configuration-needed'\" variant=\"compact\">\n </axp-state-message>\n }\n </div>\n } @else {\n <!-- Empty State (Clickable to Edit) -->\n <div class=\"__widget-empty\" [class.__editable]=\"!readonly()\" (click)=\"enterEditMode()\">\n <i class=\"fa-solid fa-puzzle-piece\"></i>\n <span>\n {{ ('@general:widgets.widget-configurator.select-widget-type' | translate | async) ?? 'Select a widget type' }}\n </span>\n </div>\n }\n }\n\n <!-- Widget Item Template (Dropdown Items) -->\n <ng-template #itemTemplate let-context>\n @let item = context.data;\n <div class=\"__item-template ax-flex ax-w-full ax-items-center ax-gap-3 ax-p-2\">\n @if (item.icon) {\n <i [class]=\"item.icon + ' ax-text-base ax-w-5 ax-text-center'\"></i>\n }\n <div class=\"ax-flex ax-items-center ax-gap-2 ax-flex-1 ax-min-w-0\">\n <div class=\"ax-text-sm ax-font-medium\">\n {{ item.text }}\n </div>\n @if (item.description) {\n <div class=\"ax-text-xs ax-text-neutral-600\">\n {{ item.description }}\n </div>\n }\n </div>\n </div>\n </ng-template>\n\n <!-- Widget Selected Template (Selected Value Display) -->\n <ng-template #selectedTemplate let-item>\n <div class=\"__selected-template\">\n @if (item?.data?.icon) {\n <i [class]=\"item.data.icon\"></i>\n }\n <span>\n {{ item?.data?.text }}\n </span>\n </div>\n </ng-template>\n</div>", styles: ["axp-widget-field-configurator{display:flex;flex-direction:column}axp-widget-field-configurator .__widget-container{border-radius:.375rem;border-width:1px;padding:1rem;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));transition:all .2s ease}axp-widget-field-configurator .__widget-selector{display:flex;flex-direction:column}axp-widget-field-configurator .__widget-selector ax-select-box{width:100%}axp-widget-field-configurator .__widget-info{display:flex;flex-direction:column;gap:.75rem}axp-widget-field-configurator .__widget-info .__widget-header{display:flex;align-items:center;justify-content:space-between;gap:.75rem;padding:.375rem .5rem}axp-widget-field-configurator .__widget-info .__widget-header.__editable{cursor:pointer}axp-widget-field-configurator .__widget-info .__widget-header.__editable:hover{border-radius:.375rem;--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-lighter-surface),var(--tw-bg-opacity, 1))}axp-widget-field-configurator .__widget-info .__widget-header:not(.__editable){cursor:not-allowed}axp-widget-field-configurator .__widget-info .__widget-header>div:first-child{display:flex;flex:1 1 0%;align-items:center;gap:.5rem}axp-widget-field-configurator .__widget-info .__widget-header>div:first-child i{font-size:1rem;line-height:1.5rem;flex-shrink:0}axp-widget-field-configurator .__widget-info .__widget-header>div:first-child>div{display:flex;flex:1 1 0%;flex-direction:column;gap:.125rem}axp-widget-field-configurator .__widget-info .__widget-header>div:first-child>div>span{font-size:.875rem;line-height:1.25rem;font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}axp-widget-field-configurator .__widget-info .__widget-header>div:first-child>div>p{margin:0;font-size:.75rem;line-height:1rem;line-height:1.625;--tw-text-opacity: 1;color:rgb(82 82 82 / var(--tw-text-opacity, 1))}axp-widget-field-configurator .__widget-info .__description{line-height:1.5}axp-widget-field-configurator .__widget-info .__action-buttons{display:flex;align-items:center;gap:.25rem;flex-shrink:0}axp-widget-field-configurator .__widget-empty{display:flex;align-items:center;gap:.5rem;padding:.5rem}axp-widget-field-configurator .__widget-empty.__editable{cursor:pointer}axp-widget-field-configurator .__widget-empty.__editable:hover{border-radius:.375rem;--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-lighter-surface),var(--tw-bg-opacity, 1))}axp-widget-field-configurator .__widget-empty:not(.__editable){cursor:not-allowed}axp-widget-field-configurator .__widget-empty>i{font-size:1rem;line-height:1.5rem;--tw-text-opacity: 1;color:rgb(163 163 163 / var(--tw-text-opacity, 1))}axp-widget-field-configurator .__widget-empty>span{font-size:.875rem;line-height:1.25rem;--tw-text-opacity: 1;color:rgb(82 82 82 / var(--tw-text-opacity, 1))}axp-widget-field-configurator .__item-template>i{flex-shrink:0;display:inline-flex;align-items:center;justify-content:center}axp-widget-field-configurator .__item-template>div>div:first-child{flex-shrink:0}axp-widget-field-configurator .__item-template>div>div:last-child{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}axp-widget-field-configurator .__selected-template{display:flex;align-items:center;gap:.5rem}axp-widget-field-configurator .__selected-template>i{font-size:.875rem;line-height:1.25rem}axp-widget-field-configurator .__selected-template>span{font-size:.875rem;line-height:1.25rem;font-weight:500}axp-widget-field-configurator :host([readonly]){pointer-events:none;opacity:.7}\n"] }]
4985
- }], ctorParameters: () => [], propDecorators: { widget: [{ type: i0.Input, args: [{ isSignal: true, alias: "widget", required: false }] }, { type: i0.Output, args: ["widgetChange"] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], fieldName: [{ type: i0.Input, args: [{ isSignal: true, alias: "fieldName", required: false }] }], fieldTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "fieldTitle", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }] } });
5861
+ ], template: "<!-- Widget Selector & Info Container -->\n<div class=\"__widget-container\">\n <!-- Edit Mode: Show Select Box -->\n @if (isEditMode()) {\n <div class=\"__widget-selector\">\n <ax-select-box #widgetSelectBox [ngModel]=\"selectedWidgetType()\" [dataSource]=\"availableWidgets()\"\n [placeholder]=\"('@general:actions.select.title' | translate | async) ?? ''\" [readonly]=\"readonly()\"\n (onValueChanged)=\"onWidgetTypeChange($event)\" valueField=\"value\" textField=\"text\" [itemTemplate]=\"itemTemplate\"\n [selectedTemplate]=\"selectedTemplate\" (onClosed)=\"exitEditMode()\">\n <ax-search-box></ax-search-box>\n <ax-clear-button></ax-clear-button>\n </ax-select-box>\n </div>\n }\n\n <!-- View Mode: Show Widget Info -->\n @if (!isEditMode()) {\n @if (selectedWidgetType() && currentWidgetConfig(); as config) {\n <div class=\"__widget-info\">\n <!-- Widget Header (Clickable to Edit) -->\n <div class=\"__widget-header\" [class.__editable]=\"!readonly()\" (click)=\"enterEditMode()\">\n <div>\n @if (config.icon) {\n <i [class]=\"config.icon\"></i>\n }\n <div>\n <span>\n {{ config.title }}\n </span>\n @if (config.description) {\n <p>\n {{ config.description }}\n </p>\n }\n </div>\n </div>\n\n <!-- Action Buttons -->\n <div class=\"__action-buttons\" (click)=\"$event.stopPropagation()\">\n <!-- Configure Button -->\n @if (config.hasProperties) {\n <ax-button [disabled]=\"!canConfigure() || readonly()\"\n [title]=\"('@general:actions.configure.title' | translate | async) ?? ''\" look=\"blank\"\n [color]=\"isConfigured() ? 'primary' : 'default'\" size=\"sm\" (onClick)=\"openPropertyViewer()\">\n <ax-icon icon=\"fa-solid fa-cog\"></ax-icon>\n </ax-button>\n }\n <!-- Preview Button -->\n <ax-button [disabled]=\"!canPreview()\" [title]=\"('@general:actions.preview.title' | translate | async) ?? ''\"\n look=\"blank\" size=\"sm\" (onClick)=\"openPreview()\">\n <ax-icon icon=\"fa-solid fa-eye\"></ax-icon>\n </ax-button>\n </div>\n </div>\n\n <!-- No Configuration Needed State -->\n @if (!config.hasProperties) {\n <axp-state-message mode=\"info\" icon=\"fa-solid fa-info-circle\"\n [description]=\"'@general:widgets.widget-configurator.no-configuration-needed'\" variant=\"compact\">\n </axp-state-message>\n }\n </div>\n } @else {\n <!-- Empty State (Clickable to Edit) -->\n <div class=\"__widget-empty\" [class.__editable]=\"!readonly()\" (click)=\"enterEditMode()\">\n <i class=\"fa-solid fa-puzzle-piece\"></i>\n <span>\n {{ ('@general:widgets.widget-configurator.select-widget-type' | translate | async) ?? 'Select a widget type' }}\n </span>\n </div>\n }\n }\n\n <!-- Widget Item Template (Dropdown Items) -->\n <ng-template #itemTemplate let-context>\n @let item = context.data;\n <div class=\"__item-template ax-flex ax-w-full ax-items-center ax-gap-3 ax-p-2\">\n @if (item.icon) {\n <i [class]=\"item.icon + ' ax-text-base ax-w-5 ax-text-center'\"></i>\n }\n <div class=\"ax-flex ax-items-center ax-gap-2 ax-flex-1 ax-min-w-0\">\n <div class=\"ax-text-sm ax-font-medium\">\n {{ item.text }}\n </div>\n @if (item.description) {\n <div class=\"ax-text-xs ax-text-neutral-600\">\n {{ item.description }}\n </div>\n }\n </div>\n </div>\n </ng-template>\n\n <!-- Widget Selected Template (Selected Value Display) -->\n <ng-template #selectedTemplate let-item>\n <div class=\"__selected-template\">\n @if (item?.data?.icon) {\n <i [class]=\"item.data.icon\"></i>\n }\n <span>\n {{ item?.data?.text }}\n </span>\n </div>\n </ng-template>\n</div>", styles: ["axp-widget-field-configurator{display:flex;flex-direction:column}axp-widget-field-configurator .__widget-container{border-radius:.375rem;border-width:1px;padding:1rem;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));transition:all .2s ease}axp-widget-field-configurator .__widget-selector{display:flex;flex-direction:column}axp-widget-field-configurator .__widget-selector ax-select-box{width:100%}axp-widget-field-configurator .__widget-info{display:flex;flex-direction:column;gap:.75rem}axp-widget-field-configurator .__widget-info .__widget-header{display:flex;align-items:center;justify-content:space-between;gap:.75rem;padding:.375rem .5rem}axp-widget-field-configurator .__widget-info .__widget-header.__editable{cursor:pointer}axp-widget-field-configurator .__widget-info .__widget-header.__editable:hover{border-radius:.375rem;--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-lighter-surface),var(--tw-bg-opacity, 1))}axp-widget-field-configurator .__widget-info .__widget-header:not(.__editable){cursor:not-allowed}axp-widget-field-configurator .__widget-info .__widget-header>div:first-child{display:flex;flex:1 1 0%;align-items:center;gap:.5rem}axp-widget-field-configurator .__widget-info .__widget-header>div:first-child i{font-size:1rem;line-height:1.5rem;flex-shrink:0}axp-widget-field-configurator .__widget-info .__widget-header>div:first-child>div{display:flex;flex:1 1 0%;flex-direction:column;gap:.125rem}axp-widget-field-configurator .__widget-info .__widget-header>div:first-child>div>span{font-size:.875rem;line-height:1.25rem;font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}axp-widget-field-configurator .__widget-info .__widget-header>div:first-child>div>p{margin:0;font-size:.75rem;line-height:1rem;line-height:1.625;--tw-text-opacity: 1;color:rgb(82 82 82 / var(--tw-text-opacity, 1))}axp-widget-field-configurator .__widget-info .__description{line-height:1.5}axp-widget-field-configurator .__widget-info .__action-buttons{display:flex;align-items:center;gap:.25rem;flex-shrink:0}axp-widget-field-configurator .__widget-empty{display:flex;align-items:center;gap:.5rem;padding:.5rem}axp-widget-field-configurator .__widget-empty.__editable{cursor:pointer}axp-widget-field-configurator .__widget-empty.__editable:hover{border-radius:.375rem;--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-lighter-surface),var(--tw-bg-opacity, 1))}axp-widget-field-configurator .__widget-empty:not(.__editable){cursor:not-allowed}axp-widget-field-configurator .__widget-empty>i{font-size:1rem;line-height:1.5rem;--tw-text-opacity: 1;color:rgb(163 163 163 / var(--tw-text-opacity, 1))}axp-widget-field-configurator .__widget-empty>span{font-size:.875rem;line-height:1.25rem;--tw-text-opacity: 1;color:rgb(82 82 82 / var(--tw-text-opacity, 1))}axp-widget-field-configurator .__item-template>i{flex-shrink:0;display:inline-flex;align-items:center;justify-content:center}axp-widget-field-configurator .__item-template>div>div:first-child{flex-shrink:0}axp-widget-field-configurator .__item-template>div>div:last-child{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}axp-widget-field-configurator .__selected-template{display:flex;align-items:center;gap:.5rem}axp-widget-field-configurator .__selected-template>i{font-size:.875rem;line-height:1.25rem}axp-widget-field-configurator .__selected-template>span{font-size:.875rem;line-height:1.25rem;font-weight:500}axp-widget-field-configurator :host([readonly]){pointer-events:none;opacity:.7}\n"] }]
5862
+ }], ctorParameters: () => [], propDecorators: { widget: [{ type: i0.Input, args: [{ isSignal: true, alias: "widget", required: false }] }, { type: i0.Output, args: ["widgetChange"] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], fieldName: [{ type: i0.Input, args: [{ isSignal: true, alias: "fieldName", required: false }] }], fieldTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "fieldTitle", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], widgetSelectBox: [{ type: i0.ViewChild, args: ['widgetSelectBox', { isSignal: true }] }] } });
4986
5863
 
4987
5864
  /**
4988
5865
  * Generic widget item component for displaying selectable widgets with icons, titles, and descriptions.
@@ -5197,7 +6074,7 @@ class AXPWidgetPropertyViewerPopupComponent extends AXBasePageComponent {
5197
6074
  </ax-button>
5198
6075
  </ax-suffix>
5199
6076
  </ax-footer>
5200
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i2$3.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.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: "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 }); }
6077
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1$1.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.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: "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 }); }
5201
6078
  }
5202
6079
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPWidgetPropertyViewerPopupComponent, decorators: [{
5203
6080
  type: Component,
@@ -5243,5 +6120,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
5243
6120
  * Generated bundle index. Do not edit.
5244
6121
  */
5245
6122
 
5246
- export { AXPActivityLogComponent, AXPCategoryTreeComponent, AXPColorPalettePickerComponent, AXPColumnItemListComponent, AXPCompareViewComponent, AXPComponentSlot, AXPComponentSlotDirective, AXPComponentSlotModule, AXPComponentSlotRegistryService, AXPDataSelectorComponent, AXPDataSelectorService, AXPDragDropListComponent, AXPImageEditorPopupComponent, AXPImageEditorService, AXPLogoComponent, AXPMenuBadgeHelper, AXPPropertyViewerComponent, AXPPropertyViewerPopupComponent, AXPPropertyViewerService, AXPQueryColumnsComponent, AXPQueryFiltersComponent, AXPQuerySortsComponent, AXPQueryViewsComponent, AXPSpreadsheetComponent, AXPStateMessageComponent, AXPStopwatchComponent, AXPTaskBadgeDirective, AXPTaskBadgeProvider, AXPTaskBadgeService, AXPTemplateViewerComponent, AXPTemplateViewerService, AXPThemeLayoutActionsComponent, AXPThemeLayoutBlockComponent, AXPThemeLayoutContainerComponent, AXPThemeLayoutEndSideComponent, AXPThemeLayoutFooterComponent, AXPThemeLayoutHeaderComponent, AXPThemeLayoutListComponent, AXPThemeLayoutListItemComponent, AXPThemeLayoutListItemsGroupComponent, AXPThemeLayoutPageHeaderComponent, AXPThemeLayoutPagePrimaryActionsComponent, AXPThemeLayoutPageSecondaryActionsComponent, AXPThemeLayoutSectionComponent, AXPThemeLayoutStartSideComponent, AXPThemeLayoutToolbarComponent, AXPUserAvatarComponent, AXPUserAvatarService, AXPWidgetFieldConfiguratorComponent, AXPWidgetItemComponent, AXPWidgetPropertyViewerComponent, AXPWidgetPropertyViewerPopupComponent, AXPWidgetPropertyViewerService, AXP_TASK_BADGE_PROVIDERS, AXP_USER_AVATAR_PROVIDER };
6123
+ export { AXPActivityLogComponent, AXPCategoryTreeComponent, AXPColorPalettePickerComponent, AXPColumnItemListComponent, AXPCompareViewComponent, AXPComponentSlot, AXPComponentSlotDirective, AXPComponentSlotModule, AXPComponentSlotRegistryService, AXPDataSelectorComponent, AXPDataSelectorService, AXPDragDropListComponent, AXPImageEditorPopupComponent, AXPImageEditorService, AXPLogoComponent, AXPMenuBadgeHelper, AXPMenuCustomizerComponent, AXPMenuCustomizerService, AXPPropertyViewerComponent, AXPPropertyViewerPopupComponent, AXPPropertyViewerService, AXPQueryColumnsComponent, AXPQueryFiltersComponent, AXPQuerySortsComponent, AXPQueryViewsComponent, AXPSpreadsheetComponent, AXPStateMessageComponent, AXPStopwatchComponent, AXPTableColumnsEditorComponent, AXPTableColumnsEditorPopupComponent, AXPTableColumnsEditorService, AXPTableDataEditorComponent, AXPTableDataEditorPopupComponent, AXPTableDataEditorService, AXPTaskBadgeDirective, AXPTaskBadgeProvider, AXPTaskBadgeService, AXPTemplateViewerComponent, AXPTemplateViewerService, AXPThemeLayoutActionsComponent, AXPThemeLayoutBlockComponent, AXPThemeLayoutContainerComponent, AXPThemeLayoutEndSideComponent, AXPThemeLayoutFooterComponent, AXPThemeLayoutHeaderComponent, AXPThemeLayoutListComponent, AXPThemeLayoutListItemComponent, AXPThemeLayoutListItemsGroupComponent, AXPThemeLayoutPageHeaderComponent, AXPThemeLayoutPagePrimaryActionsComponent, AXPThemeLayoutPageSecondaryActionsComponent, AXPThemeLayoutSectionComponent, AXPThemeLayoutStartSideComponent, AXPThemeLayoutToolbarComponent, AXPUserAvatarComponent, AXPUserAvatarService, AXPWidgetFieldConfiguratorComponent, AXPWidgetItemComponent, AXPWidgetPropertyViewerComponent, AXPWidgetPropertyViewerPopupComponent, AXPWidgetPropertyViewerService, AXP_MENU_CUSTOMIZER_SERVICE, AXP_TASK_BADGE_PROVIDERS, AXP_USER_AVATAR_PROVIDER, buildTableColumnsEditorLayout };
5247
6124
  //# sourceMappingURL=acorex-platform-layout-components.mjs.map