@acorex/platform 20.3.0-next.1 → 20.3.0-next.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.
- package/common/index.d.ts +125 -12
- package/core/index.d.ts +656 -100
- package/fesm2022/acorex-platform-auth.mjs +20 -20
- package/fesm2022/acorex-platform-auth.mjs.map +1 -1
- package/fesm2022/acorex-platform-common.mjs +120 -148
- package/fesm2022/acorex-platform-common.mjs.map +1 -1
- package/fesm2022/acorex-platform-core.mjs +885 -261
- package/fesm2022/acorex-platform-core.mjs.map +1 -1
- package/fesm2022/acorex-platform-domain.mjs +16 -16
- package/fesm2022/acorex-platform-domain.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-builder.mjs +1615 -662
- package/fesm2022/acorex-platform-layout-builder.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-components.mjs +3327 -157
- package/fesm2022/acorex-platform-layout-components.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-designer.mjs +172 -210
- package/fesm2022/acorex-platform-layout-designer.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-entity-create-entity.command-764ie8R8.mjs +52 -0
- package/fesm2022/acorex-platform-layout-entity-create-entity.command-764ie8R8.mjs.map +1 -0
- package/fesm2022/acorex-platform-layout-entity.mjs +4522 -1643
- package/fesm2022/acorex-platform-layout-entity.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-views.mjs +398 -89
- package/fesm2022/acorex-platform-layout-views.mjs.map +1 -1
- package/fesm2022/acorex-platform-native.mjs +7 -7
- package/fesm2022/acorex-platform-native.mjs.map +1 -1
- package/fesm2022/acorex-platform-runtime.mjs +40 -40
- package/fesm2022/acorex-platform-runtime.mjs.map +1 -1
- package/fesm2022/{acorex-platform-themes-default-entity-master-create-view.component-hHXxHlFG.mjs → acorex-platform-themes-default-entity-master-create-view.component-Ct-ri59W.mjs} +7 -7
- package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-Ct-ri59W.mjs.map +1 -0
- package/fesm2022/acorex-platform-themes-default-entity-master-list-view.component-7BB4LdjK.mjs +706 -0
- package/fesm2022/acorex-platform-themes-default-entity-master-list-view.component-7BB4LdjK.mjs.map +1 -0
- package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-BDJR088o.mjs +101 -0
- package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-BDJR088o.mjs.map +1 -0
- package/fesm2022/acorex-platform-themes-default-entity-master-single-view.component-BExtm1JE.mjs +244 -0
- package/fesm2022/acorex-platform-themes-default-entity-master-single-view.component-BExtm1JE.mjs.map +1 -0
- package/fesm2022/{acorex-platform-themes-default-error-401.component-D4glpFvU.mjs → acorex-platform-themes-default-error-401.component-DrO1PEOH.mjs} +4 -4
- package/fesm2022/{acorex-platform-themes-default-error-401.component-D4glpFvU.mjs.map → acorex-platform-themes-default-error-401.component-DrO1PEOH.mjs.map} +1 -1
- package/fesm2022/{acorex-platform-themes-default-error-404.component-BvGeDMjo.mjs → acorex-platform-themes-default-error-404.component-DqVq0oHX.mjs} +4 -4
- package/fesm2022/{acorex-platform-themes-default-error-404.component-BvGeDMjo.mjs.map → acorex-platform-themes-default-error-404.component-DqVq0oHX.mjs.map} +1 -1
- package/fesm2022/{acorex-platform-themes-default-error-offline.component-BINy-Zo3.mjs → acorex-platform-themes-default-error-offline.component-Bt2PTL7_.mjs} +4 -4
- package/fesm2022/{acorex-platform-themes-default-error-offline.component-BINy-Zo3.mjs.map → acorex-platform-themes-default-error-offline.component-Bt2PTL7_.mjs.map} +1 -1
- package/fesm2022/acorex-platform-themes-default.mjs +64 -509
- package/fesm2022/acorex-platform-themes-default.mjs.map +1 -1
- package/fesm2022/{acorex-platform-themes-shared-icon-chooser-view.component-C833prGO.mjs → acorex-platform-themes-shared-icon-chooser-view.component-BgEh06Tn.mjs} +24 -14
- package/fesm2022/acorex-platform-themes-shared-icon-chooser-view.component-BgEh06Tn.mjs.map +1 -0
- package/fesm2022/{acorex-platform-themes-shared-settings.provider-CXiRmniv.mjs → acorex-platform-themes-shared-settings.provider-CLUKU4y0.mjs} +2 -2
- package/fesm2022/acorex-platform-themes-shared-settings.provider-CLUKU4y0.mjs.map +1 -0
- package/fesm2022/{acorex-platform-themes-shared-color-chooser-column.component-DjKLg513.mjs → acorex-platform-themes-shared-theme-color-chooser-column.component-AeOQxjbS.mjs} +23 -8
- package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-column.component-AeOQxjbS.mjs.map +1 -0
- package/fesm2022/{acorex-platform-themes-shared-color-chooser-view.component-DE0wO98F.mjs → acorex-platform-themes-shared-theme-color-chooser-view.component-DEVzRd6-.mjs} +23 -8
- package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-view.component-DEVzRd6-.mjs.map +1 -0
- package/fesm2022/acorex-platform-themes-shared.mjs +250 -85
- package/fesm2022/acorex-platform-themes-shared.mjs.map +1 -1
- package/fesm2022/{acorex-platform-widgets-button-widget-designer.component-lNF95FJv.mjs → acorex-platform-widgets-button-widget-designer.component-DSaD9Fwc.mjs} +7 -7
- package/fesm2022/acorex-platform-widgets-button-widget-designer.component-DSaD9Fwc.mjs.map +1 -0
- package/fesm2022/acorex-platform-widgets-extra-properties-schema-widget-edit.component-D9mf08rU.mjs +50 -0
- package/fesm2022/acorex-platform-widgets-extra-properties-schema-widget-edit.component-D9mf08rU.mjs.map +1 -0
- package/fesm2022/acorex-platform-widgets-extra-properties-schema-widget-view.component-D6GQ-eyr.mjs +42 -0
- package/fesm2022/acorex-platform-widgets-extra-properties-schema-widget-view.component-D6GQ-eyr.mjs.map +1 -0
- package/fesm2022/acorex-platform-widgets-extra-properties-values-widget-edit.component-DVbIdVZ6.mjs +55 -0
- package/fesm2022/acorex-platform-widgets-extra-properties-values-widget-edit.component-DVbIdVZ6.mjs.map +1 -0
- package/fesm2022/acorex-platform-widgets-extra-properties-values-widget-view.component-D-aM64Hu.mjs +50 -0
- package/fesm2022/acorex-platform-widgets-extra-properties-values-widget-view.component-D-aM64Hu.mjs.map +1 -0
- package/fesm2022/acorex-platform-widgets-extra-properties-widget-edit.component-em2-aU8E.mjs +48 -0
- package/fesm2022/acorex-platform-widgets-extra-properties-widget-edit.component-em2-aU8E.mjs.map +1 -0
- package/fesm2022/acorex-platform-widgets-extra-properties-widget-view.component-BeuIofdr.mjs +42 -0
- package/fesm2022/acorex-platform-widgets-extra-properties-widget-view.component-BeuIofdr.mjs.map +1 -0
- package/fesm2022/{acorex-platform-widgets-file-list-popup.component-DFbPO0ud.mjs → acorex-platform-widgets-file-list-popup.component-Cmtq2bBV.mjs} +72 -7
- package/fesm2022/acorex-platform-widgets-file-list-popup.component-Cmtq2bBV.mjs.map +1 -0
- package/fesm2022/{acorex-platform-widgets-page-widget-designer.component-DRsLkulH.mjs → acorex-platform-widgets-page-widget-designer.component-B-ZEi2yd.mjs} +79 -69
- package/fesm2022/acorex-platform-widgets-page-widget-designer.component-B-ZEi2yd.mjs.map +1 -0
- package/fesm2022/{acorex-platform-widgets-tabular-data-edit-popup.component-nLZYiPnF.mjs → acorex-platform-widgets-tabular-data-edit-popup.component-CMqq_iOj.mjs} +13 -13
- package/fesm2022/acorex-platform-widgets-tabular-data-edit-popup.component-CMqq_iOj.mjs.map +1 -0
- package/fesm2022/{acorex-platform-widgets-tabular-data-view-popup.component-D6kiasYM.mjs → acorex-platform-widgets-tabular-data-view-popup.component-CRpjdiNz.mjs} +8 -7
- package/fesm2022/acorex-platform-widgets-tabular-data-view-popup.component-CRpjdiNz.mjs.map +1 -0
- package/fesm2022/{acorex-platform-widgets-text-block-widget-designer.component-CCMQtH3e.mjs → acorex-platform-widgets-text-block-widget-designer.component-DeSmBqMa.mjs} +9 -14
- package/fesm2022/acorex-platform-widgets-text-block-widget-designer.component-DeSmBqMa.mjs.map +1 -0
- package/fesm2022/acorex-platform-widgets.mjs +9152 -7182
- package/fesm2022/acorex-platform-widgets.mjs.map +1 -1
- package/fesm2022/acorex-platform-workflow.mjs +28 -25
- package/fesm2022/acorex-platform-workflow.mjs.map +1 -1
- package/layout/builder/index.d.ts +419 -185
- package/layout/components/index.d.ts +1129 -24
- package/layout/designer/index.d.ts +20 -49
- package/layout/entity/index.d.ts +424 -332
- package/layout/views/index.d.ts +129 -22
- package/package.json +25 -39
- package/widgets/index.d.ts +1908 -783
- package/workflow/index.d.ts +4 -1
- package/fesm2022/acorex-platform-themes-default-create-entity-view.component-SY0oMDoH.mjs +0 -22
- package/fesm2022/acorex-platform-themes-default-create-entity-view.component-SY0oMDoH.mjs.map +0 -1
- package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-hHXxHlFG.mjs.map +0 -1
- package/fesm2022/acorex-platform-themes-default-entity-master-list-view.component-hf4QOz_4.mjs +0 -665
- package/fesm2022/acorex-platform-themes-default-entity-master-list-view.component-hf4QOz_4.mjs.map +0 -1
- package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-DC3MrDtI.mjs +0 -108
- package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-DC3MrDtI.mjs.map +0 -1
- package/fesm2022/acorex-platform-themes-default-entity-master-single-view.component-Bb90PeHq.mjs +0 -236
- package/fesm2022/acorex-platform-themes-default-entity-master-single-view.component-Bb90PeHq.mjs.map +0 -1
- package/fesm2022/acorex-platform-themes-shared-color-chooser-column.component-DjKLg513.mjs.map +0 -1
- package/fesm2022/acorex-platform-themes-shared-color-chooser-view.component-DE0wO98F.mjs.map +0 -1
- package/fesm2022/acorex-platform-themes-shared-icon-chooser-view.component-C833prGO.mjs.map +0 -1
- package/fesm2022/acorex-platform-themes-shared-settings.provider-CXiRmniv.mjs.map +0 -1
- package/fesm2022/acorex-platform-widgets-button-widget-designer.component-lNF95FJv.mjs.map +0 -1
- package/fesm2022/acorex-platform-widgets-checkbox-widget-column.component-BNBOATPB.mjs +0 -85
- package/fesm2022/acorex-platform-widgets-checkbox-widget-column.component-BNBOATPB.mjs.map +0 -1
- package/fesm2022/acorex-platform-widgets-checkbox-widget-designer.component-BI18uzNZ.mjs +0 -55
- package/fesm2022/acorex-platform-widgets-checkbox-widget-designer.component-BI18uzNZ.mjs.map +0 -1
- package/fesm2022/acorex-platform-widgets-checkbox-widget-view.component-C6-QPsnb.mjs +0 -76
- package/fesm2022/acorex-platform-widgets-checkbox-widget-view.component-C6-QPsnb.mjs.map +0 -1
- package/fesm2022/acorex-platform-widgets-color-box-widget-designer.component-pYOQv5g8.mjs +0 -55
- package/fesm2022/acorex-platform-widgets-color-box-widget-designer.component-pYOQv5g8.mjs.map +0 -1
- package/fesm2022/acorex-platform-widgets-file-list-popup.component-DFbPO0ud.mjs.map +0 -1
- package/fesm2022/acorex-platform-widgets-file-rename-popup.component-DA_CgIvm.mjs +0 -211
- package/fesm2022/acorex-platform-widgets-file-rename-popup.component-DA_CgIvm.mjs.map +0 -1
- package/fesm2022/acorex-platform-widgets-page-widget-designer.component-DRsLkulH.mjs.map +0 -1
- package/fesm2022/acorex-platform-widgets-rich-text-popup.component-CM_v-cL4.mjs +0 -40
- package/fesm2022/acorex-platform-widgets-rich-text-popup.component-CM_v-cL4.mjs.map +0 -1
- package/fesm2022/acorex-platform-widgets-tabular-data-edit-popup.component-nLZYiPnF.mjs.map +0 -1
- package/fesm2022/acorex-platform-widgets-tabular-data-view-popup.component-D6kiasYM.mjs.map +0 -1
- package/fesm2022/acorex-platform-widgets-text-block-widget-designer.component-CCMQtH3e.mjs.map +0 -1
|
@@ -1,54 +1,104 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as i3 from '@acorex/components/button';
|
|
2
2
|
import { AXButtonModule } from '@acorex/components/button';
|
|
3
|
+
import * as i1$2 from '@acorex/cdk/common';
|
|
3
4
|
import { AXCommonModule } from '@acorex/cdk/common';
|
|
4
|
-
import * as
|
|
5
|
+
import * as i2$1 from '@acorex/components/decorators';
|
|
5
6
|
import { AXDecoratorModule } from '@acorex/components/decorators';
|
|
6
|
-
import * as
|
|
7
|
-
import {
|
|
8
|
-
import * as
|
|
7
|
+
import * as i5 from '@acorex/core/translation';
|
|
8
|
+
import { AXTranslationModule, AXTranslationService } from '@acorex/core/translation';
|
|
9
|
+
import * as i2 from '@acorex/components/skeleton';
|
|
9
10
|
import { AXSkeletonModule } from '@acorex/components/skeleton';
|
|
10
|
-
import * as
|
|
11
|
+
import * as i4 from '@acorex/core/format';
|
|
11
12
|
import { AXFormatModule } from '@acorex/core/format';
|
|
12
13
|
import { getSystemActions, AXPExpressionEvaluatorService, AXPContextStore } from '@acorex/platform/core';
|
|
13
14
|
import { AXPWorkflowService } from '@acorex/platform/workflow';
|
|
14
|
-
import * as
|
|
15
|
+
import * as i1 from '@angular/common';
|
|
15
16
|
import { CommonModule } from '@angular/common';
|
|
16
17
|
import * as i0 from '@angular/core';
|
|
17
|
-
import {
|
|
18
|
+
import { input, ChangeDetectionStrategy, ViewEncapsulation, Component, inject, signal, effect, InjectionToken, computed, Injectable, Directive, viewChild, contentChild, ElementRef, output, model, Injector, ViewContainerRef, runInInjectionContext, Optional, Inject, NgModule, viewChildren, Input, EventEmitter, untracked, Output, linkedSignal, ViewChildren } from '@angular/core';
|
|
18
19
|
import { AXAccordionCdkModule } from '@acorex/cdk/accordion';
|
|
19
20
|
import { AXTagModule } from '@acorex/components/tag';
|
|
20
21
|
import { SIGNAL, signalSetFn } from '@angular/core/primitives/signals';
|
|
21
22
|
import * as i8 from '@acorex/components/badge';
|
|
22
23
|
import { AXBadgeComponent, AXBadgeModule } from '@acorex/components/badge';
|
|
23
|
-
import * as
|
|
24
|
+
import * as i4$1 from '@acorex/components/search-box';
|
|
25
|
+
import { AXSearchBoxModule } from '@acorex/components/search-box';
|
|
26
|
+
import * as i2$2 from '@acorex/components/tree-view';
|
|
27
|
+
import { AXTreeViewModule } from '@acorex/components/tree-view';
|
|
28
|
+
import * as i6 from '@acorex/components/dropdown';
|
|
29
|
+
import { AXDropdownModule } from '@acorex/components/dropdown';
|
|
30
|
+
import * as i3$1 from '@acorex/components/switch';
|
|
31
|
+
import { AXSwitchModule } from '@acorex/components/switch';
|
|
32
|
+
import * as i9 from '@angular/cdk/drag-drop';
|
|
33
|
+
import { moveItemInArray, CdkDropList, CdkDrag, CdkDragHandle, DragDropModule } from '@angular/cdk/drag-drop';
|
|
34
|
+
import * as i1$1 from '@angular/forms';
|
|
35
|
+
import { FormsModule } from '@angular/forms';
|
|
36
|
+
import { cloneDeep, sortBy, isEmpty, isNil, isEqual, get, camelCase, merge, capitalize, unionBy, isArray, set } from 'lodash-es';
|
|
37
|
+
import * as i2$4 from '@acorex/components/form';
|
|
24
38
|
import { AXFormModule, AXFormComponent } from '@acorex/components/form';
|
|
39
|
+
import * as i4$4 from '@acorex/components/text-box';
|
|
25
40
|
import { AXTextBoxModule } from '@acorex/components/text-box';
|
|
26
|
-
import * as i2$
|
|
41
|
+
import * as i2$3 from '@acorex/components/check-box';
|
|
27
42
|
import { AXCheckBoxModule } from '@acorex/components/check-box';
|
|
28
|
-
import * as
|
|
43
|
+
import * as i3$2 from '@acorex/components/label';
|
|
29
44
|
import { AXLabelModule, AXLabelComponent } from '@acorex/components/label';
|
|
30
|
-
import * as i3$
|
|
31
|
-
import { AXPLayoutBuilderModule, AXPWidgetContainerComponent, AXPPageStatus } from '@acorex/platform/layout/builder';
|
|
32
|
-
import
|
|
45
|
+
import * as i3$3 from '@acorex/platform/layout/builder';
|
|
46
|
+
import { AXPLayoutBuilderModule, AXPWidgetContainerComponent, AXPPageStatus, AXPWidgetRegistryService, AXPWidgetsCatalog } from '@acorex/platform/layout/builder';
|
|
47
|
+
import * as i4$2 from '@acorex/components/data-table';
|
|
48
|
+
import { AXDataTableModule } from '@acorex/components/data-table';
|
|
49
|
+
import * as i4$3 from '@acorex/components/dropdown-button';
|
|
50
|
+
import { AXDropdownButtonModule } from '@acorex/components/dropdown-button';
|
|
51
|
+
import { AXBasePageComponent } from '@acorex/components/page';
|
|
52
|
+
import { AXPopupService } from '@acorex/components/popup';
|
|
53
|
+
import * as i5$1 from '@acorex/components/loading';
|
|
54
|
+
import { AXLoadingModule } from '@acorex/components/loading';
|
|
33
55
|
import { AXValidationModule } from '@acorex/core/validation';
|
|
34
|
-
import
|
|
35
|
-
import
|
|
36
|
-
import {
|
|
56
|
+
import * as i1$3 from '@acorex/components/step-wizard';
|
|
57
|
+
import { AXStepWizardComponent, AXStepWizardModule } from '@acorex/components/step-wizard';
|
|
58
|
+
import { AXPGridLayoutDirective, AXPStickyDirective, AXPFilterOperatorMiddlewareService, ALL_DEFAULT_OPERATORS } from '@acorex/platform/common';
|
|
59
|
+
import * as i5$2 from '@acorex/components/select-box';
|
|
60
|
+
import { AXSelectBoxModule } from '@acorex/components/select-box';
|
|
61
|
+
import * as i1$4 from '@acorex/components/collapse';
|
|
62
|
+
import { AXCollapseModule } from '@acorex/components/collapse';
|
|
63
|
+
import * as i2$5 from '@acorex/components/tabs';
|
|
64
|
+
import { AXTabsModule } from '@acorex/components/tabs';
|
|
37
65
|
import * as i7 from '@acorex/cdk/list-navigation';
|
|
38
66
|
import { AXListNavigationModule } from '@acorex/cdk/list-navigation';
|
|
39
|
-
import * as i4$
|
|
67
|
+
import * as i4$5 from '@acorex/components/popover';
|
|
40
68
|
import { AXPopoverModule } from '@acorex/components/popover';
|
|
41
69
|
import { AXSelectionListModule } from '@acorex/components/selection-list';
|
|
42
|
-
import * as i5$
|
|
70
|
+
import * as i5$3 from '@acorex/components/tag-box';
|
|
43
71
|
import { AXTagBoxModule } from '@acorex/components/tag-box';
|
|
44
72
|
import { AXCalendarService } from '@acorex/core/date-time';
|
|
45
73
|
import { BehaviorSubject, timer, Subject, takeUntil } from 'rxjs';
|
|
46
74
|
import { tap } from 'rxjs/operators';
|
|
47
|
-
import * as i1$
|
|
75
|
+
import * as i1$5 from '@acorex/components/avatar';
|
|
48
76
|
import { AXAvatarModule } from '@acorex/components/avatar';
|
|
49
|
-
import * as i3$
|
|
77
|
+
import * as i3$4 from '@acorex/components/image';
|
|
50
78
|
import { AXImageModule } from '@acorex/components/image';
|
|
51
79
|
|
|
80
|
+
//#endregion
|
|
81
|
+
//#region ---- Component Definition ----
|
|
82
|
+
//#endregion
|
|
83
|
+
//#region ---- Component Class ----
|
|
84
|
+
class AXPStateMessageComponent {
|
|
85
|
+
constructor() {
|
|
86
|
+
// Core properties
|
|
87
|
+
this.mode = input('empty', ...(ngDevMode ? [{ debugName: "mode" }] : []));
|
|
88
|
+
this.icon = input('', ...(ngDevMode ? [{ debugName: "icon" }] : []));
|
|
89
|
+
this.title = input('', ...(ngDevMode ? [{ debugName: "title" }] : []));
|
|
90
|
+
this.description = input('', ...(ngDevMode ? [{ debugName: "description" }] : []));
|
|
91
|
+
// Optional styling
|
|
92
|
+
this.variant = input('default', ...(ngDevMode ? [{ debugName: "variant" }] : []));
|
|
93
|
+
}
|
|
94
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPStateMessageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
95
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.1.8", type: AXPStateMessageComponent, isStandalone: true, selector: "axp-state-message", inputs: { mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"axp-state-message\" [attr.data-mode]=\"mode()\" [attr.data-variant]=\"variant()\">\n <div class=\"__icon\" *ngIf=\"icon()\">\n <i [class]=\"icon()\"></i>\n </div>\n <div class=\"__content\">\n <h3 class=\"__title\" *ngIf=\"title()\">{{ title() | translate | async }}</h3>\n <p class=\"__description\" *ngIf=\"description()\">{{ description() | translate | async }}</p>\n <div class=\"__actions\">\n <ng-content select=\"[slot=actions]\"></ng-content>\n </div>\n </div>\n</div>\n", styles: [".axp-state-message{display:flex;height:100%;flex-direction:column;align-items:center;justify-content:center;padding:3rem 1rem;text-align:center}.axp-state-message .__icon{margin-bottom:1rem}.axp-state-message .__icon i{opacity:74%;display:block;font-weight:400;font-size:2.25rem!important;line-height:2.5rem!important}.axp-state-message .__content{max-width:28rem}.axp-state-message .__title{margin-bottom:.5rem;font-size:1.125rem;line-height:1.75rem;font-weight:500}.axp-state-message .__description{margin-bottom:1rem;opacity:74%;display:block;font-weight:400;font-size:.875rem!important;line-height:1.25rem!important}.axp-state-message .__actions{display:flex;flex-direction:column;align-items:center;gap:.5rem}.axp-state-message[data-mode=empty] .__icon i{--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.axp-state-message[data-mode=error] .__icon i{--tw-text-opacity: 1;color:rgb(239 68 68 / var(--tw-text-opacity, 1))}.axp-state-message[data-mode=error] .__title{--tw-text-opacity: 1;color:rgb(220 38 38 / var(--tw-text-opacity, 1))}.axp-state-message[data-mode=loading] .__icon i{--tw-text-opacity: 1;color:rgb(59 130 246 / var(--tw-text-opacity, 1))}.axp-state-message[data-mode=loading] .__title{--tw-text-opacity: 1;color:rgb(37 99 235 / var(--tw-text-opacity, 1))}.axp-state-message[data-mode=warning] .__icon i{--tw-text-opacity: 1;color:rgb(249 115 22 / var(--tw-text-opacity, 1))}.axp-state-message[data-mode=warning] .__title{--tw-text-opacity: 1;color:rgb(234 88 12 / var(--tw-text-opacity, 1))}.axp-state-message[data-mode=info] .__icon i{--tw-text-opacity: 1;color:rgb(59 130 246 / var(--tw-text-opacity, 1))}.axp-state-message[data-mode=info] .__title{--tw-text-opacity: 1;color:rgb(37 99 235 / var(--tw-text-opacity, 1))}.axp-state-message[data-mode=success] .__icon i{--tw-text-opacity: 1;color:rgb(34 197 94 / var(--tw-text-opacity, 1))}.axp-state-message[data-mode=success] .__title{--tw-text-opacity: 1;color:rgb(22 163 74 / var(--tw-text-opacity, 1))}.axp-state-message[data-variant=compact]{padding:1.5rem .75rem}.axp-state-message[data-variant=compact] .__icon{margin-bottom:.5rem}.axp-state-message[data-variant=compact] .__icon i{font-size:1.5rem!important;line-height:2rem!important}.axp-state-message[data-variant=compact] .__title{margin-bottom:.25rem;font-size:1rem;line-height:1.5rem}.axp-state-message[data-variant=compact] .__description{margin-bottom:.5rem;font-size:.75rem;line-height:1rem}.axp-state-message[data-variant=minimal]{padding:1rem .5rem}.axp-state-message[data-variant=minimal] .__icon{margin-bottom:.25rem}.axp-state-message[data-variant=minimal] .__icon i{font-size:1.25rem!important;line-height:1.75rem!important}.axp-state-message[data-variant=minimal] .__title{margin-bottom:.25rem;font-size:.875rem;line-height:1.25rem}.axp-state-message[data-variant=minimal] .__description{margin-bottom:.25rem;font-size:.75rem;line-height:1rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
96
|
+
}
|
|
97
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPStateMessageComponent, decorators: [{
|
|
98
|
+
type: Component,
|
|
99
|
+
args: [{ selector: 'axp-state-message', standalone: true, imports: [CommonModule, AXTranslationModule], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"axp-state-message\" [attr.data-mode]=\"mode()\" [attr.data-variant]=\"variant()\">\n <div class=\"__icon\" *ngIf=\"icon()\">\n <i [class]=\"icon()\"></i>\n </div>\n <div class=\"__content\">\n <h3 class=\"__title\" *ngIf=\"title()\">{{ title() | translate | async }}</h3>\n <p class=\"__description\" *ngIf=\"description()\">{{ description() | translate | async }}</p>\n <div class=\"__actions\">\n <ng-content select=\"[slot=actions]\"></ng-content>\n </div>\n </div>\n</div>\n", styles: [".axp-state-message{display:flex;height:100%;flex-direction:column;align-items:center;justify-content:center;padding:3rem 1rem;text-align:center}.axp-state-message .__icon{margin-bottom:1rem}.axp-state-message .__icon i{opacity:74%;display:block;font-weight:400;font-size:2.25rem!important;line-height:2.5rem!important}.axp-state-message .__content{max-width:28rem}.axp-state-message .__title{margin-bottom:.5rem;font-size:1.125rem;line-height:1.75rem;font-weight:500}.axp-state-message .__description{margin-bottom:1rem;opacity:74%;display:block;font-weight:400;font-size:.875rem!important;line-height:1.25rem!important}.axp-state-message .__actions{display:flex;flex-direction:column;align-items:center;gap:.5rem}.axp-state-message[data-mode=empty] .__icon i{--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.axp-state-message[data-mode=error] .__icon i{--tw-text-opacity: 1;color:rgb(239 68 68 / var(--tw-text-opacity, 1))}.axp-state-message[data-mode=error] .__title{--tw-text-opacity: 1;color:rgb(220 38 38 / var(--tw-text-opacity, 1))}.axp-state-message[data-mode=loading] .__icon i{--tw-text-opacity: 1;color:rgb(59 130 246 / var(--tw-text-opacity, 1))}.axp-state-message[data-mode=loading] .__title{--tw-text-opacity: 1;color:rgb(37 99 235 / var(--tw-text-opacity, 1))}.axp-state-message[data-mode=warning] .__icon i{--tw-text-opacity: 1;color:rgb(249 115 22 / var(--tw-text-opacity, 1))}.axp-state-message[data-mode=warning] .__title{--tw-text-opacity: 1;color:rgb(234 88 12 / var(--tw-text-opacity, 1))}.axp-state-message[data-mode=info] .__icon i{--tw-text-opacity: 1;color:rgb(59 130 246 / var(--tw-text-opacity, 1))}.axp-state-message[data-mode=info] .__title{--tw-text-opacity: 1;color:rgb(37 99 235 / var(--tw-text-opacity, 1))}.axp-state-message[data-mode=success] .__icon i{--tw-text-opacity: 1;color:rgb(34 197 94 / var(--tw-text-opacity, 1))}.axp-state-message[data-mode=success] .__title{--tw-text-opacity: 1;color:rgb(22 163 74 / var(--tw-text-opacity, 1))}.axp-state-message[data-variant=compact]{padding:1.5rem .75rem}.axp-state-message[data-variant=compact] .__icon{margin-bottom:.5rem}.axp-state-message[data-variant=compact] .__icon i{font-size:1.5rem!important;line-height:2rem!important}.axp-state-message[data-variant=compact] .__title{margin-bottom:.25rem;font-size:1rem;line-height:1.5rem}.axp-state-message[data-variant=compact] .__description{margin-bottom:.5rem;font-size:.75rem;line-height:1rem}.axp-state-message[data-variant=minimal]{padding:1rem .5rem}.axp-state-message[data-variant=minimal] .__icon{margin-bottom:.25rem}.axp-state-message[data-variant=minimal] .__icon i{font-size:1.25rem!important;line-height:1.75rem!important}.axp-state-message[data-variant=minimal] .__title{margin-bottom:.25rem;font-size:.875rem;line-height:1.25rem}.axp-state-message[data-variant=minimal] .__description{margin-bottom:.25rem;font-size:.75rem;line-height:1rem}\n"] }]
|
|
100
|
+
}] });
|
|
101
|
+
|
|
52
102
|
//#region ---- Component Definition ----
|
|
53
103
|
class AXPActivityLogComponent {
|
|
54
104
|
//#endregion
|
|
@@ -178,10 +228,10 @@ class AXPActivityLogComponent {
|
|
|
178
228
|
const currentIndex = this.activities().findIndex(a => a.id === activity.id);
|
|
179
229
|
return currentIndex > 0; // Can compare if not the first activity
|
|
180
230
|
}
|
|
181
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.
|
|
182
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", type: AXPActivityLogComponent, isStandalone: true, selector: "axp-activity-log", inputs: { activities: { classPropertyName: "activities", publicName: "activities", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"axp-activity-log ax-accent2\" *translate=\"let t\">\n\n <!-- Activity Log Content -->\n <div class=\"__content\">\n\n <!-- Loading State -->\n @if (loading()) {\n <div class=\"__loading\">\n @for (item of [1,2,3,4]; track $index) {\n <div class=\"__item\">\n <ax-skeleton [animated]=\"true\" class=\"__avatar\"></ax-skeleton>\n <div class=\"__content\">\n <ax-skeleton [animated]=\"true\" class=\"__title\"></ax-skeleton>\n <ax-skeleton [animated]=\"true\" class=\"__subtitle\"></ax-skeleton>\n <ax-skeleton [animated]=\"true\" class=\"__description\"></ax-skeleton>\n <ax-skeleton [animated]=\"true\" class=\"__time\"></ax-skeleton>\n </div>\n </div>\n }\n </div>\n }\n\n <!-- Activity Feed -->\n @if (!loading() && activities().length > 0) {\n <div class=\"__feed\">\n @for (activity of activities(); track activity.id) {\n @let changeClasses = getChangeClasses(activity.changeType);\n @let isItemExpanded = isExpanded(activity.id);\n @let hasExpandableContentItem = hasExpandableContent(activity);\n <div class=\"__item\" [class.__collapsed]=\"!isItemExpanded\" [class.__expandable]=\"hasExpandableContentItem\">\n\n <div\n class=\"ax-size-10 ax-rounded-full ax-border ax-flex ax-items-center ax-justify-center ax-lightest-surface \">\n <i class=\"{{changeClasses.icon}} {{changeClasses.text}} fa-solid\"></i>\n </div>\n\n <!-- Activity Content -->\n <div class=\"__content\">\n <!-- Main Activity Info -->\n <div class=\"__main-info\">\n\n <!-- User and Action with Toggle Button -->\n <div class=\"__action-line __header-line\" (click)=\"toggleExpanded(activity.id)\">\n <span class=\"__user-name\">{{ activity.user.title }}</span>\n <span class=\"__action-type\">\n {{ t(`actions.${activity.changeType}.title`, {\n scope: 'general' }) | async }}\n </span>\n <span class=\"__action-text\">\n {{ activity.title | translate | async }}\n </span>\n\n <!-- Compare Button -->\n @if (canCompare(activity)) {\n <button type=\"button\" class=\"__compare-button\" (click)=\"handleCompare(activity, $event)\"\n [attr.aria-label]=\"t('compare.title', { scope: i18nScope }) | async\">\n <i class=\"fa-solid fa-code-compare\"></i>\n </button>\n }\n\n <!-- Toggle Button (only show if there's expandable content) -->\n @if (hasExpandableContentItem) {\n <button type=\"button\" class=\"__toggle-button\" [attr.aria-expanded]=\"isItemExpanded\"\n [attr.aria-label]=\"isItemExpanded ? 'Collapse details' : 'Expand details'\">\n <i class=\"fa-solid\" [class.fa-chevron-down]=\"!isItemExpanded\"\n [class.fa-chevron-up]=\"isItemExpanded\"></i>\n </button>\n }\n </div>\n\n <!-- Expandable Description/Changes -->\n @if (hasExpandableContentItem && isItemExpanded && activity.changes.length > 0) {\n <div class=\"__action-lines __expandable-content\"\n [class.__animated]=\"shouldAnimate(activity.id)\">\n @for (change of activity.changes; track $index) {\n @let changeClasses = getChangeClasses(change.type);\n <div class=\"__action-line\">\n <div class=\"ax-rounded-full ax-size-7 ax-grid ax-place-items-center\">\n <i class=\"{{changeClasses.icon}} {{changeClasses.text}}\"></i>\n </div>\n <span class=\"__action-text\">{{\n change.description | translate | async }}</span>\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Time -->\n <div class=\"__time\">\n {{ activity.date | format: 'datetime' : 'short' | async }}\n </div>\n\n </div>\n\n </div>\n }\n </div>\n }\n\n <!-- Empty State -->\n @if (!loading() && activities().length === 0) {\n <div class=\"__empty\">\n <div class=\"__icon\">\n <ax-icon icon=\"fa-light fa-history\" class=\"__svg\"></ax-icon>\n </div>\n <div class=\"__content\">\n <h4 class=\"__title\">{{ t('no-history.title', { scope: i18nScope }) | async }}</h4>\n <p class=\"__message\">{{ t('no-history.message', { scope: i18nScope }) | async }}\n </p>\n </div>\n </div>\n }\n\n </div>\n</div>\n\n<!-- \n\nax-success-surface\nax-primary-surface\nax-danger-surface\nax-warning-surface\nax-info-surface\nax-muted-surface\nax-text-success\n\n -->", styles: [".axp-activity-log{height:100%;width:100%}.axp-activity-log .__content .__loading>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.axp-activity-log .__content .__loading .__item{display:flex;align-items:flex-start;gap:1rem}.axp-activity-log .__content .__loading .__item .__avatar{height:3rem;width:3rem;flex-shrink:0;border-radius:9999px}.axp-activity-log .__content .__loading .__item .__content{flex:1 1 0%}.axp-activity-log .__content .__loading .__item .__content>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.axp-activity-log .__content .__loading .__item .__content .__title{height:1rem;width:75%;border-radius:.25rem}.axp-activity-log .__content .__loading .__item .__content .__subtitle{height:.75rem;width:50%;border-radius:.25rem}.axp-activity-log .__content .__loading .__item .__content .__description{height:.75rem;width:83.333333%;border-radius:.25rem}.axp-activity-log .__content .__loading .__item .__content .__time{height:.75rem;width:25%;border-radius:.25rem}.axp-activity-log .__content .__feed{position:relative}.axp-activity-log .__content .__feed>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))}.axp-activity-log .__content .__feed:before{content:\"\";position:absolute;inset-inline-start:1.25rem;top:.5rem;bottom:.5rem;width:0px;border-left:1px solid rgba(var(--ax-sys-color-border-surface));z-index:0}.axp-activity-log .__content .__feed .__item{position:relative;display:flex;align-items:flex-start;gap:1rem}.axp-activity-log .__content .__feed .__item axp-user-avatar{position:relative;z-index:10}.axp-activity-log .__content .__feed .__item .__content{min-width:0px;flex:1 1 0%}.axp-activity-log .__content .__feed .__item .__content .__main-info{margin-bottom:.25rem}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line{margin-top:.25rem;display:flex;flex-wrap:wrap;align-items:center;gap:.25rem;line-height:1.5}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line .__user-name{font-weight:600}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line .__action-type,.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line .__action-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.875rem;line-height:1.25rem;opacity:.85}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line{align-items:center;border-radius:.375rem;padding:.25rem .5rem}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line:hover{background-color:rgb(var(--ax-sys-color-lighter-surface));color:rgb(var(--ax-sys-color-on-lighter-surface));border-color:rgb(var(--ax-sys-color-border-lighter-surface))}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line .__compare-button{margin-left:.5rem;border-radius:9999px;padding:.25rem;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s;animation-duration:.2s;display:flex;width:1.5rem;height:1.5rem;align-items:center;justify-content:center;--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-primary-500),var(--tw-text-opacity, 1))}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line .__compare-button:hover{background-color:rgb(var(--ax-sys-color-primary-surface));color:rgb(var(--ax-sys-color-on-primary-surface));border-color:rgb(var(--ax-sys-color-border-primary-surface))}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line .__compare-button:focus{outline:2px solid transparent;outline-offset:2px;--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000);--tw-ring-opacity: 1;--tw-ring-color: rgba(var(--ax-sys-color-primary-500), var(--tw-ring-opacity, 1));--tw-ring-offset-width: 1px}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line .__compare-button i{font-size:.75rem;line-height:1rem}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line .__toggle-button{margin-left:auto;border-radius:9999px;padding:.25rem;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s;animation-duration:.2s;display:flex;width:1.5rem;height:1.5rem;align-items:center;justify-content:center}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line .__toggle-button:focus{outline:2px solid transparent;outline-offset:2px;--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000);--tw-ring-opacity: 1;--tw-ring-color: rgba(var(--ax-sys-color-primary-500), var(--tw-ring-opacity, 1));--tw-ring-offset-width: 1px}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line .__toggle-button i{font-size:.75rem;line-height:1rem;transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s;animation-duration:.2s}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-lines{margin-top:.5rem;margin-bottom:.5rem;display:flex;flex-direction:column;font-size:.875rem;line-height:1.25rem}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-lines.__expandable-content{overflow:hidden}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-lines.__expandable-content.__animated{transition-property:all;transition-duration:.3s;transition-timing-function:cubic-bezier(.4,0,.2,1);animation-duration:.3s;animation-timing-function:cubic-bezier(.4,0,.2,1);animation:slideDown .3s ease-out}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-lines .__action-line{display:flex;align-items:center;gap:.5rem;padding-top:.25rem;padding-bottom:.25rem}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-lines .__action-line .__action-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.875rem;line-height:1.25rem;opacity:.85}.axp-activity-log .__content .__feed .__item .__content .__time{padding-left:.5rem;padding-right:.5rem;font-size:.75rem;line-height:1rem;opacity:.75}.axp-activity-log .__content .__feed .__item.__collapsed .__expandable-content{display:none}.axp-activity-log .__content .__feed .__item.__expandable .__header-line{cursor:pointer}.axp-activity-log .__content .__empty{display:flex;height:12rem;flex-direction:column;align-items:center;justify-content:center;padding:2rem;text-align:center}.axp-activity-log .__content .__empty .__icon{margin-bottom:1rem}.axp-activity-log .__content .__empty .__icon .__svg{font-size:2.25rem;line-height:2.5rem;--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.axp-activity-log .__content .__empty .__content .__title{margin-bottom:.5rem;font-size:1.125rem;line-height:1.75rem;font-weight:600;--tw-text-opacity: 1;color:rgb(17 24 39 / var(--tw-text-opacity, 1))}.axp-activity-log .__content .__empty .__content .__message{max-width:20rem;line-height:1.625;--tw-text-opacity: 1;color:rgb(75 85 99 / var(--tw-text-opacity, 1))}@media (min-width: 640px){.axp-activity-log .__content .__feed .__item{gap:.625rem}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line{flex-wrap:nowrap}}@keyframes slideDown{0%{opacity:0;max-height:0;transform:translateY(-10px)}to{opacity:1;max-height:200px;transform:translateY(0)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "ngmodule", type: AXCommonModule }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i3.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "directive", type: i2.AXTranslatorDirective, selector: "[translate]" }, { kind: "ngmodule", type: AXSkeletonModule }, { kind: "component", type: i3$1.AXSkeletonComponent, selector: "ax-skeleton", inputs: ["animated"] }, { kind: "ngmodule", type: AXFormatModule }, { kind: "ngmodule", type: AXTagModule }, { kind: "ngmodule", type: AXAccordionCdkModule }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }, { kind: "pipe", type: i2.AXTranslatorPipe, name: "translate" }, { kind: "pipe", type: i5.AXFormatPipe, name: "format" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
231
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPActivityLogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
232
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.8", type: AXPActivityLogComponent, isStandalone: true, selector: "axp-activity-log", inputs: { activities: { classPropertyName: "activities", publicName: "activities", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"axp-activity-log ax-accent2\" *translate=\"let t\">\n <!-- Activity Log Content -->\n <div class=\"__content\">\n <!-- Loading State -->\n @if (loading()) {\n <div class=\"__loading\">\n @for (item of [1, 2, 3, 4]; track $index) {\n <div class=\"__item\">\n <ax-skeleton [animated]=\"true\" class=\"__avatar\"></ax-skeleton>\n <div class=\"__content\">\n <ax-skeleton [animated]=\"true\" class=\"__title\"></ax-skeleton>\n <ax-skeleton [animated]=\"true\" class=\"__subtitle\"></ax-skeleton>\n <ax-skeleton [animated]=\"true\" class=\"__description\"></ax-skeleton>\n <ax-skeleton [animated]=\"true\" class=\"__time\"></ax-skeleton>\n </div>\n </div>\n }\n </div>\n }\n\n <!-- Activity Feed -->\n @if (!loading() && activities().length > 0) {\n <div class=\"__feed\">\n @for (activity of activities(); track activity.id) {\n @let changeClasses = getChangeClasses(activity.changeType);\n @let isItemExpanded = isExpanded(activity.id);\n @let hasExpandableContentItem = hasExpandableContent(activity);\n <div class=\"__item\" [class.__collapsed]=\"!isItemExpanded\" [class.__expandable]=\"hasExpandableContentItem\">\n <div\n class=\"ax-size-10 ax-rounded-full ax-border ax-flex ax-items-center ax-justify-center ax-lightest-surface\"\n >\n <i class=\"{{ changeClasses.icon }} {{ changeClasses.text }} fa-solid\"></i>\n </div>\n\n <!-- Activity Content -->\n <div class=\"__content\">\n <!-- Main Activity Info -->\n <div class=\"__main-info\">\n <!-- User and Action with Toggle Button -->\n <div class=\"__action-line __header-line\" (click)=\"toggleExpanded(activity.id)\">\n <span class=\"__user-name\">{{ activity.user.title }}</span>\n <span class=\"__action-type\">\n {{ t(`@general:actions.${activity.changeType}.title`) | async }}\n </span>\n <span class=\"__action-text\">\n {{ activity.title | translate | async }}\n </span>\n\n <!-- Compare Button -->\n @if (canCompare(activity)) {\n <button\n type=\"button\"\n class=\"__compare-button\"\n (click)=\"handleCompare(activity, $event)\"\n [attr.aria-label]=\"t('compare.title', { scope: i18nScope }) | async\"\n >\n <i class=\"fa-solid fa-code-compare\"></i>\n </button>\n }\n\n <!-- Toggle Button (only show if there's expandable content) -->\n @if (hasExpandableContentItem) {\n <button\n type=\"button\"\n class=\"__toggle-button\"\n [attr.aria-expanded]=\"isItemExpanded\"\n [attr.aria-label]=\"isItemExpanded ? 'Collapse details' : 'Expand details'\"\n >\n <i\n class=\"fa-solid\"\n [class.fa-chevron-down]=\"!isItemExpanded\"\n [class.fa-chevron-up]=\"isItemExpanded\"\n ></i>\n </button>\n }\n </div>\n\n <!-- Expandable Description/Changes -->\n @if (hasExpandableContentItem && isItemExpanded && activity.changes.length > 0) {\n <div class=\"__action-lines __expandable-content\" [class.__animated]=\"shouldAnimate(activity.id)\">\n @for (change of activity.changes; track $index) {\n @let changeClasses = getChangeClasses(change.type);\n <div class=\"__action-line\">\n <div class=\"ax-rounded-full ax-size-7 ax-grid ax-place-items-center\">\n <i class=\"{{ changeClasses.icon }} {{ changeClasses.text }}\"></i>\n </div>\n <span class=\"__action-text\">{{ change.description | translate | async }}</span>\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Time -->\n <div class=\"__time\">\n {{ activity.date | format: 'datetime' : 'short' | async }}\n </div>\n </div>\n </div>\n }\n </div>\n }\n\n <!-- Empty State -->\n @if (!loading() && activities().length === 0) {\n <axp-state-message\n icon=\"fa-light fa-history\"\n [title]=\"'@general:no-history.title'\"\n [description]=\"'@general:no-history.message'\"\n >\n </axp-state-message>\n }\n </div>\n</div>\n\n<!-- \n\nax-success-surface\nax-primary-surface\nax-danger-surface\nax-warning-surface\nax-info-surface\nax-muted-surface\nax-text-success\n\n -->\n", styles: [".axp-activity-log{height:100%;width:100%}.axp-activity-log .__content .__loading>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.axp-activity-log .__content .__loading .__item{display:flex;align-items:flex-start;gap:1rem}.axp-activity-log .__content .__loading .__item .__avatar{height:3rem;width:3rem;flex-shrink:0;border-radius:9999px}.axp-activity-log .__content .__loading .__item .__content{flex:1 1 0%}.axp-activity-log .__content .__loading .__item .__content>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.axp-activity-log .__content .__loading .__item .__content .__title{height:1rem;width:75%;border-radius:.25rem}.axp-activity-log .__content .__loading .__item .__content .__subtitle{height:.75rem;width:50%;border-radius:.25rem}.axp-activity-log .__content .__loading .__item .__content .__description{height:.75rem;width:83.333333%;border-radius:.25rem}.axp-activity-log .__content .__loading .__item .__content .__time{height:.75rem;width:25%;border-radius:.25rem}.axp-activity-log .__content .__feed{position:relative}.axp-activity-log .__content .__feed>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))}.axp-activity-log .__content .__feed:before{content:\"\";position:absolute;inset-inline-start:1.25rem;top:.5rem;bottom:.5rem;width:0px;border-left:1px solid rgba(var(--ax-sys-color-border-surface));z-index:0}.axp-activity-log .__content .__feed .__item{position:relative;display:flex;align-items:flex-start;gap:1rem}.axp-activity-log .__content .__feed .__item axp-user-avatar{position:relative;z-index:10}.axp-activity-log .__content .__feed .__item .__content{min-width:0px;flex:1 1 0%}.axp-activity-log .__content .__feed .__item .__content .__main-info{margin-bottom:.25rem}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line{margin-top:.25rem;display:flex;flex-wrap:wrap;align-items:center;gap:.25rem;line-height:1.5}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line .__user-name{font-weight:600}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line .__action-type,.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line .__action-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.875rem;line-height:1.25rem;opacity:.85}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line{align-items:center;border-radius:.375rem;padding:.25rem .5rem}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line:hover{background-color:rgb(var(--ax-sys-color-lighter-surface));color:rgb(var(--ax-sys-color-on-lighter-surface));border-color:rgb(var(--ax-sys-color-border-lighter-surface))}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line .__compare-button{margin-left:.5rem;border-radius:9999px;padding:.25rem;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s;animation-duration:.2s;display:flex;width:1.5rem;height:1.5rem;align-items:center;justify-content:center;--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-primary-500),var(--tw-text-opacity, 1))}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line .__compare-button:hover{background-color:rgb(var(--ax-sys-color-primary-surface));color:rgb(var(--ax-sys-color-on-primary-surface));border-color:rgb(var(--ax-sys-color-border-primary-surface))}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line .__compare-button:focus{outline:2px solid transparent;outline-offset:2px;--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000);--tw-ring-opacity: 1;--tw-ring-color: rgba(var(--ax-sys-color-primary-500), var(--tw-ring-opacity, 1));--tw-ring-offset-width: 1px}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line .__compare-button i{font-size:.75rem;line-height:1rem}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line .__toggle-button{margin-left:auto;border-radius:9999px;padding:.25rem;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s;animation-duration:.2s;display:flex;width:1.5rem;height:1.5rem;align-items:center;justify-content:center}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line .__toggle-button:focus{outline:2px solid transparent;outline-offset:2px;--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000);--tw-ring-opacity: 1;--tw-ring-color: rgba(var(--ax-sys-color-primary-500), var(--tw-ring-opacity, 1));--tw-ring-offset-width: 1px}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line .__toggle-button i{font-size:.75rem;line-height:1rem;transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s;animation-duration:.2s}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-lines{margin-top:.5rem;margin-bottom:.5rem;display:flex;flex-direction:column;font-size:.875rem;line-height:1.25rem}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-lines.__expandable-content{overflow:hidden}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-lines.__expandable-content.__animated{transition-property:all;transition-duration:.3s;transition-timing-function:cubic-bezier(.4,0,.2,1);animation-duration:.3s;animation-timing-function:cubic-bezier(.4,0,.2,1);animation:slideDown .3s ease-out}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-lines .__action-line{display:flex;align-items:center;gap:.5rem;padding-top:.25rem;padding-bottom:.25rem}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-lines .__action-line .__action-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.875rem;line-height:1.25rem;opacity:.85}.axp-activity-log .__content .__feed .__item .__content .__time{padding-left:.5rem;padding-right:.5rem;font-size:.75rem;line-height:1rem;opacity:.75}.axp-activity-log .__content .__feed .__item.__collapsed .__expandable-content{display:none}.axp-activity-log .__content .__feed .__item.__expandable .__header-line{cursor:pointer}@media (min-width: 640px){.axp-activity-log .__content .__feed .__item{gap:.625rem}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line{flex-wrap:nowrap}}@keyframes slideDown{0%{opacity:0;max-height:0;transform:translateY(-10px)}to{opacity:1;max-height:200px;transform:translateY(0)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "ngmodule", type: AXCommonModule }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "directive", type: i5.AXTranslatorDirective, selector: "[translate]" }, { kind: "ngmodule", type: AXSkeletonModule }, { kind: "component", type: i2.AXSkeletonComponent, selector: "ax-skeleton", inputs: ["animated"] }, { kind: "ngmodule", type: AXFormatModule }, { kind: "ngmodule", type: AXTagModule }, { kind: "ngmodule", type: AXAccordionCdkModule }, { kind: "component", type: AXPStateMessageComponent, selector: "axp-state-message", inputs: ["mode", "icon", "title", "description", "variant"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }, { kind: "pipe", type: i4.AXFormatPipe, name: "format" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
183
233
|
}
|
|
184
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.
|
|
234
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPActivityLogComponent, decorators: [{
|
|
185
235
|
type: Component,
|
|
186
236
|
args: [{ selector: 'axp-activity-log', standalone: true, imports: [
|
|
187
237
|
CommonModule,
|
|
@@ -193,7 +243,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
|
|
|
193
243
|
AXFormatModule,
|
|
194
244
|
AXTagModule,
|
|
195
245
|
AXAccordionCdkModule,
|
|
196
|
-
], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<div class=\"axp-activity-log ax-accent2\" *translate=\"let t\">\n\n <!-- Activity Log Content -->\n <div class=\"__content\">\n\n <!-- Loading State -->\n @if (loading()) {\n <div class=\"__loading\">\n @for (item of [1,2,3,4]; track $index) {\n <div class=\"__item\">\n <ax-skeleton [animated]=\"true\" class=\"__avatar\"></ax-skeleton>\n <div class=\"__content\">\n <ax-skeleton [animated]=\"true\" class=\"__title\"></ax-skeleton>\n <ax-skeleton [animated]=\"true\" class=\"__subtitle\"></ax-skeleton>\n <ax-skeleton [animated]=\"true\" class=\"__description\"></ax-skeleton>\n <ax-skeleton [animated]=\"true\" class=\"__time\"></ax-skeleton>\n </div>\n </div>\n }\n </div>\n }\n\n <!-- Activity Feed -->\n @if (!loading() && activities().length > 0) {\n <div class=\"__feed\">\n @for (activity of activities(); track activity.id) {\n @let changeClasses = getChangeClasses(activity.changeType);\n @let isItemExpanded = isExpanded(activity.id);\n @let hasExpandableContentItem = hasExpandableContent(activity);\n <div class=\"__item\" [class.__collapsed]=\"!isItemExpanded\" [class.__expandable]=\"hasExpandableContentItem\">\n\n <div\n class=\"ax-size-10 ax-rounded-full ax-border ax-flex ax-items-center ax-justify-center ax-lightest-surface \">\n <i class=\"{{changeClasses.icon}} {{changeClasses.text}} fa-solid\"></i>\n </div>\n\n <!-- Activity Content -->\n <div class=\"__content\">\n <!-- Main Activity Info -->\n <div class=\"__main-info\">\n\n <!-- User and Action with Toggle Button -->\n <div class=\"__action-line __header-line\" (click)=\"toggleExpanded(activity.id)\">\n <span class=\"__user-name\">{{ activity.user.title }}</span>\n <span class=\"__action-type\">\n {{ t(`actions.${activity.changeType}.title`, {\n scope: 'general' }) | async }}\n </span>\n <span class=\"__action-text\">\n {{ activity.title | translate | async }}\n </span>\n\n <!-- Compare Button -->\n @if (canCompare(activity)) {\n <button type=\"button\" class=\"__compare-button\" (click)=\"handleCompare(activity, $event)\"\n [attr.aria-label]=\"t('compare.title', { scope: i18nScope }) | async\">\n <i class=\"fa-solid fa-code-compare\"></i>\n </button>\n }\n\n <!-- Toggle Button (only show if there's expandable content) -->\n @if (hasExpandableContentItem) {\n <button type=\"button\" class=\"__toggle-button\" [attr.aria-expanded]=\"isItemExpanded\"\n [attr.aria-label]=\"isItemExpanded ? 'Collapse details' : 'Expand details'\">\n <i class=\"fa-solid\" [class.fa-chevron-down]=\"!isItemExpanded\"\n [class.fa-chevron-up]=\"isItemExpanded\"></i>\n </button>\n }\n </div>\n\n <!-- Expandable Description/Changes -->\n @if (hasExpandableContentItem && isItemExpanded && activity.changes.length > 0) {\n <div class=\"__action-lines __expandable-content\"\n [class.__animated]=\"shouldAnimate(activity.id)\">\n @for (change of activity.changes; track $index) {\n @let changeClasses = getChangeClasses(change.type);\n <div class=\"__action-line\">\n <div class=\"ax-rounded-full ax-size-7 ax-grid ax-place-items-center\">\n <i class=\"{{changeClasses.icon}} {{changeClasses.text}}\"></i>\n </div>\n <span class=\"__action-text\">{{\n change.description | translate | async }}</span>\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Time -->\n <div class=\"__time\">\n {{ activity.date | format: 'datetime' : 'short' | async }}\n </div>\n\n </div>\n\n </div>\n }\n </div>\n }\n\n <!-- Empty State -->\n @if (!loading() && activities().length === 0) {\n <div class=\"__empty\">\n <div class=\"__icon\">\n <ax-icon icon=\"fa-light fa-history\" class=\"__svg\"></ax-icon>\n </div>\n <div class=\"__content\">\n <h4 class=\"__title\">{{ t('no-history.title', { scope: i18nScope }) | async }}</h4>\n <p class=\"__message\">{{ t('no-history.message', { scope: i18nScope }) | async }}\n </p>\n </div>\n </div>\n }\n\n </div>\n</div>\n\n<!-- \n\nax-success-surface\nax-primary-surface\nax-danger-surface\nax-warning-surface\nax-info-surface\nax-muted-surface\nax-text-success\n\n -->", styles: [".axp-activity-log{height:100%;width:100%}.axp-activity-log .__content .__loading>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.axp-activity-log .__content .__loading .__item{display:flex;align-items:flex-start;gap:1rem}.axp-activity-log .__content .__loading .__item .__avatar{height:3rem;width:3rem;flex-shrink:0;border-radius:9999px}.axp-activity-log .__content .__loading .__item .__content{flex:1 1 0%}.axp-activity-log .__content .__loading .__item .__content>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.axp-activity-log .__content .__loading .__item .__content .__title{height:1rem;width:75%;border-radius:.25rem}.axp-activity-log .__content .__loading .__item .__content .__subtitle{height:.75rem;width:50%;border-radius:.25rem}.axp-activity-log .__content .__loading .__item .__content .__description{height:.75rem;width:83.333333%;border-radius:.25rem}.axp-activity-log .__content .__loading .__item .__content .__time{height:.75rem;width:25%;border-radius:.25rem}.axp-activity-log .__content .__feed{position:relative}.axp-activity-log .__content .__feed>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))}.axp-activity-log .__content .__feed:before{content:\"\";position:absolute;inset-inline-start:1.25rem;top:.5rem;bottom:.5rem;width:0px;border-left:1px solid rgba(var(--ax-sys-color-border-surface));z-index:0}.axp-activity-log .__content .__feed .__item{position:relative;display:flex;align-items:flex-start;gap:1rem}.axp-activity-log .__content .__feed .__item axp-user-avatar{position:relative;z-index:10}.axp-activity-log .__content .__feed .__item .__content{min-width:0px;flex:1 1 0%}.axp-activity-log .__content .__feed .__item .__content .__main-info{margin-bottom:.25rem}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line{margin-top:.25rem;display:flex;flex-wrap:wrap;align-items:center;gap:.25rem;line-height:1.5}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line .__user-name{font-weight:600}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line .__action-type,.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line .__action-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.875rem;line-height:1.25rem;opacity:.85}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line{align-items:center;border-radius:.375rem;padding:.25rem .5rem}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line:hover{background-color:rgb(var(--ax-sys-color-lighter-surface));color:rgb(var(--ax-sys-color-on-lighter-surface));border-color:rgb(var(--ax-sys-color-border-lighter-surface))}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line .__compare-button{margin-left:.5rem;border-radius:9999px;padding:.25rem;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s;animation-duration:.2s;display:flex;width:1.5rem;height:1.5rem;align-items:center;justify-content:center;--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-primary-500),var(--tw-text-opacity, 1))}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line .__compare-button:hover{background-color:rgb(var(--ax-sys-color-primary-surface));color:rgb(var(--ax-sys-color-on-primary-surface));border-color:rgb(var(--ax-sys-color-border-primary-surface))}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line .__compare-button:focus{outline:2px solid transparent;outline-offset:2px;--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000);--tw-ring-opacity: 1;--tw-ring-color: rgba(var(--ax-sys-color-primary-500), var(--tw-ring-opacity, 1));--tw-ring-offset-width: 1px}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line .__compare-button i{font-size:.75rem;line-height:1rem}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line .__toggle-button{margin-left:auto;border-radius:9999px;padding:.25rem;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s;animation-duration:.2s;display:flex;width:1.5rem;height:1.5rem;align-items:center;justify-content:center}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line .__toggle-button:focus{outline:2px solid transparent;outline-offset:2px;--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000);--tw-ring-opacity: 1;--tw-ring-color: rgba(var(--ax-sys-color-primary-500), var(--tw-ring-opacity, 1));--tw-ring-offset-width: 1px}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line .__toggle-button i{font-size:.75rem;line-height:1rem;transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s;animation-duration:.2s}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-lines{margin-top:.5rem;margin-bottom:.5rem;display:flex;flex-direction:column;font-size:.875rem;line-height:1.25rem}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-lines.__expandable-content{overflow:hidden}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-lines.__expandable-content.__animated{transition-property:all;transition-duration:.3s;transition-timing-function:cubic-bezier(.4,0,.2,1);animation-duration:.3s;animation-timing-function:cubic-bezier(.4,0,.2,1);animation:slideDown .3s ease-out}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-lines .__action-line{display:flex;align-items:center;gap:.5rem;padding-top:.25rem;padding-bottom:.25rem}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-lines .__action-line .__action-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.875rem;line-height:1.25rem;opacity:.85}.axp-activity-log .__content .__feed .__item .__content .__time{padding-left:.5rem;padding-right:.5rem;font-size:.75rem;line-height:1rem;opacity:.75}.axp-activity-log .__content .__feed .__item.__collapsed .__expandable-content{display:none}.axp-activity-log .__content .__feed .__item.__expandable .__header-line{cursor:pointer}.axp-activity-log .__content .__empty{display:flex;height:12rem;flex-direction:column;align-items:center;justify-content:center;padding:2rem;text-align:center}.axp-activity-log .__content .__empty .__icon{margin-bottom:1rem}.axp-activity-log .__content .__empty .__icon .__svg{font-size:2.25rem;line-height:2.5rem;--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.axp-activity-log .__content .__empty .__content .__title{margin-bottom:.5rem;font-size:1.125rem;line-height:1.75rem;font-weight:600;--tw-text-opacity: 1;color:rgb(17 24 39 / var(--tw-text-opacity, 1))}.axp-activity-log .__content .__empty .__content .__message{max-width:20rem;line-height:1.625;--tw-text-opacity: 1;color:rgb(75 85 99 / var(--tw-text-opacity, 1))}@media (min-width: 640px){.axp-activity-log .__content .__feed .__item{gap:.625rem}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line{flex-wrap:nowrap}}@keyframes slideDown{0%{opacity:0;max-height:0;transform:translateY(-10px)}to{opacity:1;max-height:200px;transform:translateY(0)}}\n"] }]
|
|
246
|
+
AXPStateMessageComponent,
|
|
247
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<div class=\"axp-activity-log ax-accent2\" *translate=\"let t\">\n <!-- Activity Log Content -->\n <div class=\"__content\">\n <!-- Loading State -->\n @if (loading()) {\n <div class=\"__loading\">\n @for (item of [1, 2, 3, 4]; track $index) {\n <div class=\"__item\">\n <ax-skeleton [animated]=\"true\" class=\"__avatar\"></ax-skeleton>\n <div class=\"__content\">\n <ax-skeleton [animated]=\"true\" class=\"__title\"></ax-skeleton>\n <ax-skeleton [animated]=\"true\" class=\"__subtitle\"></ax-skeleton>\n <ax-skeleton [animated]=\"true\" class=\"__description\"></ax-skeleton>\n <ax-skeleton [animated]=\"true\" class=\"__time\"></ax-skeleton>\n </div>\n </div>\n }\n </div>\n }\n\n <!-- Activity Feed -->\n @if (!loading() && activities().length > 0) {\n <div class=\"__feed\">\n @for (activity of activities(); track activity.id) {\n @let changeClasses = getChangeClasses(activity.changeType);\n @let isItemExpanded = isExpanded(activity.id);\n @let hasExpandableContentItem = hasExpandableContent(activity);\n <div class=\"__item\" [class.__collapsed]=\"!isItemExpanded\" [class.__expandable]=\"hasExpandableContentItem\">\n <div\n class=\"ax-size-10 ax-rounded-full ax-border ax-flex ax-items-center ax-justify-center ax-lightest-surface\"\n >\n <i class=\"{{ changeClasses.icon }} {{ changeClasses.text }} fa-solid\"></i>\n </div>\n\n <!-- Activity Content -->\n <div class=\"__content\">\n <!-- Main Activity Info -->\n <div class=\"__main-info\">\n <!-- User and Action with Toggle Button -->\n <div class=\"__action-line __header-line\" (click)=\"toggleExpanded(activity.id)\">\n <span class=\"__user-name\">{{ activity.user.title }}</span>\n <span class=\"__action-type\">\n {{ t(`@general:actions.${activity.changeType}.title`) | async }}\n </span>\n <span class=\"__action-text\">\n {{ activity.title | translate | async }}\n </span>\n\n <!-- Compare Button -->\n @if (canCompare(activity)) {\n <button\n type=\"button\"\n class=\"__compare-button\"\n (click)=\"handleCompare(activity, $event)\"\n [attr.aria-label]=\"t('compare.title', { scope: i18nScope }) | async\"\n >\n <i class=\"fa-solid fa-code-compare\"></i>\n </button>\n }\n\n <!-- Toggle Button (only show if there's expandable content) -->\n @if (hasExpandableContentItem) {\n <button\n type=\"button\"\n class=\"__toggle-button\"\n [attr.aria-expanded]=\"isItemExpanded\"\n [attr.aria-label]=\"isItemExpanded ? 'Collapse details' : 'Expand details'\"\n >\n <i\n class=\"fa-solid\"\n [class.fa-chevron-down]=\"!isItemExpanded\"\n [class.fa-chevron-up]=\"isItemExpanded\"\n ></i>\n </button>\n }\n </div>\n\n <!-- Expandable Description/Changes -->\n @if (hasExpandableContentItem && isItemExpanded && activity.changes.length > 0) {\n <div class=\"__action-lines __expandable-content\" [class.__animated]=\"shouldAnimate(activity.id)\">\n @for (change of activity.changes; track $index) {\n @let changeClasses = getChangeClasses(change.type);\n <div class=\"__action-line\">\n <div class=\"ax-rounded-full ax-size-7 ax-grid ax-place-items-center\">\n <i class=\"{{ changeClasses.icon }} {{ changeClasses.text }}\"></i>\n </div>\n <span class=\"__action-text\">{{ change.description | translate | async }}</span>\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Time -->\n <div class=\"__time\">\n {{ activity.date | format: 'datetime' : 'short' | async }}\n </div>\n </div>\n </div>\n }\n </div>\n }\n\n <!-- Empty State -->\n @if (!loading() && activities().length === 0) {\n <axp-state-message\n icon=\"fa-light fa-history\"\n [title]=\"'@general:no-history.title'\"\n [description]=\"'@general:no-history.message'\"\n >\n </axp-state-message>\n }\n </div>\n</div>\n\n<!-- \n\nax-success-surface\nax-primary-surface\nax-danger-surface\nax-warning-surface\nax-info-surface\nax-muted-surface\nax-text-success\n\n -->\n", styles: [".axp-activity-log{height:100%;width:100%}.axp-activity-log .__content .__loading>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.axp-activity-log .__content .__loading .__item{display:flex;align-items:flex-start;gap:1rem}.axp-activity-log .__content .__loading .__item .__avatar{height:3rem;width:3rem;flex-shrink:0;border-radius:9999px}.axp-activity-log .__content .__loading .__item .__content{flex:1 1 0%}.axp-activity-log .__content .__loading .__item .__content>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.axp-activity-log .__content .__loading .__item .__content .__title{height:1rem;width:75%;border-radius:.25rem}.axp-activity-log .__content .__loading .__item .__content .__subtitle{height:.75rem;width:50%;border-radius:.25rem}.axp-activity-log .__content .__loading .__item .__content .__description{height:.75rem;width:83.333333%;border-radius:.25rem}.axp-activity-log .__content .__loading .__item .__content .__time{height:.75rem;width:25%;border-radius:.25rem}.axp-activity-log .__content .__feed{position:relative}.axp-activity-log .__content .__feed>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))}.axp-activity-log .__content .__feed:before{content:\"\";position:absolute;inset-inline-start:1.25rem;top:.5rem;bottom:.5rem;width:0px;border-left:1px solid rgba(var(--ax-sys-color-border-surface));z-index:0}.axp-activity-log .__content .__feed .__item{position:relative;display:flex;align-items:flex-start;gap:1rem}.axp-activity-log .__content .__feed .__item axp-user-avatar{position:relative;z-index:10}.axp-activity-log .__content .__feed .__item .__content{min-width:0px;flex:1 1 0%}.axp-activity-log .__content .__feed .__item .__content .__main-info{margin-bottom:.25rem}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line{margin-top:.25rem;display:flex;flex-wrap:wrap;align-items:center;gap:.25rem;line-height:1.5}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line .__user-name{font-weight:600}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line .__action-type,.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line .__action-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.875rem;line-height:1.25rem;opacity:.85}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line{align-items:center;border-radius:.375rem;padding:.25rem .5rem}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line:hover{background-color:rgb(var(--ax-sys-color-lighter-surface));color:rgb(var(--ax-sys-color-on-lighter-surface));border-color:rgb(var(--ax-sys-color-border-lighter-surface))}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line .__compare-button{margin-left:.5rem;border-radius:9999px;padding:.25rem;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s;animation-duration:.2s;display:flex;width:1.5rem;height:1.5rem;align-items:center;justify-content:center;--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-primary-500),var(--tw-text-opacity, 1))}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line .__compare-button:hover{background-color:rgb(var(--ax-sys-color-primary-surface));color:rgb(var(--ax-sys-color-on-primary-surface));border-color:rgb(var(--ax-sys-color-border-primary-surface))}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line .__compare-button:focus{outline:2px solid transparent;outline-offset:2px;--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000);--tw-ring-opacity: 1;--tw-ring-color: rgba(var(--ax-sys-color-primary-500), var(--tw-ring-opacity, 1));--tw-ring-offset-width: 1px}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line .__compare-button i{font-size:.75rem;line-height:1rem}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line .__toggle-button{margin-left:auto;border-radius:9999px;padding:.25rem;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s;animation-duration:.2s;display:flex;width:1.5rem;height:1.5rem;align-items:center;justify-content:center}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line .__toggle-button:focus{outline:2px solid transparent;outline-offset:2px;--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000);--tw-ring-opacity: 1;--tw-ring-color: rgba(var(--ax-sys-color-primary-500), var(--tw-ring-opacity, 1));--tw-ring-offset-width: 1px}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line.__header-line .__toggle-button i{font-size:.75rem;line-height:1rem;transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s;animation-duration:.2s}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-lines{margin-top:.5rem;margin-bottom:.5rem;display:flex;flex-direction:column;font-size:.875rem;line-height:1.25rem}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-lines.__expandable-content{overflow:hidden}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-lines.__expandable-content.__animated{transition-property:all;transition-duration:.3s;transition-timing-function:cubic-bezier(.4,0,.2,1);animation-duration:.3s;animation-timing-function:cubic-bezier(.4,0,.2,1);animation:slideDown .3s ease-out}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-lines .__action-line{display:flex;align-items:center;gap:.5rem;padding-top:.25rem;padding-bottom:.25rem}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-lines .__action-line .__action-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.875rem;line-height:1.25rem;opacity:.85}.axp-activity-log .__content .__feed .__item .__content .__time{padding-left:.5rem;padding-right:.5rem;font-size:.75rem;line-height:1rem;opacity:.75}.axp-activity-log .__content .__feed .__item.__collapsed .__expandable-content{display:none}.axp-activity-log .__content .__feed .__item.__expandable .__header-line{cursor:pointer}@media (min-width: 640px){.axp-activity-log .__content .__feed .__item{gap:.625rem}.axp-activity-log .__content .__feed .__item .__content .__main-info .__action-line{flex-wrap:nowrap}}@keyframes slideDown{0%{opacity:0;max-height:0;transform:translateY(-10px)}to{opacity:1;max-height:200px;transform:translateY(0)}}\n"] }]
|
|
197
248
|
}], ctorParameters: () => [] });
|
|
198
249
|
|
|
199
250
|
const AXP_TASK_BADGE_PROVIDERS = new InjectionToken('AXP_TASK_BADGE_PROVIDERS');
|
|
@@ -221,10 +272,10 @@ class AXPTaskBadgeService {
|
|
|
221
272
|
this.computedCache.set(key, total);
|
|
222
273
|
return total;
|
|
223
274
|
}
|
|
224
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.
|
|
225
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.
|
|
275
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPTaskBadgeService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
276
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPTaskBadgeService, providedIn: 'root' }); }
|
|
226
277
|
}
|
|
227
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.
|
|
278
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPTaskBadgeService, decorators: [{
|
|
228
279
|
type: Injectable,
|
|
229
280
|
args: [{ providedIn: 'root' }]
|
|
230
281
|
}], ctorParameters: () => [] });
|
|
@@ -255,10 +306,10 @@ class AXPTaskBadgeDirective {
|
|
|
255
306
|
const node = signal[SIGNAL];
|
|
256
307
|
signalSetFn(node, value);
|
|
257
308
|
}
|
|
258
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.
|
|
259
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.1.
|
|
309
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPTaskBadgeDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
310
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.1.8", type: AXPTaskBadgeDirective, isStandalone: true, selector: "[axp-task-badge]", inputs: { badgeKey: { classPropertyName: "badgeKey", publicName: "badgeKey", isSignal: true, isRequired: false, transformFunction: null }, count: { classPropertyName: "count", publicName: "axp-task-badge", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
|
|
260
311
|
}
|
|
261
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.
|
|
312
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPTaskBadgeDirective, decorators: [{
|
|
262
313
|
type: Directive,
|
|
263
314
|
args: [{
|
|
264
315
|
selector: '[axp-task-badge]',
|
|
@@ -280,10 +331,10 @@ class AXPMenuBadgeHelper {
|
|
|
280
331
|
}
|
|
281
332
|
|
|
282
333
|
class AXPThemeLayoutPagePrimaryActionsComponent {
|
|
283
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.
|
|
284
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.
|
|
334
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutPagePrimaryActionsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
335
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.8", type: AXPThemeLayoutPagePrimaryActionsComponent, isStandalone: true, selector: "axp-layout-actions-primary", ngImport: i0, template: `<ng-content select="ax-button,ax-dropdown-button"></ng-content>`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
285
336
|
}
|
|
286
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.
|
|
337
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutPagePrimaryActionsComponent, decorators: [{
|
|
287
338
|
type: Component,
|
|
288
339
|
args: [{
|
|
289
340
|
standalone: true,
|
|
@@ -294,10 +345,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
|
|
|
294
345
|
}]
|
|
295
346
|
}] });
|
|
296
347
|
class AXPThemeLayoutPageSecondaryActionsComponent {
|
|
297
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.
|
|
298
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.
|
|
348
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutPageSecondaryActionsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
349
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.8", type: AXPThemeLayoutPageSecondaryActionsComponent, isStandalone: true, selector: "axp-layout-actions-secondary", ngImport: i0, template: `<ng-content select="ax-button-item,ax-divider,ng-container"></ng-content>`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
299
350
|
}
|
|
300
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.
|
|
351
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutPageSecondaryActionsComponent, decorators: [{
|
|
301
352
|
type: Component,
|
|
302
353
|
args: [{
|
|
303
354
|
standalone: true,
|
|
@@ -316,8 +367,8 @@ class AXPThemeLayoutActionsComponent {
|
|
|
316
367
|
this.secondaryContent = contentChild(AXPThemeLayoutPageSecondaryActionsComponent, ...(ngDevMode ? [{ debugName: "secondaryContent" }] : []));
|
|
317
368
|
this.hasSecondary = computed(() => this.secondaryContent() != null, ...(ngDevMode ? [{ debugName: "hasSecondary" }] : []));
|
|
318
369
|
}
|
|
319
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.
|
|
320
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "20.1.
|
|
370
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutActionsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
371
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "20.1.8", type: AXPThemeLayoutActionsComponent, isStandalone: true, selector: "axp-layout-actions", queries: [{ propertyName: "primaryContent", first: true, predicate: AXPThemeLayoutPagePrimaryActionsComponent, descendants: true, isSignal: true }, { propertyName: "secondaryContent", first: true, predicate: AXPThemeLayoutPageSecondaryActionsComponent, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "primaryTemplate", first: true, predicate: ["primary"], descendants: true, isSignal: true }, { propertyName: "secondaryTemplate", first: true, predicate: ["secondary"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
321
372
|
|
|
322
373
|
<ng-template #primary>
|
|
323
374
|
<ng-content select="axp-layout-actions-primary"></ng-content>
|
|
@@ -330,7 +381,7 @@ class AXPThemeLayoutActionsComponent {
|
|
|
330
381
|
<ng-content></ng-content>
|
|
331
382
|
`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
332
383
|
}
|
|
333
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.
|
|
384
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutActionsComponent, decorators: [{
|
|
334
385
|
type: Component,
|
|
335
386
|
args: [{
|
|
336
387
|
imports: [],
|
|
@@ -358,10 +409,10 @@ class AXPThemeLayoutBlockComponent {
|
|
|
358
409
|
this.elementRef = inject(ElementRef);
|
|
359
410
|
this.hostElement = this.elementRef.nativeElement;
|
|
360
411
|
}
|
|
361
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.
|
|
362
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.
|
|
412
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutBlockComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
413
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.8", type: AXPThemeLayoutBlockComponent, isStandalone: true, selector: "\n\n axp-page-content, \n axp-page-footer-container,\n axp-page-footer,\n axp-page-header,\n axp-page-header-container,\n axp-page-toolbar,\n\n axp-layout-content, \n axp-layout-page-content, \n\n axp-layout-sections,\n axp-layout-body,\n axp-layout-page-body,\n axp-layout-prefix,\n axp-layout-suffix,\n axp-layout-title-bar,\n axp-layout-title, \n axp-layout-title-actions, \n axp-layout-nav-button, \n axp-layout-description, \n axp-layout-breadcrumbs,\n axp-layout-list-action,\n ", ngImport: i0, template: '<ng-content></ng-content>', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
363
414
|
}
|
|
364
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.
|
|
415
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutBlockComponent, decorators: [{
|
|
365
416
|
type: Component,
|
|
366
417
|
args: [{
|
|
367
418
|
standalone: true,
|
|
@@ -397,14 +448,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
|
|
|
397
448
|
}] });
|
|
398
449
|
|
|
399
450
|
class AXPThemeLayoutFooterComponent {
|
|
400
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.
|
|
401
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.
|
|
451
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutFooterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
452
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.8", type: AXPThemeLayoutFooterComponent, isStandalone: true, selector: "axp-layout-footer, axp-layout-page-footer", ngImport: i0, template: `
|
|
402
453
|
<ng-content select="axp-layout-prefix"></ng-content>
|
|
403
454
|
<ng-content></ng-content>
|
|
404
455
|
<ng-content select="axp-layout-suffix"></ng-content>
|
|
405
456
|
`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
406
457
|
}
|
|
407
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.
|
|
458
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutFooterComponent, decorators: [{
|
|
408
459
|
type: Component,
|
|
409
460
|
args: [{
|
|
410
461
|
imports: [],
|
|
@@ -429,8 +480,8 @@ class AXPThemeLayoutPageHeaderComponent {
|
|
|
429
480
|
this.breadcrumbs = viewChild('breadcrumbs', ...(ngDevMode ? [{ debugName: "breadcrumbs" }] : []));
|
|
430
481
|
this.navButton = viewChild('navButton', ...(ngDevMode ? [{ debugName: "navButton" }] : []));
|
|
431
482
|
}
|
|
432
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.
|
|
433
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "20.1.
|
|
483
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutPageHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
484
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "20.1.8", type: AXPThemeLayoutPageHeaderComponent, isStandalone: true, selector: "axp-layout-page-header", viewQueries: [{ propertyName: "title", first: true, predicate: ["title"], descendants: true, isSignal: true }, { propertyName: "description", first: true, predicate: ["description"], descendants: true, isSignal: true }, { propertyName: "actions", first: true, predicate: ["actions"], descendants: true, isSignal: true }, { propertyName: "navbar", first: true, predicate: ["navbar"], descendants: true, isSignal: true }, { propertyName: "breadcrumbs", first: true, predicate: ["breadcrumbs"], descendants: true, isSignal: true }, { propertyName: "navButton", first: true, predicate: ["navButton"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
434
485
|
<ng-template #breadcrumbs>
|
|
435
486
|
<ng-content select="axp-layout-breadcrumbs"></ng-content>
|
|
436
487
|
</ng-template>
|
|
@@ -455,7 +506,7 @@ class AXPThemeLayoutPageHeaderComponent {
|
|
|
455
506
|
</ng-template>
|
|
456
507
|
`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
457
508
|
}
|
|
458
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.
|
|
509
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutPageHeaderComponent, decorators: [{
|
|
459
510
|
type: Component,
|
|
460
511
|
args: [{
|
|
461
512
|
imports: [],
|
|
@@ -490,14 +541,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
|
|
|
490
541
|
}]
|
|
491
542
|
}] });
|
|
492
543
|
class AXPThemeLayoutHeaderComponent {
|
|
493
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.
|
|
494
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.
|
|
544
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
545
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.8", type: AXPThemeLayoutHeaderComponent, isStandalone: true, selector: "axp-layout-header", ngImport: i0, template: `
|
|
495
546
|
<ng-content select="axp-layout-prefix"></ng-content>
|
|
496
547
|
<ng-content></ng-content>
|
|
497
548
|
<ng-content select="axp-layout-suffix"></ng-content>
|
|
498
549
|
`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
499
550
|
}
|
|
500
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.
|
|
551
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutHeaderComponent, decorators: [{
|
|
501
552
|
type: Component,
|
|
502
553
|
args: [{
|
|
503
554
|
imports: [],
|
|
@@ -514,10 +565,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
|
|
|
514
565
|
}] });
|
|
515
566
|
|
|
516
567
|
class AXPThemeLayoutListComponent {
|
|
517
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.
|
|
518
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.
|
|
568
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
569
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.8", type: AXPThemeLayoutListComponent, isStandalone: true, selector: "axp-layout-list", ngImport: i0, template: `<ng-content select="axp-layout-list-item,axp-layout-list-group,ng-container"></ng-content>`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
519
570
|
}
|
|
520
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.
|
|
571
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutListComponent, decorators: [{
|
|
521
572
|
type: Component,
|
|
522
573
|
args: [{
|
|
523
574
|
standalone: true,
|
|
@@ -528,10 +579,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
|
|
|
528
579
|
}]
|
|
529
580
|
}] });
|
|
530
581
|
class AXPThemeLayoutListItemsGroupComponent {
|
|
531
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.
|
|
532
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.
|
|
582
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutListItemsGroupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
583
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.8", type: AXPThemeLayoutListItemsGroupComponent, isStandalone: true, selector: "axp-layout-list-group", ngImport: i0, template: `<ng-content select="axp-layout-list-item, axp-layout-title, axp-layout-header ,ng-container"></ng-content>`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
533
584
|
}
|
|
534
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.
|
|
585
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutListItemsGroupComponent, decorators: [{
|
|
535
586
|
type: Component,
|
|
536
587
|
args: [{
|
|
537
588
|
standalone: true,
|
|
@@ -542,10 +593,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
|
|
|
542
593
|
}]
|
|
543
594
|
}] });
|
|
544
595
|
class AXPThemeLayoutListItemComponent {
|
|
545
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.
|
|
546
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.
|
|
596
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutListItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
597
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.8", type: AXPThemeLayoutListItemComponent, isStandalone: true, selector: "axp-layout-list-item", ngImport: i0, template: `<ng-content select="axp-layout-content,axp-layout-prefix,axp-layout-suffix,ng-container"></ng-content>`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
547
598
|
}
|
|
548
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.
|
|
599
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutListItemComponent, decorators: [{
|
|
549
600
|
type: Component,
|
|
550
601
|
args: [{
|
|
551
602
|
standalone: true,
|
|
@@ -557,13 +608,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
|
|
|
557
608
|
}] });
|
|
558
609
|
|
|
559
610
|
class AXPThemeLayoutSectionComponent {
|
|
560
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.
|
|
561
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.
|
|
611
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutSectionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
612
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.8", type: AXPThemeLayoutSectionComponent, isStandalone: true, selector: "axp-layout-section", ngImport: i0, template: `
|
|
562
613
|
<ng-content select="axp-layout-header"></ng-content>
|
|
563
614
|
<ng-content select="axp-layout-content"></ng-content>
|
|
564
615
|
`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
565
616
|
}
|
|
566
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.
|
|
617
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutSectionComponent, decorators: [{
|
|
567
618
|
type: Component,
|
|
568
619
|
args: [{
|
|
569
620
|
imports: [],
|
|
@@ -579,15 +630,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
|
|
|
579
630
|
}] });
|
|
580
631
|
|
|
581
632
|
class AXPThemeLayoutStartSideComponent {
|
|
582
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.
|
|
583
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.
|
|
633
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutStartSideComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
634
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.8", type: AXPThemeLayoutStartSideComponent, isStandalone: true, selector: "axp-layout-page-start-side, axp-layout-start-side", ngImport: i0, template: `
|
|
584
635
|
<ng-content select="axp-layout-header"></ng-content>
|
|
585
636
|
<ng-content select="axp-layout-content"></ng-content>
|
|
586
637
|
<ng-content select="axp-layout-footer"></ng-content>
|
|
587
638
|
<ng-content></ng-content>
|
|
588
639
|
`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
589
640
|
}
|
|
590
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.
|
|
641
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutStartSideComponent, decorators: [{
|
|
591
642
|
type: Component,
|
|
592
643
|
args: [{
|
|
593
644
|
imports: [],
|
|
@@ -604,14 +655,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
|
|
|
604
655
|
}]
|
|
605
656
|
}] });
|
|
606
657
|
class AXPThemeLayoutEndSideComponent {
|
|
607
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.
|
|
608
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.
|
|
658
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutEndSideComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
659
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.8", type: AXPThemeLayoutEndSideComponent, isStandalone: true, selector: "axp-layout-page-end-side, axp-layout-end-side", ngImport: i0, template: `
|
|
609
660
|
<ng-content select="axp-layout-header"></ng-content>
|
|
610
661
|
<ng-content select="axp-layout-content"></ng-content>
|
|
611
662
|
<ng-content select="axp-layout-footer"></ng-content>
|
|
612
663
|
`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
613
664
|
}
|
|
614
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.
|
|
665
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutEndSideComponent, decorators: [{
|
|
615
666
|
type: Component,
|
|
616
667
|
args: [{
|
|
617
668
|
imports: [],
|
|
@@ -628,14 +679,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
|
|
|
628
679
|
}] });
|
|
629
680
|
|
|
630
681
|
class AXPThemeLayoutToolbarComponent {
|
|
631
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.
|
|
632
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.
|
|
682
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutToolbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
683
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.8", type: AXPThemeLayoutToolbarComponent, isStandalone: true, selector: "axp-layout-toolbar", ngImport: i0, template: `
|
|
633
684
|
<ng-content select="axp-layout-prefix"></ng-content>
|
|
634
685
|
<ng-content select="axp-layout-suffix"></ng-content>
|
|
635
686
|
<ng-content></ng-content>
|
|
636
687
|
`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
637
688
|
}
|
|
638
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.
|
|
689
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutToolbarComponent, decorators: [{
|
|
639
690
|
type: Component,
|
|
640
691
|
args: [{
|
|
641
692
|
imports: [],
|
|
@@ -670,10 +721,10 @@ class AXPThemeLayoutContainerComponent {
|
|
|
670
721
|
ngOnDestroy() {
|
|
671
722
|
this.mutationObserver?.disconnect();
|
|
672
723
|
}
|
|
673
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.
|
|
674
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.
|
|
724
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutContainerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
725
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.8", type: AXPThemeLayoutContainerComponent, isStandalone: true, selector: "axp-layout-container", ngImport: i0, template: '<ng-content></ng-content>', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
675
726
|
}
|
|
676
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.
|
|
727
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPThemeLayoutContainerComponent, decorators: [{
|
|
677
728
|
type: Component,
|
|
678
729
|
args: [{
|
|
679
730
|
standalone: true,
|
|
@@ -684,6 +735,320 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
|
|
|
684
735
|
}]
|
|
685
736
|
}] });
|
|
686
737
|
|
|
738
|
+
class AXPCategoryTreeComponent {
|
|
739
|
+
constructor() {
|
|
740
|
+
//#region ---- Services & Dependencies ----
|
|
741
|
+
this.translationService = inject(AXTranslationService);
|
|
742
|
+
//#endregion
|
|
743
|
+
//#region ---- Inputs ----
|
|
744
|
+
this.dataSource = input.required(...(ngDevMode ? [{ debugName: "dataSource" }] : []));
|
|
745
|
+
this.config = input({
|
|
746
|
+
textField: 'title',
|
|
747
|
+
valueField: 'id',
|
|
748
|
+
expandedField: 'expand',
|
|
749
|
+
showCheckbox: false,
|
|
750
|
+
searchable: true,
|
|
751
|
+
searchPlaceholder: '@general:terms.interface.category.search.placeholder',
|
|
752
|
+
emptyStateTitle: '@general:terms.interface.category.search.no-records.title',
|
|
753
|
+
emptyStateDescription: '@general:terms.interface.category.search.no-records.description',
|
|
754
|
+
emptyStateIcon: 'fa-light fa-folder-open',
|
|
755
|
+
}, ...(ngDevMode ? [{ debugName: "config" }] : []));
|
|
756
|
+
this.actions = input({
|
|
757
|
+
canCreate: true,
|
|
758
|
+
canUpdate: true,
|
|
759
|
+
canDelete: true,
|
|
760
|
+
canCreateChild: true,
|
|
761
|
+
createLabel: 'Add New',
|
|
762
|
+
updateLabel: 'Edit',
|
|
763
|
+
deleteLabel: 'Delete',
|
|
764
|
+
createChildLabel: 'Add New Child',
|
|
765
|
+
}, ...(ngDevMode ? [{ debugName: "actions" }] : []));
|
|
766
|
+
this.events = input({}, ...(ngDevMode ? [{ debugName: "events" }] : []));
|
|
767
|
+
//#endregion
|
|
768
|
+
//#region ---- Outputs ----
|
|
769
|
+
this.nodeClick = output();
|
|
770
|
+
this.nodeSelect = output();
|
|
771
|
+
this.nodeCreate = output();
|
|
772
|
+
this.nodeUpdate = output();
|
|
773
|
+
this.nodeDelete = output();
|
|
774
|
+
this.searchChange = output();
|
|
775
|
+
this.collapseChange = output();
|
|
776
|
+
//#endregion
|
|
777
|
+
//#region ---- Component State ----
|
|
778
|
+
this.tree = viewChild('tree', ...(ngDevMode ? [{ debugName: "tree" }] : []));
|
|
779
|
+
this.isLoading = signal(true, ...(ngDevMode ? [{ debugName: "isLoading" }] : []));
|
|
780
|
+
this.searchValue = signal('', ...(ngDevMode ? [{ debugName: "searchValue" }] : []));
|
|
781
|
+
this.treeItems = signal([
|
|
782
|
+
{
|
|
783
|
+
id: 'root',
|
|
784
|
+
title: '@general:terms.interface.selection.all-items',
|
|
785
|
+
description: '',
|
|
786
|
+
parentId: undefined,
|
|
787
|
+
childCount: 0,
|
|
788
|
+
expand: true,
|
|
789
|
+
children: [],
|
|
790
|
+
},
|
|
791
|
+
], ...(ngDevMode ? [{ debugName: "treeItems" }] : []));
|
|
792
|
+
//#endregion
|
|
793
|
+
//#region ---- Computed Properties ----
|
|
794
|
+
this.emptyStateTitle = computed(() => {
|
|
795
|
+
const title = this.config().emptyStateTitle || '';
|
|
796
|
+
return title;
|
|
797
|
+
}, ...(ngDevMode ? [{ debugName: "emptyStateTitle" }] : []));
|
|
798
|
+
this.emptyStateDescription = computed(() => {
|
|
799
|
+
const description = this.config().emptyStateDescription || '';
|
|
800
|
+
return description;
|
|
801
|
+
}, ...(ngDevMode ? [{ debugName: "emptyStateDescription" }] : []));
|
|
802
|
+
}
|
|
803
|
+
//#endregion
|
|
804
|
+
//#region ---- Lifecycle Methods ----
|
|
805
|
+
async ngOnInit() {
|
|
806
|
+
await this.loadRootNodes();
|
|
807
|
+
}
|
|
808
|
+
//#endregion
|
|
809
|
+
//#region ---- Data Loading Methods ----
|
|
810
|
+
async loadRootNodes() {
|
|
811
|
+
this.isLoading.set(true);
|
|
812
|
+
try {
|
|
813
|
+
const entities = await this.dataSource().loadRootNodes();
|
|
814
|
+
const nodes = this.convertEntitiesToTreeNodes(entities);
|
|
815
|
+
this.treeItems.update((prev) => prev.map((item) => ({
|
|
816
|
+
...item,
|
|
817
|
+
children: nodes,
|
|
818
|
+
})));
|
|
819
|
+
}
|
|
820
|
+
catch (error) {
|
|
821
|
+
console.error('Error loading root nodes:', error);
|
|
822
|
+
}
|
|
823
|
+
finally {
|
|
824
|
+
this.isLoading.set(false);
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
async loadChildNodes(parentId) {
|
|
828
|
+
if (!this.dataSource().loadChildNodes)
|
|
829
|
+
return;
|
|
830
|
+
this.tree()?.setNodeLoading(parentId, true);
|
|
831
|
+
try {
|
|
832
|
+
const entities = await this.dataSource().loadChildNodes(parentId);
|
|
833
|
+
const children = this.convertEntitiesToTreeNodes(entities);
|
|
834
|
+
this.updateNodeChildren(parentId, children);
|
|
835
|
+
}
|
|
836
|
+
catch (error) {
|
|
837
|
+
console.error('Error loading child nodes:', error);
|
|
838
|
+
}
|
|
839
|
+
finally {
|
|
840
|
+
this.tree()?.setNodeLoading(parentId, false);
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
async searchNodes(searchValue) {
|
|
844
|
+
if (!this.dataSource().searchNodes)
|
|
845
|
+
return;
|
|
846
|
+
this.isLoading.set(true);
|
|
847
|
+
try {
|
|
848
|
+
const entities = await this.dataSource().searchNodes(searchValue);
|
|
849
|
+
const nodes = this.convertEntitiesToTreeNodes(entities);
|
|
850
|
+
this.treeItems.update((prev) => prev.map((item) => ({
|
|
851
|
+
...item,
|
|
852
|
+
children: nodes,
|
|
853
|
+
})));
|
|
854
|
+
}
|
|
855
|
+
catch (error) {
|
|
856
|
+
console.error('Error searching nodes:', error);
|
|
857
|
+
}
|
|
858
|
+
finally {
|
|
859
|
+
this.isLoading.set(false);
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
//#endregion
|
|
863
|
+
//#region ---- Event Handlers ----
|
|
864
|
+
async handleNodeClick(event) {
|
|
865
|
+
const node = event.data;
|
|
866
|
+
// Extract the entity data (without tree-specific properties)
|
|
867
|
+
const entity = {
|
|
868
|
+
id: node.id,
|
|
869
|
+
title: node.title,
|
|
870
|
+
description: node.description,
|
|
871
|
+
parentId: node.parentId,
|
|
872
|
+
childCount: node.childCount
|
|
873
|
+
};
|
|
874
|
+
this.nodeClick.emit(entity);
|
|
875
|
+
this.events().onNodeClick?.(entity);
|
|
876
|
+
}
|
|
877
|
+
async handleCollapseChanged(event) {
|
|
878
|
+
const node = event.data;
|
|
879
|
+
// Extract the entity data (without tree-specific properties)
|
|
880
|
+
const entity = {
|
|
881
|
+
id: node.id,
|
|
882
|
+
title: node.title,
|
|
883
|
+
description: node.description,
|
|
884
|
+
parentId: node.parentId,
|
|
885
|
+
childCount: node.childCount
|
|
886
|
+
};
|
|
887
|
+
this.collapseChange.emit(entity);
|
|
888
|
+
this.events().onCollapseChange?.(entity);
|
|
889
|
+
// Load children if node is being expanded
|
|
890
|
+
// Check both expand property and active property (active seems to be the actual expansion state)
|
|
891
|
+
if ((node.expand || node.active) && this.dataSource().loadChildNodes) {
|
|
892
|
+
await this.loadChildNodes(node.id);
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
async handleSearchChange(event) {
|
|
896
|
+
const searchValue = event.value;
|
|
897
|
+
this.searchValue.set(searchValue);
|
|
898
|
+
this.searchChange.emit(searchValue);
|
|
899
|
+
this.events().onSearchChange?.(searchValue);
|
|
900
|
+
if (searchValue) {
|
|
901
|
+
await this.searchNodes(searchValue);
|
|
902
|
+
}
|
|
903
|
+
else {
|
|
904
|
+
await this.loadRootNodes();
|
|
905
|
+
}
|
|
906
|
+
}
|
|
907
|
+
//#endregion
|
|
908
|
+
//#region ---- CRUD Action Handlers ----
|
|
909
|
+
async handleCreateRootClick(event) {
|
|
910
|
+
event.nativeEvent.preventDefault();
|
|
911
|
+
event.nativeEvent.stopPropagation();
|
|
912
|
+
this.nodeCreate.emit(undefined);
|
|
913
|
+
this.events().onNodeCreate?.(undefined);
|
|
914
|
+
}
|
|
915
|
+
async handleCreateChildClick(node, event) {
|
|
916
|
+
event.nativeEvent.preventDefault();
|
|
917
|
+
event.nativeEvent.stopPropagation();
|
|
918
|
+
// Extract the entity data (without tree-specific properties)
|
|
919
|
+
const entity = {
|
|
920
|
+
id: node.id,
|
|
921
|
+
title: node.title,
|
|
922
|
+
description: node.description,
|
|
923
|
+
parentId: node.parentId,
|
|
924
|
+
childCount: node.childCount
|
|
925
|
+
};
|
|
926
|
+
this.nodeCreate.emit(entity);
|
|
927
|
+
this.events().onNodeCreate?.(entity);
|
|
928
|
+
}
|
|
929
|
+
async handleUpdateNodeClick(node, event) {
|
|
930
|
+
event.nativeEvent.preventDefault();
|
|
931
|
+
event.nativeEvent.stopPropagation();
|
|
932
|
+
// Extract the entity data (without tree-specific properties)
|
|
933
|
+
const entity = {
|
|
934
|
+
id: node.id,
|
|
935
|
+
title: node.title,
|
|
936
|
+
description: node.description,
|
|
937
|
+
parentId: node.parentId,
|
|
938
|
+
childCount: node.childCount
|
|
939
|
+
};
|
|
940
|
+
this.nodeUpdate.emit(entity);
|
|
941
|
+
this.events().onNodeUpdate?.(entity);
|
|
942
|
+
}
|
|
943
|
+
async handleDeleteNodeClick(node, event) {
|
|
944
|
+
event.nativeEvent.preventDefault();
|
|
945
|
+
event.nativeEvent.stopPropagation();
|
|
946
|
+
// Extract the entity data (without tree-specific properties)
|
|
947
|
+
const entity = {
|
|
948
|
+
id: node.id,
|
|
949
|
+
title: node.title,
|
|
950
|
+
description: node.description,
|
|
951
|
+
parentId: node.parentId,
|
|
952
|
+
childCount: node.childCount
|
|
953
|
+
};
|
|
954
|
+
this.nodeDelete.emit(entity);
|
|
955
|
+
this.events().onNodeDelete?.(entity);
|
|
956
|
+
}
|
|
957
|
+
//#endregion
|
|
958
|
+
//#region ---- Utility Methods ----
|
|
959
|
+
convertEntitiesToTreeNodes(entities) {
|
|
960
|
+
return entities.map(entity => ({
|
|
961
|
+
...entity,
|
|
962
|
+
children: entity.childCount > 0 ? [] : undefined, // Set children to empty array if has children, undefined if no children
|
|
963
|
+
expand: false,
|
|
964
|
+
hasChild: entity.childCount > 0, // Set hasChild based on childCount
|
|
965
|
+
}));
|
|
966
|
+
}
|
|
967
|
+
updateNodeChildren(parentId, children) {
|
|
968
|
+
const updateChildrenAtPath = (items, id) => {
|
|
969
|
+
return items.map((item) => {
|
|
970
|
+
if (item.id === id) {
|
|
971
|
+
return { ...item, children };
|
|
972
|
+
}
|
|
973
|
+
if (item.children?.length) {
|
|
974
|
+
return { ...item, children: updateChildrenAtPath(item.children, id) };
|
|
975
|
+
}
|
|
976
|
+
return item;
|
|
977
|
+
});
|
|
978
|
+
};
|
|
979
|
+
this.treeItems.update((prev) => prev.map((item) => ({
|
|
980
|
+
...item,
|
|
981
|
+
children: updateChildrenAtPath(item.children || [], parentId),
|
|
982
|
+
})));
|
|
983
|
+
}
|
|
984
|
+
async refreshTree(parentId) {
|
|
985
|
+
if (parentId) {
|
|
986
|
+
await this.loadChildNodes(parentId);
|
|
987
|
+
}
|
|
988
|
+
else {
|
|
989
|
+
await this.loadRootNodes();
|
|
990
|
+
}
|
|
991
|
+
}
|
|
992
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPCategoryTreeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
993
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.8", type: AXPCategoryTreeComponent, isStandalone: true, selector: "axp-category-tree", inputs: { dataSource: { classPropertyName: "dataSource", publicName: "dataSource", isSignal: true, isRequired: true, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null }, actions: { classPropertyName: "actions", publicName: "actions", isSignal: true, isRequired: false, transformFunction: null }, events: { classPropertyName: "events", publicName: "events", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { nodeClick: "nodeClick", nodeSelect: "nodeSelect", nodeCreate: "nodeCreate", nodeUpdate: "nodeUpdate", nodeDelete: "nodeDelete", searchChange: "searchChange", collapseChange: "collapseChange" }, viewQueries: [{ propertyName: "tree", first: true, predicate: ["tree"], descendants: true, isSignal: true }], ngImport: i0, template: "<axp-layout-header>\n <axp-layout-toolbar>\n @if (config().searchable) {\n <ax-search-box\n (onValueChanged)=\"handleSearchChange($event)\"\n [delayTime]=\"300\"\n [placeholder]=\"config().searchPlaceholder! | translate | async\"\n >\n </ax-search-box>\n }\n </axp-layout-toolbar>\n</axp-layout-header>\n\n<axp-layout-content>\n @if (isLoading()) {\n <div class=\"ax-p-4 ax-flex ax-flex-col ax-gap-3\" [class.ax-pt-2]=\"config().searchable\">\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n </div>\n } @else if (treeItems()[0].children?.length) {\n <div class=\"ax-px-4 ax-max-h-[calc(100vh-250px)] ax-overflow-auto\" [class.ax-pt-2]=\"config().searchable\">\n <ax-tree-view\n (onNodeClick)=\"handleNodeClick($event)\"\n (onCollapsedChanged)=\"handleCollapseChanged($event)\"\n [showCheckbox]=\"config().showCheckbox || false\"\n [itemTemplate]=\"itemTemplate\"\n #treeRef\n [textField]=\"config().textField || 'title'\"\n [valueField]=\"config().valueField || 'id'\"\n [expandedField]=\"config().expandedField || 'expand'\"\n [items]=\"treeItems()\"\n #tree\n >\n </ax-tree-view>\n </div>\n } @else {\n <axp-state-message\n [icon]=\"config().emptyStateIcon || 'fa-light fa-folder-open'\"\n [title]=\"emptyStateTitle()\"\n [description]=\"emptyStateDescription()\"\n >\n </axp-state-message>\n }\n\n <ng-template #itemTemplate let-item>\n <div class=\"ax-flex ax-items-center ax-justify-between ax-w-full ax-gap-2 ax-overflow-hidden\">\n <div class=\"ax-flex ax-items-center ax-gap-2 ax-min-w-0\">\n <ax-icon class=\"fas ax-text-warning fa-folder\"></ax-icon>\n <span class=\"ax-truncate\">{{ item.title | translate | async }}</span>\n </div>\n @if (item.id && item.id !== 'root') {\n @if (actions().canCreateChild || actions().canUpdate || actions().canDelete) {\n <div class=\"ax-flex ax-items-center ax-gap-1\">\n <ax-button class=\"ax-xs\" color=\"default\" look=\"blank\" (onClick)=\"$event.nativeEvent.stopPropagation()\">\n <ax-icon class=\"fas fa-ellipsis-v\"></ax-icon>\n <ax-dropdown-panel>\n <ax-button-item-list>\n @if (actions().canCreateChild) {\n <ax-button-item\n (onClick)=\"handleCreateChildClick(item, $event)\"\n look=\"blank\"\n color=\"default\"\n [text]=\"actions().createChildLabel || 'Add New Child'\"\n >\n <ax-icon class=\"fas fa-plus\"></ax-icon>\n </ax-button-item>\n }\n @if (actions().canUpdate) {\n <ax-button-item\n (onClick)=\"handleUpdateNodeClick(item, $event)\"\n look=\"blank\"\n [text]=\"actions().updateLabel || 'Edit'\"\n >\n <ax-icon class=\"fas fa-pen\"></ax-icon>\n </ax-button-item>\n }\n @if (actions().canDelete) {\n <ax-button-item\n (onClick)=\"handleDeleteNodeClick(item, $event)\"\n color=\"danger\"\n look=\"blank\"\n [text]=\"actions().deleteLabel || 'Delete'\"\n >\n <ax-icon class=\"fas fa-trash\"></ax-icon>\n </ax-button-item>\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-button>\n </div>\n }\n } @else if (item.id === 'root' && actions().canCreate) {\n <div class=\"ax-flex ax-items-center ax-gap-1\">\n <ax-button class=\"ax-xs\" (onClick)=\"handleCreateRootClick($event)\" look=\"blank\" color=\"default\">\n <ax-icon class=\"fas fa-plus\"></ax-icon>\n </ax-button>\n </div>\n }\n </div>\n </ng-template>\n</axp-layout-content>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "ngmodule", type: AXTreeViewModule }, { kind: "component", type: i2$2.AXTreeViewComponent, selector: "ax-tree-view", inputs: ["items", "showCheckbox", "hasCheckboxField", "selectionMode", "selectionBehavior", "selectionScope", "focusNodeEnabled", "valueField", "textField", "visibleField", "disableField", "hasChildField", "selectedField", "expandedField", "tooltipField", "childrenField", "activeField", "indeterminateField", "parentField", "iconField", "toggleIcons", "look", "showEmptyNodeMassage", "itemTemplate", "emptyTemplate", "expandOn"], outputs: ["onSelectionChanged", "onItemSelectedChanged", "onNodeClick", "onCollapsedChanged", "onNodedbClick"] }, { kind: "ngmodule", type: AXSkeletonModule }, { kind: "component", type: i2.AXSkeletonComponent, selector: "ax-skeleton", inputs: ["animated"] }, { kind: "component", type: AXPThemeLayoutBlockComponent, selector: "\n\n axp-page-content, \n axp-page-footer-container,\n axp-page-footer,\n axp-page-header,\n axp-page-header-container,\n axp-page-toolbar,\n\n axp-layout-content, \n axp-layout-page-content, \n\n axp-layout-sections,\n axp-layout-body,\n axp-layout-page-body,\n axp-layout-prefix,\n axp-layout-suffix,\n axp-layout-title-bar,\n axp-layout-title, \n axp-layout-title-actions, \n axp-layout-nav-button, \n axp-layout-description, \n axp-layout-breadcrumbs,\n axp-layout-list-action,\n " }, { kind: "ngmodule", type: AXSearchBoxModule }, { kind: "component", type: i4$1.AXSearchBoxComponent, selector: "ax-search-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "value", "state", "name", "id", "look", "class", "delayTime", "type"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "component", type: AXPThemeLayoutHeaderComponent, selector: "axp-layout-header" }, { kind: "component", type: AXPThemeLayoutToolbarComponent, selector: "axp-layout-toolbar" }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i3.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "component", type: i3.AXButtonItemComponent, selector: "ax-button-item", inputs: ["color", "disabled", "text", "selected", "divided", "data", "name"], outputs: ["onClick", "onFocus", "onBlur", "disabledChange"] }, { kind: "component", type: i3.AXButtonItemListComponent, selector: "ax-button-item-list", inputs: ["items"], outputs: ["onItemClick"] }, { kind: "ngmodule", type: AXDropdownModule }, { kind: "component", type: i6.AXDropdownPanelComponent, selector: "ax-dropdown-panel", inputs: ["isOpen", "fitParent", "dropdownWidth", "position", "placement", "_target", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "component", type: AXPStateMessageComponent, selector: "axp-state-message", inputs: ["mode", "icon", "title", "description", "variant"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }], encapsulation: i0.ViewEncapsulation.None }); }
|
|
994
|
+
}
|
|
995
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPCategoryTreeComponent, decorators: [{
|
|
996
|
+
type: Component,
|
|
997
|
+
args: [{ selector: 'axp-category-tree', standalone: true, encapsulation: ViewEncapsulation.None, imports: [
|
|
998
|
+
CommonModule,
|
|
999
|
+
AXDecoratorModule,
|
|
1000
|
+
AXTreeViewModule,
|
|
1001
|
+
AXSkeletonModule,
|
|
1002
|
+
AXPThemeLayoutBlockComponent,
|
|
1003
|
+
AXSearchBoxModule,
|
|
1004
|
+
AXPThemeLayoutHeaderComponent,
|
|
1005
|
+
AXPThemeLayoutToolbarComponent,
|
|
1006
|
+
AXTranslationModule,
|
|
1007
|
+
AXButtonModule,
|
|
1008
|
+
AXDropdownModule,
|
|
1009
|
+
AXPStateMessageComponent,
|
|
1010
|
+
], template: "<axp-layout-header>\n <axp-layout-toolbar>\n @if (config().searchable) {\n <ax-search-box\n (onValueChanged)=\"handleSearchChange($event)\"\n [delayTime]=\"300\"\n [placeholder]=\"config().searchPlaceholder! | translate | async\"\n >\n </ax-search-box>\n }\n </axp-layout-toolbar>\n</axp-layout-header>\n\n<axp-layout-content>\n @if (isLoading()) {\n <div class=\"ax-p-4 ax-flex ax-flex-col ax-gap-3\" [class.ax-pt-2]=\"config().searchable\">\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n <ax-skeleton class=\"ax-w-full ax-h-6 ax-rounded-md\"></ax-skeleton>\n </div>\n } @else if (treeItems()[0].children?.length) {\n <div class=\"ax-px-4 ax-max-h-[calc(100vh-250px)] ax-overflow-auto\" [class.ax-pt-2]=\"config().searchable\">\n <ax-tree-view\n (onNodeClick)=\"handleNodeClick($event)\"\n (onCollapsedChanged)=\"handleCollapseChanged($event)\"\n [showCheckbox]=\"config().showCheckbox || false\"\n [itemTemplate]=\"itemTemplate\"\n #treeRef\n [textField]=\"config().textField || 'title'\"\n [valueField]=\"config().valueField || 'id'\"\n [expandedField]=\"config().expandedField || 'expand'\"\n [items]=\"treeItems()\"\n #tree\n >\n </ax-tree-view>\n </div>\n } @else {\n <axp-state-message\n [icon]=\"config().emptyStateIcon || 'fa-light fa-folder-open'\"\n [title]=\"emptyStateTitle()\"\n [description]=\"emptyStateDescription()\"\n >\n </axp-state-message>\n }\n\n <ng-template #itemTemplate let-item>\n <div class=\"ax-flex ax-items-center ax-justify-between ax-w-full ax-gap-2 ax-overflow-hidden\">\n <div class=\"ax-flex ax-items-center ax-gap-2 ax-min-w-0\">\n <ax-icon class=\"fas ax-text-warning fa-folder\"></ax-icon>\n <span class=\"ax-truncate\">{{ item.title | translate | async }}</span>\n </div>\n @if (item.id && item.id !== 'root') {\n @if (actions().canCreateChild || actions().canUpdate || actions().canDelete) {\n <div class=\"ax-flex ax-items-center ax-gap-1\">\n <ax-button class=\"ax-xs\" color=\"default\" look=\"blank\" (onClick)=\"$event.nativeEvent.stopPropagation()\">\n <ax-icon class=\"fas fa-ellipsis-v\"></ax-icon>\n <ax-dropdown-panel>\n <ax-button-item-list>\n @if (actions().canCreateChild) {\n <ax-button-item\n (onClick)=\"handleCreateChildClick(item, $event)\"\n look=\"blank\"\n color=\"default\"\n [text]=\"actions().createChildLabel || 'Add New Child'\"\n >\n <ax-icon class=\"fas fa-plus\"></ax-icon>\n </ax-button-item>\n }\n @if (actions().canUpdate) {\n <ax-button-item\n (onClick)=\"handleUpdateNodeClick(item, $event)\"\n look=\"blank\"\n [text]=\"actions().updateLabel || 'Edit'\"\n >\n <ax-icon class=\"fas fa-pen\"></ax-icon>\n </ax-button-item>\n }\n @if (actions().canDelete) {\n <ax-button-item\n (onClick)=\"handleDeleteNodeClick(item, $event)\"\n color=\"danger\"\n look=\"blank\"\n [text]=\"actions().deleteLabel || 'Delete'\"\n >\n <ax-icon class=\"fas fa-trash\"></ax-icon>\n </ax-button-item>\n }\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-button>\n </div>\n }\n } @else if (item.id === 'root' && actions().canCreate) {\n <div class=\"ax-flex ax-items-center ax-gap-1\">\n <ax-button class=\"ax-xs\" (onClick)=\"handleCreateRootClick($event)\" look=\"blank\" color=\"default\">\n <ax-icon class=\"fas fa-plus\"></ax-icon>\n </ax-button>\n </div>\n }\n </div>\n </ng-template>\n</axp-layout-content>\n" }]
|
|
1011
|
+
}] });
|
|
1012
|
+
|
|
1013
|
+
//#region ---- Tree Node Interface ----
|
|
1014
|
+
//#endregion
|
|
1015
|
+
|
|
1016
|
+
class AXPQueryColumnsComponent {
|
|
1017
|
+
constructor() {
|
|
1018
|
+
this.columns = model([], ...(ngDevMode ? [{ debugName: "columns" }] : []));
|
|
1019
|
+
}
|
|
1020
|
+
handleVisibilityChange(e, name) {
|
|
1021
|
+
if (e.isUserInteraction) {
|
|
1022
|
+
this.columns.update((prev) => {
|
|
1023
|
+
return prev.map((c) => {
|
|
1024
|
+
return c.name === name ? { ...c, visible: e.value ?? true } : c;
|
|
1025
|
+
});
|
|
1026
|
+
});
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
1029
|
+
drop(event) {
|
|
1030
|
+
const columns = cloneDeep(this.columns());
|
|
1031
|
+
moveItemInArray(columns, event.previousIndex, event.currentIndex);
|
|
1032
|
+
this.columns.set(columns);
|
|
1033
|
+
}
|
|
1034
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPQueryColumnsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1035
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.8", type: AXPQueryColumnsComponent, isStandalone: true, selector: "axp-query-columns", inputs: { columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { columns: "columnsChange" }, ngImport: i0, template: "<div class=\"ax-flex ax-flex-col ax-gap-4 ax-select-none\" cdkDropList (cdkDropListDropped)=\"drop($event)\">\n <div class=\"ax-flex ax-flex-col ax-gap-3 ax-w-full ax-sorted-list ax-max-h-[calc(100vh-280px)] ax-overflow-auto\">\n @for (item of columns(); track item.name) {\n <div class=\"ax-flex ax-py-1 ax-items-center ax-justify-between\" cdkDrag cdkDragBoundary=\".ax-sorted-list\">\n <div class=\"ax-flex ax-items-center ax-gap-3\" cdkDragHandle>\n <ax-icon class=\"fa-solid fa-grip-dots-vertical ax-cursor-move\"></ax-icon>\n <p class=\"ax-font-medium ax-text-sm\">{{ item.title | translate | async }}</p>\n </div>\n <ax-switch\n class=\"ax-sm\"\n [ngModel]=\"item.visible\"\n (onValueChanged)=\"handleVisibilityChange($event, item.name)\"\n ></ax-switch>\n </div>\n }\n </div>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "ngmodule", type: AXSwitchModule }, { kind: "component", type: i3$1.AXSwitchComponent, selector: "ax-switch", inputs: ["disabled", "readonly", "color", "tabIndex", "value", "name", "isLoading"], outputs: ["onBlur", "onFocus", "valueChange", "onValueChanged", "readonlyChange", "disabledChange"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }] }); }
|
|
1036
|
+
}
|
|
1037
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPQueryColumnsComponent, decorators: [{
|
|
1038
|
+
type: Component,
|
|
1039
|
+
args: [{ selector: 'axp-query-columns', imports: [
|
|
1040
|
+
CommonModule,
|
|
1041
|
+
FormsModule,
|
|
1042
|
+
CdkDropList,
|
|
1043
|
+
CdkDrag,
|
|
1044
|
+
CdkDragHandle,
|
|
1045
|
+
AXButtonModule,
|
|
1046
|
+
AXDecoratorModule,
|
|
1047
|
+
AXSwitchModule,
|
|
1048
|
+
AXTranslationModule,
|
|
1049
|
+
], template: "<div class=\"ax-flex ax-flex-col ax-gap-4 ax-select-none\" cdkDropList (cdkDropListDropped)=\"drop($event)\">\n <div class=\"ax-flex ax-flex-col ax-gap-3 ax-w-full ax-sorted-list ax-max-h-[calc(100vh-280px)] ax-overflow-auto\">\n @for (item of columns(); track item.name) {\n <div class=\"ax-flex ax-py-1 ax-items-center ax-justify-between\" cdkDrag cdkDragBoundary=\".ax-sorted-list\">\n <div class=\"ax-flex ax-items-center ax-gap-3\" cdkDragHandle>\n <ax-icon class=\"fa-solid fa-grip-dots-vertical ax-cursor-move\"></ax-icon>\n <p class=\"ax-font-medium ax-text-sm\">{{ item.title | translate | async }}</p>\n </div>\n <ax-switch\n class=\"ax-sm\"\n [ngModel]=\"item.visible\"\n (onValueChanged)=\"handleVisibilityChange($event, item.name)\"\n ></ax-switch>\n </div>\n }\n </div>\n</div>\n" }]
|
|
1050
|
+
}] });
|
|
1051
|
+
|
|
687
1052
|
class AXPCompareViewComponent {
|
|
688
1053
|
constructor() {
|
|
689
1054
|
//#region ---- Component Properties ----
|
|
@@ -797,16 +1162,16 @@ class AXPCompareViewComponent {
|
|
|
797
1162
|
}
|
|
798
1163
|
ngOnDestroy() {
|
|
799
1164
|
}
|
|
800
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.
|
|
801
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", type: AXPCompareViewComponent, isStandalone: true, selector: "axp-compare-view", inputs: { inputs: { classPropertyName: "inputs", publicName: "inputs", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null } }, providers: [], ngImport: i0, template: "<!--\n #region ---- Compare View Table Layout ----\n-->\n<div class=\"axp-compare-view\">\n <div class=\"__table-container\">\n <table class=\"__table\">\n <thead class=\"__thead\">\n <tr class=\"__header-row\">\n <th class=\"__field-header\">\n <ax-check-box [value]=\"showOnlyChanges()\" (valueChange)=\"toggleShowOnlyChanges()\"\n class=\"__show-changes-toggle\">\n <ax-label>\n {{ 'compare-view.show-only-differences' | translate: { scope: 'common' } | async }}\n </ax-label>\n </ax-check-box>\n </th>\n @for (obj of remainingObjects(); track obj.id) {\n <th class=\"__object-header\" [attr.data-id]=\"obj.id\">\n <div class=\"__object-title\" [title]=\"obj.description\">\n <span>{{ obj.title | translate | async }}</span>\n @if (remainingObjects().length > 2) {\n <span class=\"__remove-object-button\" (click)=\"removeObject(obj.id)\">\n <i class=\"fa-light fa-times\"></i>\n </span>\n }\n </div>\n </th>\n }\n </tr>\n </thead>\n <tbody class=\"__tbody\">\n @for (field of filteredFields(); track field.path; let i = $index) {\n <tr class=\"__row\" [class.__row--odd]=\"i % 2 === 1\" [class.__row--has-differences]=\"hasUnequalValues(field.path)\"\n [class.__row--has-equal-values]=\"hasEqualValues(field.path)\">\n <td class=\"__field-cell\">\n <div class=\"__field-content\">\n <div class=\"__field-title\">\n {{ field.title | translate | async }}\n </div>\n @if (field.description) {\n <div class=\"__field-description\">{{ field.description }}</div>\n }\n </div>\n </td>\n @for (obj of remainingObjects(); track obj.id; let objIndex = $index) {\n <td class=\"__object-cell\" [attr.data-id]=\"obj.id\"\n [class.__cell--changed]=\"hasValueChangedFromPrevious(field.path, objIndex) && isChangesMode()\">\n @if (obj.context[field.path] !== undefined) {\n <div class=\"__object-content\">\n <axp-widgets-container [context]=\"obj.context\">\n <ng-container axp-widget-renderer [node]=\"field.widget\" [mode]=\"'view'\"></ng-container>\n </axp-widgets-container>\n </div>\n } @else {\n <div class=\"__object-placeholder\">---</div>\n }\n @if (hasValueChangingToNext(field.path, objIndex) && isChangesMode()) {\n <div class=\"__change-indicator\">\n <i class=\"fa-light fa-arrow-right\"></i>\n </div>\n }\n </td>\n }\n </tr>\n }\n </tbody>\n </table>\n </div>\n</div>\n<!--\n #endregion\n-->", styles: [".axp-compare-view{display:flex;height:100%;width:100%;flex-direction:column;border-radius:.375rem;border-width:1px;--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow);background-color:rgb(var(--ax-sys-color-lightest-surface));color:rgb(var(--ax-sys-color-on-lightest-surface));border-color:rgb(var(--ax-sys-color-border-lightest-surface));position:relative}.axp-compare-view .__filter-controls{flex-shrink:0;border-bottom-width:1px;padding:1rem;background-color:rgb(var(--ax-sys-color-light-surface));color:rgb(var(--ax-sys-color-on-light-surface));border-color:rgb(var(--ax-sys-color-border-light-surface))}.axp-compare-view .__filter-controls .__show-changes-toggle{font-size:.875rem;line-height:1.25rem}.axp-compare-view .__table-container{flex:1 1 0%;overflow:auto;position:relative}.axp-compare-view .__table{width:100%;border-collapse:separate;border-spacing:0;table-layout:fixed}.axp-compare-view .__table .__thead{position:-webkit-sticky;position:sticky;top:0;z-index:20}.axp-compare-view .__table .__thead .__header-row .__field-header{width:14rem;border-bottom-width:1px;border-right-width:1px;padding:.75rem 1rem;text-align:left;font-weight:700;background-color:rgb(var(--ax-sys-color-lighter-surface));color:rgb(var(--ax-sys-color-on-lighter-surface));border-color:rgb(var(--ax-sys-color-border-lighter-surface));position:-webkit-sticky;position:sticky;left:0;z-index:25}.axp-compare-view .__table .__thead .__header-row .__object-header{position:relative;border-bottom-width:1px;padding:.75rem 1rem;text-align:center;background-color:rgb(var(--ax-sys-color-lighter-surface));color:rgb(var(--ax-sys-color-on-lighter-surface));border-color:rgb(var(--ax-sys-color-border-lighter-surface));min-width:250px;width:250px}.axp-compare-view .__table .__thead .__header-row .__object-header .__object-title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.875rem;line-height:1.25rem;font-weight:600}.axp-compare-view .__table .__thead .__header-row .__object-header .__object-description{margin-top:.25rem;font-size:.75rem;line-height:1rem;opacity:.75}.axp-compare-view .__table .__thead .__header-row .__object-header .__remove-object-button{display:flex;width:1.5rem;height:1.5rem;cursor:pointer;align-items:center;justify-content:center;border-radius:9999px;--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-light-surface),var(--tw-bg-opacity, 1));font-size:.875rem;line-height:1.25rem;position:absolute;top:50%;inset-inline-end:0px;--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.axp-compare-view .__table .__thead .__header-row .__object-header .__remove-object-button:hover{--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-danger-100),var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-danger-600),var(--tw-text-opacity, 1))}.axp-compare-view .__table .__tbody .__row{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s;animation-duration:.2s}.axp-compare-view .__table .__tbody .__row.__row--odd{background-color:rgb(var(--ax-sys-color-lightest-surface));color:rgb(var(--ax-sys-color-on-lightest-surface));border-color:rgb(var(--ax-sys-color-border-lightest-surface))}.axp-compare-view .__table .__tbody .__row.__row--has-differences{border-left-width:4px;--tw-border-opacity: 1;border-left-color:rgba(var(--ax-sys-color-warning-500),var(--tw-border-opacity, 1))}.axp-compare-view .__table .__tbody .__row.__row--has-differences .__field-cell{background-color:rgba(var(--ax-sys-color-warning-500),var(--tw-bg-opacity, 1));--tw-bg-opacity: .05}.axp-compare-view .__table .__tbody .__row.__row--has-equal-values{border-left-width:4px;--tw-border-opacity: 1;border-left-color:rgba(var(--ax-sys-color-success-500),var(--tw-border-opacity, 1))}.axp-compare-view .__table .__tbody .__row.__row--has-equal-values .__field-cell{background-color:rgba(var(--ax-sys-color-success-500),var(--tw-bg-opacity, 1));--tw-bg-opacity: .05}.axp-compare-view .__table .__tbody .__row .__field-cell{width:14rem;border-bottom-width:1px;border-right-width:1px;padding:.75rem 1rem;vertical-align:top;background-color:rgb(var(--ax-sys-color-lightest-surface));color:rgb(var(--ax-sys-color-on-lightest-surface));border-color:rgb(var(--ax-sys-color-border-lightest-surface));position:-webkit-sticky;position:sticky;left:0;z-index:15}.axp-compare-view .__table .__tbody .__row .__field-cell .__field-content{display:flex;flex-direction:column;gap:.25rem}.axp-compare-view .__table .__tbody .__row .__field-cell .__field-content .__field-title{font-weight:500}.axp-compare-view .__table .__tbody .__row .__field-cell .__field-content .__field-description{font-size:.75rem;line-height:1rem;opacity:.75}.axp-compare-view .__table .__tbody .__row .__object-cell{border-bottom-width:1px;padding:.75rem 1rem;text-align:center;vertical-align:middle;position:relative}.axp-compare-view .__table .__tbody .__row .__object-cell.__cell--changed .__object-content{border-width:1px;border-style:dashed;--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-warning-200),var(--tw-border-opacity, 1));padding:.5rem}.axp-compare-view .__table .__tbody .__row .__object-cell .__object-content{position:relative;display:flex;align-items:center;justify-content:center}.axp-compare-view .__table .__tbody .__row .__object-cell .__change-indicator{position:absolute;inset-inline-end:-.25rem;top:50%;--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));line-height:1rem;--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-warning-500),var(--tw-text-opacity, 1));font-size:.875rem}.axp-compare-view .__table .__tbody .__row .__object-cell .__object-placeholder{opacity:.75}.axp-compare-view .__table .__tbody .__row.__row--has-differences .__field-cell{border-inline-start-width:4px;--tw-border-opacity: 1;border-inline-start-color:rgba(var(--ax-sys-color-warning-500),var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-warning-50),var(--tw-bg-opacity, 1))}.axp-compare-view .__table .__tbody .__row.__row--has-differences .__field-cell:is(.ax-dark *){--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-warning-900),var(--tw-bg-opacity, 1))}.axp-compare-view .__table .__tbody .__row.__row--has-equal-values .__field-cell{border-inline-start-width:4px;--tw-border-opacity: 1;border-inline-start-color:rgba(var(--ax-sys-color-success-500),var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-success-50),var(--tw-bg-opacity, 1))}.axp-compare-view .__table .__tbody .__row.__row--has-equal-values .__field-cell:is(.ax-dark *){--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-success-900),var(--tw-bg-opacity, 1))}\n"], dependencies: [{ kind: "ngmodule", type:
|
|
1165
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPCompareViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1166
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.8", type: AXPCompareViewComponent, isStandalone: true, selector: "axp-compare-view", inputs: { inputs: { classPropertyName: "inputs", publicName: "inputs", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null } }, providers: [], ngImport: i0, template: "<!--\n #region ---- Compare View Table Layout ----\n-->\n<div class=\"axp-compare-view\">\n <div class=\"__table-container\">\n <table class=\"__table\">\n <thead class=\"__thead\">\n <tr class=\"__header-row\">\n <th class=\"__field-header\">\n <ax-check-box\n [value]=\"showOnlyChanges()\"\n (valueChange)=\"toggleShowOnlyChanges()\"\n class=\"__show-changes-toggle\"\n >\n <ax-label>\n {{ '@activity-log:compare-view.show-only-differences' | translate | async }}\n </ax-label>\n </ax-check-box>\n </th>\n @for (obj of remainingObjects(); track obj.id) {\n <th class=\"__object-header\" [attr.data-id]=\"obj.id\">\n <div class=\"__object-title\" [title]=\"obj.description\">\n <span>{{ obj.title | translate | async }}</span>\n @if (remainingObjects().length > 2) {\n <span class=\"__remove-object-button\" (click)=\"removeObject(obj.id)\">\n <i class=\"fa-light fa-times\"></i>\n </span>\n }\n </div>\n </th>\n }\n </tr>\n </thead>\n <tbody class=\"__tbody\">\n @for (field of filteredFields(); track field.path; let i = $index) {\n <tr\n class=\"__row\"\n [class.__row--odd]=\"i % 2 === 1\"\n [class.__row--has-differences]=\"hasUnequalValues(field.path)\"\n [class.__row--has-equal-values]=\"hasEqualValues(field.path)\"\n >\n <td class=\"__field-cell\">\n <div class=\"__field-content\">\n <div class=\"__field-title\">\n {{ field.title | translate | async }}\n </div>\n @if (field.description) {\n <div class=\"__field-description\">{{ field.description }}</div>\n }\n </div>\n </td>\n @for (obj of remainingObjects(); track obj.id; let objIndex = $index) {\n <td\n class=\"__object-cell\"\n [attr.data-id]=\"obj.id\"\n [class.__cell--changed]=\"hasValueChangedFromPrevious(field.path, objIndex) && isChangesMode()\"\n >\n @if (obj.context[field.path] !== undefined) {\n <div class=\"__object-content\">\n <axp-widgets-container [context]=\"obj.context\">\n <ng-container axp-widget-renderer [node]=\"field.widget\" [mode]=\"'view'\"></ng-container>\n </axp-widgets-container>\n </div>\n } @else {\n <div class=\"__object-placeholder\">---</div>\n }\n @if (hasValueChangingToNext(field.path, objIndex) && isChangesMode()) {\n <div class=\"__change-indicator\">\n <i class=\"fa-light fa-arrow-right\"></i>\n </div>\n }\n </td>\n }\n </tr>\n }\n </tbody>\n </table>\n </div>\n</div>\n<!--\n #endregion\n-->\n", styles: [".axp-compare-view{display:flex;height:100%;width:100%;flex-direction:column;border-radius:.375rem;border-width:1px;--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow);background-color:rgb(var(--ax-sys-color-lightest-surface));color:rgb(var(--ax-sys-color-on-lightest-surface));border-color:rgb(var(--ax-sys-color-border-lightest-surface));position:relative}.axp-compare-view .__filter-controls{flex-shrink:0;border-bottom-width:1px;padding:1rem;background-color:rgb(var(--ax-sys-color-light-surface));color:rgb(var(--ax-sys-color-on-light-surface));border-color:rgb(var(--ax-sys-color-border-light-surface))}.axp-compare-view .__filter-controls .__show-changes-toggle{font-size:.875rem;line-height:1.25rem}.axp-compare-view .__table-container{flex:1 1 0%;overflow:auto;position:relative}.axp-compare-view .__table{width:100%;border-collapse:separate;border-spacing:0;table-layout:fixed}.axp-compare-view .__table .__thead{position:-webkit-sticky;position:sticky;top:0;z-index:20}.axp-compare-view .__table .__thead .__header-row .__field-header{width:14rem;border-bottom-width:1px;border-right-width:1px;padding:.75rem 1rem;text-align:left;font-weight:700;background-color:rgb(var(--ax-sys-color-lighter-surface));color:rgb(var(--ax-sys-color-on-lighter-surface));border-color:rgb(var(--ax-sys-color-border-lighter-surface));position:-webkit-sticky;position:sticky;left:0;z-index:25}.axp-compare-view .__table .__thead .__header-row .__object-header{position:relative;border-bottom-width:1px;padding:.75rem 1rem;text-align:center;background-color:rgb(var(--ax-sys-color-lighter-surface));color:rgb(var(--ax-sys-color-on-lighter-surface));border-color:rgb(var(--ax-sys-color-border-lighter-surface));min-width:250px;width:250px}.axp-compare-view .__table .__thead .__header-row .__object-header .__object-title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.875rem;line-height:1.25rem;font-weight:600}.axp-compare-view .__table .__thead .__header-row .__object-header .__object-description{margin-top:.25rem;font-size:.75rem;line-height:1rem;opacity:.75}.axp-compare-view .__table .__thead .__header-row .__object-header .__remove-object-button{display:flex;width:1.5rem;height:1.5rem;cursor:pointer;align-items:center;justify-content:center;border-radius:9999px;--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-light-surface),var(--tw-bg-opacity, 1));font-size:.875rem;line-height:1.25rem;position:absolute;top:50%;inset-inline-end:0px;--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.axp-compare-view .__table .__thead .__header-row .__object-header .__remove-object-button:hover{--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-danger-100),var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-danger-600),var(--tw-text-opacity, 1))}.axp-compare-view .__table .__tbody .__row{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s;animation-duration:.2s}.axp-compare-view .__table .__tbody .__row.__row--odd{background-color:rgb(var(--ax-sys-color-lightest-surface));color:rgb(var(--ax-sys-color-on-lightest-surface));border-color:rgb(var(--ax-sys-color-border-lightest-surface))}.axp-compare-view .__table .__tbody .__row.__row--has-differences{border-left-width:4px;--tw-border-opacity: 1;border-left-color:rgba(var(--ax-sys-color-warning-500),var(--tw-border-opacity, 1))}.axp-compare-view .__table .__tbody .__row.__row--has-differences .__field-cell{background-color:rgba(var(--ax-sys-color-warning-500),var(--tw-bg-opacity, 1));--tw-bg-opacity: .05}.axp-compare-view .__table .__tbody .__row.__row--has-equal-values{border-left-width:4px;--tw-border-opacity: 1;border-left-color:rgba(var(--ax-sys-color-success-500),var(--tw-border-opacity, 1))}.axp-compare-view .__table .__tbody .__row.__row--has-equal-values .__field-cell{background-color:rgba(var(--ax-sys-color-success-500),var(--tw-bg-opacity, 1));--tw-bg-opacity: .05}.axp-compare-view .__table .__tbody .__row .__field-cell{width:14rem;border-bottom-width:1px;border-right-width:1px;padding:.75rem 1rem;vertical-align:top;background-color:rgb(var(--ax-sys-color-lightest-surface));color:rgb(var(--ax-sys-color-on-lightest-surface));border-color:rgb(var(--ax-sys-color-border-lightest-surface));position:-webkit-sticky;position:sticky;left:0;z-index:15}.axp-compare-view .__table .__tbody .__row .__field-cell .__field-content{display:flex;flex-direction:column;gap:.25rem}.axp-compare-view .__table .__tbody .__row .__field-cell .__field-content .__field-title{font-weight:500}.axp-compare-view .__table .__tbody .__row .__field-cell .__field-content .__field-description{font-size:.75rem;line-height:1rem;opacity:.75}.axp-compare-view .__table .__tbody .__row .__object-cell{border-bottom-width:1px;padding:.75rem 1rem;text-align:center;vertical-align:middle;position:relative}.axp-compare-view .__table .__tbody .__row .__object-cell.__cell--changed .__object-content{border-width:1px;border-style:dashed;--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-warning-200),var(--tw-border-opacity, 1));padding:.5rem}.axp-compare-view .__table .__tbody .__row .__object-cell .__object-content{position:relative;display:flex;align-items:center;justify-content:center}.axp-compare-view .__table .__tbody .__row .__object-cell .__change-indicator{position:absolute;inset-inline-end:-.25rem;top:50%;--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));line-height:1rem;--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-warning-500),var(--tw-text-opacity, 1));font-size:.875rem}.axp-compare-view .__table .__tbody .__row .__object-cell .__object-placeholder{opacity:.75}.axp-compare-view .__table .__tbody .__row.__row--has-differences .__field-cell{border-inline-start-width:4px;--tw-border-opacity: 1;border-inline-start-color:rgba(var(--ax-sys-color-warning-500),var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-warning-50),var(--tw-bg-opacity, 1))}.axp-compare-view .__table .__tbody .__row.__row--has-differences .__field-cell:is(.ax-dark *){--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-warning-900),var(--tw-bg-opacity, 1))}.axp-compare-view .__table .__tbody .__row.__row--has-equal-values .__field-cell{border-inline-start-width:4px;--tw-border-opacity: 1;border-inline-start-color:rgba(var(--ax-sys-color-success-500),var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-success-50),var(--tw-bg-opacity, 1))}.axp-compare-view .__table .__tbody .__row.__row--has-equal-values .__field-cell:is(.ax-dark *){--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-success-900),var(--tw-bg-opacity, 1))}\n"], dependencies: [{ kind: "ngmodule", type:
|
|
802
1167
|
// Angular
|
|
803
1168
|
CommonModule }, { kind: "ngmodule", type:
|
|
804
1169
|
// ACoreX
|
|
805
|
-
AXFormModule }, { kind: "ngmodule", type: AXTextBoxModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "ngmodule", type: AXLabelModule }, { kind: "component", type:
|
|
1170
|
+
AXFormModule }, { kind: "ngmodule", type: AXTextBoxModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "ngmodule", type: AXLabelModule }, { kind: "component", type: i3$2.AXLabelComponent, selector: "ax-label", inputs: ["required", "for"], outputs: ["requiredChange"] }, { kind: "ngmodule", type: AXCheckBoxModule }, { kind: "component", type: i2$3.AXCheckBoxComponent, selector: "ax-check-box", inputs: ["disabled", "tabIndex", "readonly", "color", "value", "name", "id", "isLoading", "indeterminate"], outputs: ["onBlur", "onFocus", "valueChange", "onValueChanged"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type:
|
|
806
1171
|
// Platform
|
|
807
|
-
AXPLayoutBuilderModule }, { kind: "component", type: i3$
|
|
1172
|
+
AXPLayoutBuilderModule }, { kind: "component", type: i3$3.AXPWidgetContainerComponent, selector: "axp-widgets-container", inputs: ["context", "functions"], outputs: ["onContextChanged"] }, { kind: "directive", type: i3$3.AXPWidgetRendererDirective, selector: "[axp-widget-renderer]", inputs: ["parentNode", "index", "mode", "node"], outputs: ["onOptionsChanged", "onValueChanged"], exportAs: ["widgetRenderer"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }], encapsulation: i0.ViewEncapsulation.None }); }
|
|
808
1173
|
}
|
|
809
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.
|
|
1174
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPCompareViewComponent, decorators: [{
|
|
810
1175
|
type: Component,
|
|
811
1176
|
args: [{ selector: 'axp-compare-view', imports: [
|
|
812
1177
|
// Angular
|
|
@@ -820,14 +1185,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
|
|
|
820
1185
|
AXTranslationModule,
|
|
821
1186
|
// Platform
|
|
822
1187
|
AXPLayoutBuilderModule
|
|
823
|
-
], encapsulation: ViewEncapsulation.None, providers: [], template: "<!--\n #region ---- Compare View Table Layout ----\n-->\n<div class=\"axp-compare-view\">\n <div class=\"__table-container\">\n <table class=\"__table\">\n <thead class=\"__thead\">\n <tr class=\"__header-row\">\n <th class=\"__field-header\">\n <ax-check-box [value]=\"showOnlyChanges()\" (valueChange)=\"toggleShowOnlyChanges()\"\n class=\"__show-changes-toggle\">\n <ax-label>\n {{ 'compare-view.show-only-differences' | translate: { scope: 'common' } | async }}\n </ax-label>\n </ax-check-box>\n </th>\n @for (obj of remainingObjects(); track obj.id) {\n <th class=\"__object-header\" [attr.data-id]=\"obj.id\">\n <div class=\"__object-title\" [title]=\"obj.description\">\n <span>{{ obj.title | translate | async }}</span>\n @if (remainingObjects().length > 2) {\n <span class=\"__remove-object-button\" (click)=\"removeObject(obj.id)\">\n <i class=\"fa-light fa-times\"></i>\n </span>\n }\n </div>\n </th>\n }\n </tr>\n </thead>\n <tbody class=\"__tbody\">\n @for (field of filteredFields(); track field.path; let i = $index) {\n <tr class=\"__row\" [class.__row--odd]=\"i % 2 === 1\" [class.__row--has-differences]=\"hasUnequalValues(field.path)\"\n [class.__row--has-equal-values]=\"hasEqualValues(field.path)\">\n <td class=\"__field-cell\">\n <div class=\"__field-content\">\n <div class=\"__field-title\">\n {{ field.title | translate | async }}\n </div>\n @if (field.description) {\n <div class=\"__field-description\">{{ field.description }}</div>\n }\n </div>\n </td>\n @for (obj of remainingObjects(); track obj.id; let objIndex = $index) {\n <td class=\"__object-cell\" [attr.data-id]=\"obj.id\"\n [class.__cell--changed]=\"hasValueChangedFromPrevious(field.path, objIndex) && isChangesMode()\">\n @if (obj.context[field.path] !== undefined) {\n <div class=\"__object-content\">\n <axp-widgets-container [context]=\"obj.context\">\n <ng-container axp-widget-renderer [node]=\"field.widget\" [mode]=\"'view'\"></ng-container>\n </axp-widgets-container>\n </div>\n } @else {\n <div class=\"__object-placeholder\">---</div>\n }\n @if (hasValueChangingToNext(field.path, objIndex) && isChangesMode()) {\n <div class=\"__change-indicator\">\n <i class=\"fa-light fa-arrow-right\"></i>\n </div>\n }\n </td>\n }\n </tr>\n }\n </tbody>\n </table>\n </div>\n</div>\n<!--\n #endregion\n-->", styles: [".axp-compare-view{display:flex;height:100%;width:100%;flex-direction:column;border-radius:.375rem;border-width:1px;--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow);background-color:rgb(var(--ax-sys-color-lightest-surface));color:rgb(var(--ax-sys-color-on-lightest-surface));border-color:rgb(var(--ax-sys-color-border-lightest-surface));position:relative}.axp-compare-view .__filter-controls{flex-shrink:0;border-bottom-width:1px;padding:1rem;background-color:rgb(var(--ax-sys-color-light-surface));color:rgb(var(--ax-sys-color-on-light-surface));border-color:rgb(var(--ax-sys-color-border-light-surface))}.axp-compare-view .__filter-controls .__show-changes-toggle{font-size:.875rem;line-height:1.25rem}.axp-compare-view .__table-container{flex:1 1 0%;overflow:auto;position:relative}.axp-compare-view .__table{width:100%;border-collapse:separate;border-spacing:0;table-layout:fixed}.axp-compare-view .__table .__thead{position:-webkit-sticky;position:sticky;top:0;z-index:20}.axp-compare-view .__table .__thead .__header-row .__field-header{width:14rem;border-bottom-width:1px;border-right-width:1px;padding:.75rem 1rem;text-align:left;font-weight:700;background-color:rgb(var(--ax-sys-color-lighter-surface));color:rgb(var(--ax-sys-color-on-lighter-surface));border-color:rgb(var(--ax-sys-color-border-lighter-surface));position:-webkit-sticky;position:sticky;left:0;z-index:25}.axp-compare-view .__table .__thead .__header-row .__object-header{position:relative;border-bottom-width:1px;padding:.75rem 1rem;text-align:center;background-color:rgb(var(--ax-sys-color-lighter-surface));color:rgb(var(--ax-sys-color-on-lighter-surface));border-color:rgb(var(--ax-sys-color-border-lighter-surface));min-width:250px;width:250px}.axp-compare-view .__table .__thead .__header-row .__object-header .__object-title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.875rem;line-height:1.25rem;font-weight:600}.axp-compare-view .__table .__thead .__header-row .__object-header .__object-description{margin-top:.25rem;font-size:.75rem;line-height:1rem;opacity:.75}.axp-compare-view .__table .__thead .__header-row .__object-header .__remove-object-button{display:flex;width:1.5rem;height:1.5rem;cursor:pointer;align-items:center;justify-content:center;border-radius:9999px;--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-light-surface),var(--tw-bg-opacity, 1));font-size:.875rem;line-height:1.25rem;position:absolute;top:50%;inset-inline-end:0px;--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.axp-compare-view .__table .__thead .__header-row .__object-header .__remove-object-button:hover{--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-danger-100),var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-danger-600),var(--tw-text-opacity, 1))}.axp-compare-view .__table .__tbody .__row{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s;animation-duration:.2s}.axp-compare-view .__table .__tbody .__row.__row--odd{background-color:rgb(var(--ax-sys-color-lightest-surface));color:rgb(var(--ax-sys-color-on-lightest-surface));border-color:rgb(var(--ax-sys-color-border-lightest-surface))}.axp-compare-view .__table .__tbody .__row.__row--has-differences{border-left-width:4px;--tw-border-opacity: 1;border-left-color:rgba(var(--ax-sys-color-warning-500),var(--tw-border-opacity, 1))}.axp-compare-view .__table .__tbody .__row.__row--has-differences .__field-cell{background-color:rgba(var(--ax-sys-color-warning-500),var(--tw-bg-opacity, 1));--tw-bg-opacity: .05}.axp-compare-view .__table .__tbody .__row.__row--has-equal-values{border-left-width:4px;--tw-border-opacity: 1;border-left-color:rgba(var(--ax-sys-color-success-500),var(--tw-border-opacity, 1))}.axp-compare-view .__table .__tbody .__row.__row--has-equal-values .__field-cell{background-color:rgba(var(--ax-sys-color-success-500),var(--tw-bg-opacity, 1));--tw-bg-opacity: .05}.axp-compare-view .__table .__tbody .__row .__field-cell{width:14rem;border-bottom-width:1px;border-right-width:1px;padding:.75rem 1rem;vertical-align:top;background-color:rgb(var(--ax-sys-color-lightest-surface));color:rgb(var(--ax-sys-color-on-lightest-surface));border-color:rgb(var(--ax-sys-color-border-lightest-surface));position:-webkit-sticky;position:sticky;left:0;z-index:15}.axp-compare-view .__table .__tbody .__row .__field-cell .__field-content{display:flex;flex-direction:column;gap:.25rem}.axp-compare-view .__table .__tbody .__row .__field-cell .__field-content .__field-title{font-weight:500}.axp-compare-view .__table .__tbody .__row .__field-cell .__field-content .__field-description{font-size:.75rem;line-height:1rem;opacity:.75}.axp-compare-view .__table .__tbody .__row .__object-cell{border-bottom-width:1px;padding:.75rem 1rem;text-align:center;vertical-align:middle;position:relative}.axp-compare-view .__table .__tbody .__row .__object-cell.__cell--changed .__object-content{border-width:1px;border-style:dashed;--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-warning-200),var(--tw-border-opacity, 1));padding:.5rem}.axp-compare-view .__table .__tbody .__row .__object-cell .__object-content{position:relative;display:flex;align-items:center;justify-content:center}.axp-compare-view .__table .__tbody .__row .__object-cell .__change-indicator{position:absolute;inset-inline-end:-.25rem;top:50%;--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));line-height:1rem;--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-warning-500),var(--tw-text-opacity, 1));font-size:.875rem}.axp-compare-view .__table .__tbody .__row .__object-cell .__object-placeholder{opacity:.75}.axp-compare-view .__table .__tbody .__row.__row--has-differences .__field-cell{border-inline-start-width:4px;--tw-border-opacity: 1;border-inline-start-color:rgba(var(--ax-sys-color-warning-500),var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-warning-50),var(--tw-bg-opacity, 1))}.axp-compare-view .__table .__tbody .__row.__row--has-differences .__field-cell:is(.ax-dark *){--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-warning-900),var(--tw-bg-opacity, 1))}.axp-compare-view .__table .__tbody .__row.__row--has-equal-values .__field-cell{border-inline-start-width:4px;--tw-border-opacity: 1;border-inline-start-color:rgba(var(--ax-sys-color-success-500),var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-success-50),var(--tw-bg-opacity, 1))}.axp-compare-view .__table .__tbody .__row.__row--has-equal-values .__field-cell:is(.ax-dark *){--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-success-900),var(--tw-bg-opacity, 1))}\n"] }]
|
|
1188
|
+
], encapsulation: ViewEncapsulation.None, providers: [], template: "<!--\n #region ---- Compare View Table Layout ----\n-->\n<div class=\"axp-compare-view\">\n <div class=\"__table-container\">\n <table class=\"__table\">\n <thead class=\"__thead\">\n <tr class=\"__header-row\">\n <th class=\"__field-header\">\n <ax-check-box\n [value]=\"showOnlyChanges()\"\n (valueChange)=\"toggleShowOnlyChanges()\"\n class=\"__show-changes-toggle\"\n >\n <ax-label>\n {{ '@activity-log:compare-view.show-only-differences' | translate | async }}\n </ax-label>\n </ax-check-box>\n </th>\n @for (obj of remainingObjects(); track obj.id) {\n <th class=\"__object-header\" [attr.data-id]=\"obj.id\">\n <div class=\"__object-title\" [title]=\"obj.description\">\n <span>{{ obj.title | translate | async }}</span>\n @if (remainingObjects().length > 2) {\n <span class=\"__remove-object-button\" (click)=\"removeObject(obj.id)\">\n <i class=\"fa-light fa-times\"></i>\n </span>\n }\n </div>\n </th>\n }\n </tr>\n </thead>\n <tbody class=\"__tbody\">\n @for (field of filteredFields(); track field.path; let i = $index) {\n <tr\n class=\"__row\"\n [class.__row--odd]=\"i % 2 === 1\"\n [class.__row--has-differences]=\"hasUnequalValues(field.path)\"\n [class.__row--has-equal-values]=\"hasEqualValues(field.path)\"\n >\n <td class=\"__field-cell\">\n <div class=\"__field-content\">\n <div class=\"__field-title\">\n {{ field.title | translate | async }}\n </div>\n @if (field.description) {\n <div class=\"__field-description\">{{ field.description }}</div>\n }\n </div>\n </td>\n @for (obj of remainingObjects(); track obj.id; let objIndex = $index) {\n <td\n class=\"__object-cell\"\n [attr.data-id]=\"obj.id\"\n [class.__cell--changed]=\"hasValueChangedFromPrevious(field.path, objIndex) && isChangesMode()\"\n >\n @if (obj.context[field.path] !== undefined) {\n <div class=\"__object-content\">\n <axp-widgets-container [context]=\"obj.context\">\n <ng-container axp-widget-renderer [node]=\"field.widget\" [mode]=\"'view'\"></ng-container>\n </axp-widgets-container>\n </div>\n } @else {\n <div class=\"__object-placeholder\">---</div>\n }\n @if (hasValueChangingToNext(field.path, objIndex) && isChangesMode()) {\n <div class=\"__change-indicator\">\n <i class=\"fa-light fa-arrow-right\"></i>\n </div>\n }\n </td>\n }\n </tr>\n }\n </tbody>\n </table>\n </div>\n</div>\n<!--\n #endregion\n-->\n", styles: [".axp-compare-view{display:flex;height:100%;width:100%;flex-direction:column;border-radius:.375rem;border-width:1px;--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow);background-color:rgb(var(--ax-sys-color-lightest-surface));color:rgb(var(--ax-sys-color-on-lightest-surface));border-color:rgb(var(--ax-sys-color-border-lightest-surface));position:relative}.axp-compare-view .__filter-controls{flex-shrink:0;border-bottom-width:1px;padding:1rem;background-color:rgb(var(--ax-sys-color-light-surface));color:rgb(var(--ax-sys-color-on-light-surface));border-color:rgb(var(--ax-sys-color-border-light-surface))}.axp-compare-view .__filter-controls .__show-changes-toggle{font-size:.875rem;line-height:1.25rem}.axp-compare-view .__table-container{flex:1 1 0%;overflow:auto;position:relative}.axp-compare-view .__table{width:100%;border-collapse:separate;border-spacing:0;table-layout:fixed}.axp-compare-view .__table .__thead{position:-webkit-sticky;position:sticky;top:0;z-index:20}.axp-compare-view .__table .__thead .__header-row .__field-header{width:14rem;border-bottom-width:1px;border-right-width:1px;padding:.75rem 1rem;text-align:left;font-weight:700;background-color:rgb(var(--ax-sys-color-lighter-surface));color:rgb(var(--ax-sys-color-on-lighter-surface));border-color:rgb(var(--ax-sys-color-border-lighter-surface));position:-webkit-sticky;position:sticky;left:0;z-index:25}.axp-compare-view .__table .__thead .__header-row .__object-header{position:relative;border-bottom-width:1px;padding:.75rem 1rem;text-align:center;background-color:rgb(var(--ax-sys-color-lighter-surface));color:rgb(var(--ax-sys-color-on-lighter-surface));border-color:rgb(var(--ax-sys-color-border-lighter-surface));min-width:250px;width:250px}.axp-compare-view .__table .__thead .__header-row .__object-header .__object-title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.875rem;line-height:1.25rem;font-weight:600}.axp-compare-view .__table .__thead .__header-row .__object-header .__object-description{margin-top:.25rem;font-size:.75rem;line-height:1rem;opacity:.75}.axp-compare-view .__table .__thead .__header-row .__object-header .__remove-object-button{display:flex;width:1.5rem;height:1.5rem;cursor:pointer;align-items:center;justify-content:center;border-radius:9999px;--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-light-surface),var(--tw-bg-opacity, 1));font-size:.875rem;line-height:1.25rem;position:absolute;top:50%;inset-inline-end:0px;--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.axp-compare-view .__table .__thead .__header-row .__object-header .__remove-object-button:hover{--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-danger-100),var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-danger-600),var(--tw-text-opacity, 1))}.axp-compare-view .__table .__tbody .__row{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s;animation-duration:.2s}.axp-compare-view .__table .__tbody .__row.__row--odd{background-color:rgb(var(--ax-sys-color-lightest-surface));color:rgb(var(--ax-sys-color-on-lightest-surface));border-color:rgb(var(--ax-sys-color-border-lightest-surface))}.axp-compare-view .__table .__tbody .__row.__row--has-differences{border-left-width:4px;--tw-border-opacity: 1;border-left-color:rgba(var(--ax-sys-color-warning-500),var(--tw-border-opacity, 1))}.axp-compare-view .__table .__tbody .__row.__row--has-differences .__field-cell{background-color:rgba(var(--ax-sys-color-warning-500),var(--tw-bg-opacity, 1));--tw-bg-opacity: .05}.axp-compare-view .__table .__tbody .__row.__row--has-equal-values{border-left-width:4px;--tw-border-opacity: 1;border-left-color:rgba(var(--ax-sys-color-success-500),var(--tw-border-opacity, 1))}.axp-compare-view .__table .__tbody .__row.__row--has-equal-values .__field-cell{background-color:rgba(var(--ax-sys-color-success-500),var(--tw-bg-opacity, 1));--tw-bg-opacity: .05}.axp-compare-view .__table .__tbody .__row .__field-cell{width:14rem;border-bottom-width:1px;border-right-width:1px;padding:.75rem 1rem;vertical-align:top;background-color:rgb(var(--ax-sys-color-lightest-surface));color:rgb(var(--ax-sys-color-on-lightest-surface));border-color:rgb(var(--ax-sys-color-border-lightest-surface));position:-webkit-sticky;position:sticky;left:0;z-index:15}.axp-compare-view .__table .__tbody .__row .__field-cell .__field-content{display:flex;flex-direction:column;gap:.25rem}.axp-compare-view .__table .__tbody .__row .__field-cell .__field-content .__field-title{font-weight:500}.axp-compare-view .__table .__tbody .__row .__field-cell .__field-content .__field-description{font-size:.75rem;line-height:1rem;opacity:.75}.axp-compare-view .__table .__tbody .__row .__object-cell{border-bottom-width:1px;padding:.75rem 1rem;text-align:center;vertical-align:middle;position:relative}.axp-compare-view .__table .__tbody .__row .__object-cell.__cell--changed .__object-content{border-width:1px;border-style:dashed;--tw-border-opacity: 1;border-color:rgba(var(--ax-sys-color-warning-200),var(--tw-border-opacity, 1));padding:.5rem}.axp-compare-view .__table .__tbody .__row .__object-cell .__object-content{position:relative;display:flex;align-items:center;justify-content:center}.axp-compare-view .__table .__tbody .__row .__object-cell .__change-indicator{position:absolute;inset-inline-end:-.25rem;top:50%;--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));line-height:1rem;--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-warning-500),var(--tw-text-opacity, 1));font-size:.875rem}.axp-compare-view .__table .__tbody .__row .__object-cell .__object-placeholder{opacity:.75}.axp-compare-view .__table .__tbody .__row.__row--has-differences .__field-cell{border-inline-start-width:4px;--tw-border-opacity: 1;border-inline-start-color:rgba(var(--ax-sys-color-warning-500),var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-warning-50),var(--tw-bg-opacity, 1))}.axp-compare-view .__table .__tbody .__row.__row--has-differences .__field-cell:is(.ax-dark *){--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-warning-900),var(--tw-bg-opacity, 1))}.axp-compare-view .__table .__tbody .__row.__row--has-equal-values .__field-cell{border-inline-start-width:4px;--tw-border-opacity: 1;border-inline-start-color:rgba(var(--ax-sys-color-success-500),var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-success-50),var(--tw-bg-opacity, 1))}.axp-compare-view .__table .__tbody .__row.__row--has-equal-values .__field-cell:is(.ax-dark *){--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-success-900),var(--tw-bg-opacity, 1))}\n"] }]
|
|
824
1189
|
}] });
|
|
825
1190
|
|
|
826
1191
|
class AXPComponentSlot {
|
|
827
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.
|
|
828
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.1.
|
|
1192
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPComponentSlot, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
1193
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.1.8", type: AXPComponentSlot, isStandalone: true, ngImport: i0 }); }
|
|
829
1194
|
}
|
|
830
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.
|
|
1195
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPComponentSlot, decorators: [{
|
|
831
1196
|
type: Directive
|
|
832
1197
|
}] });
|
|
833
1198
|
|
|
@@ -847,10 +1212,10 @@ class AXPComponentSlotRegistryService {
|
|
|
847
1212
|
get(slotName) {
|
|
848
1213
|
return this.registry.get(slotName) || [];
|
|
849
1214
|
}
|
|
850
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.
|
|
851
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.
|
|
1215
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPComponentSlotRegistryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1216
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPComponentSlotRegistryService, providedIn: 'root' }); }
|
|
852
1217
|
}
|
|
853
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.
|
|
1218
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPComponentSlotRegistryService, decorators: [{
|
|
854
1219
|
type: Injectable,
|
|
855
1220
|
args: [{
|
|
856
1221
|
providedIn: 'root'
|
|
@@ -922,9 +1287,9 @@ class AXPComponentSlotDirective {
|
|
|
922
1287
|
}
|
|
923
1288
|
// load options
|
|
924
1289
|
if (typeof config.options === 'function') {
|
|
925
|
-
runInInjectionContext(this.injector, () => {
|
|
1290
|
+
await runInInjectionContext(this.injector, async () => {
|
|
926
1291
|
const fun = config.options;
|
|
927
|
-
options = fun();
|
|
1292
|
+
options = await fun();
|
|
928
1293
|
});
|
|
929
1294
|
}
|
|
930
1295
|
else if (config.options) {
|
|
@@ -949,10 +1314,10 @@ class AXPComponentSlotDirective {
|
|
|
949
1314
|
return condition(this.contextStore.data());
|
|
950
1315
|
//return condition(this.context());
|
|
951
1316
|
}
|
|
952
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.
|
|
953
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.1.
|
|
1317
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPComponentSlotDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
1318
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.1.8", type: AXPComponentSlotDirective, isStandalone: false, selector: "axp-component-slot", inputs: { name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: true, transformFunction: null }, host: { classPropertyName: "host", publicName: "host", isSignal: true, isRequired: false, transformFunction: null }, context: { classPropertyName: "context", publicName: "context", isSignal: true, isRequired: false, transformFunction: null } }, exportAs: ["slot"], ngImport: i0 }); }
|
|
954
1319
|
}
|
|
955
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.
|
|
1320
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPComponentSlotDirective, decorators: [{
|
|
956
1321
|
type: Directive,
|
|
957
1322
|
args: [{
|
|
958
1323
|
selector: 'axp-component-slot',
|
|
@@ -1012,11 +1377,11 @@ class AXPComponentSlotModule {
|
|
|
1012
1377
|
f();
|
|
1013
1378
|
});
|
|
1014
1379
|
}
|
|
1015
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.
|
|
1016
|
-
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.1.
|
|
1017
|
-
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.1.
|
|
1380
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPComponentSlotModule, deps: [{ token: 'AXPComponentSlotModuleFactory', optional: true }], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
1381
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.1.8", ngImport: i0, type: AXPComponentSlotModule, declarations: [AXPComponentSlotDirective], exports: [AXPComponentSlotDirective] }); }
|
|
1382
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPComponentSlotModule }); }
|
|
1018
1383
|
}
|
|
1019
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.
|
|
1384
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPComponentSlotModule, decorators: [{
|
|
1020
1385
|
type: NgModule,
|
|
1021
1386
|
args: [{
|
|
1022
1387
|
declarations: [AXPComponentSlotDirective],
|
|
@@ -1029,8 +1394,269 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
|
|
|
1029
1394
|
args: ['AXPComponentSlotModuleFactory']
|
|
1030
1395
|
}] }] });
|
|
1031
1396
|
|
|
1397
|
+
//#endregion
|
|
1398
|
+
class AXPDataSelectorComponent extends AXBasePageComponent {
|
|
1399
|
+
constructor() {
|
|
1400
|
+
super(...arguments);
|
|
1401
|
+
//#region ---- Properties ----
|
|
1402
|
+
this.config = signal({
|
|
1403
|
+
title: '',
|
|
1404
|
+
dataSource: null,
|
|
1405
|
+
columns: [],
|
|
1406
|
+
selectionMode: 'single',
|
|
1407
|
+
searchFields: [],
|
|
1408
|
+
parentField: undefined,
|
|
1409
|
+
allowCreate: false
|
|
1410
|
+
}, ...(ngDevMode ? [{ debugName: "config" }] : []));
|
|
1411
|
+
this.searchTerm = '';
|
|
1412
|
+
this.grid = viewChild('grid', ...(ngDevMode ? [{ debugName: "grid" }] : []));
|
|
1413
|
+
this.initialSelectedItems = [];
|
|
1414
|
+
this.selectedItems = signal([], ...(ngDevMode ? [{ debugName: "selectedItems" }] : []));
|
|
1415
|
+
// Category Filter State
|
|
1416
|
+
this.activeCategoryFilter = signal(null, ...(ngDevMode ? [{ debugName: "activeCategoryFilter" }] : []));
|
|
1417
|
+
//#endregion
|
|
1418
|
+
//#region ---- Computed Properties ----
|
|
1419
|
+
this.allowSelect = computed(() => this.selectedItems().length > 0, ...(ngDevMode ? [{ debugName: "allowSelect" }] : []));
|
|
1420
|
+
this.hasSearch = computed(() => {
|
|
1421
|
+
const searchFields = this.config().searchFields;
|
|
1422
|
+
return searchFields && searchFields.length > 0;
|
|
1423
|
+
}, ...(ngDevMode ? [{ debugName: "hasSearch" }] : []));
|
|
1424
|
+
this.searchPlaceholder = computed(() => {
|
|
1425
|
+
const searchFields = this.config().searchFields;
|
|
1426
|
+
if (!searchFields || searchFields.length === 0) {
|
|
1427
|
+
return 'Search...';
|
|
1428
|
+
}
|
|
1429
|
+
return `Search in ${searchFields.join(', ')}...`;
|
|
1430
|
+
}, ...(ngDevMode ? [{ debugName: "searchPlaceholder" }] : []));
|
|
1431
|
+
// Category Tree Configuration
|
|
1432
|
+
this.categoryTreeConfig = computed(() => ({
|
|
1433
|
+
textField: 'title',
|
|
1434
|
+
valueField: 'id',
|
|
1435
|
+
showCheckbox: false,
|
|
1436
|
+
searchable: true,
|
|
1437
|
+
searchPlaceholder: '@general:terms.interface.category.search.placeholder',
|
|
1438
|
+
emptyStateTitle: '@general:terms.interface.category.search.no-records.title',
|
|
1439
|
+
emptyStateDescription: '@general:terms.interface.category.search.no-records.description',
|
|
1440
|
+
emptyStateIcon: 'fa-light fa-folder-open',
|
|
1441
|
+
}), ...(ngDevMode ? [{ debugName: "categoryTreeConfig" }] : []));
|
|
1442
|
+
// Category Tree Actions (no CRUD in filter mode)
|
|
1443
|
+
this.categoryTreeActions = computed(() => ({
|
|
1444
|
+
canCreate: false,
|
|
1445
|
+
canUpdate: false,
|
|
1446
|
+
canDelete: false,
|
|
1447
|
+
canCreateChild: false,
|
|
1448
|
+
}), ...(ngDevMode ? [{ debugName: "categoryTreeActions" }] : []));
|
|
1449
|
+
}
|
|
1450
|
+
//#endregion
|
|
1451
|
+
//#region ---- Lifecycle Methods ----
|
|
1452
|
+
ngOnInit() {
|
|
1453
|
+
// Set config from data passed by popup service
|
|
1454
|
+
// The config will be automatically set by AXBasePageComponent
|
|
1455
|
+
}
|
|
1456
|
+
ngAfterViewInit() {
|
|
1457
|
+
if (this.initialSelectedItems.length > 0 && this.grid()) {
|
|
1458
|
+
this.grid()?.selectRows(...this.initialSelectedItems);
|
|
1459
|
+
}
|
|
1460
|
+
if (this.searchTerm) {
|
|
1461
|
+
this.applySearchFilter(this.searchTerm);
|
|
1462
|
+
}
|
|
1463
|
+
else {
|
|
1464
|
+
this.applyFilterAndSort();
|
|
1465
|
+
}
|
|
1466
|
+
}
|
|
1467
|
+
//#endregion
|
|
1468
|
+
//#region ---- Event Handlers ----
|
|
1469
|
+
handleRowDbClick(e) {
|
|
1470
|
+
this.close({ items: [e.data] });
|
|
1471
|
+
}
|
|
1472
|
+
handleRowClick(e) {
|
|
1473
|
+
if (this.config().selectionMode === 'multiple') {
|
|
1474
|
+
this.selectedItems.set([...this.selectedItems(), e.data]);
|
|
1475
|
+
}
|
|
1476
|
+
else if (this.selectedItems().length > 0) {
|
|
1477
|
+
const selected = this.selectedItems().find((item) => item.id === e.data.id);
|
|
1478
|
+
if (selected) {
|
|
1479
|
+
this.selectedItems.set(this.selectedItems().filter((item) => item.id !== selected.id));
|
|
1480
|
+
}
|
|
1481
|
+
else {
|
|
1482
|
+
this.selectedItems.set([e.data]);
|
|
1483
|
+
}
|
|
1484
|
+
}
|
|
1485
|
+
else if (this.selectedItems().length === 0) {
|
|
1486
|
+
this.selectedItems.set([e.data]);
|
|
1487
|
+
}
|
|
1488
|
+
else {
|
|
1489
|
+
this.selectedItems.set([e.data]);
|
|
1490
|
+
}
|
|
1491
|
+
}
|
|
1492
|
+
async handleSelectedRowsChange(rows) {
|
|
1493
|
+
this.selectedItems.set(rows);
|
|
1494
|
+
}
|
|
1495
|
+
handleChangeSearchValue(e) {
|
|
1496
|
+
if (e.isUserInteraction) {
|
|
1497
|
+
this.applySearchFilter(e.value);
|
|
1498
|
+
}
|
|
1499
|
+
}
|
|
1500
|
+
async handleCreateNewClick() {
|
|
1501
|
+
this.close();
|
|
1502
|
+
// TODO: Implement create new functionality
|
|
1503
|
+
}
|
|
1504
|
+
handleCloseClick() {
|
|
1505
|
+
this.close();
|
|
1506
|
+
}
|
|
1507
|
+
handleSelectClick() {
|
|
1508
|
+
this.close({ items: this.selectedItems() });
|
|
1509
|
+
}
|
|
1510
|
+
async handleExpandRow(row) {
|
|
1511
|
+
if (this.grid()) {
|
|
1512
|
+
await this.grid().expandRow(row);
|
|
1513
|
+
}
|
|
1514
|
+
}
|
|
1515
|
+
// Category Filter Event Handlers
|
|
1516
|
+
handleCategoryFilterClick(node) {
|
|
1517
|
+
const categoryConfig = this.config().categoryFilter;
|
|
1518
|
+
// Get the filter value from the node
|
|
1519
|
+
const filterValue = node.id;
|
|
1520
|
+
// Store active filter state
|
|
1521
|
+
this.activeCategoryFilter.set({
|
|
1522
|
+
node,
|
|
1523
|
+
filterValue
|
|
1524
|
+
});
|
|
1525
|
+
// Apply filter to main data source
|
|
1526
|
+
this.applyCategoryFilter(filterValue, categoryConfig);
|
|
1527
|
+
}
|
|
1528
|
+
clearCategoryFilter() {
|
|
1529
|
+
this.activeCategoryFilter.set(null);
|
|
1530
|
+
this.config().dataSource.clearFilter();
|
|
1531
|
+
this.config().dataSource.refresh();
|
|
1532
|
+
}
|
|
1533
|
+
//#endregion
|
|
1534
|
+
//#region ---- Private Methods ----
|
|
1535
|
+
applySearchFilter(searchTerm) {
|
|
1536
|
+
const searchFields = this.config().searchFields;
|
|
1537
|
+
if (!searchFields || searchFields.length === 0) {
|
|
1538
|
+
return;
|
|
1539
|
+
}
|
|
1540
|
+
if (isEmpty(searchTerm) || isNil(searchTerm)) {
|
|
1541
|
+
this.config().dataSource.clearFilter();
|
|
1542
|
+
this.config().dataSource.refresh();
|
|
1543
|
+
return;
|
|
1544
|
+
}
|
|
1545
|
+
// Apply search filter to data source
|
|
1546
|
+
// This will be implemented based on the data source type
|
|
1547
|
+
this.config().dataSource.filter({
|
|
1548
|
+
field: 'title',
|
|
1549
|
+
value: searchTerm,
|
|
1550
|
+
operator: { type: 'contains' }
|
|
1551
|
+
});
|
|
1552
|
+
this.config().dataSource.refresh();
|
|
1553
|
+
}
|
|
1554
|
+
applyFilterAndSort() {
|
|
1555
|
+
// Apply any existing filters and sorting
|
|
1556
|
+
}
|
|
1557
|
+
applyCategoryFilter(filterValue, categoryConfig) {
|
|
1558
|
+
if (isNil(filterValue) || filterValue === 'root') {
|
|
1559
|
+
this.config().dataSource.clearFilter();
|
|
1560
|
+
this.config().dataSource.refresh();
|
|
1561
|
+
return;
|
|
1562
|
+
}
|
|
1563
|
+
const filter = {
|
|
1564
|
+
field: null,
|
|
1565
|
+
logic: 'and',
|
|
1566
|
+
operator: null,
|
|
1567
|
+
filters: [{
|
|
1568
|
+
field: categoryConfig.filterField,
|
|
1569
|
+
value: filterValue,
|
|
1570
|
+
operator: { type: 'contains' }
|
|
1571
|
+
}]
|
|
1572
|
+
};
|
|
1573
|
+
// Apply filter to data source (adds to existing filters)
|
|
1574
|
+
this.config().dataSource.filter(filter);
|
|
1575
|
+
this.config().dataSource.refresh();
|
|
1576
|
+
}
|
|
1577
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPDataSelectorComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
1578
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.8", type: AXPDataSelectorComponent, isStandalone: true, selector: "axp-data-selector", viewQueries: [{ propertyName: "grid", first: true, predicate: ["grid"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"axp-data-selector\">\n <!-- Main Content Area -->\n <div class=\"axp-data-selector-content\" [class.with-category-filter]=\"config().categoryFilter?.enabled\">\n <!-- Category Filter Side Panel -->\n @if (config().categoryFilter?.enabled) {\n <div class=\"axp-category-filter-panel\" [style.width]=\"config().categoryFilter?.width || '300px'\">\n <axp-category-tree [dataSource]=\"config().categoryFilter!.dataSource\" [config]=\"categoryTreeConfig()\"\n [actions]=\"categoryTreeActions()\" (nodeClick)=\"handleCategoryFilterClick($event)\">\n </axp-category-tree>\n </div>\n }\n\n <!-- Main Data Area -->\n <div class=\"axp-main-data-area\">\n @if (hasSearch()) {\n <div class=\"ax-w-full ax-mb-2\">\n <ax-search-box [placeholder]=\"searchPlaceholder()\" [value]=\"searchTerm\"\n (onValueChanged)=\"handleChangeSearchValue($event)\" [axAutoFocus]=\"true\">\n <ax-clear-button></ax-clear-button>\n </ax-search-box>\n </div>\n }\n\n <ax-data-table #grid [showFooter]=\"false\" class=\"ax-h-[50vh]\" [paging]=\"true\"\n [loading]=\"{ enabled: true, animation: true }\" [dataSource]=\"config().dataSource\"\n [parentField]=\"config().parentField\" (selectedRowsChange)=\"handleSelectedRowsChange($event)\"\n (onRowClick)=\"handleRowClick($event)\" (onRowDbClick)=\"handleRowDbClick($event)\">\n @if (config().selectionMode === 'multiple') {\n <ax-select-column fixed=\"start\" [width]=\"'50px'\"></ax-select-column>\n }\n\n @for (col of config().columns; track col.name) {\n @if (col.visible) {\n <axp-widget-column-renderer [expandHandler]=\"$index === 0 && config().parentField ? true : false\"\n [caption]=\"col.title | translate | async\" [node]=\"{\n path: col.name,\n type: col.widget.type,\n options: col.widget.options,\n }\">\n </axp-widget-column-renderer>\n }\n }\n </ax-data-table>\n </div>\n </div>\n</div>\n\n<ax-footer>\n <ax-suffix>\n <ax-button look=\"solid\" [text]=\"('@general:actions.close.title' | translate | async)!\"\n (onClick)=\"handleCloseClick()\">\n </ax-button>\n <ax-button look=\"solid\" color=\"primary\" [text]=\"('@general:actions.select.title' | translate | async)!\"\n (onClick)=\"handleSelectClick()\" [disabled]=\"allowSelect() === false\">\n </ax-button>\n <!-- @if (config().allowCreate) {\n <ax-button\n look=\"solid\"\n color=\"primary\"\n [text]=\"'@general:actions.create.title' | translate | async\"\n (onClick)=\"handleCreateNewClick()\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-solid fa-add\"></ax-icon>\n </ax-prefix>\n </ax-button>\n } -->\n </ax-suffix>\n</ax-footer>", styles: [":host{display:block;height:100%}.ax-expand-handler{cursor:pointer;display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;margin-right:8px}.ax-expand-handler:hover{opacity:.8}.ax-expand-handler.ax-invisible{visibility:hidden}.ax-h-\\[50vh\\]{height:50vh}.ax-overflow-hidden{overflow:hidden}.ax-flex{display:flex}.ax-flex-col{flex-direction:column}.ax-gap-4{gap:1rem}.ax-p-4{padding:1rem}.ax-w-full{width:100%}.axp-data-selector{display:flex;flex-direction:column;height:100%;overflow:hidden}.axp-data-selector-header{display:flex;justify-content:space-between;align-items:center;padding:1rem;border-bottom:1px solid var(--border-color);background:var(--surface-color);flex-shrink:0}.axp-data-selector-header h3{margin:0;font-size:1.25rem;font-weight:600;color:var(--text-color)}.axp-data-selector-content{display:flex;flex:1;overflow:hidden}.axp-data-selector-content.with-category-filter .axp-main-data-area{flex:1;overflow:hidden}.axp-data-selector .axp-category-filter-panel{border-right:1px solid var(--border-color);padding:1rem;overflow-y:auto;background:var(--surface-color);flex-shrink:0}.axp-data-selector .axp-main-data-area{flex:1;overflow:hidden;padding:1rem;display:flex;flex-direction:column;gap:1rem}.axp-data-selector .axp-main-data-area .ax-data-table{flex:1;min-height:0}.axp-data-selector .axp-main-data-area .ax-search-box{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXCommonModule }, { kind: "directive", type: i1$2.AXAutoFocusDirective, selector: "[axAutoFocus]", inputs: ["axAutoFocus", "axAutoFocusTime"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i3.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXFormModule }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorClearButtonComponent, selector: "ax-clear-button", inputs: ["icon"] }, { kind: "component", type: i2$1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXDropdownButtonModule }, { kind: "ngmodule", type: AXDataTableModule }, { kind: "component", type: i4$2.AXDataTableComponent, selector: "ax-data-table", inputs: ["dataSource", "selectedRows", "parentField", "rowTemplate", "emptyTemplate", "noDataTemplate", "alternative", "showHeader", "fixedHeader", "showFooter", "fixedFooter", "itemHeight", "allowReordering", "paging", "fetchDataMode", "loading", "focusedRow"], outputs: ["selectedRowsChange", "focusedRowChange", "onRowClick", "onRowDbClick", "onColumnsOrderChanged", "onColumnSizeChanged", "onPageChanged"] }, { kind: "component", type: i4$2.AXRowSelectColumnComponent, selector: "ax-select-column", inputs: ["width", "caption", "fixed"] }, { kind: "ngmodule", type: AXSearchBoxModule }, { kind: "component", type: i4$1.AXSearchBoxComponent, selector: "ax-search-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "value", "state", "name", "id", "look", "class", "delayTime", "type"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "ngmodule", type: AXPLayoutBuilderModule }, { kind: "component", type: i3$3.AXPWidgetColumnRendererComponent, selector: "axp-widget-column-renderer", inputs: ["caption", "customExpandIcon", "customCollapseIcon", "customWidth", "node", "footerTemplate", "expandHandler", "cellTemplate", "headerTemplate"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "component", type: AXPCategoryTreeComponent, selector: "axp-category-tree", inputs: ["dataSource", "config", "actions", "events"], outputs: ["nodeClick", "nodeSelect", "nodeCreate", "nodeUpdate", "nodeDelete", "searchChange", "collapseChange"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
1579
|
+
}
|
|
1580
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPDataSelectorComponent, decorators: [{
|
|
1581
|
+
type: Component,
|
|
1582
|
+
args: [{ selector: 'axp-data-selector', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
1583
|
+
CommonModule,
|
|
1584
|
+
AXCommonModule,
|
|
1585
|
+
AXButtonModule,
|
|
1586
|
+
AXFormModule,
|
|
1587
|
+
AXDecoratorModule,
|
|
1588
|
+
AXDropdownButtonModule,
|
|
1589
|
+
AXDataTableModule,
|
|
1590
|
+
AXSearchBoxModule,
|
|
1591
|
+
AXPLayoutBuilderModule,
|
|
1592
|
+
AXTranslationModule,
|
|
1593
|
+
AXBadgeModule,
|
|
1594
|
+
AXPCategoryTreeComponent,
|
|
1595
|
+
], inputs: [], template: "<div class=\"axp-data-selector\">\n <!-- Main Content Area -->\n <div class=\"axp-data-selector-content\" [class.with-category-filter]=\"config().categoryFilter?.enabled\">\n <!-- Category Filter Side Panel -->\n @if (config().categoryFilter?.enabled) {\n <div class=\"axp-category-filter-panel\" [style.width]=\"config().categoryFilter?.width || '300px'\">\n <axp-category-tree [dataSource]=\"config().categoryFilter!.dataSource\" [config]=\"categoryTreeConfig()\"\n [actions]=\"categoryTreeActions()\" (nodeClick)=\"handleCategoryFilterClick($event)\">\n </axp-category-tree>\n </div>\n }\n\n <!-- Main Data Area -->\n <div class=\"axp-main-data-area\">\n @if (hasSearch()) {\n <div class=\"ax-w-full ax-mb-2\">\n <ax-search-box [placeholder]=\"searchPlaceholder()\" [value]=\"searchTerm\"\n (onValueChanged)=\"handleChangeSearchValue($event)\" [axAutoFocus]=\"true\">\n <ax-clear-button></ax-clear-button>\n </ax-search-box>\n </div>\n }\n\n <ax-data-table #grid [showFooter]=\"false\" class=\"ax-h-[50vh]\" [paging]=\"true\"\n [loading]=\"{ enabled: true, animation: true }\" [dataSource]=\"config().dataSource\"\n [parentField]=\"config().parentField\" (selectedRowsChange)=\"handleSelectedRowsChange($event)\"\n (onRowClick)=\"handleRowClick($event)\" (onRowDbClick)=\"handleRowDbClick($event)\">\n @if (config().selectionMode === 'multiple') {\n <ax-select-column fixed=\"start\" [width]=\"'50px'\"></ax-select-column>\n }\n\n @for (col of config().columns; track col.name) {\n @if (col.visible) {\n <axp-widget-column-renderer [expandHandler]=\"$index === 0 && config().parentField ? true : false\"\n [caption]=\"col.title | translate | async\" [node]=\"{\n path: col.name,\n type: col.widget.type,\n options: col.widget.options,\n }\">\n </axp-widget-column-renderer>\n }\n }\n </ax-data-table>\n </div>\n </div>\n</div>\n\n<ax-footer>\n <ax-suffix>\n <ax-button look=\"solid\" [text]=\"('@general:actions.close.title' | translate | async)!\"\n (onClick)=\"handleCloseClick()\">\n </ax-button>\n <ax-button look=\"solid\" color=\"primary\" [text]=\"('@general:actions.select.title' | translate | async)!\"\n (onClick)=\"handleSelectClick()\" [disabled]=\"allowSelect() === false\">\n </ax-button>\n <!-- @if (config().allowCreate) {\n <ax-button\n look=\"solid\"\n color=\"primary\"\n [text]=\"'@general:actions.create.title' | translate | async\"\n (onClick)=\"handleCreateNewClick()\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-solid fa-add\"></ax-icon>\n </ax-prefix>\n </ax-button>\n } -->\n </ax-suffix>\n</ax-footer>", styles: [":host{display:block;height:100%}.ax-expand-handler{cursor:pointer;display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;margin-right:8px}.ax-expand-handler:hover{opacity:.8}.ax-expand-handler.ax-invisible{visibility:hidden}.ax-h-\\[50vh\\]{height:50vh}.ax-overflow-hidden{overflow:hidden}.ax-flex{display:flex}.ax-flex-col{flex-direction:column}.ax-gap-4{gap:1rem}.ax-p-4{padding:1rem}.ax-w-full{width:100%}.axp-data-selector{display:flex;flex-direction:column;height:100%;overflow:hidden}.axp-data-selector-header{display:flex;justify-content:space-between;align-items:center;padding:1rem;border-bottom:1px solid var(--border-color);background:var(--surface-color);flex-shrink:0}.axp-data-selector-header h3{margin:0;font-size:1.25rem;font-weight:600;color:var(--text-color)}.axp-data-selector-content{display:flex;flex:1;overflow:hidden}.axp-data-selector-content.with-category-filter .axp-main-data-area{flex:1;overflow:hidden}.axp-data-selector .axp-category-filter-panel{border-right:1px solid var(--border-color);padding:1rem;overflow-y:auto;background:var(--surface-color);flex-shrink:0}.axp-data-selector .axp-main-data-area{flex:1;overflow:hidden;padding:1rem;display:flex;flex-direction:column;gap:1rem}.axp-data-selector .axp-main-data-area .ax-data-table{flex:1;min-height:0}.axp-data-selector .axp-main-data-area .ax-search-box{width:100%}\n"] }]
|
|
1596
|
+
}] });
|
|
1597
|
+
|
|
1598
|
+
var dataSelector_component = /*#__PURE__*/Object.freeze({
|
|
1599
|
+
__proto__: null,
|
|
1600
|
+
AXPDataSelectorComponent: AXPDataSelectorComponent
|
|
1601
|
+
});
|
|
1602
|
+
|
|
1603
|
+
class AXPDataSelectorService {
|
|
1604
|
+
constructor() {
|
|
1605
|
+
//#region ---- Services & Dependencies ----
|
|
1606
|
+
this.popupService = inject(AXPopupService);
|
|
1607
|
+
}
|
|
1608
|
+
//#endregion
|
|
1609
|
+
//#region ---- Public Methods ----
|
|
1610
|
+
/**
|
|
1611
|
+
* Open data selector popup
|
|
1612
|
+
*/
|
|
1613
|
+
async open(config) {
|
|
1614
|
+
const component = await Promise.resolve().then(function () { return dataSelector_component; }).then(c => c.AXPDataSelectorComponent);
|
|
1615
|
+
const result = await this.popupService.open(component, {
|
|
1616
|
+
title: config.title,
|
|
1617
|
+
size: config.categoryFilter?.enabled ?
|
|
1618
|
+
'lg'
|
|
1619
|
+
: (config.columns.length > 3 ? 'lg' : 'md'),
|
|
1620
|
+
data: {
|
|
1621
|
+
config: signal(config)
|
|
1622
|
+
}
|
|
1623
|
+
});
|
|
1624
|
+
return result.data || null;
|
|
1625
|
+
}
|
|
1626
|
+
/**
|
|
1627
|
+
* Open data selector with category filter
|
|
1628
|
+
*/
|
|
1629
|
+
async openWithCategoryFilter(config, categoryFilterConfig) {
|
|
1630
|
+
const enhancedConfig = {
|
|
1631
|
+
...config,
|
|
1632
|
+
categoryFilter: {
|
|
1633
|
+
enabled: true,
|
|
1634
|
+
...categoryFilterConfig
|
|
1635
|
+
}
|
|
1636
|
+
};
|
|
1637
|
+
return this.open(enhancedConfig);
|
|
1638
|
+
}
|
|
1639
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPDataSelectorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1640
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPDataSelectorService, providedIn: 'root' }); }
|
|
1641
|
+
}
|
|
1642
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPDataSelectorService, decorators: [{
|
|
1643
|
+
type: Injectable,
|
|
1644
|
+
args: [{
|
|
1645
|
+
providedIn: 'root'
|
|
1646
|
+
}]
|
|
1647
|
+
}] });
|
|
1648
|
+
|
|
1032
1649
|
class AXPDynamicFormComponent {
|
|
1033
1650
|
constructor() {
|
|
1651
|
+
this.evaluatorService = inject(AXPExpressionEvaluatorService);
|
|
1652
|
+
/**
|
|
1653
|
+
* Tracks the latest scheduled evaluation to ensure last-write-wins for async evaluate
|
|
1654
|
+
*/
|
|
1655
|
+
this.evaluationRunId = 0;
|
|
1656
|
+
/**
|
|
1657
|
+
* Memoization cache for resolveParamLayout to keep stable object identities
|
|
1658
|
+
*/
|
|
1659
|
+
this.layoutCache = new Map();
|
|
1034
1660
|
//#region ---- Inputs ----
|
|
1035
1661
|
/**
|
|
1036
1662
|
* Form definition containing groups and fields
|
|
@@ -1041,9 +1667,17 @@ class AXPDynamicFormComponent {
|
|
|
1041
1667
|
*/
|
|
1042
1668
|
this.context = input.required(...(ngDevMode ? [{ debugName: "context" }] : []));
|
|
1043
1669
|
/**
|
|
1044
|
-
*
|
|
1670
|
+
* Form appearance and density styling (normal, compact, spacious)
|
|
1671
|
+
*/
|
|
1672
|
+
this.layoutLook = input('normal', ...(ngDevMode ? [{ debugName: "layoutLook" }] : []));
|
|
1673
|
+
/**
|
|
1674
|
+
* Form layout direction and flow (vertical, horizontal, grid)
|
|
1675
|
+
*/
|
|
1676
|
+
this.layoutDirection = input('vertical', ...(ngDevMode ? [{ debugName: "layoutDirection" }] : []));
|
|
1677
|
+
/**
|
|
1678
|
+
* Default form mode. Can be overridden by section/group and field.
|
|
1045
1679
|
*/
|
|
1046
|
-
this.
|
|
1680
|
+
this.mode = input('edit', ...(ngDevMode ? [{ debugName: "mode" }] : []));
|
|
1047
1681
|
/**
|
|
1048
1682
|
* Custom layout configuration for form fields
|
|
1049
1683
|
*/
|
|
@@ -1056,6 +1690,26 @@ class AXPDynamicFormComponent {
|
|
|
1056
1690
|
xxl: { colSpan: 4 },
|
|
1057
1691
|
},
|
|
1058
1692
|
}, ...(ngDevMode ? [{ debugName: "layoutConfig" }] : []));
|
|
1693
|
+
this.evaluatedFormDefinition = signal(null, ...(ngDevMode ? [{ debugName: "evaluatedFormDefinition" }] : []));
|
|
1694
|
+
/**
|
|
1695
|
+
* Evaluate definition when inputs change with last-write-wins and deep-equality guard
|
|
1696
|
+
*/
|
|
1697
|
+
this.eff = effect(() => {
|
|
1698
|
+
const formDef = this.formDefinition();
|
|
1699
|
+
const ctx = this.context();
|
|
1700
|
+
const runId = ++this.evaluationRunId;
|
|
1701
|
+
(async () => {
|
|
1702
|
+
const evaluated = await this.expressionEvaluator(formDef, ctx);
|
|
1703
|
+
// Ignore stale results
|
|
1704
|
+
if (runId !== this.evaluationRunId) {
|
|
1705
|
+
return;
|
|
1706
|
+
}
|
|
1707
|
+
const prev = this.evaluatedFormDefinition();
|
|
1708
|
+
if (!isEqual(prev, evaluated)) {
|
|
1709
|
+
this.evaluatedFormDefinition.set(evaluated);
|
|
1710
|
+
}
|
|
1711
|
+
})();
|
|
1712
|
+
}, ...(ngDevMode ? [{ debugName: "eff" }] : []));
|
|
1059
1713
|
//#endregion
|
|
1060
1714
|
//#region ---- Outputs ----
|
|
1061
1715
|
/**
|
|
@@ -1085,17 +1739,31 @@ class AXPDynamicFormComponent {
|
|
|
1085
1739
|
*/
|
|
1086
1740
|
this.computedLayout = computed(() => this.layoutConfig(), ...(ngDevMode ? [{ debugName: "computedLayout" }] : []));
|
|
1087
1741
|
/**
|
|
1088
|
-
*
|
|
1742
|
+
* Resolve effective mode with precedence: field > group > form
|
|
1089
1743
|
*/
|
|
1090
|
-
this.
|
|
1744
|
+
this.resolveParamMode = (group, param) => {
|
|
1745
|
+
const fieldMode = param?.mode;
|
|
1746
|
+
const groupMode = group?.mode;
|
|
1747
|
+
const formMode = this.mode();
|
|
1748
|
+
console.log(fieldMode, groupMode, formMode);
|
|
1749
|
+
return (fieldMode || groupMode || formMode || 'edit');
|
|
1750
|
+
};
|
|
1091
1751
|
/**
|
|
1092
|
-
* Host classes based on layout
|
|
1752
|
+
* Host classes based on layout look and direction
|
|
1093
1753
|
*/
|
|
1094
1754
|
this.hostClasses = computed(() => {
|
|
1095
1755
|
const classes = ['axp-dynamic-form'];
|
|
1096
|
-
const
|
|
1097
|
-
|
|
1098
|
-
|
|
1756
|
+
const look = this.layoutLook();
|
|
1757
|
+
const direction = this.layoutDirection();
|
|
1758
|
+
const mode = this.mode();
|
|
1759
|
+
if (look && look !== 'normal') {
|
|
1760
|
+
classes.push(`--look-${look}`);
|
|
1761
|
+
}
|
|
1762
|
+
if (direction && direction !== 'vertical') {
|
|
1763
|
+
classes.push(`--direction-${direction}`);
|
|
1764
|
+
}
|
|
1765
|
+
if (mode && mode !== 'edit') {
|
|
1766
|
+
classes.push(`--mode-${mode}`);
|
|
1099
1767
|
}
|
|
1100
1768
|
return classes.join(' ');
|
|
1101
1769
|
}, ...(ngDevMode ? [{ debugName: "hostClasses" }] : []));
|
|
@@ -1105,8 +1773,11 @@ class AXPDynamicFormComponent {
|
|
|
1105
1773
|
* Effect to sync context changes
|
|
1106
1774
|
*/
|
|
1107
1775
|
this.#contextSyncEffect = effect(() => {
|
|
1108
|
-
const
|
|
1109
|
-
this.internalContext
|
|
1776
|
+
const ctx = this.context() ?? {};
|
|
1777
|
+
const prev = this.internalContext() ?? {};
|
|
1778
|
+
if (!isEqual(prev, ctx)) {
|
|
1779
|
+
this.internalContext.set(ctx);
|
|
1780
|
+
}
|
|
1110
1781
|
}, ...(ngDevMode ? [{ debugName: "#contextSyncEffect" }] : []));
|
|
1111
1782
|
/**
|
|
1112
1783
|
* Effect to handle form status changes
|
|
@@ -1118,12 +1789,90 @@ class AXPDynamicFormComponent {
|
|
|
1118
1789
|
this.container()?.builderService.setStatus(AXPPageStatus.Rendered);
|
|
1119
1790
|
}
|
|
1120
1791
|
}, ...(ngDevMode ? [{ debugName: "#formStatusEffect" }] : []));
|
|
1792
|
+
/**
|
|
1793
|
+
* Invalidate memoization cache when layout config or evaluated definition changes
|
|
1794
|
+
*/
|
|
1795
|
+
this.#layoutCacheInvalidationEffect = effect(() => {
|
|
1796
|
+
// Depend on layout config and evaluated definition identity
|
|
1797
|
+
// Any structural change should flush the cache to ensure correctness
|
|
1798
|
+
const _layout = this.layoutConfig();
|
|
1799
|
+
const _evaluated = this.evaluatedFormDefinition();
|
|
1800
|
+
// Simple invalidation: clear cache when either changes
|
|
1801
|
+
this.layoutCache.clear();
|
|
1802
|
+
}, ...(ngDevMode ? [{ debugName: "#layoutCacheInvalidationEffect" }] : []));
|
|
1803
|
+
}
|
|
1804
|
+
//#endregion
|
|
1805
|
+
//#region ---- Evaluator ----
|
|
1806
|
+
async expressionEvaluator(expression, context) {
|
|
1807
|
+
const scope = {
|
|
1808
|
+
context: {
|
|
1809
|
+
eval: (path) => get(context, path),
|
|
1810
|
+
},
|
|
1811
|
+
};
|
|
1812
|
+
return await this.evaluatorService.evaluate(expression, scope);
|
|
1813
|
+
}
|
|
1814
|
+
/**
|
|
1815
|
+
* Resolve effective grid layout for a specific parameter, merging per-parameter override with form layout.
|
|
1816
|
+
*/
|
|
1817
|
+
resolveParamLayout(param) {
|
|
1818
|
+
const base = this.layoutConfig();
|
|
1819
|
+
const override = param.layout;
|
|
1820
|
+
// Build a signature to memoize per param + current base layout snapshot + override
|
|
1821
|
+
const signature = JSON.stringify({
|
|
1822
|
+
path: param?.path,
|
|
1823
|
+
base,
|
|
1824
|
+
override,
|
|
1825
|
+
});
|
|
1826
|
+
const cacheKey = param?.path ?? JSON.stringify(param);
|
|
1827
|
+
const cached = this.layoutCache.get(cacheKey);
|
|
1828
|
+
if (cached && cached.signature === signature) {
|
|
1829
|
+
return cached.config;
|
|
1830
|
+
}
|
|
1831
|
+
if (override == null) {
|
|
1832
|
+
this.layoutCache.set(cacheKey, { signature, config: base });
|
|
1833
|
+
return base;
|
|
1834
|
+
}
|
|
1835
|
+
const normalize = (value, fallback) => typeof value === 'number' && value > 0 ? value : fallback;
|
|
1836
|
+
const toConfig = (o) => {
|
|
1837
|
+
if (typeof o === 'number') {
|
|
1838
|
+
const cfg = {
|
|
1839
|
+
positions: {
|
|
1840
|
+
default: { colSpan: o },
|
|
1841
|
+
md: { colSpan: o },
|
|
1842
|
+
lg: { colSpan: o },
|
|
1843
|
+
xl: { colSpan: o },
|
|
1844
|
+
xxl: { colSpan: o },
|
|
1845
|
+
},
|
|
1846
|
+
};
|
|
1847
|
+
return cfg;
|
|
1848
|
+
}
|
|
1849
|
+
// When parameter layout object is provided, do NOT fall back to form layout.
|
|
1850
|
+
// Use cascading values across breakpoints: default -> md -> lg -> xl -> xxl.
|
|
1851
|
+
const d = normalize(o.default, 12);
|
|
1852
|
+
const md = normalize(o.md, d);
|
|
1853
|
+
const lg = normalize(o.lg, md);
|
|
1854
|
+
const xl = normalize(o.xl, lg);
|
|
1855
|
+
const xxl = normalize(o.xxl, xl);
|
|
1856
|
+
const cfg = {
|
|
1857
|
+
positions: {
|
|
1858
|
+
default: { colSpan: d },
|
|
1859
|
+
md: { colSpan: md },
|
|
1860
|
+
lg: { colSpan: lg },
|
|
1861
|
+
xl: { colSpan: xl },
|
|
1862
|
+
xxl: { colSpan: xxl },
|
|
1863
|
+
},
|
|
1864
|
+
};
|
|
1865
|
+
return cfg;
|
|
1866
|
+
};
|
|
1867
|
+
const result = toConfig(override);
|
|
1868
|
+
this.layoutCache.set(cacheKey, { signature, config: result });
|
|
1869
|
+
return result;
|
|
1121
1870
|
}
|
|
1122
1871
|
//#endregion
|
|
1123
1872
|
//#region ---- Lifecycle Methods ----
|
|
1124
1873
|
ngOnInit() {
|
|
1125
1874
|
// Initialize internal context with input context
|
|
1126
|
-
this.internalContext.set(this.context());
|
|
1875
|
+
this.internalContext.set(this.context() ?? {});
|
|
1127
1876
|
}
|
|
1128
1877
|
//#endregion
|
|
1129
1878
|
//#region ---- Effects ----
|
|
@@ -1135,6 +1884,10 @@ class AXPDynamicFormComponent {
|
|
|
1135
1884
|
* Effect to handle form status changes
|
|
1136
1885
|
*/
|
|
1137
1886
|
#formStatusEffect;
|
|
1887
|
+
/**
|
|
1888
|
+
* Invalidate memoization cache when layout config or evaluated definition changes
|
|
1889
|
+
*/
|
|
1890
|
+
#layoutCacheInvalidationEffect;
|
|
1138
1891
|
//#endregion
|
|
1139
1892
|
//#region ---- Event Handlers ----
|
|
1140
1893
|
/**
|
|
@@ -1145,9 +1898,20 @@ class AXPDynamicFormComponent {
|
|
|
1145
1898
|
this.contextInitiated.emit(event.data);
|
|
1146
1899
|
}
|
|
1147
1900
|
else {
|
|
1148
|
-
this.internalContext.set(event.data);
|
|
1149
|
-
this.contextChange.emit(
|
|
1901
|
+
this.internalContext.set(event.data ?? {});
|
|
1902
|
+
this.contextChange.emit(this.internalContext());
|
|
1903
|
+
}
|
|
1904
|
+
}
|
|
1905
|
+
isRequired(param) {
|
|
1906
|
+
const validations = param.widget?.options?.['validations'];
|
|
1907
|
+
if (Array.isArray(validations)) {
|
|
1908
|
+
return validations.some((v) => v?.rule === 'required');
|
|
1909
|
+
}
|
|
1910
|
+
if (validations && typeof validations === 'object') {
|
|
1911
|
+
// Support object-shaped validations like { required: true }
|
|
1912
|
+
return Boolean(validations['required']);
|
|
1150
1913
|
}
|
|
1914
|
+
return false;
|
|
1151
1915
|
}
|
|
1152
1916
|
//#endregion
|
|
1153
1917
|
//#region ---- Public Methods ----
|
|
@@ -1181,14 +1945,14 @@ class AXPDynamicFormComponent {
|
|
|
1181
1945
|
}
|
|
1182
1946
|
return false;
|
|
1183
1947
|
}
|
|
1184
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.
|
|
1185
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", type: AXPDynamicFormComponent, isStandalone: true, selector: "axp-dynamic-form", inputs: { formDefinition: { classPropertyName: "formDefinition", publicName: "formDefinition", isSignal: true, isRequired: true, transformFunction: null }, context: { classPropertyName: "context", publicName: "context", isSignal: true, isRequired: true, transformFunction: null }, layoutStyle: { classPropertyName: "layoutStyle", publicName: "layoutStyle", isSignal: true, isRequired: false, transformFunction: null }, layoutConfig: { classPropertyName: "layoutConfig", publicName: "layoutConfig", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { contextChange: "contextChange", contextInitiated: "contextInitiated", validityChange: "validityChange" }, host: { properties: { "class": "hostClasses()" }, classAttribute: "axp-dynamic-form" }, viewQueries: [{ propertyName: "form", first: true, predicate: AXFormComponent, descendants: true, isSignal: true }, { propertyName: "container", first: true, predicate: AXPWidgetContainerComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<ax-form>\n <axp-widgets-container [context]=\"internalContext()\" (onContextChanged)=\"handleContextChanged($event)\">\n <axp-layout-sections>\n @if (computedFormDefinition()) {\n @for (group of computedFormDefinition().groups; track group.name) {\n <axp-layout-section>\n <axp-layout-header>\n <axp-layout-title>{{ group.title }}</axp-layout-title>\n @if (group.description) {\n <axp-layout-description>{{ group.description }}</axp-layout-description>\n }\n </axp-layout-header>\n <axp-layout-content>\n @for (param of group.parameters; track param.path) {\n <div class=\"__field-container\">\n <ax-form-field class=\"__field-input\" [gridLayout]=\"computedLayout()\">\n <ax-label>{{ param.title }}</ax-label>\n <ng-container axp-widget-renderer [node]=\"param.widget\" [mode]=\"'edit'\"></ng-container>\n <!-- @if (param.description) {\n <axp-layout-description>{{ param.description }}</axp-layout-description>\n } -->\n </ax-form-field>\n </div>\n }\n </axp-layout-content>\n </axp-layout-section>\n }\n } @else {\n <axp-layout-section>\n <axp-layout-content>\n <div class=\"__empty-state\">\n <axp-layout-description>No form definition provided</axp-layout-description>\n </div>\n </axp-layout-content>\n </axp-layout-section>\n }\n </axp-layout-sections>\n </axp-widgets-container>\n</ax-form>\n", styles: [".axp-dynamic-form{width:100%}.axp-dynamic-form axp-layout-section axp-layout-content{display:flex;width:100%;flex-direction:column}.axp-dynamic-form axp-layout-section axp-layout-content>:not([hidden])~:not([hidden]){--tw-divide-y-reverse: 0;border-top-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px * var(--tw-divide-y-reverse));border-style:dashed;--tw-divide-opacity: 1;border-color:rgba(var(--ax-sys-color-border-lightest-surface),var(--tw-divide-opacity, 1))}.axp-dynamic-form axp-layout-section axp-layout-content .__field-container{align-items:center;gap:1rem;padding:1rem}@media (min-width: 1024px){.axp-dynamic-form axp-layout-section axp-layout-content .__field-container{padding-left:1.5rem;padding-right:1.5rem}}@media (min-width: 1280px){.axp-dynamic-form axp-layout-section axp-layout-content .__field-container{padding-left:2rem;padding-right:2rem}}@media (min-width: 1536px){.axp-dynamic-form axp-layout-section axp-layout-content .__field-container{padding-left:2.5rem;padding-right:2.5rem}}.axp-dynamic-form axp-layout-section axp-layout-content .__field-container{display:grid;grid-template-columns:repeat(12,minmax(0,1fr))}.axp-dynamic-form axp-layout-section axp-layout-content .__field-container .__field-info{grid-column:span 12 / span 12}@media (min-width: 768px){.axp-dynamic-form axp-layout-section axp-layout-content .__field-container .__field-info{grid-column:span 4 / span 4}}@media (min-width: 1024px){.axp-dynamic-form axp-layout-section axp-layout-content .__field-container .__field-info{grid-column:span 4 / span 4}}@media (min-width: 1536px){.axp-dynamic-form axp-layout-section axp-layout-content .__field-container .__field-info{grid-column:span 3 / span 3}}.axp-dynamic-form axp-layout-section axp-layout-content .__field-container axp-layout-description{margin-top:.5rem!important;font-size:.75rem!important;line-height:1rem!important}.axp-dynamic-form.--compact axp-layout-section axp-layout-content>:not([hidden])~:not([hidden]){border-style:none}.axp-dynamic-form.--compact axp-layout-section axp-layout-content .__field-container{display:flex;flex-direction:column;gap:.25rem;padding:.25rem .5rem;margin-bottom:.5rem;border-width:0px}.axp-dynamic-form.--compact axp-layout-section axp-layout-content .__field-container .__field-info{margin-bottom:.125rem;width:100%}.axp-dynamic-form.--compact axp-layout-section axp-layout-content .__field-container .__field-info axp-layout-title{font-size:.875rem;line-height:1.25rem;font-weight:500}.axp-dynamic-form.--compact axp-layout-section axp-layout-content .__field-container .__field-input{width:100%}.axp-dynamic-form.--compact axp-layout-section axp-layout-content .__field-container axp-layout-description{margin-top:.125rem!important;font-size:.75rem!important;line-height:1rem!important;opacity:.75!important}.axp-dynamic-form.--compact axp-layout-section{margin-bottom:.75rem}.axp-dynamic-form.--compact axp-layout-section axp-layout-header{margin-bottom:.5rem;gap:0px;padding:.5rem}.axp-dynamic-form.--compact axp-layout-section axp-layout-header axp-layout-title{font-size:1rem;line-height:1.5rem;font-weight:600}.axp-dynamic-form.--compact axp-layout-section axp-layout-header axp-layout-description{margin-top:.25rem;font-size:.75rem;line-height:1rem;opacity:.75}.axp-dynamic-form.--vertical axp-layout-section axp-layout-content .__field-container{display:flex;flex-direction:column;align-items:flex-start;gap:.75rem}.axp-dynamic-form.--vertical axp-layout-section axp-layout-content .__field-container .__field-info{grid-column:span 12 / span 12;width:100%}.axp-dynamic-form.--vertical axp-layout-section axp-layout-content .__field-container .__field-input{grid-column:span 12 / span 12;width:100%}.axp-dynamic-form.--vertical axp-layout-section axp-layout-content .__field-container axp-layout-description{margin-top:.25rem!important;font-size:.875rem!important;line-height:1.25rem!important}.axp-dynamic-form.--horizontal axp-layout-section axp-layout-content>:not([hidden])~:not([hidden]){border-style:none}.axp-dynamic-form.--horizontal axp-layout-section axp-layout-content .__field-container{display:flex;flex-direction:row;align-items:center;gap:1rem;padding-top:.75rem;padding-bottom:.75rem}.axp-dynamic-form.--horizontal axp-layout-section axp-layout-content .__field-container .__field-info{width:12rem;flex-shrink:0}.axp-dynamic-form.--horizontal axp-layout-section axp-layout-content .__field-container .__field-info axp-layout-title{margin-bottom:.25rem;font-size:.875rem;line-height:1.25rem;font-weight:500}.axp-dynamic-form.--horizontal axp-layout-section axp-layout-content .__field-container .__field-input{flex:1 1 0%}.axp-dynamic-form.--horizontal axp-layout-section axp-layout-content .__field-container axp-layout-description{margin-top:.25rem!important;font-size:.75rem!important;line-height:1rem!important;opacity:.75!important}.axp-dynamic-form .__empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding-top:2rem;padding-bottom:2rem;text-align:center}.axp-dynamic-form .__empty-state .__message{font-size:.875rem;line-height:1.25rem;--tw-text-opacity: 1;color:rgb(107 114 128 / var(--tw-text-opacity, 1))}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type:
|
|
1948
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPDynamicFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1949
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.8", type: AXPDynamicFormComponent, isStandalone: true, selector: "axp-dynamic-form", inputs: { formDefinition: { classPropertyName: "formDefinition", publicName: "formDefinition", isSignal: true, isRequired: true, transformFunction: null }, context: { classPropertyName: "context", publicName: "context", isSignal: true, isRequired: true, transformFunction: null }, layoutLook: { classPropertyName: "layoutLook", publicName: "layoutLook", isSignal: true, isRequired: false, transformFunction: null }, layoutDirection: { classPropertyName: "layoutDirection", publicName: "layoutDirection", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, layoutConfig: { classPropertyName: "layoutConfig", publicName: "layoutConfig", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { contextChange: "contextChange", contextInitiated: "contextInitiated", validityChange: "validityChange" }, host: { properties: { "class": "hostClasses()" }, classAttribute: "axp-dynamic-form" }, viewQueries: [{ propertyName: "form", first: true, predicate: AXFormComponent, descendants: true, isSignal: true }, { propertyName: "container", first: true, predicate: AXPWidgetContainerComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<ax-form>\n <axp-widgets-container [context]=\"internalContext()\" (onContextChanged)=\"handleContextChanged($event)\">\n <axp-layout-sections>\n @for (group of evaluatedFormDefinition()?.groups; track group.name) {\n <axp-layout-section>\n @if (group.title || group.description) {\n <axp-layout-header>\n <axp-layout-title>{{ group.title! | translate | async }}</axp-layout-title>\n @if (group.description) {\n <axp-layout-description>{{ group.description! | translate | async }}</axp-layout-description>\n }\n </axp-layout-header>\n }\n <axp-layout-content>\n @if (layoutDirection() === 'grid') {\n <div class=\"__field-container\">\n @for (param of group.parameters; track param.path) {\n @if (param.widget.options?.['hidden'] !== true) {\n <ax-form-field class=\"__field-input\" [gridLayout]=\"resolveParamLayout(param)\">\n <ax-label [required]=\"isRequired(param)\">{{ param.title! | translate | async }}</ax-label>\n <ng-container\n axp-widget-renderer\n [node]=\"param.widget\"\n [mode]=\"resolveParamMode(group, param)\"\n ></ng-container>\n @if (param.description) {\n <axp-layout-description>{{ param.description! | translate | async }}</axp-layout-description>\n }\n </ax-form-field>\n }\n }\n </div>\n } @else {\n @for (param of group.parameters; track param.path) {\n @if (param.widget.options?.['hidden'] !== true) {\n <div class=\"__field-container\">\n <ax-form-field class=\"__field-input\" [gridLayout]=\"resolveParamLayout(param)\">\n <ax-label [required]=\"isRequired(param)\">{{ param.title! | translate | async }}</ax-label>\n <ng-container\n axp-widget-renderer\n [node]=\"param.widget\"\n [mode]=\"resolveParamMode(group, param)\"\n ></ng-container>\n @if (param.description) {\n <axp-layout-description>{{ param.description! | translate | async }}</axp-layout-description>\n }\n </ax-form-field>\n </div>\n }\n }\n }\n </axp-layout-content>\n </axp-layout-section>\n } @empty {\n <axp-layout-section>\n <axp-layout-content>\n <axp-state-message\n icon=\"fa-light fa-clipboard-list\"\n [title]=\"'@general:no-form-definition.title'\"\n [description]=\"'@general:no-form-definition.description'\"\n >\n </axp-state-message>\n </axp-layout-content>\n </axp-layout-section>\n }\n </axp-layout-sections>\n </axp-widgets-container>\n</ax-form>\n", styles: ["axp-dynamic-form{width:100%}axp-dynamic-form axp-layout-section axp-layout-content{display:flex;width:100%;flex-direction:column}axp-dynamic-form axp-layout-section axp-layout-content>:not([hidden])~:not([hidden]){--tw-divide-y-reverse: 0;border-top-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px * var(--tw-divide-y-reverse));border-style:dashed;--tw-divide-opacity: 1;border-color:rgba(var(--ax-sys-color-border-lightest-surface),var(--tw-divide-opacity, 1))}axp-dynamic-form axp-layout-section axp-layout-content .__field-container{align-items:center;gap:1rem;padding:1rem}@media (min-width: 1024px){axp-dynamic-form axp-layout-section axp-layout-content .__field-container{padding-left:1.5rem;padding-right:1.5rem}}@media (min-width: 1280px){axp-dynamic-form axp-layout-section axp-layout-content .__field-container{padding-left:2rem;padding-right:2rem}}@media (min-width: 1536px){axp-dynamic-form axp-layout-section axp-layout-content .__field-container{padding-left:2.5rem;padding-right:2.5rem}}axp-dynamic-form axp-layout-section axp-layout-content .__field-container{display:grid;grid-template-columns:repeat(12,minmax(0,1fr))}axp-dynamic-form axp-layout-section axp-layout-content .__field-container .__field-info{grid-column:span 12 / span 12}@media (min-width: 768px){axp-dynamic-form axp-layout-section axp-layout-content .__field-container .__field-info{grid-column:span 4 / span 4}}@media (min-width: 1024px){axp-dynamic-form axp-layout-section axp-layout-content .__field-container .__field-info{grid-column:span 4 / span 4}}@media (min-width: 1536px){axp-dynamic-form axp-layout-section axp-layout-content .__field-container .__field-info{grid-column:span 3 / span 3}}axp-dynamic-form axp-layout-section axp-layout-content .__field-container axp-layout-description{margin-top:.5rem!important;font-size:.75rem!important;line-height:1rem!important}axp-dynamic-form.--look-compact axp-layout-section axp-layout-content>:not([hidden])~:not([hidden]){border-style:none}axp-dynamic-form.--look-compact axp-layout-section axp-layout-content .__field-container{display:flex;flex-direction:column;gap:.25rem;padding:.25rem .5rem;margin-bottom:.5rem;border-width:0px}axp-dynamic-form.--look-compact axp-layout-section axp-layout-content .__field-container .__field-info{margin-bottom:.125rem;width:100%}axp-dynamic-form.--look-compact axp-layout-section axp-layout-content .__field-container .__field-info axp-layout-title{font-size:.875rem;line-height:1.25rem;font-weight:500}axp-dynamic-form.--look-compact axp-layout-section axp-layout-content .__field-container .__field-input{width:100%}axp-dynamic-form.--look-compact axp-layout-section axp-layout-content .__field-container axp-layout-description{margin-top:.125rem!important;font-size:.75rem!important;line-height:1rem!important;opacity:.75!important}axp-dynamic-form.--look-compact axp-layout-section{margin-bottom:.75rem}axp-dynamic-form.--look-compact axp-layout-section axp-layout-header{margin-bottom:.5rem;gap:0px;padding:.5rem}axp-dynamic-form.--look-compact axp-layout-section axp-layout-header axp-layout-title{font-size:1rem;line-height:1.5rem;font-weight:600}axp-dynamic-form.--look-compact axp-layout-section axp-layout-header axp-layout-description{margin-top:.25rem;font-size:.75rem;line-height:1rem;opacity:.75}axp-dynamic-form.--look-borderless axp-layout-section{border-width:0px!important;--tw-shadow: 0 0 #0000 !important;--tw-shadow-colored: 0 0 #0000 !important;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)!important}axp-dynamic-form.--look-borderless axp-layout-section axp-layout-content>:not([hidden])~:not([hidden]){border-style:none}axp-dynamic-form.--look-borderless axp-layout-section axp-layout-content .__field-container{display:flex;flex-direction:column;gap:.25rem;padding:.25rem .5rem;margin-bottom:.5rem;border-width:0px}axp-dynamic-form.--look-borderless axp-layout-section axp-layout-content .__field-container .__field-info{margin-bottom:.125rem;width:100%}axp-dynamic-form.--look-borderless axp-layout-section axp-layout-content .__field-container .__field-info axp-layout-title{font-size:.875rem;line-height:1.25rem;font-weight:500}axp-dynamic-form.--look-borderless axp-layout-section axp-layout-content .__field-container .__field-input{width:100%}axp-dynamic-form.--look-borderless axp-layout-section axp-layout-content .__field-container axp-layout-description{margin-top:.125rem!important;font-size:.75rem!important;line-height:1rem!important;opacity:.75!important}axp-dynamic-form.--direction-vertical axp-layout-section axp-layout-content .__field-container{display:flex;flex-direction:column;align-items:flex-start;gap:.75rem}axp-dynamic-form.--direction-vertical axp-layout-section axp-layout-content .__field-container .__field-info{grid-column:span 12 / span 12;width:100%}axp-dynamic-form.--direction-vertical axp-layout-section axp-layout-content .__field-container .__field-input{grid-column:span 12 / span 12;width:100%}axp-dynamic-form.--direction-vertical axp-layout-section axp-layout-content .__field-container axp-layout-description{margin-top:.25rem!important;font-size:.875rem!important;line-height:1.25rem!important}axp-dynamic-form.--direction-horizontal axp-layout-section axp-layout-content>:not([hidden])~:not([hidden]){border-style:none}axp-dynamic-form.--direction-horizontal axp-layout-section axp-layout-content .__field-container{display:flex;flex-direction:row;align-items:center;gap:1rem;padding-top:.75rem;padding-bottom:.75rem}axp-dynamic-form.--direction-horizontal axp-layout-section axp-layout-content .__field-container .__field-info{width:12rem;flex-shrink:0}axp-dynamic-form.--direction-horizontal axp-layout-section axp-layout-content .__field-container .__field-info axp-layout-title{margin-bottom:.25rem;font-size:.875rem;line-height:1.25rem;font-weight:500}axp-dynamic-form.--direction-horizontal axp-layout-section axp-layout-content .__field-container .__field-input{flex:1 1 0%}axp-dynamic-form.--direction-horizontal axp-layout-section axp-layout-content .__field-container axp-layout-description{margin-top:.25rem!important;font-size:.75rem!important;line-height:1rem!important;opacity:.75!important}axp-dynamic-form.--direction-grid axp-layout-section axp-layout-content .__field-container{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:1rem;padding:1rem}axp-dynamic-form.--direction-grid axp-layout-section axp-layout-content .__field-container .__field-info{grid-column:span 12 / span 12}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type:
|
|
1186
1950
|
// ACoreX
|
|
1187
|
-
AXFormModule }, { kind: "component", type:
|
|
1951
|
+
AXFormModule }, { kind: "component", type: i2$4.AXFormFieldComponent, selector: "ax-form-field", inputs: ["labelMode"] }, { kind: "component", type: i2$4.AXFormComponent, selector: "ax-form", inputs: ["labelMode", "look", "messageStyle", "updateOn"], outputs: ["onValidate", "updateOnChange"] }, { kind: "ngmodule", type: AXValidationModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type:
|
|
1188
1952
|
// Platform
|
|
1189
|
-
AXPLayoutBuilderModule }, { kind: "component", type: i3$
|
|
1953
|
+
AXPLayoutBuilderModule }, { kind: "component", type: i3$3.AXPWidgetContainerComponent, selector: "axp-widgets-container", inputs: ["context", "functions"], outputs: ["onContextChanged"] }, { kind: "directive", type: i3$3.AXPWidgetRendererDirective, selector: "[axp-widget-renderer]", inputs: ["parentNode", "index", "mode", "node"], outputs: ["onOptionsChanged", "onValueChanged"], exportAs: ["widgetRenderer"] }, { kind: "component", type: AXPThemeLayoutBlockComponent, selector: "\n\n axp-page-content, \n axp-page-footer-container,\n axp-page-footer,\n axp-page-header,\n axp-page-header-container,\n axp-page-toolbar,\n\n axp-layout-content, \n axp-layout-page-content, \n\n axp-layout-sections,\n axp-layout-body,\n axp-layout-page-body,\n axp-layout-prefix,\n axp-layout-suffix,\n axp-layout-title-bar,\n axp-layout-title, \n axp-layout-title-actions, \n axp-layout-nav-button, \n axp-layout-description, \n axp-layout-breadcrumbs,\n axp-layout-list-action,\n " }, { kind: "component", type: AXPThemeLayoutHeaderComponent, selector: "axp-layout-header" }, { kind: "component", type: AXPThemeLayoutSectionComponent, selector: "axp-layout-section" }, { kind: "directive", type: AXPGridLayoutDirective, selector: "[gridLayout]", inputs: ["gridLayout"] }, { kind: "component", type: AXLabelComponent, selector: "ax-label", inputs: ["required", "for"], outputs: ["requiredChange"] }, { kind: "component", type: AXPStateMessageComponent, selector: "axp-state-message", inputs: ["mode", "icon", "title", "description", "variant"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
1190
1954
|
}
|
|
1191
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.
|
|
1955
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPDynamicFormComponent, decorators: [{
|
|
1192
1956
|
type: Component,
|
|
1193
1957
|
args: [{ standalone: true, selector: 'axp-dynamic-form', imports: [
|
|
1194
1958
|
CommonModule,
|
|
@@ -1196,44 +1960,2168 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
|
|
|
1196
1960
|
// ACoreX
|
|
1197
1961
|
AXFormModule,
|
|
1198
1962
|
AXValidationModule,
|
|
1963
|
+
AXTranslationModule,
|
|
1199
1964
|
// Platform
|
|
1200
1965
|
AXPLayoutBuilderModule,
|
|
1201
1966
|
AXPThemeLayoutBlockComponent,
|
|
1202
1967
|
AXPThemeLayoutHeaderComponent,
|
|
1203
1968
|
AXPThemeLayoutSectionComponent,
|
|
1204
1969
|
AXPGridLayoutDirective,
|
|
1205
|
-
AXLabelComponent
|
|
1970
|
+
AXLabelComponent,
|
|
1971
|
+
AXPStateMessageComponent,
|
|
1206
1972
|
], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
|
|
1207
1973
|
class: 'axp-dynamic-form',
|
|
1208
1974
|
'[class]': 'hostClasses()',
|
|
1209
|
-
}, template: "<ax-form>\n <axp-widgets-container [context]=\"internalContext()\" (onContextChanged)=\"handleContextChanged($event)\">\n <axp-layout-sections>\n @
|
|
1975
|
+
}, template: "<ax-form>\n <axp-widgets-container [context]=\"internalContext()\" (onContextChanged)=\"handleContextChanged($event)\">\n <axp-layout-sections>\n @for (group of evaluatedFormDefinition()?.groups; track group.name) {\n <axp-layout-section>\n @if (group.title || group.description) {\n <axp-layout-header>\n <axp-layout-title>{{ group.title! | translate | async }}</axp-layout-title>\n @if (group.description) {\n <axp-layout-description>{{ group.description! | translate | async }}</axp-layout-description>\n }\n </axp-layout-header>\n }\n <axp-layout-content>\n @if (layoutDirection() === 'grid') {\n <div class=\"__field-container\">\n @for (param of group.parameters; track param.path) {\n @if (param.widget.options?.['hidden'] !== true) {\n <ax-form-field class=\"__field-input\" [gridLayout]=\"resolveParamLayout(param)\">\n <ax-label [required]=\"isRequired(param)\">{{ param.title! | translate | async }}</ax-label>\n <ng-container\n axp-widget-renderer\n [node]=\"param.widget\"\n [mode]=\"resolveParamMode(group, param)\"\n ></ng-container>\n @if (param.description) {\n <axp-layout-description>{{ param.description! | translate | async }}</axp-layout-description>\n }\n </ax-form-field>\n }\n }\n </div>\n } @else {\n @for (param of group.parameters; track param.path) {\n @if (param.widget.options?.['hidden'] !== true) {\n <div class=\"__field-container\">\n <ax-form-field class=\"__field-input\" [gridLayout]=\"resolveParamLayout(param)\">\n <ax-label [required]=\"isRequired(param)\">{{ param.title! | translate | async }}</ax-label>\n <ng-container\n axp-widget-renderer\n [node]=\"param.widget\"\n [mode]=\"resolveParamMode(group, param)\"\n ></ng-container>\n @if (param.description) {\n <axp-layout-description>{{ param.description! | translate | async }}</axp-layout-description>\n }\n </ax-form-field>\n </div>\n }\n }\n }\n </axp-layout-content>\n </axp-layout-section>\n } @empty {\n <axp-layout-section>\n <axp-layout-content>\n <axp-state-message\n icon=\"fa-light fa-clipboard-list\"\n [title]=\"'@general:no-form-definition.title'\"\n [description]=\"'@general:no-form-definition.description'\"\n >\n </axp-state-message>\n </axp-layout-content>\n </axp-layout-section>\n }\n </axp-layout-sections>\n </axp-widgets-container>\n</ax-form>\n", styles: ["axp-dynamic-form{width:100%}axp-dynamic-form axp-layout-section axp-layout-content{display:flex;width:100%;flex-direction:column}axp-dynamic-form axp-layout-section axp-layout-content>:not([hidden])~:not([hidden]){--tw-divide-y-reverse: 0;border-top-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px * var(--tw-divide-y-reverse));border-style:dashed;--tw-divide-opacity: 1;border-color:rgba(var(--ax-sys-color-border-lightest-surface),var(--tw-divide-opacity, 1))}axp-dynamic-form axp-layout-section axp-layout-content .__field-container{align-items:center;gap:1rem;padding:1rem}@media (min-width: 1024px){axp-dynamic-form axp-layout-section axp-layout-content .__field-container{padding-left:1.5rem;padding-right:1.5rem}}@media (min-width: 1280px){axp-dynamic-form axp-layout-section axp-layout-content .__field-container{padding-left:2rem;padding-right:2rem}}@media (min-width: 1536px){axp-dynamic-form axp-layout-section axp-layout-content .__field-container{padding-left:2.5rem;padding-right:2.5rem}}axp-dynamic-form axp-layout-section axp-layout-content .__field-container{display:grid;grid-template-columns:repeat(12,minmax(0,1fr))}axp-dynamic-form axp-layout-section axp-layout-content .__field-container .__field-info{grid-column:span 12 / span 12}@media (min-width: 768px){axp-dynamic-form axp-layout-section axp-layout-content .__field-container .__field-info{grid-column:span 4 / span 4}}@media (min-width: 1024px){axp-dynamic-form axp-layout-section axp-layout-content .__field-container .__field-info{grid-column:span 4 / span 4}}@media (min-width: 1536px){axp-dynamic-form axp-layout-section axp-layout-content .__field-container .__field-info{grid-column:span 3 / span 3}}axp-dynamic-form axp-layout-section axp-layout-content .__field-container axp-layout-description{margin-top:.5rem!important;font-size:.75rem!important;line-height:1rem!important}axp-dynamic-form.--look-compact axp-layout-section axp-layout-content>:not([hidden])~:not([hidden]){border-style:none}axp-dynamic-form.--look-compact axp-layout-section axp-layout-content .__field-container{display:flex;flex-direction:column;gap:.25rem;padding:.25rem .5rem;margin-bottom:.5rem;border-width:0px}axp-dynamic-form.--look-compact axp-layout-section axp-layout-content .__field-container .__field-info{margin-bottom:.125rem;width:100%}axp-dynamic-form.--look-compact axp-layout-section axp-layout-content .__field-container .__field-info axp-layout-title{font-size:.875rem;line-height:1.25rem;font-weight:500}axp-dynamic-form.--look-compact axp-layout-section axp-layout-content .__field-container .__field-input{width:100%}axp-dynamic-form.--look-compact axp-layout-section axp-layout-content .__field-container axp-layout-description{margin-top:.125rem!important;font-size:.75rem!important;line-height:1rem!important;opacity:.75!important}axp-dynamic-form.--look-compact axp-layout-section{margin-bottom:.75rem}axp-dynamic-form.--look-compact axp-layout-section axp-layout-header{margin-bottom:.5rem;gap:0px;padding:.5rem}axp-dynamic-form.--look-compact axp-layout-section axp-layout-header axp-layout-title{font-size:1rem;line-height:1.5rem;font-weight:600}axp-dynamic-form.--look-compact axp-layout-section axp-layout-header axp-layout-description{margin-top:.25rem;font-size:.75rem;line-height:1rem;opacity:.75}axp-dynamic-form.--look-borderless axp-layout-section{border-width:0px!important;--tw-shadow: 0 0 #0000 !important;--tw-shadow-colored: 0 0 #0000 !important;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)!important}axp-dynamic-form.--look-borderless axp-layout-section axp-layout-content>:not([hidden])~:not([hidden]){border-style:none}axp-dynamic-form.--look-borderless axp-layout-section axp-layout-content .__field-container{display:flex;flex-direction:column;gap:.25rem;padding:.25rem .5rem;margin-bottom:.5rem;border-width:0px}axp-dynamic-form.--look-borderless axp-layout-section axp-layout-content .__field-container .__field-info{margin-bottom:.125rem;width:100%}axp-dynamic-form.--look-borderless axp-layout-section axp-layout-content .__field-container .__field-info axp-layout-title{font-size:.875rem;line-height:1.25rem;font-weight:500}axp-dynamic-form.--look-borderless axp-layout-section axp-layout-content .__field-container .__field-input{width:100%}axp-dynamic-form.--look-borderless axp-layout-section axp-layout-content .__field-container axp-layout-description{margin-top:.125rem!important;font-size:.75rem!important;line-height:1rem!important;opacity:.75!important}axp-dynamic-form.--direction-vertical axp-layout-section axp-layout-content .__field-container{display:flex;flex-direction:column;align-items:flex-start;gap:.75rem}axp-dynamic-form.--direction-vertical axp-layout-section axp-layout-content .__field-container .__field-info{grid-column:span 12 / span 12;width:100%}axp-dynamic-form.--direction-vertical axp-layout-section axp-layout-content .__field-container .__field-input{grid-column:span 12 / span 12;width:100%}axp-dynamic-form.--direction-vertical axp-layout-section axp-layout-content .__field-container axp-layout-description{margin-top:.25rem!important;font-size:.875rem!important;line-height:1.25rem!important}axp-dynamic-form.--direction-horizontal axp-layout-section axp-layout-content>:not([hidden])~:not([hidden]){border-style:none}axp-dynamic-form.--direction-horizontal axp-layout-section axp-layout-content .__field-container{display:flex;flex-direction:row;align-items:center;gap:1rem;padding-top:.75rem;padding-bottom:.75rem}axp-dynamic-form.--direction-horizontal axp-layout-section axp-layout-content .__field-container .__field-info{width:12rem;flex-shrink:0}axp-dynamic-form.--direction-horizontal axp-layout-section axp-layout-content .__field-container .__field-info axp-layout-title{margin-bottom:.25rem;font-size:.875rem;line-height:1.25rem;font-weight:500}axp-dynamic-form.--direction-horizontal axp-layout-section axp-layout-content .__field-container .__field-input{flex:1 1 0%}axp-dynamic-form.--direction-horizontal axp-layout-section axp-layout-content .__field-container axp-layout-description{margin-top:.25rem!important;font-size:.75rem!important;line-height:1rem!important;opacity:.75!important}axp-dynamic-form.--direction-grid axp-layout-section axp-layout-content .__field-container{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:1rem;padding:1rem}axp-dynamic-form.--direction-grid axp-layout-section axp-layout-content .__field-container .__field-info{grid-column:span 12 / span 12}\n"] }]
|
|
1210
1976
|
}] });
|
|
1211
1977
|
|
|
1212
|
-
|
|
1978
|
+
//#endregion
|
|
1979
|
+
class AXPDynamicFormStepperComponent {
|
|
1213
1980
|
constructor() {
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
this.
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
this.
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
this.
|
|
1227
|
-
this.
|
|
1228
|
-
this.
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1981
|
+
//#region ---- Inputs ----
|
|
1982
|
+
/**
|
|
1983
|
+
* Stepper definition providing steps metadata and behavior configuration
|
|
1984
|
+
*/
|
|
1985
|
+
this.definition = input.required(...(ngDevMode ? [{ debugName: "definition" }] : []));
|
|
1986
|
+
/**
|
|
1987
|
+
* Shared root context for all steps
|
|
1988
|
+
*/
|
|
1989
|
+
this.context = input.required(...(ngDevMode ? [{ debugName: "context" }] : []));
|
|
1990
|
+
/**
|
|
1991
|
+
* Optional pass-through layout props for inner forms
|
|
1992
|
+
*/
|
|
1993
|
+
this.layoutLook = input('normal', ...(ngDevMode ? [{ debugName: "layoutLook" }] : []));
|
|
1994
|
+
this.stepperDirection = input('horizontal', ...(ngDevMode ? [{ debugName: "stepperDirection" }] : []));
|
|
1995
|
+
this.layoutConfig = input(...(ngDevMode ? [undefined, { debugName: "layoutConfig" }] : []));
|
|
1996
|
+
/**
|
|
1997
|
+
* Optional guard that controls advancing to the next step (async only)
|
|
1998
|
+
*/
|
|
1999
|
+
this.guardNext = input(...(ngDevMode ? [undefined, { debugName: "guardNext" }] : []));
|
|
2000
|
+
//#endregion
|
|
2001
|
+
//#region ---- Outputs ----
|
|
2002
|
+
/**
|
|
2003
|
+
* Emits when the shared root context changes
|
|
2004
|
+
*/
|
|
2005
|
+
this.contextChange = output();
|
|
2006
|
+
/**
|
|
2007
|
+
* Emits when the active step changes
|
|
2008
|
+
*/
|
|
2009
|
+
this.stepChange = output();
|
|
2010
|
+
/**
|
|
2011
|
+
* Emits after successful finish
|
|
2012
|
+
*/
|
|
2013
|
+
this.finished = output();
|
|
2014
|
+
/**
|
|
2015
|
+
* Emits when cancelled by API
|
|
2016
|
+
*/
|
|
2017
|
+
this.cancel = output();
|
|
2018
|
+
/**
|
|
2019
|
+
* Emits when navigation is blocked by validation or policy
|
|
2020
|
+
*/
|
|
2021
|
+
this.navigationBlocked = output();
|
|
2022
|
+
//#endregion
|
|
2023
|
+
//#region ---- State ----
|
|
2024
|
+
/**
|
|
2025
|
+
* Internal reactive copy of the shared context
|
|
2026
|
+
*/
|
|
2027
|
+
this.internalContext = signal({}, ...(ngDevMode ? [{ debugName: "internalContext" }] : []));
|
|
2028
|
+
/**
|
|
2029
|
+
* Active step index
|
|
2030
|
+
*/
|
|
2031
|
+
this.currentStepIndex = signal(0, ...(ngDevMode ? [{ debugName: "currentStepIndex" }] : []));
|
|
2032
|
+
/**
|
|
2033
|
+
* Navigation lock while async guards are pending
|
|
2034
|
+
*/
|
|
2035
|
+
this.navigationLocked = signal(false, ...(ngDevMode ? [{ debugName: "navigationLocked" }] : []));
|
|
2036
|
+
/**
|
|
2037
|
+
* Reference to underlying step wizard to sync visual navigation
|
|
2038
|
+
*/
|
|
2039
|
+
this.wizard = viewChild(AXStepWizardComponent, ...(ngDevMode ? [{ debugName: "wizard" }] : []));
|
|
2040
|
+
/**
|
|
2041
|
+
* References to rendered dynamic forms (usually one active)
|
|
2042
|
+
*/
|
|
2043
|
+
this.forms = viewChildren(AXPDynamicFormComponent, ...(ngDevMode ? [{ debugName: "forms" }] : []));
|
|
2044
|
+
//#endregion
|
|
2045
|
+
//#region ---- Computed Properties ----
|
|
2046
|
+
this.steps = computed(() => this.definition().steps ?? [], ...(ngDevMode ? [{ debugName: "steps" }] : []));
|
|
2047
|
+
this.stepCount = computed(() => this.steps().length, ...(ngDevMode ? [{ debugName: "stepCount" }] : []));
|
|
2048
|
+
this.currentStep = computed(() => this.steps()[this.currentStepIndex()] ?? undefined, ...(ngDevMode ? [{ debugName: "currentStep" }] : []));
|
|
2049
|
+
this.isFirstComputed = computed(() => this.currentStepIndex() === 0, ...(ngDevMode ? [{ debugName: "isFirstComputed" }] : []));
|
|
2050
|
+
this.isLastComputed = computed(() => this.currentStepIndex() === Math.max(0, this.stepCount() - 1), ...(ngDevMode ? [{ debugName: "isLastComputed" }] : []));
|
|
2051
|
+
/**
|
|
2052
|
+
* Non-undefined layout config for inner dynamic forms
|
|
2053
|
+
*/
|
|
2054
|
+
this.effectiveLayoutConfig = computed(() => this.layoutConfig() ?? {
|
|
2055
|
+
positions: {
|
|
2056
|
+
default: { colSpan: 12 },
|
|
2057
|
+
md: { colSpan: 8 },
|
|
2058
|
+
lg: { colSpan: 6 },
|
|
2059
|
+
xl: { colSpan: 5 },
|
|
2060
|
+
xxl: { colSpan: 4 },
|
|
2061
|
+
},
|
|
2062
|
+
}, ...(ngDevMode ? [{ debugName: "effectiveLayoutConfig" }] : []));
|
|
2063
|
+
//#endregion
|
|
2064
|
+
//#region ---- Effects ----
|
|
2065
|
+
/**
|
|
2066
|
+
* Keep internal context in sync with input context
|
|
2067
|
+
*/
|
|
2068
|
+
this.#contextSync = effect(() => {
|
|
2069
|
+
const ctx = this.context();
|
|
2070
|
+
this.internalContext.set(ctx ?? {});
|
|
2071
|
+
}, ...(ngDevMode ? [{ debugName: "#contextSync" }] : []));
|
|
2072
|
+
}
|
|
2073
|
+
//#endregion
|
|
2074
|
+
//#region ---- Effects ----
|
|
2075
|
+
/**
|
|
2076
|
+
* Keep internal context in sync with input context
|
|
2077
|
+
*/
|
|
2078
|
+
#contextSync;
|
|
2079
|
+
//#endregion
|
|
2080
|
+
//#region ---- Public API ----
|
|
2081
|
+
/**
|
|
2082
|
+
* Returns the current step pointer
|
|
2083
|
+
*/
|
|
2084
|
+
getCurrentStep() {
|
|
2085
|
+
const step = this.currentStep();
|
|
2086
|
+
return { index: this.currentStepIndex(), id: step?.id ?? '' };
|
|
2087
|
+
}
|
|
2088
|
+
/**
|
|
2089
|
+
* Public helpers for templates/consumers
|
|
2090
|
+
*/
|
|
2091
|
+
isFirst() {
|
|
2092
|
+
return this.currentStepIndex() === 0;
|
|
2093
|
+
}
|
|
2094
|
+
isLast() {
|
|
2095
|
+
return this.currentStepIndex() === Math.max(0, this.stepCount() - 1);
|
|
2096
|
+
}
|
|
2097
|
+
/**
|
|
2098
|
+
* Returns the root context
|
|
2099
|
+
*/
|
|
2100
|
+
getContext() {
|
|
2101
|
+
return this.internalContext();
|
|
2102
|
+
}
|
|
2103
|
+
/**
|
|
2104
|
+
* Replaces the root context programmatically
|
|
2105
|
+
*/
|
|
2106
|
+
setContext(ctx) {
|
|
2107
|
+
this.internalContext.set(ctx ?? {});
|
|
2108
|
+
this.contextChange.emit(this.internalContext());
|
|
2109
|
+
}
|
|
2110
|
+
/**
|
|
2111
|
+
* Validates the current step.
|
|
2112
|
+
*/
|
|
2113
|
+
async validateCurrentStep() {
|
|
2114
|
+
const instances = this.forms();
|
|
2115
|
+
if (!instances || instances.length === 0) {
|
|
2116
|
+
return true;
|
|
2117
|
+
}
|
|
2118
|
+
const index = this.currentStepIndex();
|
|
2119
|
+
const form = instances[index] ?? instances[0];
|
|
2120
|
+
if (form && typeof form.validate === 'function') {
|
|
2121
|
+
return await form.validate();
|
|
2122
|
+
}
|
|
2123
|
+
return true;
|
|
2124
|
+
}
|
|
2125
|
+
/**
|
|
2126
|
+
* Attempts to advance to the next step applying validation and guard
|
|
2127
|
+
*/
|
|
2128
|
+
async next() {
|
|
2129
|
+
if (this.navigationLocked()) {
|
|
2130
|
+
return;
|
|
2131
|
+
}
|
|
2132
|
+
const valid = await this.validateCurrentStep();
|
|
2133
|
+
if (!valid) {
|
|
2134
|
+
const step = this.currentStep();
|
|
2135
|
+
if (step) {
|
|
2136
|
+
this.navigationBlocked.emit({ reason: 'invalid', stepId: step.id });
|
|
2137
|
+
}
|
|
2138
|
+
return;
|
|
2139
|
+
}
|
|
2140
|
+
const index = this.currentStepIndex();
|
|
2141
|
+
const step = this.steps()[index];
|
|
2142
|
+
if (!step) {
|
|
2143
|
+
return;
|
|
2144
|
+
}
|
|
2145
|
+
const event = { index, id: step.id, fullContext: this.internalContext() };
|
|
2146
|
+
const guard = this.guardNext();
|
|
2147
|
+
if (guard) {
|
|
2148
|
+
try {
|
|
2149
|
+
this.navigationLocked.set(true);
|
|
2150
|
+
const allowed = await guard(event);
|
|
2151
|
+
if (!allowed) {
|
|
2152
|
+
return;
|
|
2153
|
+
}
|
|
2154
|
+
}
|
|
2155
|
+
finally {
|
|
2156
|
+
this.navigationLocked.set(false);
|
|
2157
|
+
}
|
|
2158
|
+
}
|
|
2159
|
+
// Context is already synced through onStepContextChange
|
|
2160
|
+
this.contextChange.emit(this.internalContext());
|
|
2161
|
+
// Advance
|
|
2162
|
+
if (index < this.stepCount() - 1) {
|
|
2163
|
+
this.#activateStep(index + 1);
|
|
2164
|
+
// Sync visual wizard
|
|
2165
|
+
this.wizard()?.next();
|
|
2166
|
+
}
|
|
2167
|
+
}
|
|
2168
|
+
/**
|
|
2169
|
+
* Goes back to the previous step if possible
|
|
2170
|
+
*/
|
|
2171
|
+
async previous() {
|
|
2172
|
+
if (this.navigationLocked()) {
|
|
2173
|
+
return;
|
|
2174
|
+
}
|
|
2175
|
+
const index = this.currentStepIndex();
|
|
2176
|
+
if (index <= 0) {
|
|
2177
|
+
return;
|
|
2178
|
+
}
|
|
2179
|
+
const current = this.steps()[index];
|
|
2180
|
+
if (current && current.canGoBack === false) {
|
|
2181
|
+
this.navigationBlocked.emit({ reason: 'cannot-go-back', stepId: current.id, targetIndex: index - 1 });
|
|
2182
|
+
return;
|
|
2183
|
+
}
|
|
2184
|
+
this.#activateStep(index - 1);
|
|
2185
|
+
// Sync visual wizard
|
|
2186
|
+
this.wizard()?.previous();
|
|
2187
|
+
}
|
|
2188
|
+
/**
|
|
2189
|
+
* Navigates to a specific step by id or index
|
|
2190
|
+
*/
|
|
2191
|
+
async goTo(stepIdOrIndex) {
|
|
2192
|
+
if (typeof stepIdOrIndex === 'number') {
|
|
2193
|
+
await this.#attemptNavigateToIndex(stepIdOrIndex);
|
|
2194
|
+
return;
|
|
2195
|
+
}
|
|
2196
|
+
const idx = this.steps().findIndex((s) => s.id === stepIdOrIndex);
|
|
2197
|
+
if (idx >= 0) {
|
|
2198
|
+
await this.#attemptNavigateToIndex(idx);
|
|
2199
|
+
}
|
|
2200
|
+
}
|
|
2201
|
+
/**
|
|
2202
|
+
* Validates all steps and emits finished when successful
|
|
2203
|
+
*/
|
|
2204
|
+
async finish() {
|
|
2205
|
+
// MVP: assume all steps valid
|
|
2206
|
+
this.finished.emit(this.internalContext());
|
|
2207
|
+
}
|
|
2208
|
+
/**
|
|
2209
|
+
* Emits cancel event without state changes
|
|
2210
|
+
*/
|
|
2211
|
+
cancelFlow() {
|
|
2212
|
+
this.cancel.emit();
|
|
2213
|
+
}
|
|
2214
|
+
//#endregion
|
|
2215
|
+
//#region ---- Utilities ----
|
|
2216
|
+
#activateStep(index) {
|
|
2217
|
+
this.currentStepIndex.set(index);
|
|
2218
|
+
const step = this.steps()[index];
|
|
2219
|
+
if (step?.dataPath) {
|
|
2220
|
+
// Ensure the path exists for binding
|
|
2221
|
+
this.#ensurePath(step.dataPath);
|
|
2222
|
+
}
|
|
2223
|
+
if (step) {
|
|
2224
|
+
this.stepChange.emit({ index, id: step.id });
|
|
2225
|
+
}
|
|
2226
|
+
}
|
|
2227
|
+
/**
|
|
2228
|
+
* Attempts navigation to a specific index while enforcing linear/skip/back rules and validation.
|
|
2229
|
+
*/
|
|
2230
|
+
async #attemptNavigateToIndex(targetIndex) {
|
|
2231
|
+
if (targetIndex < 0 || targetIndex >= this.stepCount()) {
|
|
2232
|
+
return;
|
|
2233
|
+
}
|
|
2234
|
+
const currentIndex = this.currentStepIndex();
|
|
2235
|
+
if (targetIndex === currentIndex) {
|
|
2236
|
+
return;
|
|
2237
|
+
}
|
|
2238
|
+
const steps = this.steps();
|
|
2239
|
+
const current = steps[currentIndex];
|
|
2240
|
+
const target = steps[targetIndex];
|
|
2241
|
+
if (!current || !target) {
|
|
2242
|
+
return;
|
|
2243
|
+
}
|
|
2244
|
+
// Moving backward: ensure all steps between have canGoBack !== false
|
|
2245
|
+
if (targetIndex < currentIndex) {
|
|
2246
|
+
for (let i = currentIndex; i > targetIndex; i--) {
|
|
2247
|
+
const step = steps[i];
|
|
2248
|
+
if (step && step.canGoBack === false) {
|
|
2249
|
+
this.navigationBlocked.emit({ reason: 'cannot-go-back', stepId: step.id, targetIndex });
|
|
2250
|
+
return;
|
|
2251
|
+
}
|
|
2252
|
+
}
|
|
2253
|
+
this.#activateStep(targetIndex);
|
|
2254
|
+
const w = this.wizard();
|
|
2255
|
+
if (w && typeof w.goStep === 'function') {
|
|
2256
|
+
w.goStep(targetIndex);
|
|
2257
|
+
}
|
|
2258
|
+
else {
|
|
2259
|
+
this.wizard()?.previous();
|
|
2260
|
+
}
|
|
2261
|
+
return;
|
|
2262
|
+
}
|
|
2263
|
+
// Moving forward: enforce linear and canSkip
|
|
2264
|
+
const isLinear = !!this.definition().linear;
|
|
2265
|
+
if (isLinear && targetIndex > currentIndex + 1) {
|
|
2266
|
+
this.navigationBlocked.emit({ reason: 'linear', stepId: current.id, targetIndex });
|
|
2267
|
+
return;
|
|
2268
|
+
}
|
|
2269
|
+
// Check skipped steps for canSkip
|
|
2270
|
+
for (let i = currentIndex + 1; i < targetIndex; i++) {
|
|
2271
|
+
const step = steps[i];
|
|
2272
|
+
if (step && step.canSkip !== true) {
|
|
2273
|
+
this.navigationBlocked.emit({ reason: 'cannot-skip', stepId: step.id, targetIndex });
|
|
2274
|
+
return;
|
|
2275
|
+
}
|
|
2276
|
+
}
|
|
2277
|
+
// Forward navigation should validate current step and pass guard
|
|
2278
|
+
const valid = await this.validateCurrentStep();
|
|
2279
|
+
if (!valid) {
|
|
2280
|
+
this.navigationBlocked.emit({ reason: 'invalid', stepId: current.id, targetIndex });
|
|
2281
|
+
return;
|
|
2282
|
+
}
|
|
2283
|
+
const guard = this.guardNext();
|
|
2284
|
+
if (guard) {
|
|
2285
|
+
try {
|
|
2286
|
+
this.navigationLocked.set(true);
|
|
2287
|
+
const allowed = await guard({ index: currentIndex, id: current.id, fullContext: this.internalContext() });
|
|
2288
|
+
if (!allowed) {
|
|
2289
|
+
return;
|
|
2290
|
+
}
|
|
2291
|
+
}
|
|
2292
|
+
finally {
|
|
2293
|
+
this.navigationLocked.set(false);
|
|
2294
|
+
}
|
|
2295
|
+
}
|
|
2296
|
+
this.#activateStep(targetIndex);
|
|
2297
|
+
const w = this.wizard();
|
|
2298
|
+
if (w && typeof w.goStep === 'function') {
|
|
2299
|
+
w.goStep(targetIndex);
|
|
2300
|
+
}
|
|
2301
|
+
else {
|
|
2302
|
+
this.wizard()?.next();
|
|
2303
|
+
}
|
|
2304
|
+
}
|
|
2305
|
+
#readStepSlice(path) {
|
|
2306
|
+
const root = this.internalContext();
|
|
2307
|
+
if (!path) {
|
|
2308
|
+
return { slice: root, exists: true };
|
|
2309
|
+
}
|
|
2310
|
+
const parts = path.split('.').filter(Boolean);
|
|
2311
|
+
let node = root;
|
|
2312
|
+
for (const key of parts) {
|
|
2313
|
+
if (node == null || typeof node !== 'object') {
|
|
2314
|
+
return { slice: undefined, exists: false };
|
|
2315
|
+
}
|
|
2316
|
+
node = node[key];
|
|
2317
|
+
}
|
|
2318
|
+
return { slice: node, exists: node !== undefined };
|
|
2319
|
+
}
|
|
2320
|
+
#writeStepSlice(path, value) {
|
|
2321
|
+
if (!path) {
|
|
2322
|
+
// Replace full root with value only if value is an object
|
|
2323
|
+
if (value && typeof value === 'object') {
|
|
2324
|
+
this.internalContext.set(value);
|
|
2325
|
+
}
|
|
2326
|
+
return;
|
|
2327
|
+
}
|
|
2328
|
+
const root = { ...this.internalContext() };
|
|
2329
|
+
const parts = path.split('.').filter(Boolean);
|
|
2330
|
+
let node = root;
|
|
2331
|
+
for (let i = 0; i < parts.length; i++) {
|
|
2332
|
+
const key = parts[i];
|
|
2333
|
+
if (i === parts.length - 1) {
|
|
2334
|
+
node[key] = value;
|
|
2335
|
+
}
|
|
2336
|
+
else {
|
|
2337
|
+
node[key] = node[key] && typeof node[key] === 'object' ? { ...node[key] } : {};
|
|
2338
|
+
node = node[key];
|
|
2339
|
+
}
|
|
2340
|
+
}
|
|
2341
|
+
this.internalContext.set(root);
|
|
2342
|
+
}
|
|
2343
|
+
#ensurePath(path) {
|
|
2344
|
+
const root = { ...this.internalContext() };
|
|
2345
|
+
const parts = path.split('.').filter(Boolean);
|
|
2346
|
+
let node = root;
|
|
2347
|
+
for (const key of parts) {
|
|
2348
|
+
if (!node[key] || typeof node[key] !== 'object') {
|
|
2349
|
+
node[key] = {};
|
|
2350
|
+
}
|
|
2351
|
+
node = node[key];
|
|
2352
|
+
}
|
|
2353
|
+
this.internalContext.set(root);
|
|
2354
|
+
}
|
|
2355
|
+
/**
|
|
2356
|
+
* Handle per-step context changes and keep internal root context in sync.
|
|
2357
|
+
*/
|
|
2358
|
+
onStepContextChange(stepId, stepContext) {
|
|
2359
|
+
const step = this.steps().find((s) => s.id === stepId);
|
|
2360
|
+
if (!step) {
|
|
2361
|
+
return;
|
|
2362
|
+
}
|
|
2363
|
+
this.#writeStepSlice(step.dataPath, stepContext);
|
|
2364
|
+
this.contextChange.emit(this.internalContext());
|
|
2365
|
+
}
|
|
2366
|
+
/**
|
|
2367
|
+
* Exposes reading a step slice to the template
|
|
2368
|
+
*/
|
|
2369
|
+
readStepSlice(path) {
|
|
2370
|
+
return this.#readStepSlice(path);
|
|
2371
|
+
}
|
|
2372
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPDynamicFormStepperComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2373
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.8", type: AXPDynamicFormStepperComponent, isStandalone: true, selector: "axp-dynamic-form-stepper", inputs: { definition: { classPropertyName: "definition", publicName: "definition", isSignal: true, isRequired: true, transformFunction: null }, context: { classPropertyName: "context", publicName: "context", isSignal: true, isRequired: true, transformFunction: null }, layoutLook: { classPropertyName: "layoutLook", publicName: "layoutLook", isSignal: true, isRequired: false, transformFunction: null }, stepperDirection: { classPropertyName: "stepperDirection", publicName: "stepperDirection", isSignal: true, isRequired: false, transformFunction: null }, layoutConfig: { classPropertyName: "layoutConfig", publicName: "layoutConfig", isSignal: true, isRequired: false, transformFunction: null }, guardNext: { classPropertyName: "guardNext", publicName: "guardNext", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { contextChange: "contextChange", stepChange: "stepChange", finished: "finished", cancel: "cancel", navigationBlocked: "navigationBlocked" }, host: { properties: { "class.--vertical": "stepperDirection() === 'vertical'" }, classAttribute: "axp-dynamic-form-stepper" }, viewQueries: [{ propertyName: "wizard", first: true, predicate: AXStepWizardComponent, descendants: true, isSignal: true }, { propertyName: "forms", predicate: AXPDynamicFormComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<ax-step-wizard\n class=\"ax-sticky ax-top-0 ax-z-10 ax-transition-all\"\n #sticky=\"axpSticky\"\n [axpSticky]=\"'ax-bg-lightest ax-shadow-md ax-pt-4'\"\n [stickyParent]=\"'.ax-popup-body-container'\"\n #wizard\n [content]=\"wizardContent\"\n [stickyOffset]=\"100\"\n [look]=\"'text-line'\"\n [orientation]=\"stepperDirection()\"\n>\n @for (step of steps(); track step.id) {\n <ax-step-wizard-item [label]=\"(step.title || '' | translate | async)!\" [id]=\"step.id\">\n @if (step.icon) {\n <ax-icon [class]=\"step.icon\"></ax-icon>\n }\n <ax-content>\n <axp-dynamic-form\n [formDefinition]=\"{ groups: step.groups }\"\n [context]=\"readStepSlice(step.dataPath).slice\"\n [layoutLook]=\"layoutLook()\"\n [layoutDirection]=\"step.formDirection || 'vertical'\"\n [layoutConfig]=\"effectiveLayoutConfig()\"\n (contextChange)=\"onStepContextChange(step.id, $event)\"\n ></axp-dynamic-form>\n </ax-content>\n </ax-step-wizard-item>\n }\n</ax-step-wizard>\n\n<ng-template [axStepWizardContent] #wizardContent=\"axStepWizardContent\"></ng-template>\n", styles: [".axp-dynamic-form-stepper.--vertical{display:flex;gap:1rem}.axp-dynamic-form-stepper.--vertical ax-step-wizard{width:unset}.axp-dynamic-form-stepper.--vertical ax-content{flex:1 1 auto}.axp-dynamic-form-stepper axp-layout-section{margin-bottom:.75rem}.axp-dynamic-form-stepper axp-layout-section axp-layout-header{margin-bottom:.5rem;gap:0px;padding:.5rem;padding:0}.axp-dynamic-form-stepper axp-layout-section axp-layout-header axp-layout-title{padding-bottom:1rem;font-size:1.25rem;line-height:1.75rem;font-weight:700}.axp-dynamic-form-stepper axp-layout-section axp-layout-header axp-layout-description{margin-top:.25rem;font-size:.75rem;line-height:1rem;opacity:.75}.axp-dynamic-form-stepper axp-layout-section axp-layout-section axp-layout-content{padding:0}.axp-dynamic-form-stepper axp-layout-section axp-layout-section axp-layout-content .__field-container{padding:0!important}.axp-dynamic-form-stepper ax-step-wizard{margin-bottom:2rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXStepWizardModule }, { kind: "component", type: i1$3.AXStepWizardComponent, selector: "ax-step-wizard", inputs: ["connector", "size", "look", "changeStep", "orientation", "content"], outputs: ["stepChanged"] }, { kind: "component", type: i1$3.AXStepWizardItemComponent, selector: "ax-step-wizard-item", inputs: ["disabled", "color", "step", "label", "description", "customTemplate", "active", "passed", "look", "state", "id"], outputs: ["activeChange", "passedChange", "lookChange", "stateChange"] }, { kind: "directive", type: i1$3.AXStepWizardContentDirective, selector: "[axStepWizardContent]", inputs: ["axStepWizardContent"], exportAs: ["axStepWizardContent"] }, { kind: "component", type: AXPDynamicFormComponent, selector: "axp-dynamic-form", inputs: ["formDefinition", "context", "layoutLook", "layoutDirection", "mode", "layoutConfig"], outputs: ["contextChange", "contextInitiated", "validityChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i2$1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "directive", type: AXPStickyDirective, selector: "[axpSticky]", inputs: ["axpSticky", "stickyOffset", "stickyParent", "stickyTarget"], outputs: ["isStickyChange"], exportAs: ["axpSticky"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
2374
|
+
}
|
|
2375
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPDynamicFormStepperComponent, decorators: [{
|
|
2376
|
+
type: Component,
|
|
2377
|
+
args: [{ standalone: true, selector: 'axp-dynamic-form-stepper', imports: [
|
|
2378
|
+
CommonModule,
|
|
2379
|
+
AXStepWizardModule,
|
|
2380
|
+
AXPDynamicFormComponent,
|
|
2381
|
+
AXDecoratorModule,
|
|
2382
|
+
AXTranslationModule,
|
|
2383
|
+
AXPStickyDirective,
|
|
2384
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
|
|
2385
|
+
class: 'axp-dynamic-form-stepper',
|
|
2386
|
+
'[class.--vertical]': "stepperDirection() === 'vertical'",
|
|
2387
|
+
}, template: "<ax-step-wizard\n class=\"ax-sticky ax-top-0 ax-z-10 ax-transition-all\"\n #sticky=\"axpSticky\"\n [axpSticky]=\"'ax-bg-lightest ax-shadow-md ax-pt-4'\"\n [stickyParent]=\"'.ax-popup-body-container'\"\n #wizard\n [content]=\"wizardContent\"\n [stickyOffset]=\"100\"\n [look]=\"'text-line'\"\n [orientation]=\"stepperDirection()\"\n>\n @for (step of steps(); track step.id) {\n <ax-step-wizard-item [label]=\"(step.title || '' | translate | async)!\" [id]=\"step.id\">\n @if (step.icon) {\n <ax-icon [class]=\"step.icon\"></ax-icon>\n }\n <ax-content>\n <axp-dynamic-form\n [formDefinition]=\"{ groups: step.groups }\"\n [context]=\"readStepSlice(step.dataPath).slice\"\n [layoutLook]=\"layoutLook()\"\n [layoutDirection]=\"step.formDirection || 'vertical'\"\n [layoutConfig]=\"effectiveLayoutConfig()\"\n (contextChange)=\"onStepContextChange(step.id, $event)\"\n ></axp-dynamic-form>\n </ax-content>\n </ax-step-wizard-item>\n }\n</ax-step-wizard>\n\n<ng-template [axStepWizardContent] #wizardContent=\"axStepWizardContent\"></ng-template>\n", styles: [".axp-dynamic-form-stepper.--vertical{display:flex;gap:1rem}.axp-dynamic-form-stepper.--vertical ax-step-wizard{width:unset}.axp-dynamic-form-stepper.--vertical ax-content{flex:1 1 auto}.axp-dynamic-form-stepper axp-layout-section{margin-bottom:.75rem}.axp-dynamic-form-stepper axp-layout-section axp-layout-header{margin-bottom:.5rem;gap:0px;padding:.5rem;padding:0}.axp-dynamic-form-stepper axp-layout-section axp-layout-header axp-layout-title{padding-bottom:1rem;font-size:1.25rem;line-height:1.75rem;font-weight:700}.axp-dynamic-form-stepper axp-layout-section axp-layout-header axp-layout-description{margin-top:.25rem;font-size:.75rem;line-height:1rem;opacity:.75}.axp-dynamic-form-stepper axp-layout-section axp-layout-section axp-layout-content{padding:0}.axp-dynamic-form-stepper axp-layout-section axp-layout-section axp-layout-content .__field-container{padding:0!important}.axp-dynamic-form-stepper ax-step-wizard{margin-bottom:2rem}\n"] }]
|
|
2388
|
+
}] });
|
|
2389
|
+
|
|
2390
|
+
class AXPDynamicDialogComponent extends AXBasePageComponent {
|
|
2391
|
+
constructor() {
|
|
2392
|
+
super(...arguments);
|
|
2393
|
+
this.dynamicForm = viewChild(AXPDynamicFormComponent, ...(ngDevMode ? [{ debugName: "dynamicForm" }] : []));
|
|
2394
|
+
this.stepper = viewChild(AXPDynamicFormStepperComponent, ...(ngDevMode ? [{ debugName: "stepper" }] : []));
|
|
2395
|
+
this.isSubmitting = signal(false, ...(ngDevMode ? [{ debugName: "isSubmitting" }] : []));
|
|
2396
|
+
this.previousContext = signal({}, ...(ngDevMode ? [{ debugName: "previousContext" }] : []));
|
|
2397
|
+
this.formData = signal({}, ...(ngDevMode ? [{ debugName: "formData" }] : []));
|
|
2398
|
+
// This will be set by the popup service automatically
|
|
2399
|
+
this.dialogResult = null;
|
|
2400
|
+
this.isSubmittingFromDialog = false;
|
|
2401
|
+
this.callBack = () => { };
|
|
2402
|
+
//#region ---- Computed Properties ----
|
|
2403
|
+
/**
|
|
2404
|
+
* Form context for widget container
|
|
2405
|
+
*/
|
|
2406
|
+
this.formContext = computed(() => this.formData(), ...(ngDevMode ? [{ debugName: "formContext" }] : []));
|
|
2407
|
+
/**
|
|
2408
|
+
* Combined loading state from both signal and dialog
|
|
2409
|
+
*/
|
|
2410
|
+
this.isFormLoading = computed(() => this.isSubmitting() || this.isSubmittingFromDialog, ...(ngDevMode ? [{ debugName: "isFormLoading" }] : []));
|
|
2411
|
+
this.defaultLayout = () => ({
|
|
2412
|
+
positions: {
|
|
2413
|
+
default: { colSpan: 12 },
|
|
2414
|
+
md: { colSpan: 8 },
|
|
2415
|
+
lg: { colSpan: 6 },
|
|
2416
|
+
xl: { colSpan: 5 },
|
|
2417
|
+
xxl: { colSpan: 4 },
|
|
2418
|
+
},
|
|
2419
|
+
});
|
|
2420
|
+
/**
|
|
2421
|
+
* Determine rendering mode and effective definitions
|
|
2422
|
+
*/
|
|
2423
|
+
this.hasLegacyForm = computed(() => !!this.config.formDefinition, ...(ngDevMode ? [{ debugName: "hasLegacyForm" }] : []));
|
|
2424
|
+
this.providedDefinition = computed(() => this.config.definition, ...(ngDevMode ? [{ debugName: "providedDefinition" }] : []));
|
|
2425
|
+
this.providedMode = computed(() => this.config.mode || 'edit', ...(ngDevMode ? [{ debugName: "providedMode" }] : []));
|
|
2426
|
+
this.isStepperDefinition = computed(() => {
|
|
2427
|
+
const def = this.providedDefinition();
|
|
2428
|
+
return !!def && Array.isArray(def?.steps) && def.steps.length > 1;
|
|
2429
|
+
}, ...(ngDevMode ? [{ debugName: "isStepperDefinition" }] : []));
|
|
2430
|
+
this.shouldRenderForm = computed(() => {
|
|
2431
|
+
if (this.hasLegacyForm())
|
|
2432
|
+
return true;
|
|
2433
|
+
const def = this.providedDefinition();
|
|
2434
|
+
// Render form when definition is form-like or single/no step
|
|
2435
|
+
if (!def)
|
|
2436
|
+
return false;
|
|
2437
|
+
if (Array.isArray(def?.steps)) {
|
|
2438
|
+
return def.steps.length <= 1;
|
|
2439
|
+
}
|
|
2440
|
+
// No steps property -> treat as AXPDynamicFormDefinition
|
|
2441
|
+
return true;
|
|
2442
|
+
}, ...(ngDevMode ? [{ debugName: "shouldRenderForm" }] : []));
|
|
2443
|
+
this.effectiveFormDefinition = computed(() => {
|
|
2444
|
+
if (this.config.formDefinition)
|
|
2445
|
+
return this.config.formDefinition;
|
|
2446
|
+
const def = this.providedDefinition();
|
|
2447
|
+
if (!def)
|
|
2448
|
+
return undefined;
|
|
2449
|
+
if (Array.isArray(def?.steps)) {
|
|
2450
|
+
// Single-step stepper -> convert to form def
|
|
2451
|
+
const step = def.steps[0];
|
|
2452
|
+
return step ? { groups: step.groups } : undefined;
|
|
2453
|
+
}
|
|
2454
|
+
return def;
|
|
2455
|
+
}, ...(ngDevMode ? [{ debugName: "effectiveFormDefinition" }] : []));
|
|
2456
|
+
this.resolvedFormDefinition = computed(() => {
|
|
2457
|
+
return (this.effectiveFormDefinition() ?? { groups: [] });
|
|
2458
|
+
}, ...(ngDevMode ? [{ debugName: "resolvedFormDefinition" }] : []));
|
|
2459
|
+
this.effectiveLayoutLook = computed(() => this.config.layoutLook ?? 'borderless', ...(ngDevMode ? [{ debugName: "effectiveLayoutLook" }] : []));
|
|
2460
|
+
this.effectiveLayoutConfig = computed(() => this.config.layoutConfig ?? this.defaultLayout(), ...(ngDevMode ? [{ debugName: "effectiveLayoutConfig" }] : []));
|
|
2461
|
+
// Stepper-only
|
|
2462
|
+
this.stepperGuardNext = computed(() => this.config.stepper?.guardNext, ...(ngDevMode ? [{ debugName: "stepperGuardNext" }] : []));
|
|
2463
|
+
this.stepperDirection = computed(() => this.config.stepper?.stepperDirection ?? 'horizontal', ...(ngDevMode ? [{ debugName: "stepperDirection" }] : []));
|
|
2464
|
+
this.stepperDefinition = computed(() => {
|
|
2465
|
+
const def = this.providedDefinition();
|
|
2466
|
+
return (def ?? { steps: [] });
|
|
2467
|
+
}, ...(ngDevMode ? [{ debugName: "stepperDefinition" }] : []));
|
|
2468
|
+
this.stepperIsFirst = computed(() => this.stepper()?.isFirst() ?? true, ...(ngDevMode ? [{ debugName: "stepperIsFirst" }] : []));
|
|
2469
|
+
this.stepperIsLast = computed(() => this.stepper()?.isLast() ?? false, ...(ngDevMode ? [{ debugName: "stepperIsLast" }] : []));
|
|
2470
|
+
/**
|
|
2471
|
+
* Effective form direction when rendering dynamic-form (single-step or legacy form).
|
|
2472
|
+
* If a single-step definition is provided and that step specifies formDirection, use it.
|
|
2473
|
+
*/
|
|
2474
|
+
this.effectiveFormDirection = computed(() => {
|
|
2475
|
+
if (this.hasLegacyForm()) {
|
|
2476
|
+
return 'vertical';
|
|
2477
|
+
}
|
|
2478
|
+
const def = this.providedDefinition();
|
|
2479
|
+
if (def && Array.isArray(def?.steps) && def.steps.length === 1) {
|
|
2480
|
+
return def.steps[0]?.formDirection ?? 'vertical';
|
|
2481
|
+
}
|
|
2482
|
+
return 'vertical';
|
|
2483
|
+
}, ...(ngDevMode ? [{ debugName: "effectiveFormDirection" }] : []));
|
|
2484
|
+
/**
|
|
2485
|
+
* Footer actions for dynamic button system
|
|
2486
|
+
*/
|
|
2487
|
+
this.footerPrefixActions = computed(() => this.config.actions?.footer?.prefix || [], ...(ngDevMode ? [{ debugName: "footerPrefixActions" }] : []));
|
|
2488
|
+
this.footerSuffixActions = computed(() => this.config.actions?.footer?.suffix || [], ...(ngDevMode ? [{ debugName: "footerSuffixActions" }] : []));
|
|
2489
|
+
this.visibleFooterPrefixActions = computed(() => {
|
|
2490
|
+
const prefixFooterActions = this.footerPrefixActions();
|
|
2491
|
+
return prefixFooterActions.filter((action) => action.visible != false);
|
|
2492
|
+
}, ...(ngDevMode ? [{ debugName: "visibleFooterPrefixActions" }] : []));
|
|
2493
|
+
this.visibleFooterSuffixActions = computed(() => {
|
|
2494
|
+
const suffixFooterActions = this.footerSuffixActions();
|
|
2495
|
+
return suffixFooterActions.filter((action) => action.visible != false);
|
|
2496
|
+
}, ...(ngDevMode ? [{ debugName: "visibleFooterSuffixActions" }] : []));
|
|
2497
|
+
this.hasFooterActions = computed(() => {
|
|
2498
|
+
const prefixActions = this.visibleFooterPrefixActions();
|
|
2499
|
+
const suffixActions = this.visibleFooterSuffixActions();
|
|
2500
|
+
return prefixActions.length > 0 || suffixActions.length > 0;
|
|
2501
|
+
}, ...(ngDevMode ? [{ debugName: "hasFooterActions" }] : []));
|
|
2502
|
+
/** Stepper footer: choose a single confirm action from provided suffix actions (first visible). */
|
|
2503
|
+
this.confirmAction = computed(() => {
|
|
2504
|
+
const items = this.footerSuffixActions();
|
|
2505
|
+
return items.find((a) => a.visible !== false);
|
|
2506
|
+
}, ...(ngDevMode ? [{ debugName: "confirmAction" }] : []));
|
|
2507
|
+
this.confirmActionTitle = computed(() => this.confirmAction()?.title ?? 'Confirm', ...(ngDevMode ? [{ debugName: "confirmActionTitle" }] : []));
|
|
2508
|
+
}
|
|
2509
|
+
//#endregion
|
|
2510
|
+
//#region ---- Lifecycle Methods ----
|
|
2511
|
+
ngOnInit() {
|
|
2512
|
+
this.formData.set(this.config.context ?? {});
|
|
2513
|
+
}
|
|
2514
|
+
//#endregion
|
|
2515
|
+
//#region ---- Event Handlers ----
|
|
2516
|
+
handleContextInitiated(context) {
|
|
2517
|
+
this.previousContext.set(context);
|
|
2518
|
+
}
|
|
2519
|
+
handleContextChanged(context) {
|
|
2520
|
+
this.formData.set(context);
|
|
2521
|
+
}
|
|
2522
|
+
//#endregion
|
|
2523
|
+
//#region ---- Action Execution ----
|
|
2524
|
+
/**
|
|
2525
|
+
* Execute a dynamic action
|
|
2526
|
+
*/
|
|
2527
|
+
async executeAction(action) {
|
|
2528
|
+
if (action.command) {
|
|
2529
|
+
// Execute the command if provided
|
|
2530
|
+
await this.executeCommand(action.command);
|
|
2531
|
+
}
|
|
2532
|
+
else {
|
|
2533
|
+
// Handle custom action logic here
|
|
2534
|
+
const result = {
|
|
2535
|
+
context: this.formData(),
|
|
2536
|
+
action: action.name || action.title,
|
|
2537
|
+
};
|
|
2538
|
+
this.close(result);
|
|
2539
|
+
}
|
|
2540
|
+
}
|
|
2541
|
+
/**
|
|
2542
|
+
* Execute a command
|
|
2543
|
+
*/
|
|
2544
|
+
async executeCommand(command) {
|
|
2545
|
+
// Handle command execution logic here
|
|
2546
|
+
if (command.options?.['validate'] == true) {
|
|
2547
|
+
if (!(await this.isFormValid())) {
|
|
2548
|
+
return;
|
|
2549
|
+
}
|
|
2550
|
+
}
|
|
2551
|
+
//
|
|
2552
|
+
if (command.name == 'cancel') {
|
|
2553
|
+
this.close();
|
|
2554
|
+
}
|
|
2555
|
+
const result = {
|
|
2556
|
+
context: this.formData(),
|
|
2557
|
+
action: command.name,
|
|
2558
|
+
};
|
|
2559
|
+
// Store result in component property and popup data
|
|
2560
|
+
this.dialogResult = result;
|
|
2561
|
+
// Store in popup data for DialogRef access
|
|
2562
|
+
if (this.data) {
|
|
2563
|
+
this.data.context = result.context;
|
|
2564
|
+
this.data.action = result.action;
|
|
2565
|
+
}
|
|
2566
|
+
// Call the callback with DialogRef
|
|
2567
|
+
this.callBack({
|
|
2568
|
+
close: (result) => {
|
|
2569
|
+
this.close(result);
|
|
2570
|
+
},
|
|
2571
|
+
context: () => {
|
|
2572
|
+
return this.formData();
|
|
2573
|
+
},
|
|
2574
|
+
action: () => {
|
|
2575
|
+
return result.action;
|
|
2576
|
+
},
|
|
2577
|
+
setLoading: (loading) => {
|
|
2578
|
+
this.isSubmitting.set(loading);
|
|
2579
|
+
},
|
|
2580
|
+
});
|
|
2581
|
+
}
|
|
2582
|
+
//#endregion
|
|
2583
|
+
//#region ---- Public Methods ----
|
|
2584
|
+
/**
|
|
2585
|
+
* Check if form is valid
|
|
2586
|
+
*/
|
|
2587
|
+
async isFormValid() {
|
|
2588
|
+
if (this.isStepperDefinition()) {
|
|
2589
|
+
return (await this.stepper()?.validateCurrentStep()) ?? false;
|
|
2590
|
+
}
|
|
2591
|
+
return (await this.dynamicForm()?.validate()) ?? false;
|
|
2592
|
+
}
|
|
2593
|
+
/** Stepper navigation handlers */
|
|
2594
|
+
goPrev() {
|
|
2595
|
+
this.stepper()?.previous();
|
|
2596
|
+
}
|
|
2597
|
+
goNext() {
|
|
2598
|
+
this.stepper()?.next();
|
|
2599
|
+
}
|
|
2600
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPDynamicDialogComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
2601
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.8", type: AXPDynamicDialogComponent, isStandalone: true, selector: "axp-dynamic-dialog", inputs: { config: "config" }, viewQueries: [{ propertyName: "dynamicForm", first: true, predicate: AXPDynamicFormComponent, descendants: true, isSignal: true }, { propertyName: "stepper", first: true, predicate: AXPDynamicFormStepperComponent, descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "@if (shouldRenderForm()) {\n <div class=\"ax-p-4\">\n <axp-dynamic-form\n [formDefinition]=\"resolvedFormDefinition()\"\n [context]=\"formContext()\"\n [mode]=\"providedMode()\"\n [layoutConfig]=\"effectiveLayoutConfig()\"\n [layoutLook]=\"effectiveLayoutLook()\"\n [layoutDirection]=\"effectiveFormDirection()\"\n (contextChange)=\"handleContextChanged($event)\"\n (contextInitiated)=\"handleContextInitiated($event)\"\n >\n </axp-dynamic-form>\n </div>\n\n <ax-footer>\n <ax-prefix>\n <ng-container *ngTemplateOutlet=\"footerPrefixActions\"></ng-container>\n </ax-prefix>\n <ax-suffix>\n <ng-container *ngTemplateOutlet=\"footerSuffixActions\"></ng-container>\n </ax-suffix>\n </ax-footer>\n} @else {\n <div class=\"ax-p-4\">\n <axp-dynamic-form-stepper\n #stepperRef\n [definition]=\"stepperDefinition()\"\n [context]=\"formContext()\"\n [layoutLook]=\"effectiveLayoutLook()\"\n [layoutConfig]=\"effectiveLayoutConfig()\"\n [stepperDirection]=\"stepperDirection()\"\n [guardNext]=\"stepperGuardNext()\"\n (contextChange)=\"handleContextChanged($event)\"\n >\n </axp-dynamic-form-stepper>\n </div>\n\n <ax-footer>\n <ax-prefix>\n <ax-button\n [disabled]=\"stepperIsFirst()\"\n [text]=\"'@general:actions.previous.title' | translate | async\"\n [look]=\"'outline'\"\n (onClick)=\"goPrev()\"\n ></ax-button>\n </ax-prefix>\n <ax-suffix>\n @if (!stepperIsLast()) {\n <ax-button\n [text]=\"'@general:actions.next.title' | translate | async\"\n [color]=\"'primary'\"\n (onClick)=\"goNext()\"\n ></ax-button>\n } @else {\n <ax-suffix>\n <ng-container *ngTemplateOutlet=\"footerSuffixActions\"></ng-container>\n </ax-suffix>\n }\n </ax-suffix>\n </ax-footer>\n}\n<!-- Footer Prefix Actions -->\n<ng-template #footerPrefixActions>\n @for (action of visibleFooterPrefixActions(); track $index) {\n <ax-button\n [disabled]=\"action.disabled || isFormLoading()\"\n [text]=\"(action.title | translate | async)!\"\n [look]=\"'outline'\"\n [color]=\"action.color\"\n (onClick)=\"executeAction(action)\"\n >\n @if (isFormLoading() && action.command?.name != 'cancel') {\n <ax-loading></ax-loading>\n }\n <ax-prefix>\n <i class=\"{{ action.icon }}\"></i>\n </ax-prefix>\n </ax-button>\n }\n</ng-template>\n\n<!-- Footer Suffix Actions -->\n<ng-template #footerSuffixActions>\n @for (action of visibleFooterSuffixActions(); track $index) {\n @if (action?.items && (action?.items?.length ?? 0) > 0) {\n <ax-dropdown-button\n [disabled]=\"action.disabled || isSubmitting()\"\n [text]=\"(action.title | translate | async)!\"\n [look]=\"'solid'\"\n [color]=\"action.color\"\n (onClick)=\"executeAction(action)\"\n >\n @if (action.icon) {\n <ax-prefix>\n <ax-icon icon=\"{{ action.icon }}\"></ax-icon>\n </ax-prefix>\n }\n <ax-button-item-list>\n @for (sub of action?.items; track $index) {\n <ax-button-item\n [text]=\"(sub.title | translate | async)!\"\n [color]=\"sub.color\"\n [disabled]=\"sub.disabled\"\n (onClick)=\"executeAction(sub)\"\n >\n @if (sub.icon) {\n <ax-prefix>\n <ax-icon icon=\"{{ sub.icon }}\"></ax-icon>\n </ax-prefix>\n }\n </ax-button-item>\n @if (sub.break) {\n <ax-divider></ax-divider>\n }\n }\n </ax-button-item-list>\n </ax-dropdown-button>\n } @else {\n <ax-button\n [disabled]=\"action.disabled || isSubmitting()\"\n [text]=\"(action.title | translate | async)!\"\n [look]=\"'solid'\"\n [color]=\"action.color\"\n (onClick)=\"executeAction(action)\"\n >\n @if (action.icon) {\n <ax-prefix>\n <ax-icon icon=\"{{ action.icon }}\"></ax-icon>\n </ax-prefix>\n }\n </ax-button>\n }\n }\n</ng-template>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type:
|
|
2602
|
+
//
|
|
2603
|
+
AXFormModule }, { kind: "ngmodule", type: AXValidationModule }, { kind: "component", type: AXPDynamicFormComponent, selector: "axp-dynamic-form", inputs: ["formDefinition", "context", "layoutLook", "layoutDirection", "mode", "layoutConfig"], outputs: ["contextChange", "contextInitiated", "validityChange"] }, { kind: "component", type: AXPDynamicFormStepperComponent, selector: "axp-dynamic-form-stepper", inputs: ["definition", "context", "layoutLook", "stepperDirection", "layoutConfig", "guardNext"], outputs: ["contextChange", "stepChange", "finished", "cancel", "navigationBlocked"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i2$1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i3.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "component", type: i3.AXButtonItemComponent, selector: "ax-button-item", inputs: ["color", "disabled", "text", "selected", "divided", "data", "name"], outputs: ["onClick", "onFocus", "onBlur", "disabledChange"] }, { kind: "component", type: i3.AXButtonItemListComponent, selector: "ax-button-item-list", inputs: ["items"], outputs: ["onItemClick"] }, { kind: "ngmodule", type: AXDropdownButtonModule }, { kind: "component", type: i4$3.AXDropdownButtonComponent, selector: "ax-dropdown-button", inputs: ["disabled", "size", "color", "look", "text", "type", "mode"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "lookChange", "colorChange", "disabledChange"] }, { kind: "ngmodule", type: AXDropdownModule }, { kind: "ngmodule", type: AXLoadingModule }, { kind: "component", type: i5$1.AXLoadingComponent, selector: "ax-loading", inputs: ["visible", "type", "context"], outputs: ["visibleChange"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2604
|
+
}
|
|
2605
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPDynamicDialogComponent, decorators: [{
|
|
2606
|
+
type: Component,
|
|
2607
|
+
args: [{ selector: 'axp-dynamic-dialog', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
2608
|
+
CommonModule,
|
|
2609
|
+
//
|
|
2610
|
+
AXFormModule,
|
|
2611
|
+
AXValidationModule,
|
|
2612
|
+
AXPDynamicFormComponent,
|
|
2613
|
+
AXPDynamicFormStepperComponent,
|
|
2614
|
+
AXDecoratorModule,
|
|
2615
|
+
AXButtonModule,
|
|
2616
|
+
AXDropdownButtonModule,
|
|
2617
|
+
AXDropdownModule,
|
|
2618
|
+
AXLoadingModule,
|
|
2619
|
+
AXTranslationModule,
|
|
2620
|
+
], template: "@if (shouldRenderForm()) {\n <div class=\"ax-p-4\">\n <axp-dynamic-form\n [formDefinition]=\"resolvedFormDefinition()\"\n [context]=\"formContext()\"\n [mode]=\"providedMode()\"\n [layoutConfig]=\"effectiveLayoutConfig()\"\n [layoutLook]=\"effectiveLayoutLook()\"\n [layoutDirection]=\"effectiveFormDirection()\"\n (contextChange)=\"handleContextChanged($event)\"\n (contextInitiated)=\"handleContextInitiated($event)\"\n >\n </axp-dynamic-form>\n </div>\n\n <ax-footer>\n <ax-prefix>\n <ng-container *ngTemplateOutlet=\"footerPrefixActions\"></ng-container>\n </ax-prefix>\n <ax-suffix>\n <ng-container *ngTemplateOutlet=\"footerSuffixActions\"></ng-container>\n </ax-suffix>\n </ax-footer>\n} @else {\n <div class=\"ax-p-4\">\n <axp-dynamic-form-stepper\n #stepperRef\n [definition]=\"stepperDefinition()\"\n [context]=\"formContext()\"\n [layoutLook]=\"effectiveLayoutLook()\"\n [layoutConfig]=\"effectiveLayoutConfig()\"\n [stepperDirection]=\"stepperDirection()\"\n [guardNext]=\"stepperGuardNext()\"\n (contextChange)=\"handleContextChanged($event)\"\n >\n </axp-dynamic-form-stepper>\n </div>\n\n <ax-footer>\n <ax-prefix>\n <ax-button\n [disabled]=\"stepperIsFirst()\"\n [text]=\"'@general:actions.previous.title' | translate | async\"\n [look]=\"'outline'\"\n (onClick)=\"goPrev()\"\n ></ax-button>\n </ax-prefix>\n <ax-suffix>\n @if (!stepperIsLast()) {\n <ax-button\n [text]=\"'@general:actions.next.title' | translate | async\"\n [color]=\"'primary'\"\n (onClick)=\"goNext()\"\n ></ax-button>\n } @else {\n <ax-suffix>\n <ng-container *ngTemplateOutlet=\"footerSuffixActions\"></ng-container>\n </ax-suffix>\n }\n </ax-suffix>\n </ax-footer>\n}\n<!-- Footer Prefix Actions -->\n<ng-template #footerPrefixActions>\n @for (action of visibleFooterPrefixActions(); track $index) {\n <ax-button\n [disabled]=\"action.disabled || isFormLoading()\"\n [text]=\"(action.title | translate | async)!\"\n [look]=\"'outline'\"\n [color]=\"action.color\"\n (onClick)=\"executeAction(action)\"\n >\n @if (isFormLoading() && action.command?.name != 'cancel') {\n <ax-loading></ax-loading>\n }\n <ax-prefix>\n <i class=\"{{ action.icon }}\"></i>\n </ax-prefix>\n </ax-button>\n }\n</ng-template>\n\n<!-- Footer Suffix Actions -->\n<ng-template #footerSuffixActions>\n @for (action of visibleFooterSuffixActions(); track $index) {\n @if (action?.items && (action?.items?.length ?? 0) > 0) {\n <ax-dropdown-button\n [disabled]=\"action.disabled || isSubmitting()\"\n [text]=\"(action.title | translate | async)!\"\n [look]=\"'solid'\"\n [color]=\"action.color\"\n (onClick)=\"executeAction(action)\"\n >\n @if (action.icon) {\n <ax-prefix>\n <ax-icon icon=\"{{ action.icon }}\"></ax-icon>\n </ax-prefix>\n }\n <ax-button-item-list>\n @for (sub of action?.items; track $index) {\n <ax-button-item\n [text]=\"(sub.title | translate | async)!\"\n [color]=\"sub.color\"\n [disabled]=\"sub.disabled\"\n (onClick)=\"executeAction(sub)\"\n >\n @if (sub.icon) {\n <ax-prefix>\n <ax-icon icon=\"{{ sub.icon }}\"></ax-icon>\n </ax-prefix>\n }\n </ax-button-item>\n @if (sub.break) {\n <ax-divider></ax-divider>\n }\n }\n </ax-button-item-list>\n </ax-dropdown-button>\n } @else {\n <ax-button\n [disabled]=\"action.disabled || isSubmitting()\"\n [text]=\"(action.title | translate | async)!\"\n [look]=\"'solid'\"\n [color]=\"action.color\"\n (onClick)=\"executeAction(action)\"\n >\n @if (action.icon) {\n <ax-prefix>\n <ax-icon icon=\"{{ action.icon }}\"></ax-icon>\n </ax-prefix>\n }\n </ax-button>\n }\n }\n</ng-template>\n" }]
|
|
2621
|
+
}], propDecorators: { config: [{
|
|
2622
|
+
type: Input,
|
|
2623
|
+
args: [{ required: true }]
|
|
2624
|
+
}] } });
|
|
2625
|
+
|
|
2626
|
+
var dynamicDialog_component = /*#__PURE__*/Object.freeze({
|
|
2627
|
+
__proto__: null,
|
|
2628
|
+
AXPDynamicDialogComponent: AXPDynamicDialogComponent
|
|
2629
|
+
});
|
|
2630
|
+
|
|
2631
|
+
class AXPDynamicDialogService {
|
|
2632
|
+
constructor() {
|
|
2633
|
+
this.popupService = inject(AXPopupService);
|
|
2634
|
+
}
|
|
2635
|
+
/**
|
|
2636
|
+
* Show a dynamic dialog with the given configuration
|
|
2637
|
+
* @param config Dialog configuration including fields, validation, and UI options
|
|
2638
|
+
* @returns Promise resolving to dialog reference for controlling the dialog
|
|
2639
|
+
*/
|
|
2640
|
+
async showDialog(config) {
|
|
2641
|
+
const component = await Promise.resolve().then(function () { return dynamicDialog_component; }).then(c => c.AXPDynamicDialogComponent);
|
|
2642
|
+
return new Promise(async (resolve) => {
|
|
2643
|
+
// Open popup and wait for it to close
|
|
2644
|
+
await this.popupService.open(component, {
|
|
2645
|
+
title: config.title,
|
|
2646
|
+
size: config.size || 'md',
|
|
2647
|
+
closeButton: config.closeButton,
|
|
2648
|
+
closeOnBackdropClick: false,
|
|
2649
|
+
draggable: false,
|
|
2650
|
+
data: {
|
|
2651
|
+
config,
|
|
2652
|
+
dialogResult: null,
|
|
2653
|
+
isSubmittingFromDialog: false,
|
|
2654
|
+
callBack: (result) => {
|
|
2655
|
+
resolve(result);
|
|
2656
|
+
}
|
|
2657
|
+
}
|
|
2658
|
+
});
|
|
2659
|
+
});
|
|
2660
|
+
}
|
|
2661
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPDynamicDialogService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
2662
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPDynamicDialogService, providedIn: 'root' }); }
|
|
2663
|
+
}
|
|
2664
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPDynamicDialogService, decorators: [{
|
|
2665
|
+
type: Injectable,
|
|
2666
|
+
args: [{
|
|
2667
|
+
providedIn: 'root'
|
|
2668
|
+
}]
|
|
2669
|
+
}] });
|
|
2670
|
+
|
|
2671
|
+
class AXPDynamicFormBuilderService {
|
|
2672
|
+
constructor() {
|
|
2673
|
+
//#region ---- Services & Dependencies ----
|
|
2674
|
+
this.dialogService = inject(AXPDynamicDialogService);
|
|
2675
|
+
}
|
|
2676
|
+
//#endregion
|
|
2677
|
+
//#region ---- Public Methods ----
|
|
2678
|
+
/**
|
|
2679
|
+
* Create a new form builder
|
|
2680
|
+
*/
|
|
2681
|
+
form() {
|
|
2682
|
+
return new FormBuilder();
|
|
2683
|
+
}
|
|
2684
|
+
/**
|
|
2685
|
+
* Create a new dialog builder
|
|
2686
|
+
*/
|
|
2687
|
+
dialog() {
|
|
2688
|
+
return new DialogBuilder(this.dialogService);
|
|
2689
|
+
}
|
|
2690
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPDynamicFormBuilderService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
2691
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPDynamicFormBuilderService, providedIn: 'root' }); }
|
|
2692
|
+
}
|
|
2693
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPDynamicFormBuilderService, decorators: [{
|
|
2694
|
+
type: Injectable,
|
|
2695
|
+
args: [{
|
|
2696
|
+
providedIn: 'root',
|
|
2697
|
+
}]
|
|
2698
|
+
}] });
|
|
2699
|
+
//#region ---- Form Builder Implementation ----
|
|
2700
|
+
class FormBuilder {
|
|
2701
|
+
constructor() {
|
|
2702
|
+
this.state = {
|
|
2703
|
+
groups: [],
|
|
2704
|
+
layoutConfig: {
|
|
2705
|
+
positions: {
|
|
2706
|
+
default: { colSpan: 12 },
|
|
2707
|
+
md: { colSpan: 8 },
|
|
2708
|
+
lg: { colSpan: 6 },
|
|
2709
|
+
xl: { colSpan: 5 },
|
|
2710
|
+
xxl: { colSpan: 4 },
|
|
2711
|
+
},
|
|
2712
|
+
},
|
|
2713
|
+
look: 'normal',
|
|
2714
|
+
direction: 'vertical',
|
|
2715
|
+
};
|
|
2716
|
+
}
|
|
2717
|
+
group(name, delegate) {
|
|
2718
|
+
const groupBuilder = new GroupBuilder(this, name);
|
|
2719
|
+
if (delegate) {
|
|
2720
|
+
delegate(groupBuilder);
|
|
2721
|
+
}
|
|
2722
|
+
this.addGroup(groupBuilder.build());
|
|
2723
|
+
return this;
|
|
2724
|
+
}
|
|
2725
|
+
layout(config) {
|
|
2726
|
+
this.state.layoutConfig = { ...this.state.layoutConfig, ...config };
|
|
2727
|
+
return this;
|
|
2728
|
+
}
|
|
2729
|
+
look(look) {
|
|
2730
|
+
this.state.look = look;
|
|
2731
|
+
return this;
|
|
2732
|
+
}
|
|
2733
|
+
direction(direction) {
|
|
2734
|
+
this.state.direction = direction;
|
|
2735
|
+
return this;
|
|
2736
|
+
}
|
|
2737
|
+
mode(mode) {
|
|
2738
|
+
this.state.mode = mode;
|
|
2739
|
+
return this;
|
|
2740
|
+
}
|
|
2741
|
+
build() {
|
|
2742
|
+
return {
|
|
2743
|
+
groups: this.state.groups,
|
|
2744
|
+
mode: this.state.mode,
|
|
2745
|
+
};
|
|
2746
|
+
}
|
|
2747
|
+
addGroup(group) {
|
|
2748
|
+
this.state.groups.push(group);
|
|
2749
|
+
}
|
|
2750
|
+
}
|
|
2751
|
+
//#endregion
|
|
2752
|
+
//#region ---- Group Builder Implementation ----
|
|
2753
|
+
class GroupBuilder {
|
|
2754
|
+
constructor(formBuilder, name) {
|
|
2755
|
+
this.formBuilder = formBuilder;
|
|
2756
|
+
this.groupState = {
|
|
2757
|
+
name: '',
|
|
2758
|
+
title: '',
|
|
2759
|
+
description: '',
|
|
2760
|
+
parameters: [],
|
|
2761
|
+
};
|
|
2762
|
+
this.groupState.name = name;
|
|
2763
|
+
}
|
|
2764
|
+
title(title) {
|
|
2765
|
+
this.groupState.title = title;
|
|
2766
|
+
return this;
|
|
2767
|
+
}
|
|
2768
|
+
description(description) {
|
|
2769
|
+
this.groupState.description = description;
|
|
2770
|
+
return this;
|
|
2771
|
+
}
|
|
2772
|
+
mode(mode) {
|
|
2773
|
+
this.groupState.mode = mode;
|
|
2774
|
+
return this;
|
|
2775
|
+
}
|
|
2776
|
+
field(path, delegate) {
|
|
2777
|
+
const fieldBuilder = new FieldBuilder(this, path);
|
|
2778
|
+
if (delegate) {
|
|
2779
|
+
delegate(fieldBuilder);
|
|
2780
|
+
}
|
|
2781
|
+
this.addField(fieldBuilder.build());
|
|
2782
|
+
return this;
|
|
2783
|
+
}
|
|
2784
|
+
group(name, delegate) {
|
|
2785
|
+
const nestedGroupBuilder = new GroupBuilder(this.formBuilder, name);
|
|
2786
|
+
if (delegate) {
|
|
2787
|
+
delegate(nestedGroupBuilder);
|
|
2788
|
+
}
|
|
2789
|
+
this.addGroup(nestedGroupBuilder.build());
|
|
2790
|
+
return this;
|
|
2791
|
+
}
|
|
2792
|
+
build() {
|
|
2793
|
+
return {
|
|
2794
|
+
name: this.groupState.name,
|
|
2795
|
+
title: this.groupState.title,
|
|
2796
|
+
description: this.groupState.description,
|
|
2797
|
+
parameters: this.groupState.parameters,
|
|
2798
|
+
mode: this.groupState.mode,
|
|
2799
|
+
};
|
|
2800
|
+
}
|
|
2801
|
+
addField(field) {
|
|
2802
|
+
this.groupState.parameters.push(field);
|
|
2803
|
+
}
|
|
2804
|
+
addGroup(group) {
|
|
2805
|
+
// For nested groups, we add them to the parent form builder
|
|
2806
|
+
this.formBuilder['addGroup'](group);
|
|
2807
|
+
}
|
|
2808
|
+
}
|
|
2809
|
+
//#endregion
|
|
2810
|
+
//#region ---- Field Builder Implementation ----
|
|
2811
|
+
class FieldBuilder {
|
|
2812
|
+
constructor(groupBuilder, path) {
|
|
2813
|
+
this.groupBuilder = groupBuilder;
|
|
2814
|
+
this.fieldState = {
|
|
2815
|
+
path: '',
|
|
2816
|
+
title: '',
|
|
2817
|
+
description: '',
|
|
2818
|
+
defaultValue: undefined,
|
|
2819
|
+
hidden: undefined,
|
|
2820
|
+
readonly: undefined,
|
|
2821
|
+
disabled: undefined,
|
|
2822
|
+
widget: undefined,
|
|
2823
|
+
};
|
|
2824
|
+
this.fieldState.path = path;
|
|
2825
|
+
this.fieldState.title = path;
|
|
2826
|
+
}
|
|
2827
|
+
//#region ---- Utility Methods ----
|
|
2828
|
+
/**
|
|
2829
|
+
* Merge provided widget options with field-level options
|
|
2830
|
+
*/
|
|
2831
|
+
mergeWithFieldOptions(options) {
|
|
2832
|
+
return {
|
|
2833
|
+
hidden: this.fieldState.hidden,
|
|
2834
|
+
readonly: this.fieldState.readonly,
|
|
2835
|
+
disabled: this.fieldState.disabled,
|
|
2836
|
+
...options,
|
|
2837
|
+
};
|
|
2838
|
+
}
|
|
2839
|
+
//#endregion
|
|
2840
|
+
title(title) {
|
|
2841
|
+
this.fieldState.title = title;
|
|
2842
|
+
return this;
|
|
2843
|
+
}
|
|
2844
|
+
description(description) {
|
|
2845
|
+
this.fieldState.description = description;
|
|
2846
|
+
return this;
|
|
2847
|
+
}
|
|
2848
|
+
mode(mode) {
|
|
2849
|
+
this.fieldState.mode = mode;
|
|
2850
|
+
return this;
|
|
2851
|
+
}
|
|
2852
|
+
options(options) {
|
|
2853
|
+
this.fieldState.defaultValue = options['defaultValue'];
|
|
2854
|
+
this.fieldState.hidden = options['hidden'];
|
|
2855
|
+
this.fieldState.readonly = options['readonly'];
|
|
2856
|
+
this.fieldState.disabled = options['disabled'];
|
|
2857
|
+
return this;
|
|
2858
|
+
}
|
|
2859
|
+
layout(layout) {
|
|
2860
|
+
this.fieldState.layout = layout;
|
|
2861
|
+
return this;
|
|
2862
|
+
}
|
|
2863
|
+
textBox(options) {
|
|
2864
|
+
this.fieldState.widget = {
|
|
2865
|
+
type: 'text-editor',
|
|
2866
|
+
path: this.fieldState.path,
|
|
2867
|
+
defaultValue: this.fieldState.defaultValue,
|
|
2868
|
+
options: this.mergeWithFieldOptions(options),
|
|
2869
|
+
};
|
|
2870
|
+
return this;
|
|
2871
|
+
}
|
|
2872
|
+
largeTextBox(options) {
|
|
2873
|
+
this.fieldState.widget = {
|
|
2874
|
+
type: 'large-text-editor',
|
|
2875
|
+
path: this.fieldState.path,
|
|
2876
|
+
defaultValue: this.fieldState.defaultValue,
|
|
2877
|
+
options: this.mergeWithFieldOptions(options),
|
|
2878
|
+
};
|
|
2879
|
+
return this;
|
|
2880
|
+
}
|
|
2881
|
+
richText(options) {
|
|
2882
|
+
this.fieldState.widget = {
|
|
2883
|
+
type: 'rich-text-editor',
|
|
2884
|
+
path: this.fieldState.path,
|
|
2885
|
+
defaultValue: this.fieldState.defaultValue,
|
|
2886
|
+
options: this.mergeWithFieldOptions(options),
|
|
2887
|
+
};
|
|
2888
|
+
return this;
|
|
2889
|
+
}
|
|
2890
|
+
passwordBox(options) {
|
|
2891
|
+
this.fieldState.widget = {
|
|
2892
|
+
type: 'password-editor',
|
|
2893
|
+
path: this.fieldState.path,
|
|
2894
|
+
defaultValue: this.fieldState.defaultValue,
|
|
2895
|
+
options: this.mergeWithFieldOptions(options),
|
|
2896
|
+
};
|
|
2897
|
+
return this;
|
|
2898
|
+
}
|
|
2899
|
+
selectBox(options) {
|
|
2900
|
+
this.fieldState.widget = {
|
|
2901
|
+
type: 'select-editor',
|
|
2902
|
+
path: this.fieldState.path,
|
|
2903
|
+
defaultValue: this.fieldState.defaultValue,
|
|
2904
|
+
options: this.mergeWithFieldOptions(options),
|
|
2905
|
+
};
|
|
2906
|
+
return this;
|
|
2907
|
+
}
|
|
2908
|
+
selectionList(options) {
|
|
2909
|
+
this.fieldState.widget = {
|
|
2910
|
+
type: 'selection-list-editor',
|
|
2911
|
+
path: this.fieldState.path,
|
|
2912
|
+
defaultValue: this.fieldState.defaultValue,
|
|
2913
|
+
options: this.mergeWithFieldOptions(options),
|
|
2914
|
+
};
|
|
2915
|
+
return this;
|
|
2916
|
+
}
|
|
2917
|
+
lookupBox(options) {
|
|
2918
|
+
this.fieldState.widget = {
|
|
2919
|
+
type: 'lookup-editor',
|
|
2920
|
+
path: this.fieldState.path,
|
|
2921
|
+
defaultValue: this.fieldState.defaultValue,
|
|
2922
|
+
options: this.mergeWithFieldOptions(options),
|
|
2923
|
+
};
|
|
2924
|
+
return this;
|
|
2925
|
+
}
|
|
2926
|
+
numberBox(options) {
|
|
2927
|
+
this.fieldState.widget = {
|
|
2928
|
+
type: 'number-editor',
|
|
2929
|
+
path: this.fieldState.path,
|
|
2930
|
+
defaultValue: this.fieldState.defaultValue,
|
|
2931
|
+
options: this.mergeWithFieldOptions(options),
|
|
2932
|
+
};
|
|
2933
|
+
return this;
|
|
2934
|
+
}
|
|
2935
|
+
dateTimeBox(options) {
|
|
2936
|
+
this.fieldState.widget = {
|
|
2937
|
+
type: 'date-time-editor',
|
|
2938
|
+
path: this.fieldState.path,
|
|
2939
|
+
defaultValue: this.fieldState.defaultValue,
|
|
2940
|
+
options: this.mergeWithFieldOptions(options),
|
|
2941
|
+
};
|
|
2942
|
+
return this;
|
|
2943
|
+
}
|
|
2944
|
+
toggleSwitch(options) {
|
|
2945
|
+
this.fieldState.widget = {
|
|
2946
|
+
type: 'toggle-editor',
|
|
2947
|
+
path: this.fieldState.path,
|
|
2948
|
+
defaultValue: this.fieldState.defaultValue,
|
|
2949
|
+
options: this.mergeWithFieldOptions(options),
|
|
2950
|
+
};
|
|
2951
|
+
return this;
|
|
2952
|
+
}
|
|
2953
|
+
colorBox(options) {
|
|
2954
|
+
this.fieldState.widget = {
|
|
2955
|
+
type: 'color-editor',
|
|
2956
|
+
path: this.fieldState.path,
|
|
2957
|
+
defaultValue: this.fieldState.defaultValue,
|
|
2958
|
+
options: this.mergeWithFieldOptions(options),
|
|
2959
|
+
};
|
|
2960
|
+
return this;
|
|
2961
|
+
}
|
|
2962
|
+
widget(type, options) {
|
|
2963
|
+
this.fieldState.widget = {
|
|
2964
|
+
type,
|
|
2965
|
+
path: this.fieldState.path,
|
|
2966
|
+
defaultValue: this.fieldState.defaultValue,
|
|
2967
|
+
options: this.mergeWithFieldOptions(options),
|
|
2968
|
+
};
|
|
2969
|
+
return this;
|
|
2970
|
+
}
|
|
2971
|
+
build() {
|
|
2972
|
+
return {
|
|
2973
|
+
path: this.fieldState.path,
|
|
2974
|
+
title: this.fieldState.title,
|
|
2975
|
+
description: this.fieldState.description,
|
|
2976
|
+
widget: this.fieldState.widget,
|
|
2977
|
+
layout: this.fieldState.layout,
|
|
2978
|
+
mode: this.fieldState.mode,
|
|
2979
|
+
};
|
|
2980
|
+
}
|
|
2981
|
+
}
|
|
2982
|
+
//#endregion
|
|
2983
|
+
//#region ---- Dialog Builder Implementation ----
|
|
2984
|
+
class DialogBuilder extends FormBuilder {
|
|
2985
|
+
constructor(dialogService) {
|
|
2986
|
+
super();
|
|
2987
|
+
this.dialogService = dialogService;
|
|
2988
|
+
this.dialogState = {
|
|
2989
|
+
groups: [],
|
|
2990
|
+
steps: [],
|
|
2991
|
+
layoutConfig: {
|
|
2992
|
+
positions: {
|
|
2993
|
+
default: { colSpan: 12 },
|
|
2994
|
+
md: { colSpan: 8 },
|
|
2995
|
+
lg: { colSpan: 6 },
|
|
2996
|
+
xl: { colSpan: 5 },
|
|
2997
|
+
xxl: { colSpan: 4 },
|
|
2998
|
+
},
|
|
2999
|
+
},
|
|
3000
|
+
look: 'borderless',
|
|
3001
|
+
direction: 'vertical',
|
|
3002
|
+
mode: 'edit',
|
|
3003
|
+
closeButton: false,
|
|
3004
|
+
title: '',
|
|
3005
|
+
message: '',
|
|
3006
|
+
size: 'md',
|
|
3007
|
+
context: {},
|
|
3008
|
+
actions: {
|
|
3009
|
+
footer: {
|
|
3010
|
+
prefix: [],
|
|
3011
|
+
suffix: [],
|
|
3012
|
+
},
|
|
3013
|
+
},
|
|
3014
|
+
};
|
|
3015
|
+
}
|
|
3016
|
+
// Override to keep chaining within dialog context
|
|
3017
|
+
group(name, delegate) {
|
|
3018
|
+
super.group(name, delegate);
|
|
3019
|
+
return this;
|
|
3020
|
+
}
|
|
3021
|
+
step(id, delegate) {
|
|
3022
|
+
const builder = new StepBuilder(this, id);
|
|
3023
|
+
if (delegate) {
|
|
3024
|
+
delegate(builder);
|
|
3025
|
+
}
|
|
3026
|
+
this.dialogState.steps.push(builder.build());
|
|
3027
|
+
return this;
|
|
3028
|
+
}
|
|
3029
|
+
stepperDirection(direction) {
|
|
3030
|
+
this.dialogState.stepperDirection = direction;
|
|
3031
|
+
return this;
|
|
3032
|
+
}
|
|
3033
|
+
guardNext(guard) {
|
|
3034
|
+
this.dialogState.guardNext = guard;
|
|
3035
|
+
return this;
|
|
3036
|
+
}
|
|
3037
|
+
// Ensure dialog state mirrors form state and chaining type stays IDialogBuilder
|
|
3038
|
+
layout(config) {
|
|
3039
|
+
super.layout(config);
|
|
3040
|
+
this.dialogState.layoutConfig = { ...this.dialogState.layoutConfig, ...config };
|
|
3041
|
+
return this;
|
|
3042
|
+
}
|
|
3043
|
+
look(look) {
|
|
3044
|
+
super.look(look);
|
|
3045
|
+
this.dialogState.look = look;
|
|
3046
|
+
return this;
|
|
3047
|
+
}
|
|
3048
|
+
direction(direction) {
|
|
3049
|
+
super.direction(direction);
|
|
3050
|
+
this.dialogState.direction = direction;
|
|
3051
|
+
return this;
|
|
3052
|
+
}
|
|
3053
|
+
mode(mode) {
|
|
3054
|
+
console.log(mode);
|
|
3055
|
+
super.mode(mode);
|
|
3056
|
+
this.dialogState.mode = mode;
|
|
3057
|
+
return this;
|
|
3058
|
+
}
|
|
3059
|
+
closeButton(closeButton) {
|
|
3060
|
+
this.dialogState.closeButton = closeButton;
|
|
3061
|
+
return this;
|
|
3062
|
+
}
|
|
3063
|
+
title(title) {
|
|
3064
|
+
this.dialogState.title = title;
|
|
3065
|
+
return this;
|
|
3066
|
+
}
|
|
3067
|
+
message(message) {
|
|
3068
|
+
this.dialogState.message = message;
|
|
3069
|
+
return this;
|
|
3070
|
+
}
|
|
3071
|
+
size(size) {
|
|
3072
|
+
this.dialogState.size = size;
|
|
3073
|
+
return this;
|
|
3074
|
+
}
|
|
3075
|
+
context(context) {
|
|
3076
|
+
this.dialogState.context = context;
|
|
3077
|
+
return this;
|
|
3078
|
+
}
|
|
3079
|
+
actions(delegate) {
|
|
3080
|
+
const actionBuilder = new ActionBuilder(this);
|
|
3081
|
+
if (delegate) {
|
|
3082
|
+
delegate(actionBuilder);
|
|
3083
|
+
}
|
|
3084
|
+
return this;
|
|
3085
|
+
}
|
|
3086
|
+
async show() {
|
|
3087
|
+
const built = this.build();
|
|
3088
|
+
const hasSteps = this.dialogState.steps.length > 0;
|
|
3089
|
+
const config = {
|
|
3090
|
+
title: this.dialogState.title,
|
|
3091
|
+
message: this.dialogState.message,
|
|
3092
|
+
closeButton: this.dialogState.closeButton,
|
|
3093
|
+
definition: hasSteps
|
|
3094
|
+
? {
|
|
3095
|
+
steps: this.dialogState.steps.map((s) => ({
|
|
3096
|
+
id: s.id,
|
|
3097
|
+
title: s.title,
|
|
3098
|
+
description: s.description,
|
|
3099
|
+
icon: s.icon,
|
|
3100
|
+
groups: s.groups,
|
|
3101
|
+
formDirection: s.formDirection,
|
|
3102
|
+
})),
|
|
3103
|
+
}
|
|
3104
|
+
: {
|
|
3105
|
+
steps: [
|
|
3106
|
+
{
|
|
3107
|
+
id: 'form',
|
|
3108
|
+
groups: built.groups,
|
|
3109
|
+
formDirection: this.dialogState.direction,
|
|
3110
|
+
},
|
|
3111
|
+
],
|
|
3112
|
+
},
|
|
3113
|
+
context: this.dialogState.context,
|
|
3114
|
+
size: this.dialogState.size,
|
|
3115
|
+
actions: this.dialogState.actions,
|
|
3116
|
+
layoutConfig: this.dialogState.layoutConfig,
|
|
3117
|
+
layoutLook: this.dialogState.look,
|
|
3118
|
+
mode: this.dialogState.mode,
|
|
3119
|
+
stepper: hasSteps
|
|
3120
|
+
? {
|
|
3121
|
+
guardNext: this.dialogState.guardNext,
|
|
3122
|
+
stepperDirection: this.dialogState.stepperDirection,
|
|
3123
|
+
}
|
|
3124
|
+
: undefined,
|
|
3125
|
+
};
|
|
3126
|
+
return await this.dialogService.showDialog(config);
|
|
3127
|
+
}
|
|
3128
|
+
}
|
|
3129
|
+
//#endregion
|
|
3130
|
+
//#region ---- Action Builder Implementation ----
|
|
3131
|
+
class ActionBuilder {
|
|
3132
|
+
constructor(dialogBuilder) {
|
|
3133
|
+
this.dialogBuilder = dialogBuilder;
|
|
3134
|
+
}
|
|
3135
|
+
cancel(text) {
|
|
3136
|
+
if (!this.dialogBuilder['dialogState'].actions.footer.suffix) {
|
|
3137
|
+
this.dialogBuilder['dialogState'].actions.footer.suffix = [];
|
|
3138
|
+
}
|
|
3139
|
+
this.dialogBuilder['dialogState'].actions.footer.suffix.push({
|
|
3140
|
+
title: text || '@general:actions.cancel.title',
|
|
3141
|
+
icon: 'fa-times',
|
|
3142
|
+
color: 'default',
|
|
3143
|
+
command: { name: 'cancel' },
|
|
3144
|
+
});
|
|
3145
|
+
return this;
|
|
3146
|
+
}
|
|
3147
|
+
submit(text) {
|
|
3148
|
+
if (!this.dialogBuilder['dialogState'].actions.footer.suffix) {
|
|
3149
|
+
this.dialogBuilder['dialogState'].actions.footer.suffix = [];
|
|
3150
|
+
}
|
|
3151
|
+
this.dialogBuilder['dialogState'].actions.footer.suffix.push({
|
|
3152
|
+
title: text || '@general:actions.submit.title',
|
|
3153
|
+
icon: 'fa-check',
|
|
3154
|
+
color: 'primary',
|
|
3155
|
+
command: { name: 'submit', options: { validate: true } },
|
|
3156
|
+
});
|
|
3157
|
+
return this;
|
|
3158
|
+
}
|
|
3159
|
+
custom(action) {
|
|
3160
|
+
if (!this.dialogBuilder['dialogState'].actions.footer.suffix) {
|
|
3161
|
+
this.dialogBuilder['dialogState'].actions.footer.suffix = [];
|
|
3162
|
+
}
|
|
3163
|
+
this.dialogBuilder['dialogState'].actions.footer.suffix.push(action);
|
|
3164
|
+
return this;
|
|
3165
|
+
}
|
|
3166
|
+
}
|
|
3167
|
+
// #region ---- Step Builder Implementation ----
|
|
3168
|
+
class StepBuilder {
|
|
3169
|
+
constructor(dialogBuilder, id) {
|
|
3170
|
+
this.dialogBuilder = dialogBuilder;
|
|
3171
|
+
this.stepState = {
|
|
3172
|
+
id: '',
|
|
3173
|
+
groups: [],
|
|
3174
|
+
};
|
|
3175
|
+
this.stepState.id = id;
|
|
3176
|
+
}
|
|
3177
|
+
title(title) {
|
|
3178
|
+
this.stepState.title = title;
|
|
3179
|
+
return this;
|
|
3180
|
+
}
|
|
3181
|
+
description(description) {
|
|
3182
|
+
this.stepState.description = description;
|
|
3183
|
+
return this;
|
|
3184
|
+
}
|
|
3185
|
+
icon(icon) {
|
|
3186
|
+
this.stepState.icon = icon;
|
|
3187
|
+
return this;
|
|
3188
|
+
}
|
|
3189
|
+
direction(direction) {
|
|
3190
|
+
this.stepState.formDirection = direction;
|
|
3191
|
+
return this;
|
|
3192
|
+
}
|
|
3193
|
+
group(name, delegate) {
|
|
3194
|
+
const groupBuilder = new GroupBuilder(this.dialogBuilder, name);
|
|
3195
|
+
if (delegate) {
|
|
3196
|
+
delegate(groupBuilder);
|
|
3197
|
+
}
|
|
3198
|
+
this.stepState.groups.push(groupBuilder.build());
|
|
3199
|
+
return this;
|
|
3200
|
+
}
|
|
3201
|
+
build() {
|
|
3202
|
+
return this.stepState;
|
|
3203
|
+
}
|
|
3204
|
+
}
|
|
3205
|
+
|
|
3206
|
+
//#endregion
|
|
3207
|
+
|
|
3208
|
+
//#region ---- Imports ----
|
|
3209
|
+
//#endregion
|
|
3210
|
+
|
|
3211
|
+
//#endregion
|
|
3212
|
+
//#region ---- Injection Tokens ----
|
|
3213
|
+
/**
|
|
3214
|
+
* Injection token to provide available extra property types.
|
|
3215
|
+
*/
|
|
3216
|
+
const AXP_EXTRA_PROPERTY_TYPES = new InjectionToken('AXP_EXTRA_PROPERTY_TYPES');
|
|
3217
|
+
//#endregion
|
|
3218
|
+
|
|
3219
|
+
class AXPExtraPropertiesComponent {
|
|
3220
|
+
constructor() {
|
|
3221
|
+
//#region ---- Inputs ----
|
|
3222
|
+
this.items = input([], ...(ngDevMode ? [{ debugName: "items" }] : []));
|
|
3223
|
+
this.mode = input('edit', ...(ngDevMode ? [{ debugName: "mode" }] : []));
|
|
3224
|
+
//#endregion
|
|
3225
|
+
//#region ---- Outputs ----
|
|
3226
|
+
this.itemsChange = output();
|
|
3227
|
+
//#endregion
|
|
3228
|
+
//#region ---- Services & Dependencies ----
|
|
3229
|
+
this.providedTypes = inject(AXP_EXTRA_PROPERTY_TYPES, { optional: true }) ?? [];
|
|
3230
|
+
this.translationService = inject(AXTranslationService);
|
|
3231
|
+
//#endregion
|
|
3232
|
+
//#region ---- Class Properties ----
|
|
3233
|
+
this.newKey = signal('', ...(ngDevMode ? [{ debugName: "newKey" }] : []));
|
|
3234
|
+
this.newTitle = signal('', ...(ngDevMode ? [{ debugName: "newTitle" }] : []));
|
|
3235
|
+
this.newTypeId = signal('', ...(ngDevMode ? [{ debugName: "newTypeId" }] : []));
|
|
3236
|
+
this.newValue = signal(undefined, ...(ngDevMode ? [{ debugName: "newValue" }] : []));
|
|
3237
|
+
/** Local, ephemeral context for widget rendering */
|
|
3238
|
+
this.internalContext = signal({}, ...(ngDevMode ? [{ debugName: "internalContext" }] : []));
|
|
3239
|
+
this.lastTypeByKey = {};
|
|
3240
|
+
this.draftVersion = signal(0, ...(ngDevMode ? [{ debugName: "draftVersion" }] : []));
|
|
3241
|
+
this.draftKey = computed(() => `__draft__v${this.draftVersion()}`, ...(ngDevMode ? [{ debugName: "draftKey" }] : []));
|
|
3242
|
+
this.typeOptions = computed(() => this.providedTypes, ...(ngDevMode ? [{ debugName: "typeOptions" }] : []));
|
|
3243
|
+
this.presetTypes = computed(() => this.providedTypes.slice(0, 5), ...(ngDevMode ? [{ debugName: "presetTypes" }] : []));
|
|
3244
|
+
this.canAdd = computed(() => {
|
|
3245
|
+
const key = this.newKey()?.trim();
|
|
3246
|
+
const title = this.newTitle()?.trim();
|
|
3247
|
+
const typeId = this.newTypeId();
|
|
3248
|
+
const val = this.newValue();
|
|
3249
|
+
const hasValue = val !== undefined && val !== null && (typeof val !== 'string' || val.trim() !== '');
|
|
3250
|
+
if (!key || !title || !typeId || !hasValue)
|
|
3251
|
+
return false;
|
|
3252
|
+
return !this.items().some((i) => i.key === key);
|
|
3253
|
+
}, ...(ngDevMode ? [{ debugName: "canAdd" }] : []));
|
|
3254
|
+
//#endregion
|
|
3255
|
+
//#region ---- Effects ----
|
|
3256
|
+
/** Sync incoming items' values into internal context for rendering */
|
|
3257
|
+
this.syncContextFromItems = effect(() => {
|
|
3258
|
+
const items = this.items();
|
|
3259
|
+
const current = this.internalContext();
|
|
3260
|
+
const currentExtra = current['extra'] ?? {};
|
|
3261
|
+
const extra = { ...currentExtra };
|
|
3262
|
+
for (const it of items) {
|
|
3263
|
+
if (it.value !== undefined && it.value !== null) {
|
|
3264
|
+
extra[it.key] = it.value;
|
|
3265
|
+
}
|
|
3266
|
+
else if (Object.prototype.hasOwnProperty.call(extra, it.key)) {
|
|
3267
|
+
delete extra[it.key];
|
|
3268
|
+
}
|
|
3269
|
+
}
|
|
3270
|
+
const nextContext = { ...current, extra };
|
|
3271
|
+
if (!isEqual(nextContext, current)) {
|
|
3272
|
+
this.internalContext.set(nextContext);
|
|
3273
|
+
}
|
|
3274
|
+
}, ...(ngDevMode ? [{ debugName: "syncContextFromItems" }] : []));
|
|
3275
|
+
/**
|
|
3276
|
+
* Clear item values when their widget type changes to avoid incompatible stale values
|
|
3277
|
+
*/
|
|
3278
|
+
this.clearValueOnTypeChange = effect(() => {
|
|
3279
|
+
const items = this.items();
|
|
3280
|
+
const changedKeys = new Set();
|
|
3281
|
+
for (const it of items) {
|
|
3282
|
+
const prevType = this.lastTypeByKey[it.key];
|
|
3283
|
+
if (prevType && prevType !== it.type) {
|
|
3284
|
+
changedKeys.add(it.key);
|
|
3285
|
+
}
|
|
3286
|
+
this.lastTypeByKey[it.key] = it.type;
|
|
3287
|
+
}
|
|
3288
|
+
if (changedKeys.size > 0) {
|
|
3289
|
+
const updated = items.map((it) => (changedKeys.has(it.key) ? { ...it, value: undefined } : it));
|
|
3290
|
+
// Reset cached default values for affected nodes
|
|
3291
|
+
changedKeys.forEach((k) => {
|
|
3292
|
+
const node = this.nodeCache[k];
|
|
3293
|
+
if (node) {
|
|
3294
|
+
node.defaultValue = undefined;
|
|
3295
|
+
}
|
|
3296
|
+
});
|
|
3297
|
+
this.itemsChange.emit(updated);
|
|
3298
|
+
}
|
|
3299
|
+
}, ...(ngDevMode ? [{ debugName: "clearValueOnTypeChange" }] : []));
|
|
3300
|
+
this.nodeCache = {};
|
|
3301
|
+
}
|
|
3302
|
+
//#endregion
|
|
3303
|
+
//#region ---- Event Handlers ----
|
|
3304
|
+
onContextChanged(event) {
|
|
3305
|
+
// Ignore initial bootstrapping to prevent cycles
|
|
3306
|
+
if (event.state === 'initiated')
|
|
3307
|
+
return;
|
|
3308
|
+
const data = (event.data ?? {});
|
|
3309
|
+
const extra = data['extra'] ?? {};
|
|
3310
|
+
// sync draft value
|
|
3311
|
+
const dk = this.draftKey();
|
|
3312
|
+
if (Object.prototype.hasOwnProperty.call(extra, dk)) {
|
|
3313
|
+
this.newValue.set(extra[dk]);
|
|
3314
|
+
}
|
|
3315
|
+
const nextItems = this.items().map((it) => ({ ...it, value: extra[it.key] }));
|
|
3316
|
+
if (!isEqual(nextItems, this.items())) {
|
|
3317
|
+
this.itemsChange.emit(nextItems);
|
|
3318
|
+
}
|
|
3319
|
+
}
|
|
3320
|
+
//#endregion
|
|
3321
|
+
//#region ---- Utility Methods ----
|
|
3322
|
+
handleAddItem() {
|
|
3323
|
+
if (!this.canAdd())
|
|
3324
|
+
return;
|
|
3325
|
+
const type = this.typeOptions().find((t) => t.id === this.newTypeId());
|
|
3326
|
+
const next = {
|
|
3327
|
+
key: this.newKey().trim(),
|
|
3328
|
+
title: this.newTitle().trim(),
|
|
3329
|
+
type: this.newTypeId(),
|
|
3330
|
+
value: this.newValue(),
|
|
3331
|
+
options: cloneDeep(type?.defaultOptions ?? {}),
|
|
3332
|
+
};
|
|
3333
|
+
const updated = [...this.items(), next];
|
|
3334
|
+
this.itemsChange.emit(updated);
|
|
3335
|
+
// reset inputs
|
|
3336
|
+
this.newKey.set('');
|
|
3337
|
+
this.newTitle.set('');
|
|
3338
|
+
this.newTypeId.set('');
|
|
3339
|
+
this.newValue.set(undefined);
|
|
3340
|
+
// clear draft from context
|
|
3341
|
+
const ctx = { ...this.internalContext() };
|
|
3342
|
+
const draftExtra = { ...(ctx['extra'] ?? {}) };
|
|
3343
|
+
const dk = this.draftKey();
|
|
3344
|
+
if (Object.prototype.hasOwnProperty.call(draftExtra, dk)) {
|
|
3345
|
+
delete draftExtra[dk];
|
|
3346
|
+
this.internalContext.set({ ...ctx, extra: draftExtra });
|
|
3347
|
+
}
|
|
3348
|
+
}
|
|
3349
|
+
handleRemoveItem(key) {
|
|
3350
|
+
const updated = this.items().filter((i) => i.key !== key);
|
|
3351
|
+
this.itemsChange.emit(updated);
|
|
3352
|
+
// prune context
|
|
3353
|
+
const ctx = { ...this.internalContext() };
|
|
3354
|
+
if (ctx['extra']) {
|
|
3355
|
+
const { [key]: _, ...rest } = ctx['extra'];
|
|
3356
|
+
this.internalContext.set({ ...ctx, ['extra']: rest });
|
|
3357
|
+
}
|
|
3358
|
+
}
|
|
3359
|
+
handleDrop(event) {
|
|
3360
|
+
const arr = [...this.items()];
|
|
3361
|
+
moveItemInArray(arr, event.previousIndex, event.currentIndex);
|
|
3362
|
+
this.itemsChange.emit(arr);
|
|
3363
|
+
}
|
|
3364
|
+
selectPreset(id) {
|
|
3365
|
+
this.newTypeId.set(id);
|
|
3366
|
+
}
|
|
3367
|
+
getNode(item) {
|
|
3368
|
+
const key = item.key;
|
|
3369
|
+
let node = this.nodeCache[key];
|
|
3370
|
+
if (!node) {
|
|
3371
|
+
node = {
|
|
3372
|
+
type: item.type,
|
|
3373
|
+
path: `extra.${item.key}`,
|
|
3374
|
+
options: item.options ?? {},
|
|
3375
|
+
defaultValue: item.value,
|
|
3376
|
+
};
|
|
3377
|
+
this.nodeCache[key] = node;
|
|
3378
|
+
}
|
|
3379
|
+
else {
|
|
3380
|
+
// Keep reference stable; update nested fields if essential changes happen
|
|
3381
|
+
node.type = item.type;
|
|
3382
|
+
node.options = item.options ?? node.options;
|
|
3383
|
+
// Do not overwrite defaultValue during editing to avoid resets
|
|
3384
|
+
}
|
|
3385
|
+
return node;
|
|
3386
|
+
}
|
|
3387
|
+
draftNode() {
|
|
3388
|
+
const typeId = this.newTypeId();
|
|
3389
|
+
const type = this.typeOptions().find((t) => t.id === typeId);
|
|
3390
|
+
let node = this.draftNodeCache;
|
|
3391
|
+
const resolvedType = typeId;
|
|
3392
|
+
if (!node || node.type !== resolvedType) {
|
|
3393
|
+
node = {
|
|
3394
|
+
type: resolvedType,
|
|
3395
|
+
path: `extra.${this.draftKey()}`,
|
|
3396
|
+
options: cloneDeep(type?.defaultOptions ?? {}),
|
|
3397
|
+
defaultValue: this.newValue(),
|
|
3398
|
+
};
|
|
3399
|
+
this.draftNodeCache = node;
|
|
3400
|
+
}
|
|
3401
|
+
else {
|
|
3402
|
+
node.options = cloneDeep(type?.defaultOptions ?? {});
|
|
3403
|
+
}
|
|
3404
|
+
return node;
|
|
3405
|
+
}
|
|
3406
|
+
//#region ---- Utility Helpers ----
|
|
3407
|
+
newTypeChanged(val) {
|
|
3408
|
+
this.newTypeId.set(val);
|
|
3409
|
+
// force draft widget re-render on type change
|
|
3410
|
+
this.draftNodeCache = undefined;
|
|
3411
|
+
// clear draft value from both signal and context to avoid type mismatch
|
|
3412
|
+
const prevDraftKey = this.draftKey();
|
|
3413
|
+
this.newValue.set(undefined);
|
|
3414
|
+
const ctx = { ...this.internalContext() };
|
|
3415
|
+
const draftExtra = { ...(ctx['extra'] ?? {}) };
|
|
3416
|
+
if (Object.prototype.hasOwnProperty.call(draftExtra, prevDraftKey)) {
|
|
3417
|
+
delete draftExtra[prevDraftKey];
|
|
3418
|
+
this.internalContext.set({ ...ctx, extra: draftExtra });
|
|
3419
|
+
}
|
|
3420
|
+
// bump draft version so new draft path is isolated from old widget emissions
|
|
3421
|
+
this.draftVersion.set(this.draftVersion() + 1);
|
|
3422
|
+
const t = this.typeOptions().find((x) => x.id === val);
|
|
3423
|
+
if (t) {
|
|
3424
|
+
const autoTitle = t.title ?? val;
|
|
3425
|
+
const autoKey = this.sanitizeKey(autoTitle);
|
|
3426
|
+
// Only auto-fill when empty
|
|
3427
|
+
if (!this.newTitle()?.trim())
|
|
3428
|
+
this.newTitle.set(autoTitle);
|
|
3429
|
+
// always derive key from title
|
|
3430
|
+
this.newKey.set(autoKey);
|
|
3431
|
+
}
|
|
3432
|
+
}
|
|
3433
|
+
ngOnInit() {
|
|
3434
|
+
// auto-select first item of type list
|
|
3435
|
+
const types = this.typeOptions();
|
|
3436
|
+
if (!this.newTypeId() && types && types.length > 0) {
|
|
3437
|
+
this.newTypeChanged(types[0].id);
|
|
3438
|
+
}
|
|
3439
|
+
}
|
|
3440
|
+
handleTitleChange(val) {
|
|
3441
|
+
this.newTitle.set(val);
|
|
3442
|
+
this.newKey.set(this.sanitizeKey(val));
|
|
3443
|
+
}
|
|
3444
|
+
sanitizeKey(input) {
|
|
3445
|
+
if (!input)
|
|
3446
|
+
return '';
|
|
3447
|
+
// Convert to camelCase, remove invalid chars, ensure starts with letter/_
|
|
3448
|
+
let k = camelCase(String(input));
|
|
3449
|
+
k = k.replace(/[^a-zA-Z0-9_]/g, '');
|
|
3450
|
+
if (!/^[a-zA-Z_]/.test(k))
|
|
3451
|
+
k = `_${k}`;
|
|
3452
|
+
// enforce uniqueness by suffixing if needed
|
|
3453
|
+
const exists = (candidate) => this.items().some((i) => i.key === candidate);
|
|
3454
|
+
if (!exists(k))
|
|
3455
|
+
return k;
|
|
3456
|
+
let i = 1;
|
|
3457
|
+
while (exists(`${k}${i}`))
|
|
3458
|
+
i++;
|
|
3459
|
+
return `${k}${i}`;
|
|
3460
|
+
}
|
|
3461
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPExtraPropertiesComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3462
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.8", type: AXPExtraPropertiesComponent, isStandalone: true, selector: "axp-extra-properties", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { itemsChange: "itemsChange" }, host: { classAttribute: "ax-block ax-flex-1" }, ngImport: i0, template: `
|
|
3463
|
+
<div class="ax-grid ax-grid-cols-12 ax-gap-4">
|
|
3464
|
+
<axp-widgets-container [context]="internalContext()" (onContextChanged)="onContextChanged($event)">
|
|
3465
|
+
<div cdkDropList (cdkDropListDropped)="handleDrop($event)" class="ax-col-span-12 ax-flex ax-flex-col ax-gap-3">
|
|
3466
|
+
@for(item of items(); track item.key){
|
|
3467
|
+
@if(mode()==='edit'){
|
|
3468
|
+
<div class="ax-grid ax-grid-cols-12 ax-gap-4 ax-items-center" cdkDrag [cdkDragDisabled]="false">
|
|
3469
|
+
<div class="ax-col-span-12 md:ax-col-span-3 ax-flex ax-items-center ax-gap-3">
|
|
3470
|
+
<ax-icon class="fa-solid fa-grip-dots-vertical ax-cursor-move ax-text-neutral-500" cdkDragHandle></ax-icon>
|
|
3471
|
+
<div>
|
|
3472
|
+
<div class="ax-font-semibold">{{item.title}}</div>
|
|
3473
|
+
</div>
|
|
3474
|
+
<!-- Small-screen delete aligned with title -->
|
|
3475
|
+
<ax-button class="ax-ml-auto md:ax-hidden" look="blank" color="danger" (onClick)="handleRemoveItem(item.key)">
|
|
3476
|
+
<ax-prefix><ax-icon class="fa-light fa-trash-can"></ax-icon></ax-prefix>
|
|
3477
|
+
</ax-button>
|
|
3478
|
+
</div>
|
|
3479
|
+
<div class="ax-col-span-12 md:ax-col-span-8">
|
|
3480
|
+
<ng-container
|
|
3481
|
+
axp-widget-renderer
|
|
3482
|
+
[node]="getNode(item)"
|
|
3483
|
+
[mode]="'edit'"
|
|
3484
|
+
></ng-container>
|
|
3485
|
+
</div>
|
|
3486
|
+
<div class="ax-hidden md:ax-block md:ax-col-span-1 md:ax-justify-self-end">
|
|
3487
|
+
<ax-button look="blank" color="danger" (onClick)="handleRemoveItem(item.key)">
|
|
3488
|
+
<ax-prefix><ax-icon class="fa-light fa-trash-can"></ax-icon></ax-prefix>
|
|
3489
|
+
</ax-button>
|
|
3490
|
+
</div>
|
|
3491
|
+
</div>
|
|
3492
|
+
} @else {
|
|
3493
|
+
<div class="ax-grid ax-grid-cols-12 ax-gap-1">
|
|
3494
|
+
<div class="ax-font-semibold">{{item.title}}</div>
|
|
3495
|
+
<div class="ax-col-span-12 ax-text-muted">
|
|
3496
|
+
<ng-container
|
|
3497
|
+
axp-widget-renderer
|
|
3498
|
+
[node]="getNode(item)"
|
|
3499
|
+
[mode]="'view'"
|
|
3500
|
+
></ng-container>
|
|
3501
|
+
</div>
|
|
3502
|
+
</div>
|
|
3503
|
+
}
|
|
3504
|
+
} @empty {
|
|
3505
|
+
<div class="ax-col-span-12 ax-text-sm ax-text-gray-400">
|
|
3506
|
+
{{ 'extra-properties:messages.no-extra-properties' | translate | async }}
|
|
3507
|
+
</div>
|
|
3508
|
+
}
|
|
3509
|
+
@if(mode()==='edit'){
|
|
3510
|
+
<div class="ax-grid ax-grid-cols-12 ax-gap-4 ax-items-end ax-mt-4 ax-border-t ax-border-dashed ax-pt-4">
|
|
3511
|
+
<!-- Type -->
|
|
3512
|
+
<ax-form-field class="ax-col-span-12 md:ax-col-span-6 lg:ax-col-span-3">
|
|
3513
|
+
<ax-label>{{ 'extra-properties:labels.type' | translate | async }}</ax-label>
|
|
3514
|
+
<ax-select-box
|
|
3515
|
+
[value]="newTypeId()"
|
|
3516
|
+
[dataSource]="typeOptions()"
|
|
3517
|
+
valueField="id"
|
|
3518
|
+
textField="title"
|
|
3519
|
+
(onValueChanged)="newTypeChanged($event.value)"
|
|
3520
|
+
></ax-select-box>
|
|
3521
|
+
</ax-form-field>
|
|
3522
|
+
<!-- Title -->
|
|
3523
|
+
<ax-form-field class="ax-col-span-12 md:ax-col-span-6 lg:ax-col-span-5">
|
|
3524
|
+
<ax-label>{{ 'extra-properties:labels.title' | translate | async }}</ax-label>
|
|
3525
|
+
<ax-text-box [ngModel]="newTitle()" (onValueChanged)="handleTitleChange($event.value)"></ax-text-box>
|
|
3526
|
+
</ax-form-field>
|
|
3527
|
+
<!-- Value -->
|
|
3528
|
+
@if(newTypeId()){
|
|
3529
|
+
<ax-form-field class="ax-col-span-12 md:ax-col-span-6 lg:ax-col-span-4">
|
|
3530
|
+
<ax-label>{{ 'extra-properties:labels.value' | translate | async }}</ax-label>
|
|
3531
|
+
<div (keydown.enter)="handleAddItem()">
|
|
3532
|
+
<ng-container
|
|
3533
|
+
axp-widget-renderer
|
|
3534
|
+
[node]="draftNode()"
|
|
3535
|
+
[mode]="'edit'"
|
|
3536
|
+
></ng-container>
|
|
3537
|
+
</div>
|
|
3538
|
+
</ax-form-field>
|
|
3539
|
+
}
|
|
3540
|
+
<!-- Add moved to bottom (same as before) -->
|
|
3541
|
+
<div class="ax-col-span-12 ax-flex ax-justify-end">
|
|
3542
|
+
<ax-button look="solid" (onClick)="handleAddItem()" [disabled]="!canAdd()" text="{{ 'extra-properties:actions.add-field' | translate | async }}">
|
|
3543
|
+
<ax-prefix><ax-icon class="fa-solid fa-add"></ax-icon></ax-prefix>
|
|
3544
|
+
</ax-button>
|
|
3545
|
+
</div>
|
|
3546
|
+
</div>
|
|
3547
|
+
}
|
|
3548
|
+
</div>
|
|
3549
|
+
</axp-widgets-container>
|
|
3550
|
+
</div>
|
|
3551
|
+
|
|
3552
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: AXFormModule }, { kind: "component", type: i2$4.AXFormFieldComponent, selector: "ax-form-field", inputs: ["labelMode"] }, { kind: "ngmodule", type: AXLabelModule }, { kind: "component", type: i3$2.AXLabelComponent, selector: "ax-label", inputs: ["required", "for"], outputs: ["requiredChange"] }, { kind: "ngmodule", type: AXTextBoxModule }, { kind: "component", type: i4$4.AXTextBoxComponent, selector: "ax-text-box", inputs: ["disabled", "tabIndex", "readonly", "value", "state", "name", "id", "placeholder", "maxLength", "allowNull", "type", "autoComplete", "look", "mask-options", "class"], outputs: ["onBlur", "onFocus", "valueChange", "stateChange", "onValueChanged", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "ngmodule", type: AXSelectBoxModule }, { kind: "component", type: i5$2.AXSelectBoxComponent, selector: "ax-select-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "minValue", "maxValue", "value", "state", "name", "id", "type", "look", "multiple", "valueField", "textField", "disabledField", "textTemplate", "selectedItems", "isItemTruncated", "showItemTooltip", "dataSource", "minRecordsForSearch", "caption", "itemTemplate", "selectedTemplate", "emptyTemplate", "loadingTemplate", "dropdownWidth", "searchBoxAutoFocus"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onOpened", "onClosed", "onItemSelected", "onItemClick"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i3.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i2$1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXPLayoutBuilderModule }, { kind: "component", type: i3$3.AXPWidgetContainerComponent, selector: "axp-widgets-container", inputs: ["context", "functions"], outputs: ["onContextChanged"] }, { kind: "directive", type: i3$3.AXPWidgetRendererDirective, selector: "[axp-widget-renderer]", inputs: ["parentNode", "index", "mode", "node"], outputs: ["onOptionsChanged", "onValueChanged"], exportAs: ["widgetRenderer"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i9.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i9.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i9.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
3553
|
+
}
|
|
3554
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPExtraPropertiesComponent, decorators: [{
|
|
3555
|
+
type: Component,
|
|
3556
|
+
args: [{
|
|
3557
|
+
selector: 'axp-extra-properties',
|
|
3558
|
+
template: `
|
|
3559
|
+
<div class="ax-grid ax-grid-cols-12 ax-gap-4">
|
|
3560
|
+
<axp-widgets-container [context]="internalContext()" (onContextChanged)="onContextChanged($event)">
|
|
3561
|
+
<div cdkDropList (cdkDropListDropped)="handleDrop($event)" class="ax-col-span-12 ax-flex ax-flex-col ax-gap-3">
|
|
3562
|
+
@for(item of items(); track item.key){
|
|
3563
|
+
@if(mode()==='edit'){
|
|
3564
|
+
<div class="ax-grid ax-grid-cols-12 ax-gap-4 ax-items-center" cdkDrag [cdkDragDisabled]="false">
|
|
3565
|
+
<div class="ax-col-span-12 md:ax-col-span-3 ax-flex ax-items-center ax-gap-3">
|
|
3566
|
+
<ax-icon class="fa-solid fa-grip-dots-vertical ax-cursor-move ax-text-neutral-500" cdkDragHandle></ax-icon>
|
|
3567
|
+
<div>
|
|
3568
|
+
<div class="ax-font-semibold">{{item.title}}</div>
|
|
3569
|
+
</div>
|
|
3570
|
+
<!-- Small-screen delete aligned with title -->
|
|
3571
|
+
<ax-button class="ax-ml-auto md:ax-hidden" look="blank" color="danger" (onClick)="handleRemoveItem(item.key)">
|
|
3572
|
+
<ax-prefix><ax-icon class="fa-light fa-trash-can"></ax-icon></ax-prefix>
|
|
3573
|
+
</ax-button>
|
|
3574
|
+
</div>
|
|
3575
|
+
<div class="ax-col-span-12 md:ax-col-span-8">
|
|
3576
|
+
<ng-container
|
|
3577
|
+
axp-widget-renderer
|
|
3578
|
+
[node]="getNode(item)"
|
|
3579
|
+
[mode]="'edit'"
|
|
3580
|
+
></ng-container>
|
|
3581
|
+
</div>
|
|
3582
|
+
<div class="ax-hidden md:ax-block md:ax-col-span-1 md:ax-justify-self-end">
|
|
3583
|
+
<ax-button look="blank" color="danger" (onClick)="handleRemoveItem(item.key)">
|
|
3584
|
+
<ax-prefix><ax-icon class="fa-light fa-trash-can"></ax-icon></ax-prefix>
|
|
3585
|
+
</ax-button>
|
|
3586
|
+
</div>
|
|
3587
|
+
</div>
|
|
3588
|
+
} @else {
|
|
3589
|
+
<div class="ax-grid ax-grid-cols-12 ax-gap-1">
|
|
3590
|
+
<div class="ax-font-semibold">{{item.title}}</div>
|
|
3591
|
+
<div class="ax-col-span-12 ax-text-muted">
|
|
3592
|
+
<ng-container
|
|
3593
|
+
axp-widget-renderer
|
|
3594
|
+
[node]="getNode(item)"
|
|
3595
|
+
[mode]="'view'"
|
|
3596
|
+
></ng-container>
|
|
3597
|
+
</div>
|
|
3598
|
+
</div>
|
|
3599
|
+
}
|
|
3600
|
+
} @empty {
|
|
3601
|
+
<div class="ax-col-span-12 ax-text-sm ax-text-gray-400">
|
|
3602
|
+
{{ 'extra-properties:messages.no-extra-properties' | translate | async }}
|
|
3603
|
+
</div>
|
|
3604
|
+
}
|
|
3605
|
+
@if(mode()==='edit'){
|
|
3606
|
+
<div class="ax-grid ax-grid-cols-12 ax-gap-4 ax-items-end ax-mt-4 ax-border-t ax-border-dashed ax-pt-4">
|
|
3607
|
+
<!-- Type -->
|
|
3608
|
+
<ax-form-field class="ax-col-span-12 md:ax-col-span-6 lg:ax-col-span-3">
|
|
3609
|
+
<ax-label>{{ 'extra-properties:labels.type' | translate | async }}</ax-label>
|
|
3610
|
+
<ax-select-box
|
|
3611
|
+
[value]="newTypeId()"
|
|
3612
|
+
[dataSource]="typeOptions()"
|
|
3613
|
+
valueField="id"
|
|
3614
|
+
textField="title"
|
|
3615
|
+
(onValueChanged)="newTypeChanged($event.value)"
|
|
3616
|
+
></ax-select-box>
|
|
3617
|
+
</ax-form-field>
|
|
3618
|
+
<!-- Title -->
|
|
3619
|
+
<ax-form-field class="ax-col-span-12 md:ax-col-span-6 lg:ax-col-span-5">
|
|
3620
|
+
<ax-label>{{ 'extra-properties:labels.title' | translate | async }}</ax-label>
|
|
3621
|
+
<ax-text-box [ngModel]="newTitle()" (onValueChanged)="handleTitleChange($event.value)"></ax-text-box>
|
|
3622
|
+
</ax-form-field>
|
|
3623
|
+
<!-- Value -->
|
|
3624
|
+
@if(newTypeId()){
|
|
3625
|
+
<ax-form-field class="ax-col-span-12 md:ax-col-span-6 lg:ax-col-span-4">
|
|
3626
|
+
<ax-label>{{ 'extra-properties:labels.value' | translate | async }}</ax-label>
|
|
3627
|
+
<div (keydown.enter)="handleAddItem()">
|
|
3628
|
+
<ng-container
|
|
3629
|
+
axp-widget-renderer
|
|
3630
|
+
[node]="draftNode()"
|
|
3631
|
+
[mode]="'edit'"
|
|
3632
|
+
></ng-container>
|
|
3633
|
+
</div>
|
|
3634
|
+
</ax-form-field>
|
|
3635
|
+
}
|
|
3636
|
+
<!-- Add moved to bottom (same as before) -->
|
|
3637
|
+
<div class="ax-col-span-12 ax-flex ax-justify-end">
|
|
3638
|
+
<ax-button look="solid" (onClick)="handleAddItem()" [disabled]="!canAdd()" text="{{ 'extra-properties:actions.add-field' | translate | async }}">
|
|
3639
|
+
<ax-prefix><ax-icon class="fa-solid fa-add"></ax-icon></ax-prefix>
|
|
3640
|
+
</ax-button>
|
|
3641
|
+
</div>
|
|
3642
|
+
</div>
|
|
3643
|
+
}
|
|
3644
|
+
</div>
|
|
3645
|
+
</axp-widgets-container>
|
|
3646
|
+
</div>
|
|
3647
|
+
|
|
3648
|
+
`,
|
|
3649
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
3650
|
+
imports: [
|
|
3651
|
+
CommonModule,
|
|
3652
|
+
FormsModule,
|
|
3653
|
+
AXFormModule,
|
|
3654
|
+
AXLabelModule,
|
|
3655
|
+
AXTextBoxModule,
|
|
3656
|
+
AXSelectBoxModule,
|
|
3657
|
+
AXButtonModule,
|
|
3658
|
+
AXDecoratorModule,
|
|
3659
|
+
AXPLayoutBuilderModule,
|
|
3660
|
+
DragDropModule,
|
|
3661
|
+
AXTranslationModule,
|
|
3662
|
+
//AXPGridLayoutDirective,
|
|
3663
|
+
],
|
|
3664
|
+
standalone: true,
|
|
3665
|
+
host: {
|
|
3666
|
+
class: 'ax-block ax-flex-1',
|
|
3667
|
+
},
|
|
3668
|
+
}]
|
|
3669
|
+
}] });
|
|
3670
|
+
|
|
3671
|
+
class AXPWidgetPropertyViewerComponent {
|
|
3672
|
+
constructor() {
|
|
3673
|
+
this.widget = input.required(...(ngDevMode ? [{ debugName: "widget" }] : []));
|
|
3674
|
+
this.mode = input('simple', ...(ngDevMode ? [{ debugName: "mode" }] : []));
|
|
3675
|
+
this.widgetRegistryService = inject(AXPWidgetRegistryService);
|
|
3676
|
+
// Designer connector removed to avoid cross-entry circular dependency
|
|
3677
|
+
this.currentTabIndex = signal(0, ...(ngDevMode ? [{ debugName: "currentTabIndex" }] : []));
|
|
3678
|
+
this.config = signal(null, ...(ngDevMode ? [{ debugName: "config" }] : []));
|
|
3679
|
+
this.allPoperties = [];
|
|
3680
|
+
this.tabs = signal([], ...(ngDevMode ? [{ debugName: "tabs" }] : []));
|
|
3681
|
+
this.groups = computed(() => {
|
|
3682
|
+
return this.tabs().length ? this.tabs()[this.currentTabIndex()].groups : [];
|
|
3683
|
+
}, ...(ngDevMode ? [{ debugName: "groups" }] : []));
|
|
3684
|
+
this.groupCollapsedStates = new Map();
|
|
3685
|
+
this.onChanged = new EventEmitter();
|
|
3686
|
+
this.context = signal({}, ...(ngDevMode ? [{ debugName: "context" }] : []));
|
|
3687
|
+
this.initialContext = {};
|
|
3688
|
+
effect(() => {
|
|
3689
|
+
if (!this.widget())
|
|
3690
|
+
return;
|
|
3691
|
+
const config = this.widgetRegistryService.resolve(this.widget()?.type);
|
|
3692
|
+
if (config) {
|
|
3693
|
+
this.initialContext = {};
|
|
3694
|
+
this.config.set(config);
|
|
3695
|
+
this.fillTabs();
|
|
3696
|
+
}
|
|
3697
|
+
else {
|
|
3698
|
+
console.error(`Invalid widget name: ${this.widget()}`);
|
|
3699
|
+
}
|
|
3700
|
+
});
|
|
3701
|
+
}
|
|
3702
|
+
update(values) {
|
|
3703
|
+
this.context.set(merge(cloneDeep(this.context()), values));
|
|
3704
|
+
}
|
|
3705
|
+
fillTabs() {
|
|
3706
|
+
const tabs = [
|
|
3707
|
+
{
|
|
3708
|
+
name: 'general',
|
|
3709
|
+
title: 'General',
|
|
3710
|
+
groups: [],
|
|
3711
|
+
},
|
|
3712
|
+
];
|
|
3713
|
+
Object.entries(this.config()?.components ?? {}).forEach((c) => {
|
|
3714
|
+
if (c[1].component != null && c[1].properties?.length) {
|
|
3715
|
+
tabs.push({ name: c[0], title: capitalize(c[0]), groups: [] });
|
|
3716
|
+
}
|
|
3717
|
+
});
|
|
3718
|
+
///
|
|
3719
|
+
this.allPoperties = [];
|
|
3720
|
+
///
|
|
3721
|
+
tabs.forEach((tab) => {
|
|
3722
|
+
const props = tab.name == 'general'
|
|
3723
|
+
? (this.config()?.properties ?? [])
|
|
3724
|
+
: ((this.config()?.components)[tab.name]?.properties ?? []);
|
|
3725
|
+
//
|
|
3726
|
+
const visibleProps = props.filter((c) => c.visible != false);
|
|
3727
|
+
this.allPoperties.push(...props);
|
|
3728
|
+
tab.groups = unionBy(sortBy(visibleProps.map((pg) => ({
|
|
3729
|
+
isCollapsed: !!this.groupCollapsedStates.get(pg.group.name),
|
|
3730
|
+
name: pg.group.name,
|
|
3731
|
+
title: pg.group.title,
|
|
3732
|
+
props: sortBy(visibleProps.filter((p) => p.group.name == pg.group.name && pg.visible), ['order', 'title']),
|
|
3733
|
+
})), ['order', 'title']), 'name').filter((c) => c.props.length);
|
|
3734
|
+
});
|
|
3735
|
+
this.tabs.set(tabs.filter((c) => c.groups.length));
|
|
3736
|
+
//
|
|
3737
|
+
this.initialContext = this.allPoperties
|
|
3738
|
+
.filter((c) => (!isArray(c.schema.defaultValue) && !isNil(c.schema.defaultValue)) ||
|
|
3739
|
+
(isArray(c.schema.defaultValue) && !isEmpty(c.schema.defaultValue)))
|
|
3740
|
+
.reduce((acc, c) => {
|
|
3741
|
+
set(acc, c.schema.interface.path, c.schema.defaultValue);
|
|
3742
|
+
return acc;
|
|
3743
|
+
}, {});
|
|
3744
|
+
//
|
|
3745
|
+
untracked(() => {
|
|
3746
|
+
this.context.set(merge(cloneDeep(this.initialContext), this.widget()));
|
|
3747
|
+
this.onChanged.emit({ values: this.context(), mode: 'init' });
|
|
3748
|
+
});
|
|
3749
|
+
}
|
|
3750
|
+
handleContextChange(e) {
|
|
3751
|
+
untracked(() => {
|
|
3752
|
+
this.context.set(e.data);
|
|
3753
|
+
this.onChanged.emit({ values: this.context(), mode: e.state == 'initiated' ? 'init' : 'update' });
|
|
3754
|
+
});
|
|
3755
|
+
}
|
|
3756
|
+
handleTabChange(event) {
|
|
3757
|
+
const indx = event.index;
|
|
3758
|
+
if (this.currentTabIndex() != indx) {
|
|
3759
|
+
this.currentTabIndex.set(indx);
|
|
3760
|
+
}
|
|
3761
|
+
}
|
|
3762
|
+
handleCollapsedChange(group, collapsed) {
|
|
3763
|
+
this.groupCollapsedStates.set(group, collapsed);
|
|
3764
|
+
}
|
|
3765
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPWidgetPropertyViewerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3766
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.8", type: AXPWidgetPropertyViewerComponent, isStandalone: true, selector: "axp-widget-property-viewer", inputs: { widget: { classPropertyName: "widget", publicName: "widget", isSignal: true, isRequired: true, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onChanged: "onChanged" }, ngImport: i0, template: "<axp-widgets-container [context]=\"context()\" (onContextChanged)=\"handleContextChange($event)\">\n @if (mode() == 'advanced') {\n <div class=\"ax-flex ax-flex-col\">\n @if (tabs().length > 1) {\n <div class=\"ax-pb-2\">\n <ax-tabs look=\"default\" (onActiveTabChanged)=\"handleTabChange($event)\" [look]=\"'with-line'\">\n @for (tab of tabs(); track $index) {\n <ax-tab-item [text]=\"tab.title\" [key]=\"$index.toString()\" [active]=\"currentTabIndex() === $index\">\n </ax-tab-item>\n }\n </ax-tabs>\n </div>\n }\n <div class=\"ax-flex-1 ax-overflow-auto\">\n <ax-collapse-group class=\"ax-h-fit\" [look]=\"'flat'\">\n @for (group of groups(); track $index) {\n <ax-collapse\n class=\"!ax-mb-0\"\n [caption]=\"group.title\"\n [(isCollapsed)]=\"group.isCollapsed\"\n (isCollapsedChange)=\"handleCollapsedChange(group.name, $event)\"\n >\n <div class=\"ax-flex ax-flex-col\">\n @for (p of group.props; track $index) {\n <div class=\"ax-flex ax-flex-col ax-gap-1 ax-py-2\">\n <span class=\"ax-font-semibold\">{{ p.title }}</span>\n @if (p.schema.interface) {\n <ng-container axp-widget-renderer [node]=\"p.schema.interface\" [mode]=\"'edit'\"> </ng-container>\n }\n </div>\n }\n </div>\n </ax-collapse>\n }\n </ax-collapse-group>\n </div>\n </div>\n }\n <!-- Simple-->\n @else {\n <div class=\"ax-flex ax-flex-col ax-p-4 ax-gap-4\">\n <!-- groups -->\n @for (group of groups(); track $index) {\n <!-- props -->\n @for (p of group.props; track $index) {\n <div class=\"ax-flex ax-flex-col ax-gap-2\">\n <span class=\"ax-font-semibold\">{{ p.title | translate | async }}</span>\n @if (p.schema.interface) {\n <ng-container axp-widget-renderer [node]=\"p.schema.interface\" [mode]=\"'edit'\"> </ng-container>\n }\n </div>\n }\n }\n </div>\n }\n</axp-widgets-container>\n", styles: [":host ax-collapse .ax-collapse-header{font-weight:600}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXCollapseModule }, { kind: "component", type: i1$4.AXCollapseComponent, selector: "ax-collapse", inputs: ["disabled", "look", "isCollapsed", "showHeader", "caption", "icon", "isLoading", "headerTemplate"], outputs: ["onClick", "isCollapsedChange"] }, { kind: "component", type: i1$4.AXCollapseGroupComponent, selector: "ax-collapse-group", inputs: ["look", "accordion", "activeIndex"], outputs: ["accordionChange", "activeIndexChange"] }, { kind: "ngmodule", type: AXTabsModule }, { kind: "component", type: i2$5.AXTabsComponent, selector: "ax-tabs", inputs: ["look", "location", "fitParent", "minWidth", "content"], outputs: ["onActiveTabChanged"] }, { kind: "component", type: i2$5.AXTabItemComponent, selector: "ax-tab-item", inputs: ["disabled", "text", "key", "headerTemplate", "active"], outputs: ["disabledChange", "onClick", "onBlur", "onFocus", "activeChange"] }, { kind: "ngmodule", type: AXPLayoutBuilderModule }, { kind: "component", type: i3$3.AXPWidgetContainerComponent, selector: "axp-widgets-container", inputs: ["context", "functions"], outputs: ["onContextChanged"] }, { kind: "directive", type: i3$3.AXPWidgetRendererDirective, selector: "[axp-widget-renderer]", inputs: ["parentNode", "index", "mode", "node"], outputs: ["onOptionsChanged", "onValueChanged"], exportAs: ["widgetRenderer"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
3767
|
+
}
|
|
3768
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPWidgetPropertyViewerComponent, decorators: [{
|
|
3769
|
+
type: Component,
|
|
3770
|
+
args: [{ selector: 'axp-widget-property-viewer', changeDetection: ChangeDetectionStrategy.OnPush, imports: [CommonModule, AXCollapseModule, AXTabsModule, AXPLayoutBuilderModule, AXTranslationModule], template: "<axp-widgets-container [context]=\"context()\" (onContextChanged)=\"handleContextChange($event)\">\n @if (mode() == 'advanced') {\n <div class=\"ax-flex ax-flex-col\">\n @if (tabs().length > 1) {\n <div class=\"ax-pb-2\">\n <ax-tabs look=\"default\" (onActiveTabChanged)=\"handleTabChange($event)\" [look]=\"'with-line'\">\n @for (tab of tabs(); track $index) {\n <ax-tab-item [text]=\"tab.title\" [key]=\"$index.toString()\" [active]=\"currentTabIndex() === $index\">\n </ax-tab-item>\n }\n </ax-tabs>\n </div>\n }\n <div class=\"ax-flex-1 ax-overflow-auto\">\n <ax-collapse-group class=\"ax-h-fit\" [look]=\"'flat'\">\n @for (group of groups(); track $index) {\n <ax-collapse\n class=\"!ax-mb-0\"\n [caption]=\"group.title\"\n [(isCollapsed)]=\"group.isCollapsed\"\n (isCollapsedChange)=\"handleCollapsedChange(group.name, $event)\"\n >\n <div class=\"ax-flex ax-flex-col\">\n @for (p of group.props; track $index) {\n <div class=\"ax-flex ax-flex-col ax-gap-1 ax-py-2\">\n <span class=\"ax-font-semibold\">{{ p.title }}</span>\n @if (p.schema.interface) {\n <ng-container axp-widget-renderer [node]=\"p.schema.interface\" [mode]=\"'edit'\"> </ng-container>\n }\n </div>\n }\n </div>\n </ax-collapse>\n }\n </ax-collapse-group>\n </div>\n </div>\n }\n <!-- Simple-->\n @else {\n <div class=\"ax-flex ax-flex-col ax-p-4 ax-gap-4\">\n <!-- groups -->\n @for (group of groups(); track $index) {\n <!-- props -->\n @for (p of group.props; track $index) {\n <div class=\"ax-flex ax-flex-col ax-gap-2\">\n <span class=\"ax-font-semibold\">{{ p.title | translate | async }}</span>\n @if (p.schema.interface) {\n <ng-container axp-widget-renderer [node]=\"p.schema.interface\" [mode]=\"'edit'\"> </ng-container>\n }\n </div>\n }\n }\n </div>\n }\n</axp-widgets-container>\n", styles: [":host ax-collapse .ax-collapse-header{font-weight:600}\n"] }]
|
|
3771
|
+
}], ctorParameters: () => [], propDecorators: { onChanged: [{
|
|
3772
|
+
type: Output
|
|
3773
|
+
}] } });
|
|
3774
|
+
|
|
3775
|
+
class AXPExtraPropertiesSchemaComponent {
|
|
3776
|
+
constructor() {
|
|
3777
|
+
//#region ---- Inputs ----
|
|
3778
|
+
this.schema = input([], ...(ngDevMode ? [{ debugName: "schema" }] : []));
|
|
3779
|
+
this.mode = input('edit', ...(ngDevMode ? [{ debugName: "mode" }] : []));
|
|
3780
|
+
//#endregion
|
|
3781
|
+
//#region ---- Outputs ----
|
|
3782
|
+
this.schemaChange = output();
|
|
3783
|
+
//#endregion
|
|
3784
|
+
//#region ---- Services & Dependencies ----
|
|
3785
|
+
this.providedTypes = inject(AXP_EXTRA_PROPERTY_TYPES, { optional: true }) ?? [];
|
|
3786
|
+
this.translationService = inject(AXTranslationService);
|
|
3787
|
+
//#endregion
|
|
3788
|
+
//#region ---- Class Properties ----
|
|
3789
|
+
this.newTitle = signal('', ...(ngDevMode ? [{ debugName: "newTitle" }] : []));
|
|
3790
|
+
this.newTypeId = signal('', ...(ngDevMode ? [{ debugName: "newTypeId" }] : []));
|
|
3791
|
+
this.typeOptions = computed(() => this.providedTypes, ...(ngDevMode ? [{ debugName: "typeOptions" }] : []));
|
|
3792
|
+
this.canAdd = computed(() => {
|
|
3793
|
+
const title = this.newTitle()?.trim();
|
|
3794
|
+
const typeId = this.newTypeId();
|
|
3795
|
+
const key = this.deriveKey(title);
|
|
3796
|
+
if (!key || !title || !typeId)
|
|
3797
|
+
return false;
|
|
3798
|
+
return !this.schema().some((i) => i.key === key);
|
|
3799
|
+
}, ...(ngDevMode ? [{ debugName: "canAdd" }] : []));
|
|
3800
|
+
// Selection state for right panel editor
|
|
3801
|
+
this.selectedKey = signal(null, ...(ngDevMode ? [{ debugName: "selectedKey" }] : []));
|
|
3802
|
+
this.selectedItem = computed(() => this.schema().find((i) => i.key === this.selectedKey()) ?? null, ...(ngDevMode ? [{ debugName: "selectedItem" }] : []));
|
|
3803
|
+
// Auto-select first item when schema changes or current selection removed
|
|
3804
|
+
effect(() => {
|
|
3805
|
+
const items = this.schema();
|
|
3806
|
+
const current = this.selectedKey();
|
|
3807
|
+
if (!items.length) {
|
|
3808
|
+
if (current !== null)
|
|
3809
|
+
this.selectedKey.set(null);
|
|
3810
|
+
return;
|
|
3811
|
+
}
|
|
3812
|
+
if (!current || !items.some((i) => i.key === current)) {
|
|
3813
|
+
this.selectedKey.set(items[0].key);
|
|
3814
|
+
}
|
|
3815
|
+
});
|
|
3816
|
+
}
|
|
3817
|
+
//#endregion
|
|
3818
|
+
//#region ---- Utility Methods ----
|
|
3819
|
+
handleAdd() {
|
|
3820
|
+
if (!this.canAdd())
|
|
3821
|
+
return;
|
|
3822
|
+
const type = this.typeOptions().find((t) => t.id === this.newTypeId());
|
|
3823
|
+
const title = this.newTitle().trim();
|
|
3824
|
+
const key = this.deriveKey(title);
|
|
3825
|
+
const next = {
|
|
3826
|
+
key,
|
|
3827
|
+
title,
|
|
3828
|
+
type: this.newTypeId(),
|
|
3829
|
+
options: cloneDeep(type?.defaultOptions ?? {}),
|
|
3830
|
+
};
|
|
3831
|
+
const updated = [...this.schema(), next];
|
|
3832
|
+
this.schemaChange.emit(updated);
|
|
3833
|
+
this.newTitle.set('');
|
|
3834
|
+
this.newTypeId.set('');
|
|
3835
|
+
// select newly added item
|
|
3836
|
+
this.selectedKey.set(key);
|
|
3837
|
+
}
|
|
3838
|
+
handleRemove(key) {
|
|
3839
|
+
const updated = this.schema().filter((i) => i.key !== key);
|
|
3840
|
+
this.schemaChange.emit(updated);
|
|
3841
|
+
if (this.selectedKey() === key) {
|
|
3842
|
+
this.selectedKey.set(updated.length ? updated[0].key : null);
|
|
3843
|
+
}
|
|
3844
|
+
}
|
|
3845
|
+
handleDrop(event) {
|
|
3846
|
+
const arr = [...this.schema()];
|
|
3847
|
+
moveItemInArray(arr, event.previousIndex, event.currentIndex);
|
|
3848
|
+
this.schemaChange.emit(arr);
|
|
3849
|
+
}
|
|
3850
|
+
handleUpdateTitle(key, title) {
|
|
3851
|
+
const updated = this.schema().map((it) => (it.key === key ? { ...it, title } : it));
|
|
3852
|
+
this.schemaChange.emit(updated);
|
|
3853
|
+
}
|
|
3854
|
+
handleUpdateType(key, typeId) {
|
|
3855
|
+
const type = this.typeOptions().find((t) => t.id === typeId);
|
|
3856
|
+
const updated = this.schema().map((it) => it.key === key ? { ...it, type: typeId, options: cloneDeep(type?.defaultOptions ?? {}) } : it);
|
|
3857
|
+
this.schemaChange.emit(updated);
|
|
3858
|
+
}
|
|
3859
|
+
newTypeChanged(val) {
|
|
3860
|
+
this.newTypeId.set(val);
|
|
3861
|
+
const t = this.typeOptions().find((x) => x.id === val);
|
|
3862
|
+
if (t) {
|
|
3863
|
+
const autoTitle = t.title ?? val;
|
|
3864
|
+
if (!this.newTitle()?.trim())
|
|
3865
|
+
this.newTitle.set(autoTitle);
|
|
3866
|
+
}
|
|
3867
|
+
}
|
|
3868
|
+
handleTitleChange(val) {
|
|
3869
|
+
this.newTitle.set(val);
|
|
3870
|
+
}
|
|
3871
|
+
handleSelect(key) {
|
|
3872
|
+
this.selectedKey.set(key);
|
|
3873
|
+
}
|
|
3874
|
+
handleViewerChanged(e) {
|
|
3875
|
+
// Ignore initial emissions to prevent change detection loops
|
|
3876
|
+
if (e?.mode === 'init')
|
|
3877
|
+
return;
|
|
3878
|
+
const key = this.selectedKey();
|
|
3879
|
+
if (!key)
|
|
3880
|
+
return;
|
|
3881
|
+
const nextOptions = e?.values?.options ?? {};
|
|
3882
|
+
const updated = this.schema().map((it) => (it.key === key ? { ...it, options: cloneDeep(nextOptions) } : it));
|
|
3883
|
+
this.schemaChange.emit(updated);
|
|
3884
|
+
}
|
|
3885
|
+
deriveKey(input) {
|
|
3886
|
+
if (!input)
|
|
3887
|
+
return '';
|
|
3888
|
+
let k = camelCase(String(input));
|
|
3889
|
+
k = k.replace(/[^a-zA-Z0-9_]/g, '');
|
|
3890
|
+
if (!/^[a-zA-Z_]/.test(k))
|
|
3891
|
+
k = `_${k}`;
|
|
3892
|
+
const exists = (candidate) => this.schema().some((i) => i.key === candidate);
|
|
3893
|
+
if (!exists(k))
|
|
3894
|
+
return k;
|
|
3895
|
+
let i = 1;
|
|
3896
|
+
while (exists(`${k}${i}`))
|
|
3897
|
+
i++;
|
|
3898
|
+
return `${k}${i}`;
|
|
3899
|
+
}
|
|
3900
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPExtraPropertiesSchemaComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3901
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.8", type: AXPExtraPropertiesSchemaComponent, isStandalone: true, selector: "axp-extra-properties-schema", inputs: { schema: { classPropertyName: "schema", publicName: "schema", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { schemaChange: "schemaChange" }, host: { classAttribute: "ax-flex ax-flex-1 ax-h-full ax-gap-4 ax-p-4" }, ngImport: i0, template: "<!-- Left Panel: list/manage properties -->\n<div class=\"ax-flex ax-flex-col ax-gap-3 ax-min-h-0 ax-h-full ax-w-2/3\">\n <div class=\"ax-overflow-y-auto ax-min-h-0 ax-h-full ax-pe-2 -ax-me-2\">\n <div cdkDropList (cdkDropListDropped)=\"handleDrop($event)\" class=\"ax-flex ax-flex-col ax-gap-3\">\n @for (item of schema(); track item.key) {\n @if (mode() === 'edit') {\n <div class=\"ax-grid ax-grid-cols-12 ax-gap-4 ax-items-center ax-rounded ax-border ax-p-3 ax-cursor-pointer ax-lightest-surface \"\n [class.!ax-lighter-surface]=\"item.key === selectedKey()\" (click)=\"handleSelect(item.key)\" cdkDrag\n [cdkDragDisabled]=\"false\">\n <div class=\"ax-col-span-12 md:ax-col-span-4 ax-flex ax-items-center ax-gap-3\">\n <ax-icon class=\"fa-solid fa-grip-dots-vertical ax-cursor-move ax-text-neutral-500\"\n cdkDragHandle></ax-icon>\n <div>\n <div class=\"ax-font-semibold\">{{ item.title }}</div>\n </div>\n </div>\n <div class=\"ax-col-span-12 md:ax-col-span-7 ax-grid ax-grid-cols-12 ax-gap-4 ax-items-center\">\n <ax-form-field class=\"ax-col-span-12 md:ax-col-span-6\">\n <ax-select-box [value]=\"item.type\" [dataSource]=\"typeOptions()\" valueField=\"id\"\n textField=\"title\"\n (onValueChanged)=\"handleUpdateType(item.key, $event.value)\"></ax-select-box>\n </ax-form-field>\n <ax-form-field class=\"ax-col-span-12 md:ax-col-span-6\">\n <ax-text-box [ngModel]=\"item.title\"\n (onValueChanged)=\"handleUpdateTitle(item.key, $event.value)\"></ax-text-box>\n </ax-form-field>\n </div>\n <div class=\"ax-hidden md:ax-block md:ax-col-span-1 md:ax-justify-self-end\">\n <ax-button look=\"blank\" color=\"danger\" (onClick)=\"handleRemove(item.key)\">\n <ax-prefix><ax-icon class=\"fa-light fa-trash-can\"></ax-icon></ax-prefix>\n </ax-button>\n </div>\n </div>\n } @else {\n <div class=\"ax-grid ax-grid-cols-12 ax-gap-1 ax-rounded ax-border ax-p-3\">\n <div class=\"ax-font-semibold\">{{ item.title }}</div>\n <div class=\"ax-col-span-12 ax-text-xs ax-text-muted\">{{ item.key }}</div>\n </div>\n }\n } @empty {\n <div class=\"ax-text-sm ax-text-gray-400\">{{ '@extra-properties:messages.no-schema-fields' | translate |\n async\n }}</div>\n }\n\n @if (mode() === 'edit') {\n <div class=\"ax-grid ax-grid-cols-12 ax-gap-4 ax-items-end ax-mt-4 ax-border-t ax-border-dashed ax-pt-4\">\n <!-- Type -->\n <ax-form-field class=\"ax-col-span-12 md:ax-col-span-6 lg:ax-col-span-6\">\n <ax-label>{{ '@extra-properties:labels.type' | translate | async }}</ax-label>\n <ax-select-box [ngModel]=\"newTypeId()\" [dataSource]=\"typeOptions()\" valueField=\"id\"\n textField=\"title\" (onValueChanged)=\"newTypeChanged($event.value)\"></ax-select-box>\n </ax-form-field>\n <!-- Title -->\n <ax-form-field class=\"ax-col-span-12 md:ax-col-span-6 lg:ax-col-span-6\">\n <ax-label>{{ '@extra-properties:labels.title' | translate | async }}</ax-label>\n <ax-text-box [ngModel]=\"newTitle()\"\n (onValueChanged)=\"handleTitleChange($event.value)\"></ax-text-box>\n </ax-form-field>\n <!-- Add -->\n <div class=\"ax-col-span-12 ax-flex ax-justify-end\">\n <ax-button look=\"solid\" (onClick)=\"handleAdd()\" [disabled]=\"!canAdd()\"\n text=\"{{ '@extra-properties:actions.add-field' | translate | async }}\">\n <ax-prefix><ax-icon class=\"fa-solid fa-add\"></ax-icon></ax-prefix>\n </ax-button>\n </div>\n </div>\n }\n </div>\n </div>\n</div>\n\n<!-- Right Panel: widget property viewer for selected item -->\n<div class=\"ax-w-1/3 ax-border ax-rounded ax-h-full ax-flex ax-flex-col ax-lightest-surface\">\n @if (mode() === 'edit' && selectedItem()) {\n <div class=\"ax-p-4 ax-font-semibold ax-border-b ax-lighter-surface\">\n {{selectedItem()?.title}}\n </div>\n <div class=\"ax-overflow-y-auto ax-flex-1\">\n <axp-widget-property-viewer [widget]=\"{ type: selectedItem()!.type, options: selectedItem()!.options }\"\n [mode]=\"'advanced'\" (onChanged)=\"handleViewerChanged($event)\" />\n </div>\n }\n @else {\n <div class=\"ax-text-sm ax-text-muted ax-p-4 ax-text-center\">{{ '@extra-properties:messages.select-field-to-edit' |\n translate | async }}</div>\n }\n</div>", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: AXFormModule }, { kind: "component", type: i2$4.AXFormFieldComponent, selector: "ax-form-field", inputs: ["labelMode"] }, { kind: "ngmodule", type: AXLabelModule }, { kind: "component", type: i3$2.AXLabelComponent, selector: "ax-label", inputs: ["required", "for"], outputs: ["requiredChange"] }, { kind: "ngmodule", type: AXTextBoxModule }, { kind: "component", type: i4$4.AXTextBoxComponent, selector: "ax-text-box", inputs: ["disabled", "tabIndex", "readonly", "value", "state", "name", "id", "placeholder", "maxLength", "allowNull", "type", "autoComplete", "look", "mask-options", "class"], outputs: ["onBlur", "onFocus", "valueChange", "stateChange", "onValueChanged", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "ngmodule", type: AXSelectBoxModule }, { kind: "component", type: i5$2.AXSelectBoxComponent, selector: "ax-select-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "minValue", "maxValue", "value", "state", "name", "id", "type", "look", "multiple", "valueField", "textField", "disabledField", "textTemplate", "selectedItems", "isItemTruncated", "showItemTooltip", "dataSource", "minRecordsForSearch", "caption", "itemTemplate", "selectedTemplate", "emptyTemplate", "loadingTemplate", "dropdownWidth", "searchBoxAutoFocus"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onOpened", "onClosed", "onItemSelected", "onItemClick"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i3.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i2$1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i9.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i9.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i9.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type: AXPWidgetPropertyViewerComponent, selector: "axp-widget-property-viewer", inputs: ["widget", "mode"], outputs: ["onChanged"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
3902
|
+
}
|
|
3903
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPExtraPropertiesSchemaComponent, decorators: [{
|
|
3904
|
+
type: Component,
|
|
3905
|
+
args: [{ selector: 'axp-extra-properties-schema', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
3906
|
+
CommonModule,
|
|
3907
|
+
FormsModule,
|
|
3908
|
+
AXFormModule,
|
|
3909
|
+
AXLabelModule,
|
|
3910
|
+
AXTextBoxModule,
|
|
3911
|
+
AXSelectBoxModule,
|
|
3912
|
+
AXButtonModule,
|
|
3913
|
+
AXDecoratorModule,
|
|
3914
|
+
DragDropModule,
|
|
3915
|
+
AXTranslationModule,
|
|
3916
|
+
AXPWidgetPropertyViewerComponent,
|
|
3917
|
+
], standalone: true, host: {
|
|
3918
|
+
class: 'ax-flex ax-flex-1 ax-h-full ax-gap-4 ax-p-4',
|
|
3919
|
+
}, template: "<!-- Left Panel: list/manage properties -->\n<div class=\"ax-flex ax-flex-col ax-gap-3 ax-min-h-0 ax-h-full ax-w-2/3\">\n <div class=\"ax-overflow-y-auto ax-min-h-0 ax-h-full ax-pe-2 -ax-me-2\">\n <div cdkDropList (cdkDropListDropped)=\"handleDrop($event)\" class=\"ax-flex ax-flex-col ax-gap-3\">\n @for (item of schema(); track item.key) {\n @if (mode() === 'edit') {\n <div class=\"ax-grid ax-grid-cols-12 ax-gap-4 ax-items-center ax-rounded ax-border ax-p-3 ax-cursor-pointer ax-lightest-surface \"\n [class.!ax-lighter-surface]=\"item.key === selectedKey()\" (click)=\"handleSelect(item.key)\" cdkDrag\n [cdkDragDisabled]=\"false\">\n <div class=\"ax-col-span-12 md:ax-col-span-4 ax-flex ax-items-center ax-gap-3\">\n <ax-icon class=\"fa-solid fa-grip-dots-vertical ax-cursor-move ax-text-neutral-500\"\n cdkDragHandle></ax-icon>\n <div>\n <div class=\"ax-font-semibold\">{{ item.title }}</div>\n </div>\n </div>\n <div class=\"ax-col-span-12 md:ax-col-span-7 ax-grid ax-grid-cols-12 ax-gap-4 ax-items-center\">\n <ax-form-field class=\"ax-col-span-12 md:ax-col-span-6\">\n <ax-select-box [value]=\"item.type\" [dataSource]=\"typeOptions()\" valueField=\"id\"\n textField=\"title\"\n (onValueChanged)=\"handleUpdateType(item.key, $event.value)\"></ax-select-box>\n </ax-form-field>\n <ax-form-field class=\"ax-col-span-12 md:ax-col-span-6\">\n <ax-text-box [ngModel]=\"item.title\"\n (onValueChanged)=\"handleUpdateTitle(item.key, $event.value)\"></ax-text-box>\n </ax-form-field>\n </div>\n <div class=\"ax-hidden md:ax-block md:ax-col-span-1 md:ax-justify-self-end\">\n <ax-button look=\"blank\" color=\"danger\" (onClick)=\"handleRemove(item.key)\">\n <ax-prefix><ax-icon class=\"fa-light fa-trash-can\"></ax-icon></ax-prefix>\n </ax-button>\n </div>\n </div>\n } @else {\n <div class=\"ax-grid ax-grid-cols-12 ax-gap-1 ax-rounded ax-border ax-p-3\">\n <div class=\"ax-font-semibold\">{{ item.title }}</div>\n <div class=\"ax-col-span-12 ax-text-xs ax-text-muted\">{{ item.key }}</div>\n </div>\n }\n } @empty {\n <div class=\"ax-text-sm ax-text-gray-400\">{{ '@extra-properties:messages.no-schema-fields' | translate |\n async\n }}</div>\n }\n\n @if (mode() === 'edit') {\n <div class=\"ax-grid ax-grid-cols-12 ax-gap-4 ax-items-end ax-mt-4 ax-border-t ax-border-dashed ax-pt-4\">\n <!-- Type -->\n <ax-form-field class=\"ax-col-span-12 md:ax-col-span-6 lg:ax-col-span-6\">\n <ax-label>{{ '@extra-properties:labels.type' | translate | async }}</ax-label>\n <ax-select-box [ngModel]=\"newTypeId()\" [dataSource]=\"typeOptions()\" valueField=\"id\"\n textField=\"title\" (onValueChanged)=\"newTypeChanged($event.value)\"></ax-select-box>\n </ax-form-field>\n <!-- Title -->\n <ax-form-field class=\"ax-col-span-12 md:ax-col-span-6 lg:ax-col-span-6\">\n <ax-label>{{ '@extra-properties:labels.title' | translate | async }}</ax-label>\n <ax-text-box [ngModel]=\"newTitle()\"\n (onValueChanged)=\"handleTitleChange($event.value)\"></ax-text-box>\n </ax-form-field>\n <!-- Add -->\n <div class=\"ax-col-span-12 ax-flex ax-justify-end\">\n <ax-button look=\"solid\" (onClick)=\"handleAdd()\" [disabled]=\"!canAdd()\"\n text=\"{{ '@extra-properties:actions.add-field' | translate | async }}\">\n <ax-prefix><ax-icon class=\"fa-solid fa-add\"></ax-icon></ax-prefix>\n </ax-button>\n </div>\n </div>\n }\n </div>\n </div>\n</div>\n\n<!-- Right Panel: widget property viewer for selected item -->\n<div class=\"ax-w-1/3 ax-border ax-rounded ax-h-full ax-flex ax-flex-col ax-lightest-surface\">\n @if (mode() === 'edit' && selectedItem()) {\n <div class=\"ax-p-4 ax-font-semibold ax-border-b ax-lighter-surface\">\n {{selectedItem()?.title}}\n </div>\n <div class=\"ax-overflow-y-auto ax-flex-1\">\n <axp-widget-property-viewer [widget]=\"{ type: selectedItem()!.type, options: selectedItem()!.options }\"\n [mode]=\"'advanced'\" (onChanged)=\"handleViewerChanged($event)\" />\n </div>\n }\n @else {\n <div class=\"ax-text-sm ax-text-muted ax-p-4 ax-text-center\">{{ '@extra-properties:messages.select-field-to-edit' |\n translate | async }}</div>\n }\n</div>" }]
|
|
3920
|
+
}], ctorParameters: () => [] });
|
|
3921
|
+
|
|
3922
|
+
class AXPExtraPropertiesValuesComponent {
|
|
3923
|
+
constructor() {
|
|
3924
|
+
//#region ---- Inputs ----
|
|
3925
|
+
this.schema = input([], ...(ngDevMode ? [{ debugName: "schema" }] : []));
|
|
3926
|
+
this.values = input({}, ...(ngDevMode ? [{ debugName: "values" }] : []));
|
|
3927
|
+
this.mode = input('edit', ...(ngDevMode ? [{ debugName: "mode" }] : []));
|
|
3928
|
+
//#endregion
|
|
3929
|
+
//#region ---- Outputs ----
|
|
3930
|
+
this.valuesChange = output();
|
|
3931
|
+
//#endregion
|
|
3932
|
+
//#region ---- Outputs ----
|
|
3933
|
+
this.isRequired = (item) => {
|
|
3934
|
+
return item.options?.['validations']?.['required'] ?? false;
|
|
3935
|
+
};
|
|
3936
|
+
//#endregion
|
|
3937
|
+
//#region ---- Class Properties ----
|
|
3938
|
+
this.internalContext = signal({}, ...(ngDevMode ? [{ debugName: "internalContext" }] : []));
|
|
3939
|
+
this.nodeCache = {};
|
|
3940
|
+
this.lastTypeByKey = {};
|
|
3941
|
+
//#endregion
|
|
3942
|
+
//#region ---- Effects ----
|
|
3943
|
+
this.syncContextFromInputs = effect(() => {
|
|
3944
|
+
const schema = this.schema();
|
|
3945
|
+
const vals = this.values();
|
|
3946
|
+
const current = this.internalContext();
|
|
3947
|
+
const currentExtra = current['extra'] ?? {};
|
|
3948
|
+
const extra = {};
|
|
3949
|
+
for (const s of schema) {
|
|
3950
|
+
const v = vals[s.key];
|
|
3951
|
+
if (v !== undefined && v !== null)
|
|
3952
|
+
extra[s.key] = v;
|
|
3953
|
+
}
|
|
3954
|
+
const nextContext = { ...current, extra };
|
|
3955
|
+
if (!isEqual(nextContext, current)) {
|
|
3956
|
+
this.internalContext.set(nextContext);
|
|
3957
|
+
}
|
|
3958
|
+
}, ...(ngDevMode ? [{ debugName: "syncContextFromInputs" }] : []));
|
|
3959
|
+
this.clearOnSchemaTypeChange = effect(() => {
|
|
3960
|
+
const schema = this.schema();
|
|
3961
|
+
const changedKeys = new Set();
|
|
3962
|
+
for (const s of schema) {
|
|
3963
|
+
const prev = this.lastTypeByKey[s.key];
|
|
3964
|
+
if (prev && prev !== s.type)
|
|
3965
|
+
changedKeys.add(s.key);
|
|
3966
|
+
this.lastTypeByKey[s.key] = s.type;
|
|
3967
|
+
}
|
|
3968
|
+
if (changedKeys.size > 0) {
|
|
3969
|
+
const next = { ...this.values() };
|
|
3970
|
+
changedKeys.forEach((k) => delete next[k]);
|
|
3971
|
+
// reset cached node defaults
|
|
3972
|
+
changedKeys.forEach((k) => {
|
|
3973
|
+
const node = this.nodeCache[k];
|
|
3974
|
+
if (node)
|
|
3975
|
+
node.defaultValue = undefined;
|
|
3976
|
+
});
|
|
3977
|
+
this.valuesChange.emit(next);
|
|
3978
|
+
}
|
|
3979
|
+
}, ...(ngDevMode ? [{ debugName: "clearOnSchemaTypeChange" }] : []));
|
|
3980
|
+
}
|
|
3981
|
+
//#endregion
|
|
3982
|
+
//#region ---- Event Handlers ----
|
|
3983
|
+
onContextChanged(event) {
|
|
3984
|
+
if (event.state === 'initiated')
|
|
3985
|
+
return;
|
|
3986
|
+
const data = (event.data ?? {});
|
|
3987
|
+
const extra = data['extra'] ?? {};
|
|
3988
|
+
const nextValues = {};
|
|
3989
|
+
for (const s of this.schema()) {
|
|
3990
|
+
if (Object.prototype.hasOwnProperty.call(extra, s.key)) {
|
|
3991
|
+
nextValues[s.key] = extra[s.key];
|
|
3992
|
+
}
|
|
3993
|
+
}
|
|
3994
|
+
const currentValues = this.values();
|
|
3995
|
+
if (!isEqual(currentValues, nextValues)) {
|
|
3996
|
+
this.valuesChange.emit(nextValues);
|
|
3997
|
+
}
|
|
3998
|
+
}
|
|
3999
|
+
//#endregion
|
|
4000
|
+
//#region ---- Utility Methods ----
|
|
4001
|
+
getNode(item) {
|
|
4002
|
+
const key = item.key;
|
|
4003
|
+
let node = this.nodeCache[key];
|
|
4004
|
+
if (!node) {
|
|
4005
|
+
node = {
|
|
4006
|
+
type: item.type,
|
|
4007
|
+
path: `extra.${item.key}`,
|
|
4008
|
+
options: item.options ?? {},
|
|
4009
|
+
defaultValue: this.values()[item.key],
|
|
4010
|
+
};
|
|
4011
|
+
this.nodeCache[key] = node;
|
|
4012
|
+
}
|
|
4013
|
+
else {
|
|
4014
|
+
// Keep reference stable; update nested fields if essential changes happen
|
|
4015
|
+
node.type = item.type;
|
|
4016
|
+
node.options = item.options ?? node.options;
|
|
4017
|
+
// Do not overwrite defaultValue during editing to avoid resets
|
|
4018
|
+
}
|
|
4019
|
+
return node;
|
|
4020
|
+
}
|
|
4021
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPExtraPropertiesValuesComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4022
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.8", type: AXPExtraPropertiesValuesComponent, isStandalone: true, selector: "axp-extra-properties-values", inputs: { schema: { classPropertyName: "schema", publicName: "schema", isSignal: true, isRequired: false, transformFunction: null }, values: { classPropertyName: "values", publicName: "values", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valuesChange: "valuesChange" }, host: { classAttribute: "ax-block ax-flex-1" }, ngImport: i0, template: `
|
|
4023
|
+
<div class="ax-grid ax-grid-cols-12 ax-gap-4">
|
|
4024
|
+
<axp-widgets-container [context]="internalContext()" (onContextChanged)="onContextChanged($event)">
|
|
4025
|
+
<div class="ax-col-span-12 ax-flex ax-flex-col ax-gap-3">
|
|
4026
|
+
@for(item of schema(); track item.key){
|
|
4027
|
+
@if(mode()==='edit'){
|
|
4028
|
+
<ax-form-field>
|
|
4029
|
+
<ax-label [required]="isRequired(item)">{{item.title}}</ax-label>
|
|
4030
|
+
<ng-container
|
|
4031
|
+
axp-widget-renderer
|
|
4032
|
+
[node]="getNode(item)"
|
|
4033
|
+
[mode]="'edit'"
|
|
4034
|
+
></ng-container>
|
|
4035
|
+
</ax-form-field>
|
|
4036
|
+
} @else {
|
|
4037
|
+
<div class="ax-grid ax-grid-cols-12 ax-gap-1">
|
|
4038
|
+
<div class="ax-font-semibold">{{item.title}}</div>
|
|
4039
|
+
<div class="ax-col-span-12 ax-text-muted">
|
|
4040
|
+
<ng-container
|
|
4041
|
+
axp-widget-renderer
|
|
4042
|
+
[node]="getNode(item)"
|
|
4043
|
+
[mode]="'view'"
|
|
4044
|
+
></ng-container>
|
|
4045
|
+
</div>
|
|
4046
|
+
</div>
|
|
4047
|
+
}
|
|
4048
|
+
}
|
|
4049
|
+
</div>
|
|
4050
|
+
</axp-widgets-container>
|
|
4051
|
+
</div>
|
|
4052
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXPLayoutBuilderModule }, { kind: "component", type: i3$3.AXPWidgetContainerComponent, selector: "axp-widgets-container", inputs: ["context", "functions"], outputs: ["onContextChanged"] }, { kind: "directive", type: i3$3.AXPWidgetRendererDirective, selector: "[axp-widget-renderer]", inputs: ["parentNode", "index", "mode", "node"], outputs: ["onOptionsChanged", "onValueChanged"], exportAs: ["widgetRenderer"] }, { kind: "ngmodule", type: AXFormModule }, { kind: "component", type: i2$4.AXFormFieldComponent, selector: "ax-form-field", inputs: ["labelMode"] }, { kind: "ngmodule", type: AXLabelModule }, { kind: "component", type: i3$2.AXLabelComponent, selector: "ax-label", inputs: ["required", "for"], outputs: ["requiredChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
4053
|
+
}
|
|
4054
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPExtraPropertiesValuesComponent, decorators: [{
|
|
4055
|
+
type: Component,
|
|
4056
|
+
args: [{
|
|
4057
|
+
selector: 'axp-extra-properties-values',
|
|
4058
|
+
template: `
|
|
4059
|
+
<div class="ax-grid ax-grid-cols-12 ax-gap-4">
|
|
4060
|
+
<axp-widgets-container [context]="internalContext()" (onContextChanged)="onContextChanged($event)">
|
|
4061
|
+
<div class="ax-col-span-12 ax-flex ax-flex-col ax-gap-3">
|
|
4062
|
+
@for(item of schema(); track item.key){
|
|
4063
|
+
@if(mode()==='edit'){
|
|
4064
|
+
<ax-form-field>
|
|
4065
|
+
<ax-label [required]="isRequired(item)">{{item.title}}</ax-label>
|
|
4066
|
+
<ng-container
|
|
4067
|
+
axp-widget-renderer
|
|
4068
|
+
[node]="getNode(item)"
|
|
4069
|
+
[mode]="'edit'"
|
|
4070
|
+
></ng-container>
|
|
4071
|
+
</ax-form-field>
|
|
4072
|
+
} @else {
|
|
4073
|
+
<div class="ax-grid ax-grid-cols-12 ax-gap-1">
|
|
4074
|
+
<div class="ax-font-semibold">{{item.title}}</div>
|
|
4075
|
+
<div class="ax-col-span-12 ax-text-muted">
|
|
4076
|
+
<ng-container
|
|
4077
|
+
axp-widget-renderer
|
|
4078
|
+
[node]="getNode(item)"
|
|
4079
|
+
[mode]="'view'"
|
|
4080
|
+
></ng-container>
|
|
4081
|
+
</div>
|
|
4082
|
+
</div>
|
|
4083
|
+
}
|
|
4084
|
+
}
|
|
4085
|
+
</div>
|
|
4086
|
+
</axp-widgets-container>
|
|
4087
|
+
</div>
|
|
4088
|
+
`,
|
|
4089
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
4090
|
+
imports: [CommonModule, AXPLayoutBuilderModule, AXFormModule, AXLabelModule],
|
|
4091
|
+
standalone: true,
|
|
4092
|
+
host: {
|
|
4093
|
+
class: 'ax-block ax-flex-1',
|
|
4094
|
+
},
|
|
4095
|
+
}]
|
|
4096
|
+
}] });
|
|
4097
|
+
|
|
4098
|
+
class AXPQueryFiltersComponent {
|
|
4099
|
+
constructor() {
|
|
4100
|
+
this.translate = inject(AXTranslationService);
|
|
4101
|
+
this.calendarService = inject(AXCalendarService);
|
|
4102
|
+
this.filterOperatorMiddleware = inject(AXPFilterOperatorMiddlewareService);
|
|
4103
|
+
this.filtersDefinitions = input([], ...(ngDevMode ? [{ debugName: "filtersDefinitions" }] : []));
|
|
4104
|
+
this.initialFilters = input([], ...(ngDevMode ? [{ debugName: "initialFilters" }] : []));
|
|
4105
|
+
this.onFiltersChanged = output();
|
|
4106
|
+
this.tagBox = viewChild('tagBox', ...(ngDevMode ? [{ debugName: "tagBox" }] : []));
|
|
4107
|
+
this.selectedField = signal(null, ...(ngDevMode ? [{ debugName: "selectedField" }] : []));
|
|
4108
|
+
this.selectedFilters = linkedSignal(() => this.convertQueriesToDefinitions(this.initialFilters()), {
|
|
4109
|
+
equal: isEqual,
|
|
4110
|
+
});
|
|
4111
|
+
this.context = linkedSignal(() => this.convertQueriesToContext(this.initialFilters()));
|
|
4112
|
+
this.activeFilter = signal(null, ...(ngDevMode ? [{ debugName: "activeFilter" }] : []));
|
|
4113
|
+
this.asyncTags = signal([], ...(ngDevMode ? [{ debugName: "asyncTags" }] : []));
|
|
4114
|
+
this.popover = viewChild('popover', ...(ngDevMode ? [{ debugName: "popover" }] : []));
|
|
4115
|
+
this.inputValue = signal('', ...(ngDevMode ? [{ debugName: "inputValue" }] : []));
|
|
4116
|
+
this.inlineFilters = () => {
|
|
4117
|
+
return this.filtersDefinitions().filter((f) => f.filterType.inline &&
|
|
4118
|
+
!this.filterOperatorMiddleware
|
|
4119
|
+
.transformFilters(this.selectedFilters())
|
|
4120
|
+
.some((sf) => sf.field === f.field &&
|
|
4121
|
+
sf.operator?.type === (this.context()[sf.field]?.operation?.type || f.operator?.type)));
|
|
4122
|
+
};
|
|
1235
4123
|
this.getDisplayValue = async (filter, val) => {
|
|
1236
|
-
if (filter.widget
|
|
4124
|
+
if (filter.widget?.type === 'select-editor' || filter.widget?.type === 'select-filter') {
|
|
1237
4125
|
const dataSource = filter.widget.options?.['dataSource'];
|
|
1238
4126
|
const textField = filter.widget.options?.['textField'];
|
|
1239
4127
|
const valueField = filter.widget.options?.['valueField'];
|
|
@@ -1284,6 +4172,7 @@ class AXPLayoutFiltersComponent {
|
|
|
1284
4172
|
field: f.field,
|
|
1285
4173
|
operator: context[f.field]?.operation,
|
|
1286
4174
|
value: context[f.field]?.value,
|
|
4175
|
+
hidden: f.hidden,
|
|
1287
4176
|
}));
|
|
1288
4177
|
const newContext = {};
|
|
1289
4178
|
convertedFilters.forEach((cf) => {
|
|
@@ -1308,7 +4197,7 @@ class AXPLayoutFiltersComponent {
|
|
|
1308
4197
|
query: `${this.translate.translateSync(filter.title)} ${this.getActiveOperator(filter)} '${displayValue}'`,
|
|
1309
4198
|
};
|
|
1310
4199
|
})).then((results) => {
|
|
1311
|
-
this.asyncTags.set(results);
|
|
4200
|
+
this.asyncTags.set(results.filter((r) => !r.hidden));
|
|
1312
4201
|
});
|
|
1313
4202
|
}, ...(ngDevMode ? [{ debugName: "#effect2" }] : []));
|
|
1314
4203
|
}
|
|
@@ -1323,6 +4212,7 @@ class AXPLayoutFiltersComponent {
|
|
|
1323
4212
|
title: definition?.title || '',
|
|
1324
4213
|
widget: definition?.widget,
|
|
1325
4214
|
filterType: definition?.filterType,
|
|
4215
|
+
hidden: q.hidden,
|
|
1326
4216
|
};
|
|
1327
4217
|
});
|
|
1328
4218
|
}
|
|
@@ -1336,6 +4226,7 @@ class AXPLayoutFiltersComponent {
|
|
|
1336
4226
|
this.tagBoxInput = this.tagBox()?.getHostElement().querySelector('input');
|
|
1337
4227
|
}
|
|
1338
4228
|
handleSelectField(field) {
|
|
4229
|
+
console.log(field);
|
|
1339
4230
|
this.activeFilter.set(field);
|
|
1340
4231
|
// this.inputValue.set('');
|
|
1341
4232
|
this.tagBox()?.inputValue.set('');
|
|
@@ -1383,8 +4274,9 @@ class AXPLayoutFiltersComponent {
|
|
|
1383
4274
|
#effect;
|
|
1384
4275
|
handleSelectFilters(e) {
|
|
1385
4276
|
if (e.value?.length < this.selectedFilters().length) {
|
|
4277
|
+
const hiddenFilters = this.selectedFilters().filter((f) => f.hidden);
|
|
1386
4278
|
this.selectedFilters.update((prev) => {
|
|
1387
|
-
return e.value;
|
|
4279
|
+
return hiddenFilters.concat(e.value);
|
|
1388
4280
|
});
|
|
1389
4281
|
}
|
|
1390
4282
|
}
|
|
@@ -1431,12 +4323,12 @@ class AXPLayoutFiltersComponent {
|
|
|
1431
4323
|
}
|
|
1432
4324
|
}
|
|
1433
4325
|
#effect2;
|
|
1434
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.
|
|
1435
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.
|
|
4326
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPQueryFiltersComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4327
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.8", type: AXPQueryFiltersComponent, isStandalone: true, selector: "axp-query-filters", inputs: { filtersDefinitions: { classPropertyName: "filtersDefinitions", publicName: "filtersDefinitions", isSignal: true, isRequired: false, transformFunction: null }, initialFilters: { classPropertyName: "initialFilters", publicName: "initialFilters", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onFiltersChanged: "onFiltersChanged" }, viewQueries: [{ propertyName: "tagBox", first: true, predicate: ["tagBox"], descendants: true, isSignal: true }, { propertyName: "popover", first: true, predicate: ["popover"], descendants: true, isSignal: true }, { propertyName: "listItems", predicate: ["caseItem"], descendants: true }], ngImport: i0, template: "<div class=\"ax-flex ax-items-center ax-gap-2 ax-p-2\">\n <ax-button (keydown)=\"handleButtonKeyDown($event)\" (onClick)=\"popover.open()\" #filterButton [look]=\"'blank'\">\n <ax-icon class=\"far fa-bars-filter ax-cursor-pointer\"> </ax-icon>\n </ax-button>\n <ax-tag-box\n [ngModel]=\"asyncTags()\"\n (onValueChanged)=\"handleSelectFilters($event)\"\n [textField]=\"'query'\"\n [valueField]=\"'id'\"\n [readonly]=\"filtersDefinitions().length === 0\"\n [look]=\"'none'\"\n [readonlyField]=\"'readOnly'\"\n (onKeyDown)=\"handleKeyDown($event)\"\n [addOnEnter]=\"false\"\n [placeholder]=\"\n (filtersDefinitions().length === 0\n ? '@general:terms.interface.filter.no-filter-definitions'\n : '@general:terms.interface.filter.placeholder'\n )\n | translate\n | async\n \"\n #tagBox\n ></ax-tag-box>\n</div>\n\n<ax-popover\n [offsetY]=\"activeFilter() ? -30 : 0\"\n [target]=\"tagBoxInput\"\n [openOn]=\"'toggle'\"\n (onOpened)=\"onPopoverOpened($event)\"\n [closeOn]=\"'clickOut'\"\n (onClosed)=\"handlePopoverClosed($event)\"\n [adaptivityEnabled]=\"true\"\n #popover\n>\n <div class=\"md:ax-min-w-72 ax-border ax-surface ax-w-full ax-rounded-md md:ax-max-h-96 md:ax-overflow-auto\">\n <axp-widgets-container [context]=\"context()\" (onContextChanged)=\"onContextChanged($event)\">\n @if (activeFilter()) {\n <div class=\"ax-flex ax-flex-col ax-lightest-surface ax-shadow-md\">\n <ax-header class=\"ax-border-b ax-border-light ax-px-4 ax-py-2\">{{\n activeFilter()?.title! | translate | async\n }}</ax-header>\n <ax-content class=\"ax-p-4\">\n <div class=\"ax-mb-2\">\n <ax-badge [text]=\"getActiveOperator(activeFilter())!\"></ax-badge>\n </div>\n <ng-container\n axp-widget-renderer\n [node]=\"{\n type: activeFilter()?.widget?.type || 'text-editor',\n path: activeFilter()?.field,\n options: activeFilter()?.widget?.options,\n }\"\n [mode]=\"'edit'\"\n >\n </ng-container>\n </ax-content>\n <ax-footer class=\"ax-border-t ax-flex ax-justify-end ax-border-light ax-w-full ax-px-4 ax-py-2\">\n <ax-button\n class=\"ax-xs\"\n [text]=\"'@general:actions.apply.title' | translate | async\"\n (onClick)=\"handleApplyFilter()\"\n ></ax-button>\n </ax-footer>\n </div>\n } @else {\n <div axListNavigation #list=\"axListNavigation\" class=\"axp-list-items\">\n @if (tagBox.inputValue()) {\n @for (inlineFilter of inlineFilters(); track inlineFilter.field) {\n <div\n axListNavigationItem\n #caseItem=\"axListNavigationItem\"\n [class.axp-state-focused]=\"caseItem.isActive()\"\n tabindex=\"0\"\n (click)=\"handleSelectInlineFilter(inlineFilter)\"\n (keydown)=\"handleInlineFilterKeyDown($event, inlineFilter)\"\n >\n {{ inlineFilter.title | translate | async }} {{ getActiveOperator(inlineFilter) }} '{{\n tagBox.inputValue()\n }}'\n </div>\n }\n <span class=\"ax-w-full ax-border-t ax-border-light ax-my-1\"></span>\n }\n @for (field of filterFields(); track field.field) {\n <div\n axListNavigationItem\n #caseItem=\"axListNavigationItem\"\n [class.axp-state-focused]=\"caseItem.isActive()\"\n (click)=\"handleSelectField(field)\"\n (keydown)=\"handleFieldKeyDown($event, field)\"\n tabindex=\"0\"\n >\n <div class=\"ax-flex ax-items-end ax-gap-2\">\n <ax-icon class=\"ax-w-5\" [class]=\"'fa-light ' + field.icon\"> </ax-icon>\n {{ field.title | translate | async }}\n </div>\n </div>\n }\n </div>\n }\n </axp-widgets-container>\n </div>\n</ax-popover>\n", styles: ["axp-query-filters{width:100%}.axp-list-items{display:flex;min-width:10rem;flex-direction:column;border-radius:.375rem;border-width:1px;padding-top:1rem;padding-bottom:1rem;--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow);background-color:rgb(var(--ax-sys-color-lightest-surface));color:rgb(var(--ax-sys-color-on-lightest-surface));border-color:rgb(var(--ax-sys-color-border-lightest-surface))}.axp-list-items>div{min-width:7rem;cursor:pointer;padding:.5rem 1rem;text-align:start}.axp-list-items>div:focus{outline:none}.axp-list-items>div.axp-state-focused,.axp-list-items>div:hover{background-color:rgb(var(--ax-sys-color-surface));color:rgb(var(--ax-sys-color-on-surface));border-color:rgb(var(--ax-sys-color-border-surface))}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i3.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i2$1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: AXPopoverModule }, { kind: "component", type: i4$5.AXPopoverComponent, selector: "ax-popover", inputs: ["width", "disabled", "offsetX", "offsetY", "target", "placement", "content", "openOn", "closeOn", "hasBackdrop", "openAfter", "closeAfter", "backdropClass", "panelClass", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "ngmodule", type: AXSelectionListModule }, { kind: "ngmodule", type: AXTagBoxModule }, { kind: "component", type: i5$3.AXTagBoxComponent, selector: "ax-tag-box", inputs: ["disabled", "tabIndex", "readonly", "value", "state", "name", "id", "placeholder", "allowNull", "type", "look", "addOnComma", "addOnEnter", "valueField", "textField", "readonlyField", "allowDuplicateValues"], outputs: ["onBlur", "onFocus", "valueChange", "stateChange", "onValueChanged", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "ngmodule", type: AXPLayoutBuilderModule }, { kind: "component", type: i3$3.AXPWidgetContainerComponent, selector: "axp-widgets-container", inputs: ["context", "functions"], outputs: ["onContextChanged"] }, { kind: "directive", type: i3$3.AXPWidgetRendererDirective, selector: "[axp-widget-renderer]", inputs: ["parentNode", "index", "mode", "node"], outputs: ["onOptionsChanged", "onValueChanged"], exportAs: ["widgetRenderer"] }, { kind: "ngmodule", type: AXListNavigationModule }, { kind: "directive", type: i7.AXListNavigationDirective, selector: "[axListNavigation]", inputs: ["orientation"], outputs: ["onNavigationChanged", "onPressEnterOrSpace"], exportAs: ["axListNavigation"] }, { kind: "directive", type: i7.AXListNavigationItemDirective, selector: "[axListNavigationItem]", exportAs: ["axListNavigationItem"] }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "component", type: i8.AXBadgeComponent, selector: "ax-badge", inputs: ["color", "look", "text"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
1436
4328
|
}
|
|
1437
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.
|
|
4329
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPQueryFiltersComponent, decorators: [{
|
|
1438
4330
|
type: Component,
|
|
1439
|
-
args: [{ selector: 'axp-
|
|
4331
|
+
args: [{ selector: 'axp-query-filters', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [
|
|
1440
4332
|
CommonModule,
|
|
1441
4333
|
FormsModule,
|
|
1442
4334
|
AXButtonModule,
|
|
@@ -1448,12 +4340,250 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
|
|
|
1448
4340
|
AXPLayoutBuilderModule,
|
|
1449
4341
|
AXListNavigationModule,
|
|
1450
4342
|
AXBadgeModule,
|
|
1451
|
-
], template: "<div class=\"ax-flex ax-items-center ax-gap-2 ax-p-2\">\n <ax-button (keydown)=\"handleButtonKeyDown($event)\" (onClick)=\"popover.open()\" #filterButton [look]=\"'blank'\">\n <ax-icon class=\"far fa-bars-filter ax-cursor-pointer\"> </ax-icon>\n </ax-button>\n <ax-tag-box\n [ngModel]=\"asyncTags()\"\n (onValueChanged)=\"handleSelectFilters($event)\"\n [textField]=\"'query'\"\n [valueField]=\"'id'\"\n [readonly]=\"filtersDefinitions().length === 0\"\n [look]=\"'none'\"\n [readonlyField]=\"'readOnly'\"\n (onKeyDown)=\"handleKeyDown($event)\"\n [addOnEnter]=\"false\"\n [placeholder]=\"(filtersDefinitions().length === 0
|
|
4343
|
+
], template: "<div class=\"ax-flex ax-items-center ax-gap-2 ax-p-2\">\n <ax-button (keydown)=\"handleButtonKeyDown($event)\" (onClick)=\"popover.open()\" #filterButton [look]=\"'blank'\">\n <ax-icon class=\"far fa-bars-filter ax-cursor-pointer\"> </ax-icon>\n </ax-button>\n <ax-tag-box\n [ngModel]=\"asyncTags()\"\n (onValueChanged)=\"handleSelectFilters($event)\"\n [textField]=\"'query'\"\n [valueField]=\"'id'\"\n [readonly]=\"filtersDefinitions().length === 0\"\n [look]=\"'none'\"\n [readonlyField]=\"'readOnly'\"\n (onKeyDown)=\"handleKeyDown($event)\"\n [addOnEnter]=\"false\"\n [placeholder]=\"\n (filtersDefinitions().length === 0\n ? '@general:terms.interface.filter.no-filter-definitions'\n : '@general:terms.interface.filter.placeholder'\n )\n | translate\n | async\n \"\n #tagBox\n ></ax-tag-box>\n</div>\n\n<ax-popover\n [offsetY]=\"activeFilter() ? -30 : 0\"\n [target]=\"tagBoxInput\"\n [openOn]=\"'toggle'\"\n (onOpened)=\"onPopoverOpened($event)\"\n [closeOn]=\"'clickOut'\"\n (onClosed)=\"handlePopoverClosed($event)\"\n [adaptivityEnabled]=\"true\"\n #popover\n>\n <div class=\"md:ax-min-w-72 ax-border ax-surface ax-w-full ax-rounded-md md:ax-max-h-96 md:ax-overflow-auto\">\n <axp-widgets-container [context]=\"context()\" (onContextChanged)=\"onContextChanged($event)\">\n @if (activeFilter()) {\n <div class=\"ax-flex ax-flex-col ax-lightest-surface ax-shadow-md\">\n <ax-header class=\"ax-border-b ax-border-light ax-px-4 ax-py-2\">{{\n activeFilter()?.title! | translate | async\n }}</ax-header>\n <ax-content class=\"ax-p-4\">\n <div class=\"ax-mb-2\">\n <ax-badge [text]=\"getActiveOperator(activeFilter())!\"></ax-badge>\n </div>\n <ng-container\n axp-widget-renderer\n [node]=\"{\n type: activeFilter()?.widget?.type || 'text-editor',\n path: activeFilter()?.field,\n options: activeFilter()?.widget?.options,\n }\"\n [mode]=\"'edit'\"\n >\n </ng-container>\n </ax-content>\n <ax-footer class=\"ax-border-t ax-flex ax-justify-end ax-border-light ax-w-full ax-px-4 ax-py-2\">\n <ax-button\n class=\"ax-xs\"\n [text]=\"'@general:actions.apply.title' | translate | async\"\n (onClick)=\"handleApplyFilter()\"\n ></ax-button>\n </ax-footer>\n </div>\n } @else {\n <div axListNavigation #list=\"axListNavigation\" class=\"axp-list-items\">\n @if (tagBox.inputValue()) {\n @for (inlineFilter of inlineFilters(); track inlineFilter.field) {\n <div\n axListNavigationItem\n #caseItem=\"axListNavigationItem\"\n [class.axp-state-focused]=\"caseItem.isActive()\"\n tabindex=\"0\"\n (click)=\"handleSelectInlineFilter(inlineFilter)\"\n (keydown)=\"handleInlineFilterKeyDown($event, inlineFilter)\"\n >\n {{ inlineFilter.title | translate | async }} {{ getActiveOperator(inlineFilter) }} '{{\n tagBox.inputValue()\n }}'\n </div>\n }\n <span class=\"ax-w-full ax-border-t ax-border-light ax-my-1\"></span>\n }\n @for (field of filterFields(); track field.field) {\n <div\n axListNavigationItem\n #caseItem=\"axListNavigationItem\"\n [class.axp-state-focused]=\"caseItem.isActive()\"\n (click)=\"handleSelectField(field)\"\n (keydown)=\"handleFieldKeyDown($event, field)\"\n tabindex=\"0\"\n >\n <div class=\"ax-flex ax-items-end ax-gap-2\">\n <ax-icon class=\"ax-w-5\" [class]=\"'fa-light ' + field.icon\"> </ax-icon>\n {{ field.title | translate | async }}\n </div>\n </div>\n }\n </div>\n }\n </axp-widgets-container>\n </div>\n</ax-popover>\n", styles: ["axp-query-filters{width:100%}.axp-list-items{display:flex;min-width:10rem;flex-direction:column;border-radius:.375rem;border-width:1px;padding-top:1rem;padding-bottom:1rem;--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow);background-color:rgb(var(--ax-sys-color-lightest-surface));color:rgb(var(--ax-sys-color-on-lightest-surface));border-color:rgb(var(--ax-sys-color-border-lightest-surface))}.axp-list-items>div{min-width:7rem;cursor:pointer;padding:.5rem 1rem;text-align:start}.axp-list-items>div:focus{outline:none}.axp-list-items>div.axp-state-focused,.axp-list-items>div:hover{background-color:rgb(var(--ax-sys-color-surface));color:rgb(var(--ax-sys-color-on-surface));border-color:rgb(var(--ax-sys-color-border-surface))}\n"] }]
|
|
1452
4344
|
}], propDecorators: { listItems: [{
|
|
1453
4345
|
type: ViewChildren,
|
|
1454
4346
|
args: ['caseItem']
|
|
1455
4347
|
}] } });
|
|
1456
4348
|
|
|
4349
|
+
class AXPQuerySortsComponent {
|
|
4350
|
+
constructor() {
|
|
4351
|
+
this.sortDefinitions = model([], ...(ngDevMode ? [{ debugName: "sortDefinitions" }] : []));
|
|
4352
|
+
this.sortQueries = signal([], ...(ngDevMode ? [{ debugName: "sortQueries", equal: isEqual }] : [{
|
|
4353
|
+
equal: isEqual,
|
|
4354
|
+
}]));
|
|
4355
|
+
this.initialSortQueries = input([], ...(ngDevMode ? [{ debugName: "initialSortQueries" }] : []));
|
|
4356
|
+
this.sortQueriesChange = output();
|
|
4357
|
+
// Recompute merged sort queries whenever inputs change
|
|
4358
|
+
effect(() => {
|
|
4359
|
+
const initialQueries = this.initialSortQueries();
|
|
4360
|
+
const definitions = this.sortDefinitions();
|
|
4361
|
+
const existingQueriesMap = new Map(initialQueries.map((q) => [q.name, q]));
|
|
4362
|
+
const mergedQueries = definitions.map((def) => {
|
|
4363
|
+
const existingQuery = existingQueriesMap.get(def.name);
|
|
4364
|
+
return existingQuery ? { ...def, dir: existingQuery.dir } : { ...def };
|
|
4365
|
+
});
|
|
4366
|
+
this.sortQueries.set(mergedQueries);
|
|
4367
|
+
});
|
|
4368
|
+
effect(() => {
|
|
4369
|
+
this.sortQueriesChange.emit(this.sortQueries());
|
|
4370
|
+
});
|
|
4371
|
+
}
|
|
4372
|
+
drop(event) {
|
|
4373
|
+
const sd = this.sortDefinitions();
|
|
4374
|
+
moveItemInArray(sd, event.previousIndex, event.currentIndex);
|
|
4375
|
+
this.sortDefinitions.set([...sd]);
|
|
4376
|
+
// Reorder sortQueries based on new sortDefinitions order
|
|
4377
|
+
const sq = this.sortQueries();
|
|
4378
|
+
moveItemInArray(sq, event.previousIndex, event.currentIndex);
|
|
4379
|
+
this.sortQueries.set([...sq]);
|
|
4380
|
+
}
|
|
4381
|
+
getSortDirection(item) {
|
|
4382
|
+
return this.sortQueries().find((i) => i.name === item.name)?.dir;
|
|
4383
|
+
}
|
|
4384
|
+
changeItemSort(item) {
|
|
4385
|
+
const itemDirection = this.getSortDirection(item);
|
|
4386
|
+
const newDirection = itemDirection === 'asc' ? 'desc' : itemDirection === 'desc' ? undefined : 'asc';
|
|
4387
|
+
this.sortQueries.update((prev) => {
|
|
4388
|
+
return prev.map((field) => {
|
|
4389
|
+
if (field.name === item.name) {
|
|
4390
|
+
return { ...field, dir: newDirection };
|
|
4391
|
+
}
|
|
4392
|
+
return field;
|
|
4393
|
+
});
|
|
4394
|
+
});
|
|
4395
|
+
}
|
|
4396
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPQuerySortsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4397
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.8", type: AXPQuerySortsComponent, isStandalone: true, selector: "axp-query-sorts", inputs: { sortDefinitions: { classPropertyName: "sortDefinitions", publicName: "sortDefinitions", isSignal: true, isRequired: false, transformFunction: null }, initialSortQueries: { classPropertyName: "initialSortQueries", publicName: "initialSortQueries", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { sortDefinitions: "sortDefinitionsChange", sortQueriesChange: "sortQueriesChange" }, ngImport: i0, template: "<div class=\"ax-flex ax-flex-col ax-justify-center ax-gap-4 ax-select-none\">\n <div class=\"ax-flex ax-flex-col ax-gap-4 ax-select-none\" cdkDropList (cdkDropListDropped)=\"drop($event)\">\n <div class=\"ax-flex ax-flex-col ax-gap-3 ax-w-full ax-sorted-list ax-max-h-[calc(100vh-280px)] ax-overflow-auto\">\n @for (item of sortDefinitions(); track item.name) {\n <div class=\"ax-flex ax-py-1 ax-items-center ax-justify-between\" cdkDrag cdkDragBoundary=\".ax-sorted-list\">\n <div class=\"ax-flex ax-items-center ax-gap-3\" cdkDragHandle>\n <ax-icon class=\"fa-solid fa-grip-dots-vertical ax-cursor-move\"></ax-icon>\n <p class=\"ax-font-medium ax-text-sm\">{{ item.title | translate | async }}</p>\n </div>\n <ax-button [color]=\"'blank'\" class=\"ax-sm\" (click)=\"changeItemSort(item)\">\n <ax-icon\n [class.ax-text-primary]=\"getSortDirection(item) === 'asc'\"\n class=\"fa-solid fa-arrow-up-long ax-text-neutral-400\"\n ></ax-icon>\n <ax-icon\n [class.ax-text-primary]=\"getSortDirection(item) === 'desc'\"\n class=\"fa-solid fa-arrow-down-long ax-text-neutral-400\"\n ></ax-icon>\n </ax-button>\n </div>\n }\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "ngmodule", type: AXTabsModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i3.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
4398
|
+
}
|
|
4399
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPQuerySortsComponent, decorators: [{
|
|
4400
|
+
type: Component,
|
|
4401
|
+
args: [{ selector: 'axp-query-sorts', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [
|
|
4402
|
+
CdkDropList,
|
|
4403
|
+
CdkDrag,
|
|
4404
|
+
CdkDragHandle,
|
|
4405
|
+
AXTabsModule,
|
|
4406
|
+
AXTranslationModule,
|
|
4407
|
+
CommonModule,
|
|
4408
|
+
AXDecoratorModule,
|
|
4409
|
+
AXButtonModule,
|
|
4410
|
+
], template: "<div class=\"ax-flex ax-flex-col ax-justify-center ax-gap-4 ax-select-none\">\n <div class=\"ax-flex ax-flex-col ax-gap-4 ax-select-none\" cdkDropList (cdkDropListDropped)=\"drop($event)\">\n <div class=\"ax-flex ax-flex-col ax-gap-3 ax-w-full ax-sorted-list ax-max-h-[calc(100vh-280px)] ax-overflow-auto\">\n @for (item of sortDefinitions(); track item.name) {\n <div class=\"ax-flex ax-py-1 ax-items-center ax-justify-between\" cdkDrag cdkDragBoundary=\".ax-sorted-list\">\n <div class=\"ax-flex ax-items-center ax-gap-3\" cdkDragHandle>\n <ax-icon class=\"fa-solid fa-grip-dots-vertical ax-cursor-move\"></ax-icon>\n <p class=\"ax-font-medium ax-text-sm\">{{ item.title | translate | async }}</p>\n </div>\n <ax-button [color]=\"'blank'\" class=\"ax-sm\" (click)=\"changeItemSort(item)\">\n <ax-icon\n [class.ax-text-primary]=\"getSortDirection(item) === 'asc'\"\n class=\"fa-solid fa-arrow-up-long ax-text-neutral-400\"\n ></ax-icon>\n <ax-icon\n [class.ax-text-primary]=\"getSortDirection(item) === 'desc'\"\n class=\"fa-solid fa-arrow-down-long ax-text-neutral-400\"\n ></ax-icon>\n </ax-button>\n </div>\n }\n </div>\n </div>\n</div>\n" }]
|
|
4411
|
+
}], ctorParameters: () => [] });
|
|
4412
|
+
|
|
4413
|
+
class AXPTemplateViewerComponent extends AXBasePageComponent {
|
|
4414
|
+
constructor() {
|
|
4415
|
+
super(...arguments);
|
|
4416
|
+
//#endregion
|
|
4417
|
+
//#region ---- Component State ----
|
|
4418
|
+
this.context = {};
|
|
4419
|
+
this.document = signal({ type: AXPWidgetsCatalog.document }, ...(ngDevMode ? [{ debugName: "document" }] : []));
|
|
4420
|
+
this.currentPageIndex = signal(0, ...(ngDevMode ? [{ debugName: "currentPageIndex" }] : []));
|
|
4421
|
+
this._config = signal(undefined, ...(ngDevMode ? [{ debugName: "_config" }] : []));
|
|
4422
|
+
this.currentPage = computed(() => {
|
|
4423
|
+
return (this.document().children?.[this.currentPageIndex()] ?? { type: AXPWidgetsCatalog.pageLayout });
|
|
4424
|
+
}, ...(ngDevMode ? [{ debugName: "currentPage" }] : []));
|
|
4425
|
+
}
|
|
4426
|
+
//#region ---- Input Properties ----
|
|
4427
|
+
set config(value) {
|
|
4428
|
+
this._config.set(value);
|
|
4429
|
+
}
|
|
4430
|
+
get config() {
|
|
4431
|
+
return this._config();
|
|
4432
|
+
}
|
|
4433
|
+
//#endregion
|
|
4434
|
+
//#region ---- Lifecycle Methods ----
|
|
4435
|
+
async ngOnInit() {
|
|
4436
|
+
super.ngOnInit();
|
|
4437
|
+
await this.loadTemplate();
|
|
4438
|
+
}
|
|
4439
|
+
//#endregion
|
|
4440
|
+
//#region ---- Template Loading ----
|
|
4441
|
+
async loadTemplate() {
|
|
4442
|
+
const config = this.config;
|
|
4443
|
+
if (!config)
|
|
4444
|
+
return;
|
|
4445
|
+
let templateData;
|
|
4446
|
+
if (typeof config.template === 'string') {
|
|
4447
|
+
try {
|
|
4448
|
+
templateData = JSON.parse(config.template);
|
|
4449
|
+
}
|
|
4450
|
+
catch (error) {
|
|
4451
|
+
console.error('Failed to parse template JSON:', error);
|
|
4452
|
+
return;
|
|
4453
|
+
}
|
|
4454
|
+
}
|
|
4455
|
+
else {
|
|
4456
|
+
templateData = config.template;
|
|
4457
|
+
}
|
|
4458
|
+
this.document.set(templateData);
|
|
4459
|
+
// Set initial context if provided
|
|
4460
|
+
if (config.context) {
|
|
4461
|
+
this.context = { ...config.context };
|
|
4462
|
+
}
|
|
4463
|
+
}
|
|
4464
|
+
//#endregion
|
|
4465
|
+
//#region ---- Event Handlers ----
|
|
4466
|
+
handleContextChanged(e) {
|
|
4467
|
+
this.context = e.data;
|
|
4468
|
+
}
|
|
4469
|
+
async handleSubmit(form) {
|
|
4470
|
+
const formResult = await form.validate();
|
|
4471
|
+
if (formResult.result) {
|
|
4472
|
+
this.close({
|
|
4473
|
+
context: this.context,
|
|
4474
|
+
cancelled: false,
|
|
4475
|
+
metadata: this.config?.metadata
|
|
4476
|
+
});
|
|
4477
|
+
}
|
|
4478
|
+
}
|
|
4479
|
+
handleCancel() {
|
|
4480
|
+
this.close({
|
|
4481
|
+
context: this.context,
|
|
4482
|
+
cancelled: true,
|
|
4483
|
+
metadata: this.config?.metadata
|
|
4484
|
+
});
|
|
4485
|
+
}
|
|
4486
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPTemplateViewerComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
4487
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.8", type: AXPTemplateViewerComponent, isStandalone: true, selector: "axp-template-viewer", inputs: { config: "config" }, usesInheritance: true, ngImport: i0, template: `
|
|
4488
|
+
<div class="ax-p-4 ax-min-h-64">
|
|
4489
|
+
<ax-form #form>
|
|
4490
|
+
<axp-widgets-container [context]="context" (onContextChanged)="handleContextChanged($event)" >
|
|
4491
|
+
<ng-container axp-widget-renderer [node]="currentPage()" [mode]="config?.readOnly ? 'view' : 'edit'"></ng-container>
|
|
4492
|
+
</axp-widgets-container>
|
|
4493
|
+
</ax-form>
|
|
4494
|
+
</div>
|
|
4495
|
+
|
|
4496
|
+
@if (config?.showActions !== false) {
|
|
4497
|
+
<ax-footer>
|
|
4498
|
+
<ax-suffix>
|
|
4499
|
+
<ax-button [text]="'@general:actions.cancel.title' | translate | async" (onClick)="handleCancel()"></ax-button>
|
|
4500
|
+
@if (!config?.readOnly) {
|
|
4501
|
+
<ax-button color="primary" [text]="'@general:actions.submit.title' | translate | async" (onClick)="handleSubmit(form)"></ax-button>
|
|
4502
|
+
}
|
|
4503
|
+
</ax-suffix>
|
|
4504
|
+
</ax-footer>
|
|
4505
|
+
}
|
|
4506
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXPLayoutBuilderModule }, { kind: "component", type: i3$3.AXPWidgetContainerComponent, selector: "axp-widgets-container", inputs: ["context", "functions"], outputs: ["onContextChanged"] }, { kind: "directive", type: i3$3.AXPWidgetRendererDirective, selector: "[axp-widget-renderer]", inputs: ["parentNode", "index", "mode", "node"], outputs: ["onOptionsChanged", "onValueChanged"], exportAs: ["widgetRenderer"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i3.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXFormModule }, { kind: "component", type: i2$4.AXFormComponent, selector: "ax-form", inputs: ["labelMode", "look", "messageStyle", "updateOn"], outputs: ["onValidate", "updateOnChange"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }], encapsulation: i0.ViewEncapsulation.None }); }
|
|
4507
|
+
}
|
|
4508
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPTemplateViewerComponent, decorators: [{
|
|
4509
|
+
type: Component,
|
|
4510
|
+
args: [{
|
|
4511
|
+
selector: 'axp-template-viewer',
|
|
4512
|
+
template: `
|
|
4513
|
+
<div class="ax-p-4 ax-min-h-64">
|
|
4514
|
+
<ax-form #form>
|
|
4515
|
+
<axp-widgets-container [context]="context" (onContextChanged)="handleContextChanged($event)" >
|
|
4516
|
+
<ng-container axp-widget-renderer [node]="currentPage()" [mode]="config?.readOnly ? 'view' : 'edit'"></ng-container>
|
|
4517
|
+
</axp-widgets-container>
|
|
4518
|
+
</ax-form>
|
|
4519
|
+
</div>
|
|
4520
|
+
|
|
4521
|
+
@if (config?.showActions !== false) {
|
|
4522
|
+
<ax-footer>
|
|
4523
|
+
<ax-suffix>
|
|
4524
|
+
<ax-button [text]="'@general:actions.cancel.title' | translate | async" (onClick)="handleCancel()"></ax-button>
|
|
4525
|
+
@if (!config?.readOnly) {
|
|
4526
|
+
<ax-button color="primary" [text]="'@general:actions.submit.title' | translate | async" (onClick)="handleSubmit(form)"></ax-button>
|
|
4527
|
+
}
|
|
4528
|
+
</ax-suffix>
|
|
4529
|
+
</ax-footer>
|
|
4530
|
+
}
|
|
4531
|
+
`,
|
|
4532
|
+
encapsulation: ViewEncapsulation.None,
|
|
4533
|
+
imports: [CommonModule, AXPLayoutBuilderModule, AXDecoratorModule, AXButtonModule, AXFormModule, AXTranslationModule]
|
|
4534
|
+
}]
|
|
4535
|
+
}], propDecorators: { config: [{
|
|
4536
|
+
type: Input
|
|
4537
|
+
}] } });
|
|
4538
|
+
|
|
4539
|
+
var templateViewer_component = /*#__PURE__*/Object.freeze({
|
|
4540
|
+
__proto__: null,
|
|
4541
|
+
AXPTemplateViewerComponent: AXPTemplateViewerComponent
|
|
4542
|
+
});
|
|
4543
|
+
|
|
4544
|
+
class AXPTemplateViewerService {
|
|
4545
|
+
constructor() {
|
|
4546
|
+
this.popupService = inject(AXPopupService);
|
|
4547
|
+
}
|
|
4548
|
+
/**
|
|
4549
|
+
* Show a template viewer dialog with the given configuration
|
|
4550
|
+
* @param config Template viewer configuration including template, title, and UI options
|
|
4551
|
+
* @returns Promise resolving to viewer result with form values and cancellation status
|
|
4552
|
+
*/
|
|
4553
|
+
async showTemplate(config) {
|
|
4554
|
+
const component = await Promise.resolve().then(function () { return templateViewer_component; }).then(c => c.AXPTemplateViewerComponent);
|
|
4555
|
+
const result = await this.popupService.open(component, {
|
|
4556
|
+
title: config.title || 'Template Viewer',
|
|
4557
|
+
size: config.size || 'lg',
|
|
4558
|
+
closeButton: false,
|
|
4559
|
+
closeOnBackdropClick: false,
|
|
4560
|
+
draggable: false,
|
|
4561
|
+
data: { config }
|
|
4562
|
+
});
|
|
4563
|
+
return result?.data || { context: config.context, cancelled: true, metadata: config.metadata };
|
|
4564
|
+
}
|
|
4565
|
+
/**
|
|
4566
|
+
* Show a template viewer in read-only mode
|
|
4567
|
+
* @param config Template viewer configuration
|
|
4568
|
+
* @returns Promise resolving to viewer result
|
|
4569
|
+
*/
|
|
4570
|
+
async showTemplateReadOnly(config) {
|
|
4571
|
+
return this.showTemplate({
|
|
4572
|
+
...config,
|
|
4573
|
+
readOnly: true,
|
|
4574
|
+
showActions: false
|
|
4575
|
+
});
|
|
4576
|
+
}
|
|
4577
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPTemplateViewerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
4578
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPTemplateViewerService, providedIn: 'root' }); }
|
|
4579
|
+
}
|
|
4580
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPTemplateViewerService, decorators: [{
|
|
4581
|
+
type: Injectable,
|
|
4582
|
+
args: [{
|
|
4583
|
+
providedIn: 'root'
|
|
4584
|
+
}]
|
|
4585
|
+
}] });
|
|
4586
|
+
|
|
1457
4587
|
const AXP_USER_AVATAR_PROVIDER = new InjectionToken('AXP_USER_AVATAR_PROVIDER', {
|
|
1458
4588
|
providedIn: 'root',
|
|
1459
4589
|
factory: () => {
|
|
@@ -1587,10 +4717,10 @@ class AXPUserAvatarService {
|
|
|
1587
4717
|
throw error;
|
|
1588
4718
|
}
|
|
1589
4719
|
}
|
|
1590
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.
|
|
1591
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.
|
|
4720
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPUserAvatarService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
4721
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPUserAvatarService, providedIn: 'root' }); }
|
|
1592
4722
|
}
|
|
1593
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.
|
|
4723
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPUserAvatarService, decorators: [{
|
|
1594
4724
|
type: Injectable,
|
|
1595
4725
|
args: [{
|
|
1596
4726
|
providedIn: 'root',
|
|
@@ -1680,10 +4810,10 @@ class AXPUserAvatarComponent {
|
|
|
1680
4810
|
const idx = this.hashString(initials) % colors.length;
|
|
1681
4811
|
return colors[idx];
|
|
1682
4812
|
}
|
|
1683
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.
|
|
1684
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.
|
|
4813
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPUserAvatarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4814
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.8", type: AXPUserAvatarComponent, isStandalone: true, selector: "axp-user-avatar", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, userId: { classPropertyName: "userId", publicName: "userId", isSignal: true, isRequired: false, transformFunction: null } }, providers: [], ngImport: i0, template: "<ax-avatar #avatar [size]=\"size()\" class=\"ax-cursor-pointer\">\n @if(hasPicture()){\n <ax-image (onError)=\"onImageError($event)\" (onLoad)=\"onImageLoad($event)\" [src]=\"src()\"></ax-image>\n }@else{\n <ax-text class=\"ax-{{ avatarColor() }}-lightest \">\n <small class=\"ax-text-xs ax-font-semibold\">{{ avatarText() }}</small>\n </ax-text>\n }\n</ax-avatar>\n\n<!--\n\nax-primary-lightest\nax-warning-lightest\nax-success-lightest\nax-danger-lightest\nax-secondary-lightest\nax-accent1-lightest\nax-accent2-lightest\nax-accent3-lightest\n\n-->\n", styles: [""], dependencies: [{ kind: "ngmodule", type: AXAvatarModule }, { kind: "component", type: i1$5.AXAvatarComponent, selector: "ax-avatar", inputs: ["color", "size", "shape", "look"], outputs: ["sizeChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXImageModule }, { kind: "component", type: i3$4.AXImageComponent, selector: "ax-image", inputs: ["width", "height", "overlayMode", "src", "alt", "priority", "lazy"], outputs: ["onLoad", "onError"] }, { kind: "ngmodule", type: AXBadgeModule }], encapsulation: i0.ViewEncapsulation.None }); }
|
|
1685
4815
|
}
|
|
1686
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.
|
|
4816
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPUserAvatarComponent, decorators: [{
|
|
1687
4817
|
type: Component,
|
|
1688
4818
|
args: [{ selector: 'axp-user-avatar', imports: [
|
|
1689
4819
|
AXAvatarModule,
|
|
@@ -1693,6 +4823,46 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
|
|
|
1693
4823
|
], encapsulation: ViewEncapsulation.None, providers: [], template: "<ax-avatar #avatar [size]=\"size()\" class=\"ax-cursor-pointer\">\n @if(hasPicture()){\n <ax-image (onError)=\"onImageError($event)\" (onLoad)=\"onImageLoad($event)\" [src]=\"src()\"></ax-image>\n }@else{\n <ax-text class=\"ax-{{ avatarColor() }}-lightest \">\n <small class=\"ax-text-xs ax-font-semibold\">{{ avatarText() }}</small>\n </ax-text>\n }\n</ax-avatar>\n\n<!--\n\nax-primary-lightest\nax-warning-lightest\nax-success-lightest\nax-danger-lightest\nax-secondary-lightest\nax-accent1-lightest\nax-accent2-lightest\nax-accent3-lightest\n\n-->\n" }]
|
|
1694
4824
|
}] });
|
|
1695
4825
|
|
|
4826
|
+
class AXPQueryViewsComponent {
|
|
4827
|
+
constructor() {
|
|
4828
|
+
this.popupService = inject(AXPopupService);
|
|
4829
|
+
this.translate = inject(AXTranslationService);
|
|
4830
|
+
this.tabs = viewChild('tabs', ...(ngDevMode ? [{ debugName: "tabs" }] : []));
|
|
4831
|
+
this.views = model([], ...(ngDevMode ? [{ debugName: "views" }] : []));
|
|
4832
|
+
this.selectedView = model.required(...(ngDevMode ? [{ debugName: "selectedView" }] : []));
|
|
4833
|
+
this.isMounted = signal(false, ...(ngDevMode ? [{ debugName: "isMounted" }] : []));
|
|
4834
|
+
this.#effect = effect(() => {
|
|
4835
|
+
if (!this.isMounted())
|
|
4836
|
+
return;
|
|
4837
|
+
const views = untracked(() => this.views());
|
|
4838
|
+
if (!views)
|
|
4839
|
+
return;
|
|
4840
|
+
const selectedTab = views.findIndex((v) => v.name == this.selectedView().name);
|
|
4841
|
+
untracked(() => {
|
|
4842
|
+
if (selectedTab != -1) {
|
|
4843
|
+
this.tabs()?.select(selectedTab);
|
|
4844
|
+
}
|
|
4845
|
+
});
|
|
4846
|
+
}, ...(ngDevMode ? [{ debugName: "#effect" }] : []));
|
|
4847
|
+
}
|
|
4848
|
+
ngAfterViewInit() {
|
|
4849
|
+
this.isMounted.set(true);
|
|
4850
|
+
}
|
|
4851
|
+
#effect;
|
|
4852
|
+
setView(view) {
|
|
4853
|
+
this.selectedView.set(view);
|
|
4854
|
+
}
|
|
4855
|
+
handleActiveChange(e) {
|
|
4856
|
+
console.log(e);
|
|
4857
|
+
}
|
|
4858
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPQueryViewsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4859
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.8", type: AXPQueryViewsComponent, isStandalone: true, selector: "axp-query-views", inputs: { views: { classPropertyName: "views", publicName: "views", isSignal: true, isRequired: false, transformFunction: null }, selectedView: { classPropertyName: "selectedView", publicName: "selectedView", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { views: "viewsChange", selectedView: "selectedViewChange" }, viewQueries: [{ propertyName: "tabs", first: true, predicate: ["tabs"], descendants: true, isSignal: true }], ngImport: i0, template: "<ax-tabs #tabs [look]=\"'with-line'\" class=\"ax-font-semibold\">\n @for (item of views(); track item.name) {\n <ax-tab-item (onClick)=\"setView(item)\" [key]=\"item.name\" [text]=\"(item.title | translate | async) || 'item.title'\">\n </ax-tab-item>\n }\n <!-- <ax-tab-item\n (onClick)=\"createNew()\"\n [key]=\"'create-new'\"\n [text]=\"('@general:actions.create.title' | translate | async) || 'Create New'\"\n >\n </ax-tab-item> -->\n</ax-tabs>\n", dependencies: [{ kind: "ngmodule", type: AXTabsModule }, { kind: "component", type: i2$5.AXTabsComponent, selector: "ax-tabs", inputs: ["look", "location", "fitParent", "minWidth", "content"], outputs: ["onActiveTabChanged"] }, { kind: "component", type: i2$5.AXTabItemComponent, selector: "ax-tab-item", inputs: ["disabled", "text", "key", "headerTemplate", "active"], outputs: ["disabledChange", "onClick", "onBlur", "onFocus", "activeChange"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: CommonModule }, { kind: "pipe", type: i5.AXTranslatorPipe, name: "translate" }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
4860
|
+
}
|
|
4861
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPQueryViewsComponent, decorators: [{
|
|
4862
|
+
type: Component,
|
|
4863
|
+
args: [{ selector: 'axp-query-views', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [AXTabsModule, AXTranslationModule, CommonModule], template: "<ax-tabs #tabs [look]=\"'with-line'\" class=\"ax-font-semibold\">\n @for (item of views(); track item.name) {\n <ax-tab-item (onClick)=\"setView(item)\" [key]=\"item.name\" [text]=\"(item.title | translate | async) || 'item.title'\">\n </ax-tab-item>\n }\n <!-- <ax-tab-item\n (onClick)=\"createNew()\"\n [key]=\"'create-new'\"\n [text]=\"('@general:actions.create.title' | translate | async) || 'Create New'\"\n >\n </ax-tab-item> -->\n</ax-tabs>\n" }]
|
|
4864
|
+
}] });
|
|
4865
|
+
|
|
1696
4866
|
/**
|
|
1697
4867
|
* Generic widget item component for displaying selectable widgets with icons, titles, and descriptions.
|
|
1698
4868
|
* Can be used across different modules for consistent widget display and interaction.
|
|
@@ -1739,10 +4909,10 @@ class AXPWidgetItemComponent {
|
|
|
1739
4909
|
getIconClass() {
|
|
1740
4910
|
return this.widget().icon || 'fa-light fa-document';
|
|
1741
4911
|
}
|
|
1742
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.
|
|
1743
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.
|
|
4912
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPWidgetItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4913
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.8", type: AXPWidgetItemComponent, isStandalone: true, selector: "axp-widget-item", inputs: { widget: { classPropertyName: "widget", publicName: "widget", isSignal: true, isRequired: true, transformFunction: null }, isSelected: { classPropertyName: "isSelected", publicName: "isSelected", isSignal: true, isRequired: false, transformFunction: null }, showPinButton: { classPropertyName: "showPinButton", publicName: "showPinButton", isSignal: true, isRequired: false, transformFunction: null }, customClasses: { classPropertyName: "customClasses", publicName: "customClasses", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onWidgetClick: "onWidgetClick", onPinClick: "onPinClick" }, ngImport: i0, template: "<div (click)=\"handleClick($event)\"\n class=\"ax-py-2 ax-px-3 ax-rounded-md ax-flex ax-gap-3 ax-items-center ax-group hover:ax-bg-primary-lightest/65 hover:ax-text-primary-on-lightest ax-cursor-pointer ax-w-full\"\n [class.ax-bg-primary-lightest]=\"isSelected()\" [class.ax-text-primary-on-lightest]=\"isSelected()\"\n [class.ax-border-primary-lightest]=\"isSelected()\" [class]=\"customClasses()\">\n\n <!-- Widget Icon -->\n <div class=\"ax-min-w-10 ax-h-10 ax-flex ax-items-center ax-justify-center ax-rounded-md ax-border group-hover:ax-bg-primary-lighter group-hover:ax-text-primary-on-lighter group-hover:ax-border-primary-lighter\"\n [class.ax-bg-primary-light]=\"isSelected()\" [class.ax-text-primary-on-light]=\"isSelected()\"\n [class.ax-border-primary-light]=\"isSelected()\" [class.ax-surface]=\"!isSelected()\">\n <i [ngClass]=\"getIconClass()\" class=\"ax-text-lg\"></i>\n </div>\n\n <!-- Widget Content -->\n <div class=\"ax-flex ax-flex-col ax-gap-1 ax-flex-1 ax-w-[70%]\">\n <div class=\"ax-flex ax-items-center ax-justify-between ax-gap-2\">\n <!-- Widget Title -->\n <div class=\"ax-font-semibold ax-text-sm ax-truncate\" [title]=\"widget().title\">\n {{ widget().title }}\n </div>\n\n <!-- Pin Button -->\n @if (showPinButton()) {\n <div (click)=\"handlePinClick($event)\" class=\"ax-cursor-pointer\">\n @if (widget().isPinned) {\n <i class=\"fa-solid fa-thumbtack ax-text-sm ax-rotate-45\" title=\"Unpin\"></i>\n } @else {\n <i class=\"fa-light fa-thumbtack ax-text-sm ax-rotate-45 ax-invisible group-hover:ax-visible\"\n title=\"Pin\"></i>\n }\n </div>\n }\n </div>\n\n <!-- Widget Description -->\n @if (widget().description) {\n <span class=\"ax-text-xs ax-truncate\" [title]=\"widget().description\">\n {{ widget().description }}\n </span>\n }\n </div>\n</div>", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], encapsulation: i0.ViewEncapsulation.None }); }
|
|
1744
4914
|
}
|
|
1745
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.
|
|
4915
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.8", ngImport: i0, type: AXPWidgetItemComponent, decorators: [{
|
|
1746
4916
|
type: Component,
|
|
1747
4917
|
args: [{ selector: 'axp-widget-item', imports: [CommonModule], encapsulation: ViewEncapsulation.None, template: "<div (click)=\"handleClick($event)\"\n class=\"ax-py-2 ax-px-3 ax-rounded-md ax-flex ax-gap-3 ax-items-center ax-group hover:ax-bg-primary-lightest/65 hover:ax-text-primary-on-lightest ax-cursor-pointer ax-w-full\"\n [class.ax-bg-primary-lightest]=\"isSelected()\" [class.ax-text-primary-on-lightest]=\"isSelected()\"\n [class.ax-border-primary-lightest]=\"isSelected()\" [class]=\"customClasses()\">\n\n <!-- Widget Icon -->\n <div class=\"ax-min-w-10 ax-h-10 ax-flex ax-items-center ax-justify-center ax-rounded-md ax-border group-hover:ax-bg-primary-lighter group-hover:ax-text-primary-on-lighter group-hover:ax-border-primary-lighter\"\n [class.ax-bg-primary-light]=\"isSelected()\" [class.ax-text-primary-on-light]=\"isSelected()\"\n [class.ax-border-primary-light]=\"isSelected()\" [class.ax-surface]=\"!isSelected()\">\n <i [ngClass]=\"getIconClass()\" class=\"ax-text-lg\"></i>\n </div>\n\n <!-- Widget Content -->\n <div class=\"ax-flex ax-flex-col ax-gap-1 ax-flex-1 ax-w-[70%]\">\n <div class=\"ax-flex ax-items-center ax-justify-between ax-gap-2\">\n <!-- Widget Title -->\n <div class=\"ax-font-semibold ax-text-sm ax-truncate\" [title]=\"widget().title\">\n {{ widget().title }}\n </div>\n\n <!-- Pin Button -->\n @if (showPinButton()) {\n <div (click)=\"handlePinClick($event)\" class=\"ax-cursor-pointer\">\n @if (widget().isPinned) {\n <i class=\"fa-solid fa-thumbtack ax-text-sm ax-rotate-45\" title=\"Unpin\"></i>\n } @else {\n <i class=\"fa-light fa-thumbtack ax-text-sm ax-rotate-45 ax-invisible group-hover:ax-visible\"\n title=\"Pin\"></i>\n }\n </div>\n }\n </div>\n\n <!-- Widget Description -->\n @if (widget().description) {\n <span class=\"ax-text-xs ax-truncate\" [title]=\"widget().description\">\n {{ widget().description }}\n </span>\n }\n </div>\n</div>" }]
|
|
1748
4918
|
}] });
|
|
@@ -1751,5 +4921,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
|
|
|
1751
4921
|
* Generated bundle index. Do not edit.
|
|
1752
4922
|
*/
|
|
1753
4923
|
|
|
1754
|
-
export { AXPActivityLogComponent, AXPCompareViewComponent, AXPComponentSlot, AXPComponentSlotDirective, AXPComponentSlotModule, AXPComponentSlotRegistryService, AXPDynamicFormComponent,
|
|
4924
|
+
export { AXPActivityLogComponent, AXPCategoryTreeComponent, AXPCompareViewComponent, AXPComponentSlot, AXPComponentSlotDirective, AXPComponentSlotModule, AXPComponentSlotRegistryService, AXPDataSelectorComponent, AXPDataSelectorService, AXPDynamicDialogComponent, AXPDynamicDialogService, AXPDynamicFormBuilderService, AXPDynamicFormComponent, AXPDynamicFormStepperComponent, AXPExtraPropertiesComponent, AXPExtraPropertiesSchemaComponent, AXPExtraPropertiesValuesComponent, AXPMenuBadgeHelper, AXPQueryColumnsComponent, AXPQueryFiltersComponent, AXPQuerySortsComponent, AXPQueryViewsComponent, AXPStateMessageComponent, AXPTaskBadgeDirective, AXPTaskBadgeProvider, AXPTaskBadgeService, AXPTemplateViewerComponent, AXPTemplateViewerService, AXPThemeLayoutActionsComponent, AXPThemeLayoutBlockComponent, AXPThemeLayoutContainerComponent, AXPThemeLayoutEndSideComponent, AXPThemeLayoutFooterComponent, AXPThemeLayoutHeaderComponent, AXPThemeLayoutListComponent, AXPThemeLayoutListItemComponent, AXPThemeLayoutListItemsGroupComponent, AXPThemeLayoutPageHeaderComponent, AXPThemeLayoutPagePrimaryActionsComponent, AXPThemeLayoutPageSecondaryActionsComponent, AXPThemeLayoutSectionComponent, AXPThemeLayoutStartSideComponent, AXPThemeLayoutToolbarComponent, AXPUserAvatarComponent, AXPUserAvatarService, AXPWidgetItemComponent, AXPWidgetPropertyViewerComponent, AXP_EXTRA_PROPERTY_TYPES, AXP_TASK_BADGE_PROVIDERS, AXP_USER_AVATAR_PROVIDER };
|
|
1755
4925
|
//# sourceMappingURL=acorex-platform-layout-components.mjs.map
|