@acorex-platform/framework-client 0.0.38 → 0.0.48
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/fesm2022/acorex-platform-framework-client-auth.mjs +212 -44
- package/fesm2022/acorex-platform-framework-client-auth.mjs.map +1 -1
- package/fesm2022/{acorex-platform-framework-client-common-common-settings.provider-CzBr0cRi.mjs → acorex-platform-framework-client-common-common-settings.provider-ChU2tvyt.mjs} +31 -1
- package/fesm2022/acorex-platform-framework-client-common-common-settings.provider-ChU2tvyt.mjs.map +1 -0
- package/fesm2022/acorex-platform-framework-client-common.mjs +1172 -193
- package/fesm2022/acorex-platform-framework-client-common.mjs.map +1 -1
- package/fesm2022/acorex-platform-framework-client-core.mjs +233 -132
- package/fesm2022/acorex-platform-framework-client-core.mjs.map +1 -1
- package/fesm2022/acorex-platform-framework-client-layout-builder.mjs +295 -59
- package/fesm2022/acorex-platform-framework-client-layout-builder.mjs.map +1 -1
- package/fesm2022/{acorex-platform-framework-client-layout-components-binding-expression-editor-popup.component-Bp2cNCPO.mjs → acorex-platform-framework-client-layout-components-binding-expression-editor-popup.component-BqPaHKPM.mjs} +10 -6
- package/fesm2022/acorex-platform-framework-client-layout-components-binding-expression-editor-popup.component-BqPaHKPM.mjs.map +1 -0
- package/fesm2022/acorex-platform-framework-client-layout-components-property-viewer-inline-code-editor.component-CcpUTEVQ.mjs +66 -0
- package/fesm2022/acorex-platform-framework-client-layout-components-property-viewer-inline-code-editor.component-CcpUTEVQ.mjs.map +1 -0
- package/fesm2022/acorex-platform-framework-client-layout-components-resource-appointment-board.component-DCkpgsFH.mjs +195 -0
- package/fesm2022/acorex-platform-framework-client-layout-components-resource-appointment-board.component-DCkpgsFH.mjs.map +1 -0
- package/fesm2022/acorex-platform-framework-client-layout-components.mjs +4015 -1014
- package/fesm2022/acorex-platform-framework-client-layout-components.mjs.map +1 -1
- package/fesm2022/acorex-platform-framework-client-layout-designer.mjs +1179 -304
- package/fesm2022/acorex-platform-framework-client-layout-designer.mjs.map +1 -1
- package/fesm2022/{acorex-platform-framework-client-layout-entity-acorex-platform-framework-client-layout-entity-CvaOWbJx.mjs → acorex-platform-framework-client-layout-entity-acorex-platform-framework-client-layout-entity-UkQsf84C.mjs} +1701 -300
- package/fesm2022/acorex-platform-framework-client-layout-entity-acorex-platform-framework-client-layout-entity-UkQsf84C.mjs.map +1 -0
- package/fesm2022/{acorex-platform-framework-client-layout-entity-attachments-page.component-Ds63Rt2n.mjs → acorex-platform-framework-client-layout-entity-attachments-page.component-DmmiDLZw.mjs} +2 -2
- package/fesm2022/{acorex-platform-framework-client-layout-entity-attachments-page.component-Ds63Rt2n.mjs.map → acorex-platform-framework-client-layout-entity-attachments-page.component-DmmiDLZw.mjs.map} +1 -1
- package/fesm2022/{acorex-platform-framework-client-layout-entity-bulk-entity.command-C0pohwdo.mjs → acorex-platform-framework-client-layout-entity-bulk-entity.command-BOFTb66c.mjs} +2 -2
- package/fesm2022/{acorex-platform-framework-client-layout-entity-bulk-entity.command-C0pohwdo.mjs.map → acorex-platform-framework-client-layout-entity-bulk-entity.command-BOFTb66c.mjs.map} +1 -1
- package/fesm2022/{acorex-platform-framework-client-layout-entity-gallery-page.component-o2HuZrDN.mjs → acorex-platform-framework-client-layout-entity-gallery-page.component-Bg-cMOlQ.mjs} +2 -2
- package/fesm2022/{acorex-platform-framework-client-layout-entity-gallery-page.component-o2HuZrDN.mjs.map → acorex-platform-framework-client-layout-entity-gallery-page.component-Bg-cMOlQ.mjs.map} +1 -1
- package/fesm2022/acorex-platform-framework-client-layout-entity.mjs +2 -2
- package/fesm2022/acorex-platform-framework-client-layout-views.mjs +47 -8
- package/fesm2022/acorex-platform-framework-client-layout-views.mjs.map +1 -1
- package/fesm2022/acorex-platform-framework-client-layout-widget-core.mjs +3854 -3292
- package/fesm2022/acorex-platform-framework-client-layout-widget-core.mjs.map +1 -1
- package/fesm2022/acorex-platform-framework-client-layout-widgets-acorex-platform-framework-client-layout-widgets-DJNSBNVe.mjs +33319 -0
- package/fesm2022/acorex-platform-framework-client-layout-widgets-acorex-platform-framework-client-layout-widgets-DJNSBNVe.mjs.map +1 -0
- package/fesm2022/{acorex-platform-framework-client-layout-widgets-button-widget-designer.component-BDOdcoyN.mjs → acorex-platform-framework-client-layout-widgets-button-widget-designer.component-BkrPu1wO.mjs} +8 -5
- package/fesm2022/acorex-platform-framework-client-layout-widgets-button-widget-designer.component-BkrPu1wO.mjs.map +1 -0
- package/fesm2022/acorex-platform-framework-client-layout-widgets-code-editor-value.util-Cb7R1qLO.mjs +45 -0
- package/fesm2022/acorex-platform-framework-client-layout-widgets-code-editor-value.util-Cb7R1qLO.mjs.map +1 -0
- package/fesm2022/acorex-platform-framework-client-layout-widgets-code-editor-widget-column.component-BL621E1r.mjs +68 -0
- package/fesm2022/acorex-platform-framework-client-layout-widgets-code-editor-widget-column.component-BL621E1r.mjs.map +1 -0
- package/fesm2022/acorex-platform-framework-client-layout-widgets-code-editor-widget-edit.component-CVsPKhNl.mjs +88 -0
- package/fesm2022/acorex-platform-framework-client-layout-widgets-code-editor-widget-edit.component-CVsPKhNl.mjs.map +1 -0
- package/fesm2022/acorex-platform-framework-client-layout-widgets-code-editor-widget-view.component-BEq4O4al.mjs +71 -0
- package/fesm2022/acorex-platform-framework-client-layout-widgets-code-editor-widget-view.component-BEq4O4al.mjs.map +1 -0
- package/fesm2022/acorex-platform-framework-client-layout-widgets-condition-builder-edit-popup.component-WpiEHusZ.mjs +81 -0
- package/fesm2022/acorex-platform-framework-client-layout-widgets-condition-builder-edit-popup.component-WpiEHusZ.mjs.map +1 -0
- package/fesm2022/{acorex-platform-framework-client-layout-widgets-page-widget-designer.component-WzIiwnGC.mjs → acorex-platform-framework-client-layout-widgets-page-widget-designer.component-Cadl6guA.mjs} +41 -23
- package/fesm2022/acorex-platform-framework-client-layout-widgets-page-widget-designer.component-Cadl6guA.mjs.map +1 -0
- package/fesm2022/{acorex-platform-framework-client-layout-widgets-repeater-widget-column.component-4mX8aYzA.mjs → acorex-platform-framework-client-layout-widgets-repeater-widget-column.component-CKtGsWPI.mjs} +3 -3
- package/fesm2022/{acorex-platform-framework-client-layout-widgets-repeater-widget-column.component-4mX8aYzA.mjs.map → acorex-platform-framework-client-layout-widgets-repeater-widget-column.component-CKtGsWPI.mjs.map} +1 -1
- package/fesm2022/acorex-platform-framework-client-layout-widgets-scheduler-picker-widget-column.component-Clb27Loe.mjs +71 -0
- package/fesm2022/acorex-platform-framework-client-layout-widgets-scheduler-picker-widget-column.component-Clb27Loe.mjs.map +1 -0
- package/fesm2022/acorex-platform-framework-client-layout-widgets-scheduler-picker-widget-edit.component-l7q8A-D3.mjs +111 -0
- package/fesm2022/acorex-platform-framework-client-layout-widgets-scheduler-picker-widget-edit.component-l7q8A-D3.mjs.map +1 -0
- package/fesm2022/acorex-platform-framework-client-layout-widgets-scheduler-picker-widget-view.component-Cc1AH09b.mjs +77 -0
- package/fesm2022/acorex-platform-framework-client-layout-widgets-scheduler-picker-widget-view.component-Cc1AH09b.mjs.map +1 -0
- package/fesm2022/{acorex-platform-framework-client-layout-widgets-tabular-data-edit-popup.component-TWxthl21.mjs → acorex-platform-framework-client-layout-widgets-tabular-data-edit-popup.component-BCLxS3rS.mjs} +3 -3
- package/fesm2022/{acorex-platform-framework-client-layout-widgets-tabular-data-edit-popup.component-TWxthl21.mjs.map → acorex-platform-framework-client-layout-widgets-tabular-data-edit-popup.component-BCLxS3rS.mjs.map} +1 -1
- package/fesm2022/{acorex-platform-framework-client-layout-widgets-text-block-widget-designer.component-D6HFPmGC.mjs → acorex-platform-framework-client-layout-widgets-text-block-widget-designer.component-DYxgwR2E.mjs} +21 -8
- package/fesm2022/acorex-platform-framework-client-layout-widgets-text-block-widget-designer.component-DYxgwR2E.mjs.map +1 -0
- package/fesm2022/acorex-platform-framework-client-layout-widgets-trigger-expression-editor-popup.component-C2PGoC7r.mjs +124 -0
- package/fesm2022/acorex-platform-framework-client-layout-widgets-trigger-expression-editor-popup.component-C2PGoC7r.mjs.map +1 -0
- package/fesm2022/acorex-platform-framework-client-layout-widgets-triggers-widget-editor.component-DDDoPoQa.mjs +345 -0
- package/fesm2022/acorex-platform-framework-client-layout-widgets-triggers-widget-editor.component-DDDoPoQa.mjs.map +1 -0
- package/fesm2022/acorex-platform-framework-client-layout-widgets.mjs +1 -31985
- package/fesm2022/acorex-platform-framework-client-layout-widgets.mjs.map +1 -1
- package/fesm2022/acorex-platform-framework-client-realtime.mjs +2 -1
- package/fesm2022/acorex-platform-framework-client-realtime.mjs.map +1 -1
- package/fesm2022/acorex-platform-framework-client-runtime.mjs +2 -2
- package/fesm2022/acorex-platform-framework-client-runtime.mjs.map +1 -1
- package/fesm2022/{acorex-platform-framework-client-themes-default-entity-master-create-view.component-CT7WWWG0.mjs → acorex-platform-framework-client-themes-default-entity-master-create-view.component-DlS4v_zb.mjs} +3 -3
- package/fesm2022/acorex-platform-framework-client-themes-default-entity-master-create-view.component-DlS4v_zb.mjs.map +1 -0
- package/fesm2022/acorex-platform-framework-client-themes-default-entity-master-modify-view.component-DBmdBKBL.mjs +122 -0
- package/fesm2022/acorex-platform-framework-client-themes-default-entity-master-modify-view.component-DBmdBKBL.mjs.map +1 -0
- package/fesm2022/{acorex-platform-framework-client-themes-default-entity-master-single-view.component-DBUwSzvg.mjs → acorex-platform-framework-client-themes-default-entity-master-single-view.component-CkpRT1a9.mjs} +3 -3
- package/fesm2022/acorex-platform-framework-client-themes-default-entity-master-single-view.component-CkpRT1a9.mjs.map +1 -0
- package/fesm2022/acorex-platform-framework-client-themes-default.mjs +424 -103
- package/fesm2022/acorex-platform-framework-client-themes-default.mjs.map +1 -1
- package/fesm2022/{acorex-platform-framework-client-themes-shared-settings.provider-CpsAIsxj.mjs → acorex-platform-framework-client-themes-shared-settings.provider-DIkjSTU7.mjs} +102 -1
- package/fesm2022/acorex-platform-framework-client-themes-shared-settings.provider-DIkjSTU7.mjs.map +1 -0
- package/fesm2022/acorex-platform-framework-client-themes-shared.mjs +174 -22
- package/fesm2022/acorex-platform-framework-client-themes-shared.mjs.map +1 -1
- package/package.json +2 -2
- package/realtime/README.md +1 -1
- package/types/acorex-platform-framework-client-auth.d.ts +18 -1
- package/types/acorex-platform-framework-client-common.d.ts +243 -9
- package/types/acorex-platform-framework-client-core.d.ts +152 -119
- package/types/acorex-platform-framework-client-layout-builder.d.ts +29 -0
- package/types/acorex-platform-framework-client-layout-components.d.ts +717 -147
- package/types/acorex-platform-framework-client-layout-designer.d.ts +192 -14
- package/types/acorex-platform-framework-client-layout-entity.d.ts +167 -92
- package/types/acorex-platform-framework-client-layout-views.d.ts +23 -1
- package/types/acorex-platform-framework-client-layout-widget-core.d.ts +148 -40
- package/types/acorex-platform-framework-client-layout-widgets.d.ts +261 -119
- package/types/acorex-platform-framework-client-realtime.d.ts +16 -3
- package/types/acorex-platform-framework-client-themes-default.d.ts +62 -11
- package/types/acorex-platform-framework-client-themes-shared.d.ts +25 -2
- package/fesm2022/acorex-platform-framework-client-common-common-settings.provider-CzBr0cRi.mjs.map +0 -1
- package/fesm2022/acorex-platform-framework-client-layout-components-binding-expression-editor-popup.component-Bp2cNCPO.mjs.map +0 -1
- package/fesm2022/acorex-platform-framework-client-layout-components-file-provider-picker.popup.component-BtLEUWAA.mjs +0 -77
- package/fesm2022/acorex-platform-framework-client-layout-components-file-provider-picker.popup.component-BtLEUWAA.mjs.map +0 -1
- package/fesm2022/acorex-platform-framework-client-layout-entity-acorex-platform-framework-client-layout-entity-CvaOWbJx.mjs.map +0 -1
- package/fesm2022/acorex-platform-framework-client-layout-widgets-button-widget-designer.component-BDOdcoyN.mjs.map +0 -1
- package/fesm2022/acorex-platform-framework-client-layout-widgets-page-widget-designer.component-WzIiwnGC.mjs.map +0 -1
- package/fesm2022/acorex-platform-framework-client-layout-widgets-text-block-widget-designer.component-D6HFPmGC.mjs.map +0 -1
- package/fesm2022/acorex-platform-framework-client-themes-default-entity-master-create-view.component-CT7WWWG0.mjs.map +0 -1
- package/fesm2022/acorex-platform-framework-client-themes-default-entity-master-modify-view.component-DienTcPE.mjs +0 -122
- package/fesm2022/acorex-platform-framework-client-themes-default-entity-master-modify-view.component-DienTcPE.mjs.map +0 -1
- package/fesm2022/acorex-platform-framework-client-themes-default-entity-master-single-view.component-DBUwSzvg.mjs.map +0 -1
- package/fesm2022/acorex-platform-framework-client-themes-shared-settings.provider-CpsAIsxj.mjs.map +0 -1
|
@@ -3,20 +3,20 @@ import { AXButtonModule } from '@acorex/components/button';
|
|
|
3
3
|
import * as i1 from '@acorex/components/decorators';
|
|
4
4
|
import { AXDecoratorModule } from '@acorex/components/decorators';
|
|
5
5
|
import * as i1$3 from '@acorex-platform/framework-client/layout/widget-core';
|
|
6
|
-
import { AXPWidgetRegistryService, AXPLayoutBaseWidgetComponent, AXPValueWidgetComponent, AXPWidgetCoreModule } from '@acorex-platform/framework-client/layout/widget-core';
|
|
6
|
+
import { AXPWidgetRegistryService, AXP_LOCAL_DATA_SOURCES_OPTION, createDefaultLocalDataSourceColumns, readLocalDataSourcesFromNode, AXPLayoutBaseWidgetComponent, AXPValueWidgetComponent, AXPWidgetCoreModule, AXP_LOCAL_DATA_SOURCE_STORE, AXP_LAYOUT_PROFILE } from '@acorex-platform/framework-client/layout/widget-core';
|
|
7
7
|
import * as i0 from '@angular/core';
|
|
8
8
|
import { signal, computed, Injectable, inject, effect, ViewEncapsulation, ChangeDetectionStrategy, Component, input, output, EventEmitter, HostBinding, Output, model, HostListener, Injector, viewChild, afterNextRender, NgZone, ViewContainerRef, Directive, ElementRef, ViewChild, DestroyRef } from '@angular/core';
|
|
9
|
-
import { AXPWidgetGroupEnum, AXP_WIDGET_TOKEN, AXPWidgetStatus } from '@acorex-platform/framework-shared/widget-core';
|
|
10
9
|
import { AXLoadingDialogService } from '@acorex/components/loading-dialog';
|
|
11
10
|
import { AXPopupService } from '@acorex/components/popup';
|
|
12
11
|
import { AXToastService } from '@acorex/components/toast';
|
|
13
12
|
import { AXFileService } from '@acorex/core/file';
|
|
14
|
-
import { AXPWidgetsCatalog, AXPPlatformScope,
|
|
15
|
-
import {
|
|
13
|
+
import { AXPWidgetsCatalog, AXPPlatformScope, AXPKeyboardShortcutPriority } from '@acorex-platform/framework-shared/core';
|
|
14
|
+
import { AXPBroadcastEventService, AXPDataGenerator, AXPHookService, AXPKeyboardShortcutRegistry, chordToKbdItemKeys, AXPLogoComponent } from '@acorex-platform/framework-client/core';
|
|
15
|
+
import { isEqual, cloneDeep, assign, sortBy, get, set, isNil, isEmpty, orderBy, castArray, uniqBy, merge } from 'lodash-es';
|
|
16
16
|
import { Subject, distinctUntilChanged, filter, debounceTime, first, merge as merge$1 } from 'rxjs';
|
|
17
|
-
import
|
|
18
|
-
import * as i8 from '@acorex/core/translation';
|
|
17
|
+
import * as i4 from '@acorex/core/translation';
|
|
19
18
|
import { AXTranslationService, AXTranslationModule } from '@acorex/core/translation';
|
|
19
|
+
import { AXPWidgetGroupEnum, AXP_WIDGET_TOKEN, AXPWidgetStatus, designerPreviewSizeToLayoutSize } from '@acorex-platform/framework-shared/widget-core';
|
|
20
20
|
import * as i1$1 from '@acorex/cdk/common';
|
|
21
21
|
import { AXCommonModule } from '@acorex/cdk/common';
|
|
22
22
|
import { AXBasePageComponent } from '@acorex/components/page';
|
|
@@ -25,7 +25,7 @@ import { AXSearchBoxModule } from '@acorex/components/search-box';
|
|
|
25
25
|
import * as i5 from '@acorex/components/tabs';
|
|
26
26
|
import { AXTabsModule } from '@acorex/components/tabs';
|
|
27
27
|
import { AXPSettingsService, AXPStickyDirective, AXPClipBoardService } from '@acorex-platform/framework-client/common';
|
|
28
|
-
import { AXPWidgetItemComponent, AXPStateMessageComponent, AXPWidgetPropertyViewerComponent } from '@acorex-platform/framework-client/layout/components';
|
|
28
|
+
import { AXPWidgetItemComponent, AXPLocalDataSourceEditorDialogService, AXPStateMessageComponent, AXPWidgetPropertyViewerComponent } from '@acorex-platform/framework-client/layout/components';
|
|
29
29
|
import * as i1$2 from '@angular/common';
|
|
30
30
|
import { CommonModule, AsyncPipe } from '@angular/common';
|
|
31
31
|
import * as i2$1 from '@angular/forms';
|
|
@@ -34,7 +34,7 @@ import * as i1$5 from '@acorex/components/button-group';
|
|
|
34
34
|
import { AXButtonGroupModule } from '@acorex/components/button-group';
|
|
35
35
|
import * as i3 from '@acorex/components/drawer';
|
|
36
36
|
import { AXDrawerModule } from '@acorex/components/drawer';
|
|
37
|
-
import * as i4 from '@acorex/components/dropdown';
|
|
37
|
+
import * as i4$1 from '@acorex/components/dropdown';
|
|
38
38
|
import { AXDropdownModule } from '@acorex/components/dropdown';
|
|
39
39
|
import * as i5$1 from '@acorex/components/dropdown-button';
|
|
40
40
|
import { AXDropdownButtonModule } from '@acorex/components/dropdown-button';
|
|
@@ -42,14 +42,13 @@ import * as i2$2 from '@acorex/components/menu';
|
|
|
42
42
|
import { AXMenuModule } from '@acorex/components/menu';
|
|
43
43
|
import * as i1$4 from '@acorex/components/breadcrumbs';
|
|
44
44
|
import { AXBreadcrumbsModule } from '@acorex/components/breadcrumbs';
|
|
45
|
-
import { AXPCommandService, AXPQueryService } from '@acorex-platform/framework-client/runtime';
|
|
46
45
|
import { AXKBDComponent, AXKBDItemComponent } from '@acorex/components/kbd';
|
|
47
46
|
import { AXUnsubscriber } from '@acorex/core/utils';
|
|
48
|
-
import * as i4$
|
|
47
|
+
import * as i4$2 from '@acorex/components/json-viewer';
|
|
49
48
|
import { AXJsonViewerModule } from '@acorex/components/json-viewer';
|
|
50
|
-
import { AXSafePipe } from '@acorex/core/pipes';
|
|
51
49
|
|
|
52
|
-
|
|
50
|
+
//#endregion
|
|
51
|
+
//#region ----- Commands -----
|
|
53
52
|
class AddWidgetCommand {
|
|
54
53
|
constructor(widget, parent, previousSelection) {
|
|
55
54
|
this.widget = widget;
|
|
@@ -74,10 +73,10 @@ class AddWidgetCommand {
|
|
|
74
73
|
return `fa-solid fa-square-plus`;
|
|
75
74
|
}
|
|
76
75
|
getExecutionSelection() {
|
|
77
|
-
return this.widget;
|
|
76
|
+
return this.widget;
|
|
78
77
|
}
|
|
79
78
|
getUndoSelection() {
|
|
80
|
-
return this.previousSelection;
|
|
79
|
+
return this.previousSelection;
|
|
81
80
|
}
|
|
82
81
|
}
|
|
83
82
|
class RemoveWidgetCommand {
|
|
@@ -86,16 +85,19 @@ class RemoveWidgetCommand {
|
|
|
86
85
|
this.parent = parent;
|
|
87
86
|
this.previousSelection = previousSelection;
|
|
88
87
|
parent.children = parent.children || [];
|
|
89
|
-
this.index = parent.children.indexOf(widget);
|
|
88
|
+
this.index = parent.children.indexOf(widget);
|
|
90
89
|
}
|
|
91
90
|
execute() {
|
|
92
91
|
this.parent.children = this.parent.children || [];
|
|
93
|
-
this.index = this.parent.children.indexOf(this.widget);
|
|
94
|
-
|
|
92
|
+
this.index = this.parent.children.indexOf(this.widget);
|
|
93
|
+
if (this.index > -1) {
|
|
94
|
+
this.parent.children.splice(this.index, 1);
|
|
95
|
+
}
|
|
95
96
|
}
|
|
96
97
|
undo() {
|
|
97
98
|
this.parent.children = this.parent.children || [];
|
|
98
|
-
|
|
99
|
+
const insertAt = Math.min(Math.max(this.index, 0), this.parent.children.length);
|
|
100
|
+
this.parent.children.splice(insertAt, 0, this.widget);
|
|
99
101
|
}
|
|
100
102
|
description() {
|
|
101
103
|
return `Removed widget ${this.widget.name}`;
|
|
@@ -104,24 +106,25 @@ class RemoveWidgetCommand {
|
|
|
104
106
|
return `fa-solid fa-square-minus`;
|
|
105
107
|
}
|
|
106
108
|
getExecutionSelection() {
|
|
107
|
-
return this.previousSelection;
|
|
109
|
+
return this.previousSelection;
|
|
108
110
|
}
|
|
109
111
|
getUndoSelection() {
|
|
110
|
-
return this.widget;
|
|
112
|
+
return this.widget;
|
|
111
113
|
}
|
|
112
114
|
}
|
|
113
115
|
class UpdateWidgetCommand {
|
|
114
116
|
constructor(widget, values, previousSelection) {
|
|
115
117
|
this.widget = widget;
|
|
116
|
-
this.newState = merge(cloneDeep(widget), values);
|
|
117
118
|
this.previousSelection = previousSelection;
|
|
118
|
-
this.previousState =
|
|
119
|
+
this.previousState = this.captureState(widget);
|
|
120
|
+
this.newState = this.captureState(widget);
|
|
121
|
+
this.applyPatch(this.newState, values);
|
|
119
122
|
}
|
|
120
123
|
execute() {
|
|
121
|
-
|
|
124
|
+
this.restoreState(this.widget, this.newState);
|
|
122
125
|
}
|
|
123
126
|
undo() {
|
|
124
|
-
this.
|
|
127
|
+
this.restoreState(this.widget, this.previousState);
|
|
125
128
|
}
|
|
126
129
|
description() {
|
|
127
130
|
return `Updated widget ${this.widget.name}`;
|
|
@@ -130,111 +133,242 @@ class UpdateWidgetCommand {
|
|
|
130
133
|
return `fa-solid fa-pen`;
|
|
131
134
|
}
|
|
132
135
|
getExecutionSelection() {
|
|
133
|
-
return this.widget;
|
|
136
|
+
return this.widget;
|
|
134
137
|
}
|
|
135
138
|
getUndoSelection() {
|
|
136
|
-
return this.
|
|
139
|
+
return this.widget;
|
|
137
140
|
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
141
|
+
canCoalesceWith(command) {
|
|
142
|
+
return command instanceof UpdateWidgetCommand && command.widget === this.widget;
|
|
143
|
+
}
|
|
144
|
+
coalesceWith(command) {
|
|
145
|
+
if (!(command instanceof UpdateWidgetCommand)) {
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
this.newState = command.newState;
|
|
149
|
+
}
|
|
150
|
+
isNoOp() {
|
|
151
|
+
return isEqual(this.previousState, this.newState);
|
|
152
|
+
}
|
|
153
|
+
captureState(node) {
|
|
154
|
+
const { children: _children, ...rest } = node;
|
|
155
|
+
return cloneDeep(rest);
|
|
156
|
+
}
|
|
157
|
+
applyPatch(target, values) {
|
|
158
|
+
Object.keys(values).forEach((key) => {
|
|
159
|
+
if (key === 'children' || key === '__meta__') {
|
|
160
|
+
return;
|
|
144
161
|
}
|
|
145
|
-
|
|
146
|
-
|
|
162
|
+
const incoming = values[key];
|
|
163
|
+
const current = target[key];
|
|
164
|
+
if (incoming === undefined) {
|
|
165
|
+
return;
|
|
147
166
|
}
|
|
167
|
+
if (incoming &&
|
|
168
|
+
typeof incoming === 'object' &&
|
|
169
|
+
!Array.isArray(incoming) &&
|
|
170
|
+
current &&
|
|
171
|
+
typeof current === 'object' &&
|
|
172
|
+
!Array.isArray(current)) {
|
|
173
|
+
this.applyPatch(current, incoming);
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
target[key] = cloneDeep(incoming);
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
restoreState(target, source) {
|
|
180
|
+
const preservedChildren = target.children;
|
|
181
|
+
const preservedMeta = target.__meta__;
|
|
182
|
+
Object.keys(target).forEach((key) => {
|
|
183
|
+
if (key === 'children' || key === '__meta__') {
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
if (!(key in source)) {
|
|
187
|
+
delete target[key];
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
Object.keys(source).forEach((key) => {
|
|
191
|
+
if (key === 'children' || key === '__meta__') {
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
target[key] = cloneDeep(source[key]);
|
|
148
195
|
});
|
|
149
|
-
|
|
150
|
-
|
|
196
|
+
if (preservedChildren) {
|
|
197
|
+
target.children = preservedChildren;
|
|
198
|
+
}
|
|
199
|
+
if (preservedMeta) {
|
|
200
|
+
target.__meta__ = preservedMeta;
|
|
201
|
+
}
|
|
151
202
|
}
|
|
152
203
|
}
|
|
204
|
+
class CompositeCommand {
|
|
205
|
+
constructor(commands, label) {
|
|
206
|
+
this.commands = commands;
|
|
207
|
+
this.label = label;
|
|
208
|
+
}
|
|
209
|
+
execute() {
|
|
210
|
+
this.commands.forEach((command) => command.execute());
|
|
211
|
+
}
|
|
212
|
+
undo() {
|
|
213
|
+
for (let index = this.commands.length - 1; index >= 0; index--) {
|
|
214
|
+
this.commands[index].undo();
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
description() {
|
|
218
|
+
if (this.label) {
|
|
219
|
+
return this.label;
|
|
220
|
+
}
|
|
221
|
+
const addCount = this.commands.filter((command) => command instanceof AddWidgetCommand).length;
|
|
222
|
+
if (addCount > 1 && addCount === this.commands.length) {
|
|
223
|
+
return `Added ${addCount} widgets`;
|
|
224
|
+
}
|
|
225
|
+
return this.commands[this.commands.length - 1]?.description() ?? 'Multiple changes';
|
|
226
|
+
}
|
|
227
|
+
icon() {
|
|
228
|
+
return this.commands[0]?.icon() ?? 'fa-solid fa-layer-group';
|
|
229
|
+
}
|
|
230
|
+
getExecutionSelection() {
|
|
231
|
+
const update = this.commands.find((command) => command instanceof UpdateWidgetCommand);
|
|
232
|
+
if (update) {
|
|
233
|
+
return update.getExecutionSelection();
|
|
234
|
+
}
|
|
235
|
+
return this.commands[this.commands.length - 1].getExecutionSelection();
|
|
236
|
+
}
|
|
237
|
+
getUndoSelection() {
|
|
238
|
+
return this.commands[0].getUndoSelection();
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
//#endregion
|
|
242
|
+
//#region ----- Command manager -----
|
|
153
243
|
class CommandManager {
|
|
154
244
|
constructor() {
|
|
155
245
|
this.undoStack = signal([], /* @ts-ignore */
|
|
156
246
|
...(ngDevMode ? [{ debugName: "undoStack" }] : /* istanbul ignore next */ []));
|
|
157
247
|
this.currentIndex = signal(-1, /* @ts-ignore */
|
|
158
248
|
...(ngDevMode ? [{ debugName: "currentIndex" }] : /* istanbul ignore next */ []));
|
|
249
|
+
this.transactionDepth = 0;
|
|
250
|
+
this.transactionCommands = [];
|
|
159
251
|
this.selectedNode = signal(null, /* @ts-ignore */
|
|
160
252
|
...(ngDevMode ? [{ debugName: "selectedNode" }] : /* istanbul ignore next */ []));
|
|
161
253
|
this.canUndo = computed(() => this.currentIndex() >= 0, /* @ts-ignore */
|
|
162
254
|
...(ngDevMode ? [{ debugName: "canUndo" }] : /* istanbul ignore next */ []));
|
|
163
255
|
this.canRedo = computed(() => this.currentIndex() < this.undoStack().length - 1, /* @ts-ignore */
|
|
164
256
|
...(ngDevMode ? [{ debugName: "canRedo" }] : /* istanbul ignore next */ []));
|
|
257
|
+
this.isInTransaction = () => this.transactionDepth > 0;
|
|
165
258
|
this.history = computed(() => this.undoStack().map((cmd, index) => ({
|
|
166
259
|
description: cmd.description(),
|
|
167
260
|
icon: cmd.icon(),
|
|
168
261
|
isPast: this.currentIndex() > index,
|
|
169
262
|
isFuture: this.currentIndex() < index,
|
|
170
|
-
isCurrent: this.currentIndex() == index
|
|
263
|
+
isCurrent: this.currentIndex() == index,
|
|
171
264
|
})), /* @ts-ignore */
|
|
172
265
|
...(ngDevMode ? [{ debugName: "history" }] : /* istanbul ignore next */ []));
|
|
173
266
|
}
|
|
174
|
-
|
|
175
|
-
|
|
267
|
+
beginTransaction(description) {
|
|
268
|
+
if (this.transactionDepth === 0) {
|
|
269
|
+
this.transactionCommands = [];
|
|
270
|
+
this.transactionDescription = description;
|
|
271
|
+
}
|
|
272
|
+
else if (description && !this.transactionDescription) {
|
|
273
|
+
this.transactionDescription = description;
|
|
274
|
+
}
|
|
275
|
+
this.transactionDepth++;
|
|
276
|
+
}
|
|
277
|
+
endTransaction() {
|
|
278
|
+
if (this.transactionDepth === 0) {
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
this.transactionDepth--;
|
|
282
|
+
if (this.transactionDepth > 0) {
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
const commands = this.transactionCommands;
|
|
286
|
+
const description = this.transactionDescription;
|
|
287
|
+
this.transactionCommands = [];
|
|
288
|
+
this.transactionDescription = undefined;
|
|
289
|
+
if (commands.length === 0) {
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
176
292
|
if (this.currentIndex() !== this.undoStack().length - 1) {
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
293
|
+
this.undoStack.set(this.undoStack().slice(0, this.currentIndex() + 1));
|
|
294
|
+
}
|
|
295
|
+
const command = commands.length === 1 ? commands[0] : new CompositeCommand(commands, description);
|
|
296
|
+
this.undoStack.set([...this.undoStack(), command]);
|
|
297
|
+
this.currentIndex.set(this.undoStack().length - 1);
|
|
298
|
+
this.selectedNode.set(command.getExecutionSelection());
|
|
299
|
+
}
|
|
300
|
+
executeCommand(command) {
|
|
301
|
+
if (command instanceof UpdateWidgetCommand && command.isNoOp()) {
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
const lastCommand = this.transactionDepth > 0
|
|
305
|
+
? this.transactionCommands[this.transactionCommands.length - 1]
|
|
306
|
+
: this.undoStack()[this.currentIndex()];
|
|
307
|
+
if (lastCommand?.canCoalesceWith?.(command) && lastCommand.coalesceWith) {
|
|
308
|
+
lastCommand.coalesceWith(command);
|
|
309
|
+
command.execute();
|
|
310
|
+
this.selectedNode.set(command.getExecutionSelection());
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
if (this.transactionDepth === 0 && this.currentIndex() !== this.undoStack().length - 1) {
|
|
314
|
+
this.undoStack.set(this.undoStack().slice(0, this.currentIndex() + 1));
|
|
180
315
|
}
|
|
181
316
|
command.execute();
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
317
|
+
if (this.transactionDepth > 0) {
|
|
318
|
+
this.transactionCommands.push(command);
|
|
319
|
+
this.selectedNode.set(command.getExecutionSelection());
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
this.undoStack.set([...this.undoStack(), command]);
|
|
323
|
+
this.currentIndex.set(this.undoStack().length - 1);
|
|
324
|
+
this.selectedNode.set(command.getExecutionSelection());
|
|
185
325
|
}
|
|
186
326
|
undo() {
|
|
187
|
-
if (this.currentIndex()
|
|
188
|
-
|
|
189
|
-
command.undo();
|
|
190
|
-
this.currentIndex.set(this.currentIndex() - 1);
|
|
191
|
-
if (this.currentIndex() >= 0) {
|
|
192
|
-
this.selectedNode.set(this.undoStack()[this.currentIndex()].getUndoSelection());
|
|
193
|
-
}
|
|
194
|
-
else {
|
|
195
|
-
this.selectedNode.set(null); // No selection if all commands are undone
|
|
196
|
-
}
|
|
327
|
+
if (this.currentIndex() < 0) {
|
|
328
|
+
return;
|
|
197
329
|
}
|
|
330
|
+
const command = this.undoStack()[this.currentIndex()];
|
|
331
|
+
command.undo();
|
|
332
|
+
this.currentIndex.set(this.currentIndex() - 1);
|
|
333
|
+
this.selectedNode.set(command.getUndoSelection());
|
|
198
334
|
}
|
|
199
335
|
redo() {
|
|
200
|
-
if (this.currentIndex()
|
|
201
|
-
|
|
202
|
-
const command = this.undoStack()[this.currentIndex()];
|
|
203
|
-
command.execute();
|
|
204
|
-
this.selectedNode.set(command.getExecutionSelection());
|
|
336
|
+
if (this.currentIndex() >= this.undoStack().length - 1) {
|
|
337
|
+
return;
|
|
205
338
|
}
|
|
339
|
+
this.currentIndex.set(this.currentIndex() + 1);
|
|
340
|
+
const command = this.undoStack()[this.currentIndex()];
|
|
341
|
+
command.execute();
|
|
342
|
+
this.selectedNode.set(command.getExecutionSelection());
|
|
206
343
|
}
|
|
207
344
|
goToCommand(index) {
|
|
208
|
-
if (index <
|
|
209
|
-
return;
|
|
345
|
+
if (index < -1 || index >= this.undoStack().length || index === this.currentIndex()) {
|
|
346
|
+
return;
|
|
210
347
|
}
|
|
211
348
|
if (index > this.currentIndex()) {
|
|
212
|
-
// Need to redo until reaching the desired index
|
|
213
349
|
while (this.currentIndex() < index) {
|
|
214
350
|
this.redo();
|
|
215
351
|
}
|
|
216
352
|
}
|
|
217
353
|
else {
|
|
218
|
-
// Need to undo until reaching the desired index
|
|
219
354
|
while (this.currentIndex() > index) {
|
|
220
355
|
this.undo();
|
|
221
356
|
}
|
|
222
357
|
}
|
|
223
|
-
// Optionally update any UI components or state here
|
|
224
|
-
this.selectedNode.set(this.undoStack()[this.currentIndex()].getExecutionSelection());
|
|
225
358
|
}
|
|
226
359
|
clear() {
|
|
227
360
|
this.undoStack.set([]);
|
|
228
361
|
this.currentIndex.set(-1);
|
|
362
|
+
this.selectedNode.set(null);
|
|
363
|
+
this.transactionDepth = 0;
|
|
364
|
+
this.transactionCommands = [];
|
|
365
|
+
this.transactionDescription = undefined;
|
|
229
366
|
}
|
|
230
367
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: CommandManager, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
231
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: CommandManager
|
|
368
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: CommandManager }); }
|
|
232
369
|
}
|
|
233
370
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: CommandManager, decorators: [{
|
|
234
|
-
type: Injectable
|
|
235
|
-
args: [{
|
|
236
|
-
providedIn: 'root'
|
|
237
|
-
}]
|
|
371
|
+
type: Injectable
|
|
238
372
|
}] });
|
|
239
373
|
|
|
240
374
|
class AXPDesignerConnector {
|
|
@@ -323,15 +457,75 @@ const AXPDesignerMessageKeys = {
|
|
|
323
457
|
FormSaved: 'designer-form-saved-content',
|
|
324
458
|
};
|
|
325
459
|
|
|
460
|
+
//#region ----- Constants -----
|
|
461
|
+
const PREVIEW_DOCUMENT_STORAGE_KEY = 'axp-layout-designer-preview-document';
|
|
462
|
+
//#endregion
|
|
463
|
+
//#region ----- Preview session -----
|
|
464
|
+
function storeDesignerPreviewDocument(document) {
|
|
465
|
+
try {
|
|
466
|
+
sessionStorage.setItem(PREVIEW_DOCUMENT_STORAGE_KEY, JSON.stringify(document));
|
|
467
|
+
}
|
|
468
|
+
catch {
|
|
469
|
+
// sessionStorage can be unavailable in some iframe / privacy modes
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
function readDesignerPreviewDocument() {
|
|
473
|
+
try {
|
|
474
|
+
const raw = sessionStorage.getItem(PREVIEW_DOCUMENT_STORAGE_KEY);
|
|
475
|
+
if (!raw) {
|
|
476
|
+
return null;
|
|
477
|
+
}
|
|
478
|
+
return JSON.parse(raw);
|
|
479
|
+
}
|
|
480
|
+
catch {
|
|
481
|
+
return null;
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
//#endregion
|
|
485
|
+
|
|
326
486
|
/**
|
|
327
487
|
* Suffixes for `forms:widgets:picker:last-tab:{id}` user settings keys.
|
|
328
488
|
* Use one id per distinct widget-picker host (different tab strips / widget sets).
|
|
329
489
|
*/
|
|
330
490
|
const AXP_WIDGET_PICKER_TAB_CONTEXT = {
|
|
331
491
|
layoutDesignerFormElements: 'layout-designer-form-elements',
|
|
492
|
+
layoutDesignerWidgetTemplate: 'layout-designer-widget-template',
|
|
493
|
+
layoutDesignerPage: 'layout-designer-page',
|
|
332
494
|
dashboardHome: 'dashboard-home',
|
|
333
495
|
};
|
|
334
496
|
|
|
497
|
+
//#endregion
|
|
498
|
+
//#region ----- Constants -----
|
|
499
|
+
const DEFAULT_FORM_DRAWERS = ['pages', 'dataSources', 'outline', 'history'];
|
|
500
|
+
//#endregion
|
|
501
|
+
//#region ----- Filter -----
|
|
502
|
+
/**
|
|
503
|
+
* Include if any include rule hits, then subtract `excludeNames`.
|
|
504
|
+
* An empty include set matches nothing (fail closed).
|
|
505
|
+
*/
|
|
506
|
+
function widgetMatchesDesignerSurface(widget, profile) {
|
|
507
|
+
const filter = profile.widgets;
|
|
508
|
+
if (filter?.excludeNames?.includes(widget.name)) {
|
|
509
|
+
return false;
|
|
510
|
+
}
|
|
511
|
+
const includeGroups = filter?.includeGroups ?? [];
|
|
512
|
+
const includeTypes = filter?.includeTypes ?? [];
|
|
513
|
+
const includeNames = filter?.includeNames ?? [];
|
|
514
|
+
const hasInclude = includeGroups.length > 0 || includeTypes.length > 0 || includeNames.length > 0;
|
|
515
|
+
if (!hasInclude) {
|
|
516
|
+
return false;
|
|
517
|
+
}
|
|
518
|
+
const groupHit = includeGroups.some((group) => widget.groups?.includes(group));
|
|
519
|
+
const typeHit = includeTypes.includes(widget.type);
|
|
520
|
+
const nameHit = includeNames.includes(widget.name);
|
|
521
|
+
return groupHit || typeHit || nameHit;
|
|
522
|
+
}
|
|
523
|
+
function designerSurfaceHasDrawer(profile, drawer) {
|
|
524
|
+
const drawers = profile.chrome?.drawers ?? DEFAULT_FORM_DRAWERS;
|
|
525
|
+
return drawers.includes(drawer);
|
|
526
|
+
}
|
|
527
|
+
//#endregion
|
|
528
|
+
|
|
335
529
|
class AXPWidgetPickerService {
|
|
336
530
|
constructor() {
|
|
337
531
|
this.popupService = inject(AXPopupService);
|
|
@@ -341,7 +535,7 @@ class AXPWidgetPickerService {
|
|
|
341
535
|
async showPicker(options) {
|
|
342
536
|
const com = await Promise.resolve().then(function () { return widgetPicker_component; }).then((c) => c.AXPDesignerWidgetPickerComponent);
|
|
343
537
|
const widgets = this.widgetRegistryService.all();
|
|
344
|
-
const filteredWidgets = widgets.filter((
|
|
538
|
+
const filteredWidgets = widgets.filter((widget) => this.matchesPickerOptions(widget, options));
|
|
345
539
|
//
|
|
346
540
|
const result = await this.popupService.open(com, {
|
|
347
541
|
title: await this.translationService.translateAsync('@form-template-management:designer.components.widget-picker.title'),
|
|
@@ -361,6 +555,12 @@ class AXPWidgetPickerService {
|
|
|
361
555
|
meta: c.meta,
|
|
362
556
|
}));
|
|
363
557
|
}
|
|
558
|
+
matchesPickerOptions(widget, options) {
|
|
559
|
+
if (options.profile) {
|
|
560
|
+
return widgetMatchesDesignerSurface(widget, options.profile);
|
|
561
|
+
}
|
|
562
|
+
return options.groups?.some((group) => widget.groups?.includes(group)) ?? false;
|
|
563
|
+
}
|
|
364
564
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPWidgetPickerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
365
565
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPWidgetPickerService, providedIn: 'root' }); }
|
|
366
566
|
}
|
|
@@ -371,6 +571,105 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
371
571
|
}]
|
|
372
572
|
}] });
|
|
373
573
|
|
|
574
|
+
//#region ----- Imports -----
|
|
575
|
+
//#endregion
|
|
576
|
+
//#region ----- Constants -----
|
|
577
|
+
/** Child cells and document shells: registered, not pickable. */
|
|
578
|
+
const DESIGNER_CHILD_AND_SHELL_WIDGETS = [
|
|
579
|
+
'tabset-item',
|
|
580
|
+
'flex-item-layout',
|
|
581
|
+
'grid-item-layout',
|
|
582
|
+
'table-item-layout',
|
|
583
|
+
'advanced-grid-item-layout',
|
|
584
|
+
'page-layout',
|
|
585
|
+
'document-layout',
|
|
586
|
+
];
|
|
587
|
+
/** Field widgets that belong on forms but are not tagged `form-element`. */
|
|
588
|
+
const FORM_EXTRA_WIDGET_NAMES = [
|
|
589
|
+
'signature',
|
|
590
|
+
'password-editor',
|
|
591
|
+
'qrcode',
|
|
592
|
+
'icon',
|
|
593
|
+
'table-editor',
|
|
594
|
+
'template-box-editor',
|
|
595
|
+
'meta-data-editor',
|
|
596
|
+
'lookup-editor',
|
|
597
|
+
];
|
|
598
|
+
const FORM_WIDGETS = {
|
|
599
|
+
includeGroups: [AXPWidgetGroupEnum.FormElement],
|
|
600
|
+
includeNames: [...FORM_EXTRA_WIDGET_NAMES],
|
|
601
|
+
excludeNames: [...DESIGNER_CHILD_AND_SHELL_WIDGETS],
|
|
602
|
+
};
|
|
603
|
+
/**
|
|
604
|
+
* Default Form Builder surface. Hosts may pass this explicitly or omit `profile`.
|
|
605
|
+
*/
|
|
606
|
+
const AXP_FORM_DESIGNER_SURFACE_PROFILE = {
|
|
607
|
+
id: 'form',
|
|
608
|
+
documentKind: 'widget-tree',
|
|
609
|
+
rootWidget: 'page-layout',
|
|
610
|
+
widgets: FORM_WIDGETS,
|
|
611
|
+
chrome: {
|
|
612
|
+
drawers: ['pages', 'dataSources', 'outline', 'history'],
|
|
613
|
+
},
|
|
614
|
+
preview: {
|
|
615
|
+
player: 'angular',
|
|
616
|
+
},
|
|
617
|
+
pickerTabContext: AXP_WIDGET_PICKER_TAB_CONTEXT.layoutDesignerFormElements,
|
|
618
|
+
};
|
|
619
|
+
/**
|
|
620
|
+
* Composed widget template: same offer list as form, no Pages drawer.
|
|
621
|
+
*/
|
|
622
|
+
const AXP_WIDGET_DESIGNER_SURFACE_PROFILE = {
|
|
623
|
+
id: 'widget',
|
|
624
|
+
documentKind: 'widget-tree',
|
|
625
|
+
rootWidget: 'page-layout',
|
|
626
|
+
widgets: FORM_WIDGETS,
|
|
627
|
+
chrome: {
|
|
628
|
+
drawers: ['dataSources', 'outline', 'history'],
|
|
629
|
+
},
|
|
630
|
+
preview: {
|
|
631
|
+
player: 'angular',
|
|
632
|
+
},
|
|
633
|
+
pickerTabContext: AXP_WIDGET_PICKER_TAB_CONTEXT.layoutDesignerWidgetTemplate,
|
|
634
|
+
};
|
|
635
|
+
/**
|
|
636
|
+
* Website page surface. Palette chrome is declared; walker preview is Phase 2.
|
|
637
|
+
* Offer list is name-based until a `page-widget` group exists.
|
|
638
|
+
*/
|
|
639
|
+
const AXP_PAGE_DESIGNER_SURFACE_PROFILE = {
|
|
640
|
+
id: 'page',
|
|
641
|
+
documentKind: 'widget-tree',
|
|
642
|
+
widgets: {
|
|
643
|
+
includeNames: [
|
|
644
|
+
'flex-layout',
|
|
645
|
+
'grid-layout',
|
|
646
|
+
'block-layout',
|
|
647
|
+
'panel-layout',
|
|
648
|
+
'fieldset-layout',
|
|
649
|
+
'table-layout',
|
|
650
|
+
'advanced-grid-layout',
|
|
651
|
+
'text-block-layout',
|
|
652
|
+
'alert-box-layout',
|
|
653
|
+
'badge-layout',
|
|
654
|
+
'image',
|
|
655
|
+
'icon',
|
|
656
|
+
'button-action',
|
|
657
|
+
'tabset-layout',
|
|
658
|
+
'step-wizard',
|
|
659
|
+
],
|
|
660
|
+
excludeNames: [...DESIGNER_CHILD_AND_SHELL_WIDGETS, 'password-editor', 'signature', 'lookup-editor'],
|
|
661
|
+
},
|
|
662
|
+
chrome: {
|
|
663
|
+
drawers: ['palette', 'outline', 'history'],
|
|
664
|
+
},
|
|
665
|
+
preview: {
|
|
666
|
+
player: 'html-walker',
|
|
667
|
+
walkerChannel: 'html',
|
|
668
|
+
},
|
|
669
|
+
pickerTabContext: AXP_WIDGET_PICKER_TAB_CONTEXT.layoutDesignerPage,
|
|
670
|
+
};
|
|
671
|
+
//#endregion
|
|
672
|
+
|
|
374
673
|
class AXPDesignerService {
|
|
375
674
|
#ef;
|
|
376
675
|
constructor() {
|
|
@@ -388,6 +687,9 @@ class AXPDesignerService {
|
|
|
388
687
|
...(ngDevMode ? [{ debugName: "currentPageIndex" }] : /* istanbul ignore next */ []));
|
|
389
688
|
this.currentPage = signal(this.document().children?.[0], /* @ts-ignore */
|
|
390
689
|
...(ngDevMode ? [{ debugName: "currentPage" }] : /* istanbul ignore next */ []));
|
|
690
|
+
/** Bumps when the board must remount the page without cloning it off `document`. */
|
|
691
|
+
this.pageRenderEpoch = signal(0, /* @ts-ignore */
|
|
692
|
+
...(ngDevMode ? [{ debugName: "pageRenderEpoch" }] : /* istanbul ignore next */ []));
|
|
391
693
|
this.commandManager = inject(CommandManager);
|
|
392
694
|
this.clipboard = signal(null, /* @ts-ignore */
|
|
393
695
|
...(ngDevMode ? [{ debugName: "clipboard" }] : /* istanbul ignore next */ []));
|
|
@@ -412,12 +714,22 @@ class AXPDesignerService {
|
|
|
412
714
|
...(ngDevMode ? [{ debugName: "canSave" }] : /* istanbul ignore next */ []));
|
|
413
715
|
this.unsavedChanges = signal(false, /* @ts-ignore */
|
|
414
716
|
...(ngDevMode ? [{ debugName: "unsavedChanges" }] : /* istanbul ignore next */ []));
|
|
717
|
+
this.surfaceProfile = signal(AXP_FORM_DESIGNER_SURFACE_PROFILE, /* @ts-ignore */
|
|
718
|
+
...(ngDevMode ? [{ debugName: "surfaceProfile" }] : /* istanbul ignore next */ []));
|
|
719
|
+
this.localDataSources = signal([], /* @ts-ignore */
|
|
720
|
+
...(ngDevMode ? [{ debugName: "localDataSources" }] : /* istanbul ignore next */ []));
|
|
721
|
+
this.sources = this.localDataSources.asReadonly();
|
|
415
722
|
this.breadcrumbs = computed(() => {
|
|
416
723
|
return this.selectedNode() ? this.findBreadcrumbs(this.currentPage(), this.selectedNode()) ?? [] : [];
|
|
417
724
|
}, /* @ts-ignore */
|
|
418
725
|
...(ngDevMode ? [{ debugName: "breadcrumbs" }] : /* istanbul ignore next */ []));
|
|
419
726
|
this.selectedNode = signal(null, /* @ts-ignore */
|
|
420
727
|
...(ngDevMode ? [{ debugName: "selectedNode" }] : /* istanbul ignore next */ []));
|
|
728
|
+
this.widgetInstances = new Map();
|
|
729
|
+
/** Property-panel writes are recorded only after the user focuses the panel. */
|
|
730
|
+
this.acceptPropertyPanelHistory = false;
|
|
731
|
+
/** Last panel payload applied to the canvas. Equal echoes must not republish the preview. */
|
|
732
|
+
this.lastAppliedPropertyPanelValues = null;
|
|
421
733
|
this.selectedNodeConfig = computed(() => get(this.selectedNode(), '__meta__.config'), /* @ts-ignore */
|
|
422
734
|
...(ngDevMode ? [{ debugName: "selectedNodeConfig" }] : /* istanbul ignore next */ []));
|
|
423
735
|
this._focusedNode = null;
|
|
@@ -475,20 +787,52 @@ class AXPDesignerService {
|
|
|
475
787
|
});
|
|
476
788
|
}
|
|
477
789
|
register(command) {
|
|
478
|
-
this.
|
|
790
|
+
const key = this.widgetInstanceKey(command.widget, command.id);
|
|
791
|
+
if (key) {
|
|
792
|
+
this.widgetInstances.set(key, command.instance);
|
|
793
|
+
}
|
|
794
|
+
if (!this.selectedNode()) {
|
|
795
|
+
this.select({ widget: command.widget });
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
unregister(widget) {
|
|
799
|
+
const key = this.widgetInstanceKey(widget);
|
|
800
|
+
if (key) {
|
|
801
|
+
this.widgetInstances.delete(key);
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
getWidgetInstance(widget) {
|
|
805
|
+
const key = this.widgetInstanceKey(widget);
|
|
806
|
+
return key ? this.widgetInstances.get(key) ?? null : null;
|
|
807
|
+
}
|
|
808
|
+
widgetInstanceKey(widget, id) {
|
|
809
|
+
const key = id ?? get(widget, '__meta__.id');
|
|
810
|
+
return key == null ? null : String(key);
|
|
479
811
|
}
|
|
480
812
|
select(command) {
|
|
813
|
+
this.acceptPropertyPanelHistory = false;
|
|
814
|
+
this.lastAppliedPropertyPanelValues = null;
|
|
481
815
|
this.selectedNode.set(command.widget);
|
|
482
816
|
this.onSelected.next(command);
|
|
483
817
|
}
|
|
818
|
+
armPropertyPanelHistory() {
|
|
819
|
+
this.acceptPropertyPanelHistory = true;
|
|
820
|
+
}
|
|
821
|
+
applyPropertyPanelChange(event) {
|
|
822
|
+
// Init is hydration. update() always republishes the preview.
|
|
823
|
+
if (event.mode !== 'update' || isEqual(event.values, this.lastAppliedPropertyPanelValues)) {
|
|
824
|
+
return;
|
|
825
|
+
}
|
|
826
|
+
this.lastAppliedPropertyPanelValues = event.values;
|
|
827
|
+
this.update({ values: event.values, mode: 'update' });
|
|
828
|
+
}
|
|
484
829
|
update(command) {
|
|
485
830
|
const node = command.widget ?? this.selectedNode();
|
|
486
831
|
if (command.mode == 'update' && node) {
|
|
487
832
|
this.commandManager.executeCommand(new UpdateWidgetCommand(node, command.values, node));
|
|
833
|
+
this.unsavedChanges.set(true);
|
|
488
834
|
}
|
|
489
|
-
//this.selectedNode.update((c) => merge(node, command.values));
|
|
490
835
|
this.onUpdate.next({ widget: node, values: command.values });
|
|
491
|
-
this.unsavedChanges.set(true);
|
|
492
836
|
this.updatePreview();
|
|
493
837
|
}
|
|
494
838
|
focus(command) {
|
|
@@ -521,21 +865,31 @@ class AXPDesignerService {
|
|
|
521
865
|
return undefined;
|
|
522
866
|
}
|
|
523
867
|
async showPicker(currentNode = this.selectedNode()) {
|
|
868
|
+
const profile = this.surfaceProfile();
|
|
524
869
|
const widgets = await this.widgetPickerService.showPicker({
|
|
525
|
-
|
|
526
|
-
tabPersistenceContext: AXP_WIDGET_PICKER_TAB_CONTEXT.layoutDesignerFormElements,
|
|
870
|
+
profile,
|
|
871
|
+
tabPersistenceContext: profile.pickerTabContext ?? AXP_WIDGET_PICKER_TAB_CONTEXT.layoutDesignerFormElements,
|
|
527
872
|
});
|
|
528
873
|
const result = [];
|
|
529
874
|
if (widgets.length) {
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
875
|
+
const addAll = () => {
|
|
876
|
+
widgets.forEach((c) => {
|
|
877
|
+
result.push(this.addWidget(currentNode, { type: c.type }));
|
|
878
|
+
});
|
|
879
|
+
};
|
|
880
|
+
if (widgets.length > 1) {
|
|
881
|
+
this.runTransaction(addAll, 'Added widgets');
|
|
882
|
+
}
|
|
883
|
+
else {
|
|
884
|
+
addAll();
|
|
885
|
+
}
|
|
533
886
|
}
|
|
534
887
|
return result;
|
|
535
888
|
}
|
|
536
889
|
new() {
|
|
537
890
|
this.commandManager.clear();
|
|
538
891
|
this.document.set(this.createDoc());
|
|
892
|
+
this.localDataSources.set([]);
|
|
539
893
|
this.currentPage.set(this.document().children?.[0]);
|
|
540
894
|
this.reRenderPage();
|
|
541
895
|
}
|
|
@@ -544,10 +898,72 @@ class AXPDesignerService {
|
|
|
544
898
|
type: AXPWidgetsCatalog.document,
|
|
545
899
|
children: [this.createPage()],
|
|
546
900
|
name: 'document',
|
|
901
|
+
options: { [AXP_LOCAL_DATA_SOURCES_OPTION]: [] },
|
|
547
902
|
};
|
|
548
903
|
set(doc, '__meta__.id', this.generateUniqueId());
|
|
549
904
|
return doc;
|
|
550
905
|
}
|
|
906
|
+
//#region ----- Local data sources -----
|
|
907
|
+
toLocalDataSourceStore() {
|
|
908
|
+
return {
|
|
909
|
+
sources: this.sources,
|
|
910
|
+
get: (id) => this.getLocalDataSource(id),
|
|
911
|
+
create: (name) => this.createLocalDataSource(name),
|
|
912
|
+
update: (id, patch) => this.updateLocalDataSource(id, patch),
|
|
913
|
+
remove: (id) => this.removeLocalDataSource(id),
|
|
914
|
+
};
|
|
915
|
+
}
|
|
916
|
+
getLocalDataSource(id) {
|
|
917
|
+
return this.localDataSources().find((row) => row.id === id);
|
|
918
|
+
}
|
|
919
|
+
createLocalDataSource(name) {
|
|
920
|
+
const trimmed = name.trim();
|
|
921
|
+
const source = {
|
|
922
|
+
id: AXPDataGenerator.uuid(),
|
|
923
|
+
name: trimmed.length > 0 ? trimmed : `List ${this.localDataSources().length + 1}`,
|
|
924
|
+
columns: createDefaultLocalDataSourceColumns(),
|
|
925
|
+
items: [],
|
|
926
|
+
};
|
|
927
|
+
this.localDataSources.update((list) => [...list, source]);
|
|
928
|
+
this.persistLocalDataSources(true);
|
|
929
|
+
return source;
|
|
930
|
+
}
|
|
931
|
+
updateLocalDataSource(id, patch) {
|
|
932
|
+
this.localDataSources.update((list) => list.map((row) => (row.id === id ? { ...row, ...patch } : row)));
|
|
933
|
+
this.persistLocalDataSources(true);
|
|
934
|
+
}
|
|
935
|
+
removeLocalDataSource(id) {
|
|
936
|
+
this.localDataSources.update((list) => list.filter((row) => row.id !== id));
|
|
937
|
+
this.persistLocalDataSources(true);
|
|
938
|
+
}
|
|
939
|
+
hydrateLocalDataSources(root) {
|
|
940
|
+
const fromDoc = readLocalDataSourcesFromNode(root);
|
|
941
|
+
const fromPages = fromDoc.length > 0
|
|
942
|
+
? []
|
|
943
|
+
: (root.children ?? []).flatMap((page) => readLocalDataSourcesFromNode(page));
|
|
944
|
+
this.localDataSources.set(fromDoc.length > 0 ? fromDoc : fromPages);
|
|
945
|
+
this.persistLocalDataSources(false);
|
|
946
|
+
}
|
|
947
|
+
persistLocalDataSources(markDirty) {
|
|
948
|
+
const list = this.localDataSources();
|
|
949
|
+
const doc = this.document();
|
|
950
|
+
doc.options = { ...(doc.options ?? {}), [AXP_LOCAL_DATA_SOURCES_OPTION]: list };
|
|
951
|
+
this.stripLocalDataSourcesFromPages(doc);
|
|
952
|
+
if (markDirty) {
|
|
953
|
+
this.unsavedChanges.set(true);
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
stripLocalDataSourcesFromPages(doc) {
|
|
957
|
+
for (const page of doc.children ?? []) {
|
|
958
|
+
const options = page.options;
|
|
959
|
+
if (!options || !(AXP_LOCAL_DATA_SOURCES_OPTION in options)) {
|
|
960
|
+
continue;
|
|
961
|
+
}
|
|
962
|
+
const { [AXP_LOCAL_DATA_SOURCES_OPTION]: _removed, ...rest } = options;
|
|
963
|
+
page.options = rest;
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
//#endregion
|
|
551
967
|
createPage() {
|
|
552
968
|
const config = this.widgetRegisteryService.resolve('page-layout');
|
|
553
969
|
const page = {
|
|
@@ -579,9 +995,20 @@ class AXPDesignerService {
|
|
|
579
995
|
this.select({ widget: this.currentPage() });
|
|
580
996
|
}
|
|
581
997
|
reRenderPage() {
|
|
582
|
-
this.
|
|
998
|
+
const page = this.document().children?.[this.currentPageIndex()];
|
|
999
|
+
if (!page) {
|
|
1000
|
+
return;
|
|
1001
|
+
}
|
|
1002
|
+
// Keep the same object as `document.children[i]`. A shallow copy made the
|
|
1003
|
+
// board edit a detached page, so page options never appeared in export.
|
|
1004
|
+
this.currentPage.set(page);
|
|
1005
|
+
this.pageRenderEpoch.update((epoch) => epoch + 1);
|
|
1006
|
+
const selected = this.selectedNode();
|
|
1007
|
+
if (selected?.type === 'page-layout' && selected !== page) {
|
|
1008
|
+
this.select({ widget: page });
|
|
1009
|
+
}
|
|
583
1010
|
setTimeout(() => {
|
|
584
|
-
this.refresh({ widget:
|
|
1011
|
+
this.refresh({ widget: page });
|
|
585
1012
|
});
|
|
586
1013
|
}
|
|
587
1014
|
findWidgetById(root, id) {
|
|
@@ -638,22 +1065,61 @@ class AXPDesignerService {
|
|
|
638
1065
|
}
|
|
639
1066
|
return null; // Return null if no container found
|
|
640
1067
|
}
|
|
641
|
-
|
|
642
|
-
//
|
|
1068
|
+
createWidgetNode(node) {
|
|
643
1069
|
const cloned = cloneDeep(node);
|
|
644
|
-
|
|
645
|
-
|
|
1070
|
+
this.stampNewWidgetTree(cloned, { keepNames: true, reservedNames: this.collectDocumentNameSet() });
|
|
1071
|
+
return cloned;
|
|
1072
|
+
}
|
|
1073
|
+
/** Fills missing `__meta__.id`, config, and name on an already-on-canvas tree (e.g. AI-added children). */
|
|
1074
|
+
ensureWidgetTreeMeta(root = this.document()) {
|
|
1075
|
+
this.stampMissingWidgetMeta(root, this.collectDocumentNameSet());
|
|
1076
|
+
}
|
|
1077
|
+
/**
|
|
1078
|
+
* Assigns unique `__meta__.id`, registry config, and a name on every node.
|
|
1079
|
+
* Nested AI add-widget trees must be stamped the same way paste already does;
|
|
1080
|
+
* otherwise children share `undefined` ids and the designer selects them all.
|
|
1081
|
+
*/
|
|
1082
|
+
stampNewWidgetTree(node, options) {
|
|
1083
|
+
const existing = typeof node.name === 'string' ? node.name.trim() : '';
|
|
1084
|
+
if (!options.keepNames || !existing || options.reservedNames.has(existing)) {
|
|
1085
|
+
node.name = this.nextUniqueName(node.type, options.reservedNames);
|
|
1086
|
+
}
|
|
1087
|
+
else {
|
|
1088
|
+
node.name = existing;
|
|
1089
|
+
}
|
|
1090
|
+
options.reservedNames.add(node.name);
|
|
1091
|
+
set(node, '__meta__.id', this.generateUniqueId());
|
|
1092
|
+
set(node, '__meta__.config', this.widgetRegisteryService.resolve(node.type));
|
|
1093
|
+
set(node, '__meta__.added', true);
|
|
1094
|
+
node.children?.forEach((child) => this.stampNewWidgetTree(child, options));
|
|
1095
|
+
}
|
|
1096
|
+
stampMissingWidgetMeta(node, reservedNames) {
|
|
1097
|
+
if (get(node, '__meta__.id') == null) {
|
|
1098
|
+
set(node, '__meta__.id', this.generateUniqueId());
|
|
1099
|
+
}
|
|
1100
|
+
if (!get(node, '__meta__.config') && node.type) {
|
|
1101
|
+
set(node, '__meta__.config', this.widgetRegisteryService.resolve(node.type));
|
|
1102
|
+
}
|
|
1103
|
+
const existing = typeof node.name === 'string' ? node.name.trim() : '';
|
|
1104
|
+
if (!existing) {
|
|
1105
|
+
node.name = this.nextUniqueName(node.type, reservedNames);
|
|
1106
|
+
}
|
|
1107
|
+
else {
|
|
1108
|
+
node.name = existing;
|
|
1109
|
+
}
|
|
1110
|
+
reservedNames.add(node.name);
|
|
1111
|
+
node.children?.forEach((child) => this.stampMissingWidgetMeta(child, reservedNames));
|
|
1112
|
+
}
|
|
1113
|
+
addWidget(currentNode, node) {
|
|
1114
|
+
const cloned = this.createWidgetNode(node);
|
|
646
1115
|
this.commandManager.executeCommand(new AddWidgetCommand(cloned, currentNode, currentNode));
|
|
1116
|
+
this.ensureDefaultTabsetChild(cloned);
|
|
647
1117
|
//
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
this.reRenderPage();
|
|
654
|
-
//
|
|
655
|
-
this.refresh({ widget: currentNode });
|
|
656
|
-
this.select({ widget: cloned });
|
|
1118
|
+
if (!this.commandManager.isInTransaction()) {
|
|
1119
|
+
this.reRenderPage();
|
|
1120
|
+
this.refresh({ widget: currentNode });
|
|
1121
|
+
this.select({ widget: cloned });
|
|
1122
|
+
}
|
|
657
1123
|
return cloned;
|
|
658
1124
|
}
|
|
659
1125
|
removeWidget(node = this.selectedNode()) {
|
|
@@ -679,24 +1145,44 @@ class AXPDesignerService {
|
|
|
679
1145
|
}
|
|
680
1146
|
navigateTo(index) {
|
|
681
1147
|
this.commandManager.goToCommand(index);
|
|
682
|
-
this.
|
|
683
|
-
const currentSelection = this.commandManager.selectedNode();
|
|
684
|
-
this.refresh({ widget: this.currentPage() });
|
|
685
|
-
this.select({ widget: currentSelection });
|
|
1148
|
+
this.syncCanvasAfterHistory();
|
|
686
1149
|
}
|
|
687
1150
|
redo() {
|
|
1151
|
+
if (!this.canRedo()) {
|
|
1152
|
+
return;
|
|
1153
|
+
}
|
|
688
1154
|
this.commandManager.redo();
|
|
689
|
-
this.
|
|
690
|
-
const currentSelection = this.commandManager.selectedNode();
|
|
691
|
-
this.refresh({ widget: this.currentPage() });
|
|
692
|
-
this.select({ widget: currentSelection });
|
|
1155
|
+
this.syncCanvasAfterHistory();
|
|
693
1156
|
}
|
|
694
1157
|
undo() {
|
|
1158
|
+
if (!this.canUndo()) {
|
|
1159
|
+
return;
|
|
1160
|
+
}
|
|
695
1161
|
this.commandManager.undo();
|
|
696
|
-
this.
|
|
697
|
-
|
|
1162
|
+
this.syncCanvasAfterHistory();
|
|
1163
|
+
}
|
|
1164
|
+
isInTransaction() {
|
|
1165
|
+
return this.commandManager.isInTransaction();
|
|
1166
|
+
}
|
|
1167
|
+
runTransaction(action, description) {
|
|
1168
|
+
this.commandManager.beginTransaction(description);
|
|
1169
|
+
try {
|
|
1170
|
+
return action();
|
|
1171
|
+
}
|
|
1172
|
+
finally {
|
|
1173
|
+
this.commandManager.endTransaction();
|
|
1174
|
+
if (!this.commandManager.isInTransaction()) {
|
|
1175
|
+
this.syncCanvasAfterHistory();
|
|
1176
|
+
}
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1179
|
+
syncCanvasAfterHistory() {
|
|
1180
|
+
const selected = this.commandManager.selectedNode() ?? this.currentPage();
|
|
698
1181
|
this.refresh({ widget: this.currentPage() });
|
|
699
|
-
|
|
1182
|
+
if (selected) {
|
|
1183
|
+
this.onUpdate.next({ widget: selected, values: { options: selected.options ?? {} } });
|
|
1184
|
+
}
|
|
1185
|
+
this.select({ widget: selected });
|
|
700
1186
|
}
|
|
701
1187
|
clearHistory() {
|
|
702
1188
|
this.commandManager.clear();
|
|
@@ -721,19 +1207,22 @@ class AXPDesignerService {
|
|
|
721
1207
|
// If the value is not an object or array, return it as is
|
|
722
1208
|
return obj;
|
|
723
1209
|
}
|
|
724
|
-
async addMetaToNodes(node, processedNodes, progressCallback) {
|
|
725
|
-
// Apply your meta logic here
|
|
1210
|
+
async addMetaToNodes(node, processedNodes, progressCallback, reservedNames) {
|
|
726
1211
|
const config = this.widgetRegisteryService.resolve(node.type);
|
|
727
|
-
|
|
1212
|
+
const existing = typeof node.name === 'string' ? node.name.trim() : '';
|
|
1213
|
+
if (!existing) {
|
|
1214
|
+
node.name = this.nextUniqueName(node.type, reservedNames);
|
|
1215
|
+
}
|
|
1216
|
+
else {
|
|
1217
|
+
node.name = existing;
|
|
1218
|
+
}
|
|
1219
|
+
reservedNames.add(node.name);
|
|
728
1220
|
set(node, '__meta__.id', this.generateUniqueId());
|
|
729
1221
|
set(node, '__meta__.config', config);
|
|
730
|
-
//
|
|
731
|
-
// Increment the processed node count and update the progress dialog
|
|
732
1222
|
processedNodes.count++;
|
|
733
1223
|
progressCallback(processedNodes.count);
|
|
734
|
-
// Recursively process child nodes using Promise.all
|
|
735
1224
|
if (node.children && node.children.length > 0) {
|
|
736
|
-
node.children = await Promise.all(node.children.map(async (child) =>
|
|
1225
|
+
node.children = await Promise.all(node.children.map(async (child) => this.addMetaToNodes(child, processedNodes, progressCallback, reservedNames)));
|
|
737
1226
|
}
|
|
738
1227
|
return node;
|
|
739
1228
|
}
|
|
@@ -775,14 +1264,7 @@ class AXPDesignerService {
|
|
|
775
1264
|
nearestContainer.children = [];
|
|
776
1265
|
}
|
|
777
1266
|
//
|
|
778
|
-
|
|
779
|
-
set(node, 'name', this.generateUniqueName(node.type));
|
|
780
|
-
set(node, '__meta__.id', this.generateUniqueId());
|
|
781
|
-
node.children?.forEach((n) => {
|
|
782
|
-
setNameId(n);
|
|
783
|
-
});
|
|
784
|
-
};
|
|
785
|
-
setNameId(newNode);
|
|
1267
|
+
this.stampNewWidgetTree(newNode, { keepNames: false, reservedNames: this.collectDocumentNameSet() });
|
|
786
1268
|
//
|
|
787
1269
|
this.commandManager.executeCommand(new AddWidgetCommand(newNode, nearestContainer, nearestContainer));
|
|
788
1270
|
//
|
|
@@ -888,13 +1370,16 @@ class AXPDesignerService {
|
|
|
888
1370
|
buttons: [button],
|
|
889
1371
|
});
|
|
890
1372
|
try {
|
|
1373
|
+
const reservedNames = new Set();
|
|
891
1374
|
const root = await this.addMetaToNodes(rootNode, processedNodes, (count) => {
|
|
892
1375
|
dialog.setProgressValue(Math.ceil((count / totalNode) * 100));
|
|
893
1376
|
dialog.setProgressStatus(`${count} of ${totalNode}`);
|
|
894
|
-
});
|
|
1377
|
+
}, reservedNames);
|
|
895
1378
|
const page = root.children?.[0];
|
|
1379
|
+
this.commandManager.clear();
|
|
896
1380
|
this.document.set(root);
|
|
897
1381
|
this.currentPage.set(page);
|
|
1382
|
+
this.hydrateLocalDataSources(root);
|
|
898
1383
|
dialog.setProgressColor('success');
|
|
899
1384
|
dialog.setProgressText('Content loaded successfully');
|
|
900
1385
|
button.text = 'Okay';
|
|
@@ -919,15 +1404,36 @@ class AXPDesignerService {
|
|
|
919
1404
|
}
|
|
920
1405
|
return count;
|
|
921
1406
|
}
|
|
1407
|
+
ensureDefaultTabsetChild(node) {
|
|
1408
|
+
if (node.type !== 'tabset-layout' || (node.children?.length ?? 0) > 0) {
|
|
1409
|
+
return;
|
|
1410
|
+
}
|
|
1411
|
+
const tabType = 'tabset-item';
|
|
1412
|
+
const tabConfig = this.widgetRegisteryService.resolve(tabType);
|
|
1413
|
+
const tab = {
|
|
1414
|
+
type: tabType,
|
|
1415
|
+
name: this.generateUniqueName(tabType),
|
|
1416
|
+
options: {
|
|
1417
|
+
title: '@platform-layout-widgets:widgets.tabset-item.default-title',
|
|
1418
|
+
},
|
|
1419
|
+
children: [],
|
|
1420
|
+
};
|
|
1421
|
+
set(tab, '__meta__.id', this.generateUniqueId());
|
|
1422
|
+
set(tab, '__meta__.config', tabConfig);
|
|
1423
|
+
node.children = [tab];
|
|
1424
|
+
}
|
|
922
1425
|
generateUniqueName(type) {
|
|
923
|
-
|
|
924
|
-
|
|
1426
|
+
return this.nextUniqueName(type, this.collectDocumentNameSet());
|
|
1427
|
+
}
|
|
1428
|
+
collectDocumentNameSet() {
|
|
1429
|
+
const names = new Set();
|
|
1430
|
+
this.collectAllNames(this.document(), names);
|
|
1431
|
+
return names;
|
|
1432
|
+
}
|
|
1433
|
+
nextUniqueName(type, existingNames) {
|
|
1434
|
+
const baseName = (type || 'widget').charAt(0).toLowerCase() + (type || 'widget').slice(1);
|
|
925
1435
|
let index = 1;
|
|
926
1436
|
let uniqueName = `${baseName}${index}`;
|
|
927
|
-
// Gather all existing names to check against
|
|
928
|
-
const existingNames = new Set();
|
|
929
|
-
this.collectAllNames(this.document(), existingNames);
|
|
930
|
-
// Increment the index until a unique name is found
|
|
931
1437
|
while (existingNames.has(uniqueName)) {
|
|
932
1438
|
index++;
|
|
933
1439
|
uniqueName = `${baseName}${index}`;
|
|
@@ -948,12 +1454,15 @@ class AXPDesignerService {
|
|
|
948
1454
|
}
|
|
949
1455
|
}
|
|
950
1456
|
updatePreview() {
|
|
1457
|
+
const document = this.removeMetaProp(this.document());
|
|
1458
|
+
storeDesignerPreviewDocument(document);
|
|
951
1459
|
this.eventService.publish(AXPDesignerMessageKeys.Preview, {
|
|
952
1460
|
id: this.templateId(),
|
|
953
|
-
document
|
|
1461
|
+
document,
|
|
954
1462
|
});
|
|
955
1463
|
}
|
|
956
1464
|
async openPreviewDialog() {
|
|
1465
|
+
this.updatePreview();
|
|
957
1466
|
const com = await Promise.resolve().then(function () { return preview_component; }).then((c) => c.AXPLayoutDesignerPreviewComponent);
|
|
958
1467
|
await this.popupService.open(com, {
|
|
959
1468
|
header: false,
|
|
@@ -965,30 +1474,30 @@ class AXPDesignerService {
|
|
|
965
1474
|
});
|
|
966
1475
|
}
|
|
967
1476
|
openPreviewWindow() {
|
|
1477
|
+
this.updatePreview();
|
|
968
1478
|
window.open('/forms/preview', '_blank');
|
|
969
1479
|
}
|
|
970
1480
|
getContextMenuItems(instance, isRoot = false) {
|
|
971
1481
|
const widget = instance;
|
|
972
|
-
|
|
1482
|
+
return this.buildContextMenuItems(widget.node, instance, isRoot);
|
|
1483
|
+
}
|
|
1484
|
+
getContextMenuItemsForNode(node, isRoot = false) {
|
|
1485
|
+
return this.buildContextMenuItems(node, this.getWidgetInstance(node), isRoot);
|
|
1486
|
+
}
|
|
1487
|
+
buildContextMenuItems(node, instance, isRoot = false) {
|
|
973
1488
|
const items = [];
|
|
974
|
-
//
|
|
975
1489
|
if (this.can(node).insert) {
|
|
976
1490
|
items.push(cloneWidgetMenu(AXP_DESIGNER_ADD_WIDGET_MENU, {
|
|
977
1491
|
break: true,
|
|
978
1492
|
}));
|
|
979
1493
|
}
|
|
980
|
-
//
|
|
981
1494
|
items.push(cloneWidgetMenu(AXP_DESIGNER_CLONE_MENU, { disabled: !this.can(node).copyOrCut }));
|
|
982
1495
|
items.push(cloneWidgetMenu(AXP_DESIGNER_CUT_MENU, { disabled: !this.can(node).copyOrCut }));
|
|
983
1496
|
items.push(cloneWidgetMenu(AXP_DESIGNER_COPY_MENU, { disabled: !this.can(node).copyOrCut }));
|
|
984
1497
|
items.push(cloneWidgetMenu(AXP_DESIGNER_PASTE_MENU, { disabled: !this.can(node).paste, break: true }));
|
|
985
|
-
//
|
|
986
1498
|
items.push(cloneWidgetMenu(AXP_DESIGNER_DELETE_WIDGET_MENU, { disabled: !this.can(node).delete, break: true }));
|
|
987
|
-
//
|
|
988
1499
|
items.push(cloneWidgetMenu(AXP_DESIGNER_SAVE_AS_WIDGET_MENU));
|
|
989
|
-
|
|
990
|
-
instance.onContextMenu({ items });
|
|
991
|
-
}
|
|
1500
|
+
instance?.onContextMenu?.({ items });
|
|
992
1501
|
if (!isRoot) {
|
|
993
1502
|
items.forEach(item => {
|
|
994
1503
|
item.suffix = undefined;
|
|
@@ -997,49 +1506,51 @@ class AXPDesignerService {
|
|
|
997
1506
|
return items;
|
|
998
1507
|
}
|
|
999
1508
|
async executeCommand(context) {
|
|
1000
|
-
const
|
|
1001
|
-
|
|
1509
|
+
const instance = context.instance ?? (context.node ? this.getWidgetInstance(context.node) : null);
|
|
1510
|
+
const widget = instance;
|
|
1511
|
+
const node = widget?.node ?? context.node;
|
|
1512
|
+
if (!node) {
|
|
1513
|
+
return;
|
|
1514
|
+
}
|
|
1515
|
+
if (instance?.executeCommand) {
|
|
1002
1516
|
const command = {
|
|
1003
1517
|
name: context.name,
|
|
1004
1518
|
data: context.data,
|
|
1005
1519
|
handled: false
|
|
1006
1520
|
};
|
|
1007
|
-
await
|
|
1521
|
+
await instance.executeCommand(command);
|
|
1008
1522
|
if (command.handled)
|
|
1009
1523
|
return;
|
|
1010
1524
|
}
|
|
1011
1525
|
switch (context.name) {
|
|
1012
1526
|
case AXP_DESIGNER_SELECT_WIDGET_MENU.name: {
|
|
1013
|
-
this.select({ widget:
|
|
1527
|
+
this.select({ widget: node });
|
|
1014
1528
|
break;
|
|
1015
1529
|
}
|
|
1016
1530
|
case AXP_DESIGNER_ADD_WIDGET_MENU.name: {
|
|
1017
|
-
this.showPicker(
|
|
1531
|
+
this.showPicker(node);
|
|
1018
1532
|
break;
|
|
1019
1533
|
}
|
|
1020
|
-
//
|
|
1021
1534
|
case AXP_DESIGNER_DELETE_WIDGET_MENU.name: {
|
|
1022
|
-
this.removeWidget(
|
|
1535
|
+
this.removeWidget(node);
|
|
1023
1536
|
break;
|
|
1024
1537
|
}
|
|
1025
|
-
//
|
|
1026
1538
|
case AXP_DESIGNER_CLONE_MENU.name: {
|
|
1027
|
-
this.clone(
|
|
1539
|
+
this.clone(node);
|
|
1028
1540
|
break;
|
|
1029
1541
|
}
|
|
1030
1542
|
case AXP_DESIGNER_CUT_MENU.name: {
|
|
1031
|
-
this.cut(
|
|
1543
|
+
this.cut(node);
|
|
1032
1544
|
break;
|
|
1033
1545
|
}
|
|
1034
1546
|
case AXP_DESIGNER_COPY_MENU.name: {
|
|
1035
|
-
this.copy(
|
|
1547
|
+
this.copy(node);
|
|
1036
1548
|
break;
|
|
1037
1549
|
}
|
|
1038
1550
|
case AXP_DESIGNER_PASTE_MENU.name: {
|
|
1039
|
-
this.paste(
|
|
1551
|
+
this.paste(node);
|
|
1040
1552
|
break;
|
|
1041
1553
|
}
|
|
1042
|
-
//
|
|
1043
1554
|
}
|
|
1044
1555
|
}
|
|
1045
1556
|
unsubscribeEvents() {
|
|
@@ -1219,12 +1730,12 @@ class AXPDesignerFlexDrawerComponent {
|
|
|
1219
1730
|
</tr>
|
|
1220
1731
|
<tr>
|
|
1221
1732
|
<td [attr.colspan]="items().length" class="text-center">
|
|
1222
|
-
<small>{{ range() }}</small>
|
|
1733
|
+
<small>{{ range() > 0 ? range() : ' ' }}</small>
|
|
1223
1734
|
</td>
|
|
1224
1735
|
</tr>
|
|
1225
1736
|
</tbody>
|
|
1226
1737
|
</table>
|
|
1227
|
-
`, isInline: true, styles: ["@layer properties;:host{width:100%}:host table{width:
|
|
1738
|
+
`, isInline: true, styles: ["@layer properties;:host{display:block;width:100%}:host table{margin-inline:auto;width:auto;border-collapse:separate;--tw-border-spacing-x: var(--spacing, .25rem);--tw-border-spacing-y: var(--spacing, .25rem);border-spacing:var(--tw-border-spacing-x) var(--tw-border-spacing-y);empty-cells:show}:host table td{height:calc(var(--spacing, .25rem) * 6);width:calc(var(--spacing, .25rem) * 6);border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-border-default)}:host table td[colspan]{height:auto;width:auto;border-style:var(--tw-border-style);border-width:0px}:host table td.picked{border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-border-default);background-color:rgba(var(--ax-sys-color-primary-100))}@property --tw-border-spacing-x{syntax: \"<length>\"; inherits: false; initial-value: 0;}@property --tw-border-spacing-y{syntax: \"<length>\"; inherits: false; initial-value: 0;}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-border-style: solid}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
1228
1739
|
}
|
|
1229
1740
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPDesignerFlexDrawerComponent, decorators: [{
|
|
1230
1741
|
type: Component,
|
|
@@ -1238,12 +1749,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
1238
1749
|
</tr>
|
|
1239
1750
|
<tr>
|
|
1240
1751
|
<td [attr.colspan]="items().length" class="text-center">
|
|
1241
|
-
<small>{{ range() }}</small>
|
|
1752
|
+
<small>{{ range() > 0 ? range() : ' ' }}</small>
|
|
1242
1753
|
</td>
|
|
1243
1754
|
</tr>
|
|
1244
1755
|
</tbody>
|
|
1245
1756
|
</table>
|
|
1246
|
-
`, changeDetection: ChangeDetectionStrategy.OnPush, imports: [], styles: ["@layer properties;:host{width:100%}:host table{width:
|
|
1757
|
+
`, changeDetection: ChangeDetectionStrategy.OnPush, imports: [], styles: ["@layer properties;:host{display:block;width:100%}:host table{margin-inline:auto;width:auto;border-collapse:separate;--tw-border-spacing-x: var(--spacing, .25rem);--tw-border-spacing-y: var(--spacing, .25rem);border-spacing:var(--tw-border-spacing-x) var(--tw-border-spacing-y);empty-cells:show}:host table td{height:calc(var(--spacing, .25rem) * 6);width:calc(var(--spacing, .25rem) * 6);border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-border-default)}:host table td[colspan]{height:auto;width:auto;border-style:var(--tw-border-style);border-width:0px}:host table td.picked{border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-border-default);background-color:rgba(var(--ax-sys-color-primary-100))}@property --tw-border-spacing-x{syntax: \"<length>\"; inherits: false; initial-value: 0;}@property --tw-border-spacing-y{syntax: \"<length>\"; inherits: false; initial-value: 0;}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-border-style: solid}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
|
|
1247
1758
|
}], propDecorators: { itemsCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }, { type: i0.Output, args: ["itemsChange"] }], onSelect: [{ type: i0.Output, args: ["onSelect"] }], handleMouseLeave: [{
|
|
1248
1759
|
type: HostListener,
|
|
1249
1760
|
args: ['mouseleave', ['$event']]
|
|
@@ -1274,13 +1785,8 @@ class AXPDesignerGridDrawerComponent {
|
|
|
1274
1785
|
this.rangeR.set(0);
|
|
1275
1786
|
this.rangeC.set(0);
|
|
1276
1787
|
}
|
|
1277
|
-
get __style() {
|
|
1278
|
-
return {
|
|
1279
|
-
'--cols-width': `${this.colsCount() == 0 ? 0 : 100 / this.colsCount()}%`,
|
|
1280
|
-
};
|
|
1281
|
-
}
|
|
1282
1788
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPDesignerGridDrawerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1283
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPDesignerGridDrawerComponent, isStandalone: true, selector: "axp-designer-grid-drawer", inputs: { rowsCount: { classPropertyName: "rowsCount", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, colsCount: { classPropertyName: "colsCount", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { rowsCount: "rowsChange", colsCount: "columnsChange", onSelect: "onSelect" }, host: { listeners: { "mouseleave": "handleMouseLeave($event)" }
|
|
1789
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPDesignerGridDrawerComponent, isStandalone: true, selector: "axp-designer-grid-drawer", inputs: { rowsCount: { classPropertyName: "rowsCount", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, colsCount: { classPropertyName: "colsCount", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { rowsCount: "rowsChange", colsCount: "columnsChange", onSelect: "onSelect" }, host: { listeners: { "mouseleave": "handleMouseLeave($event)" } }, ngImport: i0, template: `
|
|
1284
1790
|
<table class="table-picker">
|
|
1285
1791
|
<tbody>
|
|
1286
1792
|
@for (r of rows(); track $index) {
|
|
@@ -1296,12 +1802,12 @@ class AXPDesignerGridDrawerComponent {
|
|
|
1296
1802
|
}
|
|
1297
1803
|
<tr>
|
|
1298
1804
|
<td [attr.colspan]="columns().length" class="text-center">
|
|
1299
|
-
<small>{{ rangeC()
|
|
1805
|
+
<small>{{ rangeC() > 0 && rangeR() > 0 ? rangeC() + '×' + rangeR() : ' ' }}</small>
|
|
1300
1806
|
</td>
|
|
1301
1807
|
</tr>
|
|
1302
1808
|
</tbody>
|
|
1303
1809
|
</table>
|
|
1304
|
-
`, isInline: true, styles: ["@layer properties;:host{width:100%}:host table{width:
|
|
1810
|
+
`, isInline: true, styles: ["@layer properties;:host{display:block;width:100%}:host table{margin-inline:auto;width:auto;border-collapse:separate;--tw-border-spacing-x: var(--spacing, .25rem);--tw-border-spacing-y: var(--spacing, .25rem);border-spacing:var(--tw-border-spacing-x) var(--tw-border-spacing-y);empty-cells:show}:host table td{height:calc(var(--spacing, .25rem) * 6);width:calc(var(--spacing, .25rem) * 6);border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-border-default)}:host table td[colspan]{height:auto;width:auto;border-style:var(--tw-border-style);border-width:0px}:host table td.picked{border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-border-default);background-color:rgba(var(--ax-sys-color-primary-100))}@property --tw-border-spacing-x{syntax: \"<length>\"; inherits: false; initial-value: 0;}@property --tw-border-spacing-y{syntax: \"<length>\"; inherits: false; initial-value: 0;}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-border-style: solid}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
1305
1811
|
}
|
|
1306
1812
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPDesignerGridDrawerComponent, decorators: [{
|
|
1307
1813
|
type: Component,
|
|
@@ -1321,18 +1827,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
1321
1827
|
}
|
|
1322
1828
|
<tr>
|
|
1323
1829
|
<td [attr.colspan]="columns().length" class="text-center">
|
|
1324
|
-
<small>{{ rangeC()
|
|
1830
|
+
<small>{{ rangeC() > 0 && rangeR() > 0 ? rangeC() + '×' + rangeR() : ' ' }}</small>
|
|
1325
1831
|
</td>
|
|
1326
1832
|
</tr>
|
|
1327
1833
|
</tbody>
|
|
1328
1834
|
</table>
|
|
1329
|
-
`, changeDetection: ChangeDetectionStrategy.OnPush, imports: [], styles: ["@layer properties;:host{width:100%}:host table{width:
|
|
1835
|
+
`, changeDetection: ChangeDetectionStrategy.OnPush, imports: [], styles: ["@layer properties;:host{display:block;width:100%}:host table{margin-inline:auto;width:auto;border-collapse:separate;--tw-border-spacing-x: var(--spacing, .25rem);--tw-border-spacing-y: var(--spacing, .25rem);border-spacing:var(--tw-border-spacing-x) var(--tw-border-spacing-y);empty-cells:show}:host table td{height:calc(var(--spacing, .25rem) * 6);width:calc(var(--spacing, .25rem) * 6);border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-border-default)}:host table td[colspan]{height:auto;width:auto;border-style:var(--tw-border-style);border-width:0px}:host table td.picked{border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-border-default);background-color:rgba(var(--ax-sys-color-primary-100))}@property --tw-border-spacing-x{syntax: \"<length>\"; inherits: false; initial-value: 0;}@property --tw-border-spacing-y{syntax: \"<length>\"; inherits: false; initial-value: 0;}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-border-style: solid}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
|
|
1330
1836
|
}], propDecorators: { rowsCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: false }] }, { type: i0.Output, args: ["rowsChange"] }], colsCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }, { type: i0.Output, args: ["columnsChange"] }], onSelect: [{ type: i0.Output, args: ["onSelect"] }], handleMouseLeave: [{
|
|
1331
1837
|
type: HostListener,
|
|
1332
1838
|
args: ['mouseleave', ['$event']]
|
|
1333
|
-
}], __style: [{
|
|
1334
|
-
type: HostBinding,
|
|
1335
|
-
args: ['style']
|
|
1336
1839
|
}] } });
|
|
1337
1840
|
|
|
1338
1841
|
const WIDGET_PICKER_I18N = {
|
|
@@ -1613,7 +2116,7 @@ class AXPDesignerWidgetPickerComponent extends AXBasePageComponent {
|
|
|
1613
2116
|
return this.isWidgetSelected(originalWidget);
|
|
1614
2117
|
}
|
|
1615
2118
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPDesignerWidgetPickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1616
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPDesignerWidgetPickerComponent, isStandalone: true, selector: "ng-component", inputs: { searchTerm: { classPropertyName: "searchTerm", publicName: "searchTerm", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { searchTerm: "searchTermChange" }, viewQueries: [{ propertyName: "tabsHost", first: true, predicate: ["tabsHost"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div [class]=\"pickerShellClass()\">\n <div>\n <ax-tabs #tabsHost [look]=\"'with-line'\" (onActiveTabChanged)=\"handleTabChange($event)\">\n @for (w of tabs(); track w.name; let i = $index) {\n <ax-tab-item\n [text]=\"(w.title | translate | async)!\"\n [key]=\"w.name\"\n [active]=\"currentTabIndex() === i\"\n ></ax-tab-item>\n }\n </ax-tabs>\n </div>\n <div class=\"overflow-auto\" #content>\n <div\n class=\"p-4 sticky top-0 z-10 transition-all\"\n #sticky=\"axpSticky\"\n [axpSticky]=\"'
|
|
2119
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPDesignerWidgetPickerComponent, isStandalone: true, selector: "ng-component", inputs: { searchTerm: { classPropertyName: "searchTerm", publicName: "searchTerm", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { searchTerm: "searchTermChange" }, viewQueries: [{ propertyName: "tabsHost", first: true, predicate: ["tabsHost"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div [class]=\"pickerShellClass()\">\n <div>\n <ax-tabs #tabsHost [look]=\"'with-line'\" (onActiveTabChanged)=\"handleTabChange($event)\">\n @for (w of tabs(); track w.name; let i = $index) {\n <ax-tab-item\n [text]=\"(w.title | translate | async)!\"\n [key]=\"w.name\"\n [active]=\"currentTabIndex() === i\"\n ></ax-tab-item>\n }\n </ax-tabs>\n </div>\n <div class=\"overflow-auto\" #content>\n <div\n class=\"p-4 sticky top-0 z-10 transition-all\"\n #sticky=\"axpSticky\"\n [axpSticky]=\"'lightest-surface shadow-xl'\"\n [stickyParent]=\"content\"\n [stickyOffset]=\"10\"\n >\n <ax-search-box\n look=\"fill\"\n [placeholder]=\"(i18n.searchPlaceholder | translate | async) ?? ''\"\n [(ngModel)]=\"searchTerm\"\n [delayTime]=\"300\"\n [axAutoFocus]=\"true\"\n >\n <ax-clear-button></ax-clear-button>\n </ax-search-box>\n </div>\n <div class=\"flex flex-col p-4 pt-0\">\n @if (pinnedWidgetItems().length) {\n <div class=\"axp-designer-widget-picker__section axp-designer-widget-picker__section--first\">\n <div class=\"axp-designer-widget-picker__group-heading\">\n <span class=\"axp-designer-widget-picker__group-title\">{{\n (i18n.pinnedSectionTitle | translate | async) ?? ''\n }}</span>\n <span class=\"axp-designer-widget-picker__group-line\"></span>\n </div>\n <div class=\"grid grid-cols-2 gap-2\">\n @for (widgetItem of pinnedWidgetItems(); track $any(widgetItem.data).name) {\n <axp-widget-item\n [widget]=\"widgetItem\"\n [isSelected]=\"isWidgetItemSelected(widgetItem)\"\n (onWidgetClick)=\"handleWidgetClick($event)\"\n (onPinClick)=\"handleWidgetPinClick($event)\"\n >\n </axp-widget-item>\n }\n </div>\n </div>\n }\n @for (group of regularGroupedSections(); track group.trackKey; let isFirst = $first) {\n <div\n class=\"axp-designer-widget-picker__section\"\n [class.axp-designer-widget-picker__section--first]=\"isFirst && pinnedWidgetItems().length === 0\"\n >\n @if (group.title) {\n <div class=\"axp-designer-widget-picker__group-heading\">\n <span class=\"axp-designer-widget-picker__group-title\">{{\n (group.title | translate | async) ?? ''\n }}</span>\n <span class=\"axp-designer-widget-picker__group-line\"></span>\n </div>\n }\n <div class=\"grid grid-cols-2 gap-2\">\n @for (widgetItem of group.widgetItems; track $any(widgetItem.data).name) {\n <axp-widget-item\n [widget]=\"widgetItem\"\n [isSelected]=\"isWidgetItemSelected(widgetItem)\"\n (onWidgetClick)=\"handleWidgetClick($event)\"\n (onPinClick)=\"handleWidgetPinClick($event)\"\n >\n </axp-widget-item>\n }\n </div>\n </div>\n }\n </div>\n </div>\n</div>\n@if (selectedWidgets().length) {\n <ax-footer>\n <ax-suffix>\n <ax-button\n look=\"solid\"\n color=\"primary\"\n [text]=\"(i18n.selectedCount | translate: { params: { count: selectedWidgets().length } } | async) ?? ''\"\n (onClick)=\"handleConfirmSelection()\"\n ></ax-button>\n </ax-suffix>\n </ax-footer>\n}\n", styles: ["@layer properties;.axp-designer-widget-picker__group-heading{margin-bottom:calc(var(--spacing, .25rem) * 3);display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 3);padding-bottom:var(--spacing, .25rem)}.axp-designer-widget-picker__group-title{flex-shrink:0;font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600);color:rgba(var(--ax-sys-color-primary-600))}.axp-designer-widget-picker__group-line{min-width:calc(var(--spacing, .25rem) * 4);flex:1;border-top-style:var(--tw-border-style);border-top-width:1px;border-color:var(--color-border-default)}.axp-designer-widget-picker__section{margin-top:calc(var(--spacing, .25rem) * 6);padding-top:var(--spacing, .25rem)}.axp-designer-widget-picker__section.axp-designer-widget-picker__section--first{margin-top:0;padding-top:0}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-font-weight: initial;--tw-border-style: solid}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXCommonModule }, { kind: "directive", type: i1$1.AXAutoFocusDirective, selector: "[axAutoFocus]", inputs: ["axAutoFocus", "axAutoFocusTime"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i2.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "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: i1.AXDecoratorClearButtonComponent, selector: "ax-clear-button", inputs: ["icon"] }, { kind: "component", type: i1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXTabsModule }, { kind: "component", type: i5.AXTabsComponent, selector: "ax-tabs", inputs: ["look", "location", "reorderable", "reorderDelay", "renderMode", "stacked", "fitParent", "minWidth", "content"], outputs: ["onActiveTabChanged", "onTabsReordered"] }, { kind: "component", type: i5.AXTabItemComponent, selector: "ax-tab-item", inputs: ["disabled", "text", "key", "headerTemplate", "active"], outputs: ["disabledChange", "onClick", "onBlur", "onFocus", "activeChange"] }, { kind: "ngmodule", type: AXSearchBoxModule }, { kind: "component", type: i6.AXSearchBoxComponent, selector: "ax-search-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "value", "state", "name", "id", "look", "class", "delayTime", "type", "autoSearch"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "directive", type: AXPStickyDirective, selector: "[axpSticky]", inputs: ["axpSticky", "stickyOffset", "stickyParent", "stickyTarget"], outputs: ["isStickyChange"], exportAs: ["axpSticky"] }, { kind: "component", type: AXPWidgetItemComponent, selector: "axp-widget-item", inputs: ["widget", "isSelected", "showPinButton", "customClasses"], outputs: ["onWidgetClick", "onPinClick"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i1$2.AsyncPipe, name: "async" }, { kind: "pipe", type: i4.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.Eager, encapsulation: i0.ViewEncapsulation.None }); }
|
|
1617
2120
|
}
|
|
1618
2121
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPDesignerWidgetPickerComponent, decorators: [{
|
|
1619
2122
|
type: Component,
|
|
@@ -1628,7 +2131,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
1628
2131
|
AXPStickyDirective,
|
|
1629
2132
|
AXPWidgetItemComponent,
|
|
1630
2133
|
AXTranslationModule,
|
|
1631
|
-
], changeDetection: ChangeDetectionStrategy.Eager, encapsulation: ViewEncapsulation.None, template: "<div [class]=\"pickerShellClass()\">\n <div>\n <ax-tabs #tabsHost [look]=\"'with-line'\" (onActiveTabChanged)=\"handleTabChange($event)\">\n @for (w of tabs(); track w.name; let i = $index) {\n <ax-tab-item\n [text]=\"(w.title | translate | async)!\"\n [key]=\"w.name\"\n [active]=\"currentTabIndex() === i\"\n ></ax-tab-item>\n }\n </ax-tabs>\n </div>\n <div class=\"overflow-auto\" #content>\n <div\n class=\"p-4 sticky top-0 z-10 transition-all\"\n #sticky=\"axpSticky\"\n [axpSticky]=\"'
|
|
2134
|
+
], changeDetection: ChangeDetectionStrategy.Eager, encapsulation: ViewEncapsulation.None, template: "<div [class]=\"pickerShellClass()\">\n <div>\n <ax-tabs #tabsHost [look]=\"'with-line'\" (onActiveTabChanged)=\"handleTabChange($event)\">\n @for (w of tabs(); track w.name; let i = $index) {\n <ax-tab-item\n [text]=\"(w.title | translate | async)!\"\n [key]=\"w.name\"\n [active]=\"currentTabIndex() === i\"\n ></ax-tab-item>\n }\n </ax-tabs>\n </div>\n <div class=\"overflow-auto\" #content>\n <div\n class=\"p-4 sticky top-0 z-10 transition-all\"\n #sticky=\"axpSticky\"\n [axpSticky]=\"'lightest-surface shadow-xl'\"\n [stickyParent]=\"content\"\n [stickyOffset]=\"10\"\n >\n <ax-search-box\n look=\"fill\"\n [placeholder]=\"(i18n.searchPlaceholder | translate | async) ?? ''\"\n [(ngModel)]=\"searchTerm\"\n [delayTime]=\"300\"\n [axAutoFocus]=\"true\"\n >\n <ax-clear-button></ax-clear-button>\n </ax-search-box>\n </div>\n <div class=\"flex flex-col p-4 pt-0\">\n @if (pinnedWidgetItems().length) {\n <div class=\"axp-designer-widget-picker__section axp-designer-widget-picker__section--first\">\n <div class=\"axp-designer-widget-picker__group-heading\">\n <span class=\"axp-designer-widget-picker__group-title\">{{\n (i18n.pinnedSectionTitle | translate | async) ?? ''\n }}</span>\n <span class=\"axp-designer-widget-picker__group-line\"></span>\n </div>\n <div class=\"grid grid-cols-2 gap-2\">\n @for (widgetItem of pinnedWidgetItems(); track $any(widgetItem.data).name) {\n <axp-widget-item\n [widget]=\"widgetItem\"\n [isSelected]=\"isWidgetItemSelected(widgetItem)\"\n (onWidgetClick)=\"handleWidgetClick($event)\"\n (onPinClick)=\"handleWidgetPinClick($event)\"\n >\n </axp-widget-item>\n }\n </div>\n </div>\n }\n @for (group of regularGroupedSections(); track group.trackKey; let isFirst = $first) {\n <div\n class=\"axp-designer-widget-picker__section\"\n [class.axp-designer-widget-picker__section--first]=\"isFirst && pinnedWidgetItems().length === 0\"\n >\n @if (group.title) {\n <div class=\"axp-designer-widget-picker__group-heading\">\n <span class=\"axp-designer-widget-picker__group-title\">{{\n (group.title | translate | async) ?? ''\n }}</span>\n <span class=\"axp-designer-widget-picker__group-line\"></span>\n </div>\n }\n <div class=\"grid grid-cols-2 gap-2\">\n @for (widgetItem of group.widgetItems; track $any(widgetItem.data).name) {\n <axp-widget-item\n [widget]=\"widgetItem\"\n [isSelected]=\"isWidgetItemSelected(widgetItem)\"\n (onWidgetClick)=\"handleWidgetClick($event)\"\n (onPinClick)=\"handleWidgetPinClick($event)\"\n >\n </axp-widget-item>\n }\n </div>\n </div>\n }\n </div>\n </div>\n</div>\n@if (selectedWidgets().length) {\n <ax-footer>\n <ax-suffix>\n <ax-button\n look=\"solid\"\n color=\"primary\"\n [text]=\"(i18n.selectedCount | translate: { params: { count: selectedWidgets().length } } | async) ?? ''\"\n (onClick)=\"handleConfirmSelection()\"\n ></ax-button>\n </ax-suffix>\n </ax-footer>\n}\n", styles: ["@layer properties;.axp-designer-widget-picker__group-heading{margin-bottom:calc(var(--spacing, .25rem) * 3);display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 3);padding-bottom:var(--spacing, .25rem)}.axp-designer-widget-picker__group-title{flex-shrink:0;font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600);color:rgba(var(--ax-sys-color-primary-600))}.axp-designer-widget-picker__group-line{min-width:calc(var(--spacing, .25rem) * 4);flex:1;border-top-style:var(--tw-border-style);border-top-width:1px;border-color:var(--color-border-default)}.axp-designer-widget-picker__section{margin-top:calc(var(--spacing, .25rem) * 6);padding-top:var(--spacing, .25rem)}.axp-designer-widget-picker__section.axp-designer-widget-picker__section--first{margin-top:0;padding-top:0}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-font-weight: initial;--tw-border-style: solid}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
|
|
1632
2135
|
}], ctorParameters: () => [], propDecorators: { tabsHost: [{ type: i0.ViewChild, args: ['tabsHost', { isSignal: true }] }], searchTerm: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchTerm", required: false }] }, { type: i0.Output, args: ["searchTermChange"] }] } });
|
|
1633
2136
|
|
|
1634
2137
|
var widgetPicker_component = /*#__PURE__*/Object.freeze({
|
|
@@ -1637,6 +2140,38 @@ var widgetPicker_component = /*#__PURE__*/Object.freeze({
|
|
|
1637
2140
|
});
|
|
1638
2141
|
|
|
1639
2142
|
class AXPWidgetDesignerRendererDirective {
|
|
2143
|
+
/** Prefer `__meta__.id`; fall back to object identity so nameless AI children are not all treated as the same widget. */
|
|
2144
|
+
sameWidget(a, b) {
|
|
2145
|
+
if (!a || !b) {
|
|
2146
|
+
return a === b;
|
|
2147
|
+
}
|
|
2148
|
+
const idA = this.getId(a);
|
|
2149
|
+
const idB = this.getId(b);
|
|
2150
|
+
if (idA != null && idB != null) {
|
|
2151
|
+
return idA == idB;
|
|
2152
|
+
}
|
|
2153
|
+
return a === b;
|
|
2154
|
+
}
|
|
2155
|
+
/**
|
|
2156
|
+
* Drawer inserts (flex, grid, table) run inside a transaction that refreshes the page only.
|
|
2157
|
+
* Each widget copies `node.children` into its own signal at creation, so a page refresh must
|
|
2158
|
+
* also sync every nested container or the size picker stays on screen after cells are added.
|
|
2159
|
+
*/
|
|
2160
|
+
shouldSyncChildren(widget) {
|
|
2161
|
+
return this.isCurrentWidget(widget) || this.isNestedUnder(widget, this.node());
|
|
2162
|
+
}
|
|
2163
|
+
isNestedUnder(ancestor, node) {
|
|
2164
|
+
const children = ancestor.children;
|
|
2165
|
+
if (!children?.length) {
|
|
2166
|
+
return false;
|
|
2167
|
+
}
|
|
2168
|
+
for (const child of children) {
|
|
2169
|
+
if (this.sameWidget(child, node) || this.isNestedUnder(child, node)) {
|
|
2170
|
+
return true;
|
|
2171
|
+
}
|
|
2172
|
+
}
|
|
2173
|
+
return false;
|
|
2174
|
+
}
|
|
1640
2175
|
/**
|
|
1641
2176
|
* @ignore
|
|
1642
2177
|
*/
|
|
@@ -1668,18 +2203,18 @@ class AXPWidgetDesignerRendererDirective {
|
|
|
1668
2203
|
...(ngDevMode ? [{ debugName: "node" }] : /* istanbul ignore next */ []));
|
|
1669
2204
|
this.hostElement = () => this.instance?.host;
|
|
1670
2205
|
this.getId = (w) => get(w, '__meta__.id');
|
|
1671
|
-
this.isCurrentWidget = (w) => this.
|
|
2206
|
+
this.isCurrentWidget = (w) => this.sameWidget(w, this.node());
|
|
1672
2207
|
this.subs = [];
|
|
1673
2208
|
this.subs[0] = this.service.onUpdate
|
|
1674
2209
|
.pipe(
|
|
1675
2210
|
//debounceTime(time),
|
|
1676
|
-
distinctUntilChanged((p, c) => this.
|
|
2211
|
+
distinctUntilChanged((p, c) => this.sameWidget(p.widget, c.widget) && isEqual(p.values?.options, c.values?.options)), filter((c) => this.isCurrentWidget(c.widget) && !this.locked()))
|
|
1677
2212
|
.subscribe((c) => {
|
|
1678
2213
|
this.applyOptions(c.values?.options);
|
|
1679
2214
|
});
|
|
1680
2215
|
//
|
|
1681
2216
|
this.subs[1] = this.service.onSelected
|
|
1682
|
-
.pipe(distinctUntilChanged((p, c) => this.
|
|
2217
|
+
.pipe(distinctUntilChanged((p, c) => this.sameWidget(p.widget, c.widget)))
|
|
1683
2218
|
.subscribe((c) => {
|
|
1684
2219
|
this.zone.runOutsideAngular(() => {
|
|
1685
2220
|
if (this.isCurrentWidget(c.widget) && !this.locked()) {
|
|
@@ -1692,7 +2227,7 @@ class AXPWidgetDesignerRendererDirective {
|
|
|
1692
2227
|
});
|
|
1693
2228
|
//
|
|
1694
2229
|
this.subs[2] = this.service.onFocused
|
|
1695
|
-
.pipe(distinctUntilChanged((p, c) =>
|
|
2230
|
+
.pipe(distinctUntilChanged((p, c) => this.sameWidget(p.widget, c.widget)))
|
|
1696
2231
|
.subscribe((c) => {
|
|
1697
2232
|
if (c.widget && this.isCurrentWidget(c.widget)) {
|
|
1698
2233
|
this.addOverlay();
|
|
@@ -1703,9 +2238,12 @@ class AXPWidgetDesignerRendererDirective {
|
|
|
1703
2238
|
});
|
|
1704
2239
|
//
|
|
1705
2240
|
this.subs[3] = this.service.onRefresh
|
|
1706
|
-
.pipe(debounceTime(200), filter((c) => this.
|
|
2241
|
+
.pipe(debounceTime(200), filter((c) => this.shouldSyncChildren(c.widget)))
|
|
1707
2242
|
.subscribe((c) => {
|
|
1708
2243
|
this.instance?.setChildren(this.node().children ?? []);
|
|
2244
|
+
if (this.isCurrentWidget(c.widget)) {
|
|
2245
|
+
this.applyOptions(this.node().options);
|
|
2246
|
+
}
|
|
1709
2247
|
});
|
|
1710
2248
|
//
|
|
1711
2249
|
}
|
|
@@ -1725,6 +2263,9 @@ class AXPWidgetDesignerRendererDirective {
|
|
|
1725
2263
|
this.subs.forEach((s) => {
|
|
1726
2264
|
s.unsubscribe();
|
|
1727
2265
|
});
|
|
2266
|
+
if (this.node()) {
|
|
2267
|
+
this.service.unregister(this.node());
|
|
2268
|
+
}
|
|
1728
2269
|
// Clear loading state and reset tracking variables
|
|
1729
2270
|
this.isLoadingComponent = false;
|
|
1730
2271
|
this.currentNodeId = null;
|
|
@@ -1745,6 +2286,9 @@ class AXPWidgetDesignerRendererDirective {
|
|
|
1745
2286
|
// this.isLoadingComponent = false;
|
|
1746
2287
|
// return;
|
|
1747
2288
|
// }
|
|
2289
|
+
if (this.instance && this.node()) {
|
|
2290
|
+
this.service.unregister(this.node());
|
|
2291
|
+
}
|
|
1748
2292
|
this.viewContainerRef.clear();
|
|
1749
2293
|
this.isLoading.set(true);
|
|
1750
2294
|
this.currentNodeId = nodeId;
|
|
@@ -1774,7 +2318,13 @@ class AXPWidgetDesignerRendererDirective {
|
|
|
1774
2318
|
},
|
|
1775
2319
|
],
|
|
1776
2320
|
});
|
|
1777
|
-
|
|
2321
|
+
const loadComponent = this.config?.components[this.mode()]?.component ??
|
|
2322
|
+
this.config?.components['edit']?.component ??
|
|
2323
|
+
this.config?.components['view']?.component;
|
|
2324
|
+
const com = await loadComponent?.();
|
|
2325
|
+
if (!com) {
|
|
2326
|
+
throw new Error(`No designer/edit/view component registered for widget "${this.node().type}"`);
|
|
2327
|
+
}
|
|
1778
2328
|
this.instance = this.viewContainerRef.createComponent(com, { injector: token }).instance;
|
|
1779
2329
|
this.instance.locked = this.locked();
|
|
1780
2330
|
this.instance.parent = this.parentNode();
|
|
@@ -1848,9 +2398,28 @@ class AXPWidgetDesignerRendererDirective {
|
|
|
1848
2398
|
applySelectedStyle() {
|
|
1849
2399
|
if (this.locked())
|
|
1850
2400
|
return;
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
2401
|
+
const host = this.hostElement();
|
|
2402
|
+
if (!host) {
|
|
2403
|
+
return;
|
|
2404
|
+
}
|
|
2405
|
+
host.classList.add('axp-state-selected');
|
|
2406
|
+
if (!this.isHostFullyVisible(host)) {
|
|
2407
|
+
host.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
|
|
2408
|
+
}
|
|
2409
|
+
}
|
|
2410
|
+
isHostFullyVisible(host) {
|
|
2411
|
+
const canvas = host.closest('.axp-designer-canvas');
|
|
2412
|
+
const board = host.closest('.axp-designer-board');
|
|
2413
|
+
const container = canvas instanceof HTMLElement ? canvas : board instanceof HTMLElement ? board : host.parentElement;
|
|
2414
|
+
if (!container) {
|
|
2415
|
+
return true;
|
|
2416
|
+
}
|
|
2417
|
+
const hostRect = host.getBoundingClientRect();
|
|
2418
|
+
const containerRect = container.getBoundingClientRect();
|
|
2419
|
+
return (hostRect.top >= containerRect.top &&
|
|
2420
|
+
hostRect.bottom <= containerRect.bottom &&
|
|
2421
|
+
hostRect.left >= containerRect.left &&
|
|
2422
|
+
hostRect.right <= containerRect.right);
|
|
1854
2423
|
}
|
|
1855
2424
|
removeSelectedStyle() {
|
|
1856
2425
|
this.hostElement()?.classList.remove('axp-state-selected');
|
|
@@ -2003,6 +2572,24 @@ class AXPDesignerBoardComponent {
|
|
|
2003
2572
|
this.contextMenu?.refresh();
|
|
2004
2573
|
});
|
|
2005
2574
|
}
|
|
2575
|
+
handleBoardContextMenu(event) {
|
|
2576
|
+
const target = event.target;
|
|
2577
|
+
if (!(target instanceof Element)) {
|
|
2578
|
+
return;
|
|
2579
|
+
}
|
|
2580
|
+
const host = target.closest('.axp-widget-host');
|
|
2581
|
+
if (!(host instanceof HTMLElement)) {
|
|
2582
|
+
return;
|
|
2583
|
+
}
|
|
2584
|
+
const renderer = get(host, '__meta__.renderer');
|
|
2585
|
+
const instance = get(host, '__meta__.instance');
|
|
2586
|
+
if (!renderer || !instance) {
|
|
2587
|
+
return;
|
|
2588
|
+
}
|
|
2589
|
+
event.preventDefault();
|
|
2590
|
+
event.stopPropagation();
|
|
2591
|
+
this.contextMenu?.showAt({ x: event.clientX, y: event.clientY }, host);
|
|
2592
|
+
}
|
|
2006
2593
|
handleContextMenuOpening(e) {
|
|
2007
2594
|
const renderer = get(e.targetElement, '__meta__.renderer');
|
|
2008
2595
|
const instance = get(e.targetElement, '__meta__.instance');
|
|
@@ -2093,26 +2680,32 @@ class AXPDesignerBoardComponent {
|
|
|
2093
2680
|
const cls = {};
|
|
2094
2681
|
cls[`width`] = this.width();
|
|
2095
2682
|
cls[`max-width`] = '1280px';
|
|
2683
|
+
cls[`min-height`] = 'calc(100% - 5rem)';
|
|
2096
2684
|
return cls;
|
|
2097
2685
|
}
|
|
2098
2686
|
get __class() {
|
|
2099
2687
|
const cls = {};
|
|
2100
2688
|
cls[`axp-designer-board`] = true;
|
|
2101
2689
|
cls[`axp-state-design`] = true;
|
|
2102
|
-
cls['h-full'] = true;
|
|
2690
|
+
cls['min-h-full'] = true;
|
|
2691
|
+
cls['shrink-0'] = true;
|
|
2692
|
+
cls['self-start'] = true;
|
|
2103
2693
|
cls['overflow-auto'] = true;
|
|
2104
2694
|
cls[`axp-preview-${this.service.size()}`] = true;
|
|
2105
2695
|
return cls;
|
|
2106
2696
|
}
|
|
2107
2697
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPDesignerBoardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2108
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
2698
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPDesignerBoardComponent, isStandalone: true, selector: "axp-designer-board", host: { listeners: { "contextmenu": "handleBoardContextMenu($event)" }, properties: { "style": "this.__style", "class": "this.__class" } }, viewQueries: [{ propertyName: "contextMenu", first: true, predicate: ["contextMenu"], descendants: true }], ngImport: i0, template: "<axp-widgets-container [context]=\"context\">\n <!-- ----- Remount the page when epoch changes; keep the document node identity ----- -->\n @for (epoch of [service.pageRenderEpoch()]; track epoch) {\n <ng-container axp-widget-designer-renderer [node]=\"service.currentPage()\" [mode]=\"'designer'\"></ng-container>\n }\n</axp-widgets-container>\n\n<!-- Opened from the board host contextmenu; [target] cannot bind hosts that render after the menu. -->\n<ax-context-menu\n class=\"ax-dark\"\n #contextMenu\n [orientation]=\"'vertical'\"\n [closeOn]=\"'leave'\"\n (onOpening)=\"handleContextMenuOpening($event)\"\n (onItemClick)=\"handleContextMenuItemClick($event)\"\n>\n</ax-context-menu>", dependencies: [{ kind: "ngmodule", type: AXPWidgetCoreModule }, { kind: "component", type: i1$3.AXPWidgetContainerComponent, selector: "axp-widgets-container", inputs: ["context", "functions"], outputs: ["onContextChanged"] }, { kind: "directive", type: AXPWidgetDesignerRendererDirective, selector: "[axp-widget-designer-renderer]", inputs: ["parentNode", "parentElement", "parentComponent", "index", "locked", "mode", "node"] }, { kind: "ngmodule", type: AXMenuModule }, { kind: "component", type: i2$2.AXContextMenuComponent, selector: "ax-context-menu", inputs: ["orientation", "openOn", "closeOn", "closeOnRouteChange", "items", "target"], outputs: ["onItemClick", "onOpening", "onClose"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
2109
2699
|
}
|
|
2110
2700
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPDesignerBoardComponent, decorators: [{
|
|
2111
2701
|
type: Component,
|
|
2112
|
-
args: [{ selector: 'axp-designer-board', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, imports: [AXPWidgetCoreModule, AXPWidgetDesignerRendererDirective, AXMenuModule], template: "<axp-widgets-container [context]=\"context\">\n <ng-container axp-widget-designer-renderer [node]=\"service.currentPage()\" [mode]=\"'designer'\"></ng-container>\n</axp-widgets-container>\n\n<ax-context-menu
|
|
2702
|
+
args: [{ selector: 'axp-designer-board', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, imports: [AXPWidgetCoreModule, AXPWidgetDesignerRendererDirective, AXMenuModule], template: "<axp-widgets-container [context]=\"context\">\n <!-- ----- Remount the page when epoch changes; keep the document node identity ----- -->\n @for (epoch of [service.pageRenderEpoch()]; track epoch) {\n <ng-container axp-widget-designer-renderer [node]=\"service.currentPage()\" [mode]=\"'designer'\"></ng-container>\n }\n</axp-widgets-container>\n\n<!-- Opened from the board host contextmenu; [target] cannot bind hosts that render after the menu. -->\n<ax-context-menu\n class=\"ax-dark\"\n #contextMenu\n [orientation]=\"'vertical'\"\n [closeOn]=\"'leave'\"\n (onOpening)=\"handleContextMenuOpening($event)\"\n (onItemClick)=\"handleContextMenuItemClick($event)\"\n>\n</ax-context-menu>" }]
|
|
2113
2703
|
}], ctorParameters: () => [], propDecorators: { contextMenu: [{
|
|
2114
2704
|
type: ViewChild,
|
|
2115
2705
|
args: ['contextMenu']
|
|
2706
|
+
}], handleBoardContextMenu: [{
|
|
2707
|
+
type: HostListener,
|
|
2708
|
+
args: ['contextmenu', ['$event']]
|
|
2116
2709
|
}], __style: [{
|
|
2117
2710
|
type: HostBinding,
|
|
2118
2711
|
args: ['style']
|
|
@@ -2146,7 +2739,7 @@ class AXPDesignerBreadcrumbsComponent {
|
|
|
2146
2739
|
<i class="ax-icon ax-icon-chevron-right"></i>
|
|
2147
2740
|
</ng-template>
|
|
2148
2741
|
</ax-breadcrumbs>
|
|
2149
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type: AXPWidgetCoreModule }, { kind: "ngmodule", type: AXBreadcrumbsModule }, { kind: "component", type: i1$4.AXBreadCrumbsComponent, selector: "ax-breadcrumbs" }, { kind: "component", type: i1$4.AXBreadCrumbsItemComponent, selector: "ax-breadcrumbs-item", inputs: ["disabled", "active"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type:
|
|
2742
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: AXPWidgetCoreModule }, { kind: "ngmodule", type: AXBreadcrumbsModule }, { kind: "component", type: i1$4.AXBreadCrumbsComponent, selector: "ax-breadcrumbs" }, { kind: "component", type: i1$4.AXBreadCrumbsItemComponent, selector: "ax-breadcrumbs-item", inputs: ["disabled", "active"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i4.AXTranslatorPipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
2150
2743
|
}
|
|
2151
2744
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPDesignerBreadcrumbsComponent, decorators: [{
|
|
2152
2745
|
type: Component,
|
|
@@ -2174,73 +2767,66 @@ class AXPLayoutDesignerDrawerContentComponent {
|
|
|
2174
2767
|
constructor() { }
|
|
2175
2768
|
ngOnInit() { }
|
|
2176
2769
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPLayoutDesignerDrawerContentComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2177
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.8", type: AXPLayoutDesignerDrawerContentComponent, isStandalone: true, selector: "axp-designer-drawer-content", ngImport: i0, template: "<div class=\"flex flex-col border-e w-72 h-full\">\n <div class=\"flex flex-row w-full justify-between p-2 border-b\">\n <div class=\"flex flex-row gap-2 items-center font-semibold\">\n <ng-content select=\"ax-title\"></ng-content>\n </div>\n <div class=\"flex gap-1 items-center\">\n <ng-content select=\"ax-content[header]\">\n </ng-content>\n <ax-close-button></ax-close-button>\n </div>\n </div>\n <div class=\"flex-1 h-full overflow-auto\">\n <ng-content select=\"ax-content[body]\">\n\n </ng-content>\n </div>\n</div>", dependencies: [{ kind: "ngmodule", type:
|
|
2770
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.8", type: AXPLayoutDesignerDrawerContentComponent, isStandalone: true, selector: "axp-designer-drawer-content", ngImport: i0, template: "<div class=\"flex flex-col border-e w-72 h-full\">\n <div class=\"flex flex-row w-full justify-between p-2 border-b\">\n <div class=\"flex flex-row gap-2 items-center font-semibold\">\n <ng-content select=\"ax-title\"></ng-content>\n </div>\n <div class=\"flex gap-1 items-center\">\n <ng-content select=\"ax-content[header]\">\n </ng-content>\n <ax-close-button class=\"ax-sm\"></ax-close-button>\n </div>\n </div>\n <div class=\"flex-1 h-full overflow-auto\">\n <ng-content select=\"ax-content[body]\">\n\n </ng-content>\n </div>\n</div>", dependencies: [{ kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i2.AXDecoratorCloseButtonComponent, selector: "ax-close-button", inputs: ["closeAll", "icon"] }, { kind: "ngmodule", type: AXDecoratorModule }], changeDetection: i0.ChangeDetectionStrategy.Eager }); }
|
|
2178
2771
|
}
|
|
2179
2772
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPLayoutDesignerDrawerContentComponent, decorators: [{
|
|
2180
2773
|
type: Component,
|
|
2181
|
-
args: [{ imports: [AXDecoratorModule], selector: 'axp-designer-drawer-content', changeDetection: ChangeDetectionStrategy.Eager, template: "<div class=\"flex flex-col border-e w-72 h-full\">\n <div class=\"flex flex-row w-full justify-between p-2 border-b\">\n <div class=\"flex flex-row gap-2 items-center font-semibold\">\n <ng-content select=\"ax-title\"></ng-content>\n </div>\n <div class=\"flex gap-1 items-center\">\n <ng-content select=\"ax-content[header]\">\n </ng-content>\n <ax-close-button></ax-close-button>\n </div>\n </div>\n <div class=\"flex-1 h-full overflow-auto\">\n <ng-content select=\"ax-content[body]\">\n\n </ng-content>\n </div>\n</div>" }]
|
|
2774
|
+
args: [{ imports: [AXButtonModule, AXDecoratorModule], selector: 'axp-designer-drawer-content', changeDetection: ChangeDetectionStrategy.Eager, template: "<div class=\"flex flex-col border-e w-72 h-full\">\n <div class=\"flex flex-row w-full justify-between p-2 border-b\">\n <div class=\"flex flex-row gap-2 items-center font-semibold\">\n <ng-content select=\"ax-title\"></ng-content>\n </div>\n <div class=\"flex gap-1 items-center\">\n <ng-content select=\"ax-content[header]\">\n </ng-content>\n <ax-close-button class=\"ax-sm\"></ax-close-button>\n </div>\n </div>\n <div class=\"flex-1 h-full overflow-auto\">\n <ng-content select=\"ax-content[body]\">\n\n </ng-content>\n </div>\n</div>" }]
|
|
2182
2775
|
}], ctorParameters: () => [] });
|
|
2183
2776
|
|
|
2184
|
-
|
|
2777
|
+
//#region ----- Imports -----
|
|
2778
|
+
//#endregion
|
|
2779
|
+
//#region ----- Component -----
|
|
2185
2780
|
class AXPDesignerDataSourcesComponent {
|
|
2186
2781
|
constructor() {
|
|
2187
|
-
|
|
2188
|
-
this.
|
|
2189
|
-
this.
|
|
2190
|
-
this.list = signal([], /* @ts-ignore */
|
|
2191
|
-
...(ngDevMode ? [{ debugName: "list" }] : /* istanbul ignore next */ []));
|
|
2782
|
+
//#region ----- Services & Dependencies -----
|
|
2783
|
+
this.store = inject(AXP_LOCAL_DATA_SOURCE_STORE);
|
|
2784
|
+
this.listDialog = inject(AXPLocalDataSourceEditorDialogService);
|
|
2192
2785
|
}
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
take: 5000,
|
|
2198
|
-
});
|
|
2199
|
-
const page = runtimeQueryCollectionData(result);
|
|
2200
|
-
const items = (page?.items ?? []).map((c) => {
|
|
2201
|
-
const row = c;
|
|
2202
|
-
return { name: row.name, title: row.title };
|
|
2203
|
-
});
|
|
2204
|
-
this.list.set(items);
|
|
2205
|
-
}
|
|
2206
|
-
catch {
|
|
2207
|
-
this.list.set([]);
|
|
2208
|
-
}
|
|
2786
|
+
//#endregion
|
|
2787
|
+
//#region ----- Event Handlers -----
|
|
2788
|
+
handleAddClick() {
|
|
2789
|
+
void this.openListDialog();
|
|
2209
2790
|
}
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
size: 'lg',
|
|
2226
|
-
},
|
|
2227
|
-
},
|
|
2228
|
-
metadata: {
|
|
2229
|
-
formBuilder: true,
|
|
2230
|
-
},
|
|
2791
|
+
handleEdit(id) {
|
|
2792
|
+
void this.openListDialog(id);
|
|
2793
|
+
}
|
|
2794
|
+
handleRemove(id) {
|
|
2795
|
+
this.store.remove(id);
|
|
2796
|
+
}
|
|
2797
|
+
//#endregion
|
|
2798
|
+
//#region ----- Private -----
|
|
2799
|
+
async openListDialog(id) {
|
|
2800
|
+
const existing = id ? this.store.get(id) : undefined;
|
|
2801
|
+
const form = await this.listDialog.open({
|
|
2802
|
+
mode: existing ? 'edit' : 'create',
|
|
2803
|
+
name: existing?.name,
|
|
2804
|
+
columns: existing?.columns,
|
|
2805
|
+
items: existing?.items,
|
|
2231
2806
|
});
|
|
2807
|
+
if (!form) {
|
|
2808
|
+
return;
|
|
2809
|
+
}
|
|
2810
|
+
if (existing && id) {
|
|
2811
|
+
this.store.update(id, { name: form.name, items: form.items, columns: form.columns });
|
|
2812
|
+
return;
|
|
2813
|
+
}
|
|
2814
|
+
const created = this.store.create(form.name);
|
|
2815
|
+
this.store.update(created.id, { items: form.items, columns: form.columns });
|
|
2232
2816
|
}
|
|
2233
2817
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPDesignerDataSourcesComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2234
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPDesignerDataSourcesComponent, isStandalone: true, selector: "axp-designer-data-sources", ngImport: i0, template: "<axp-designer-drawer-content>\n <ax-title>
|
|
2818
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPDesignerDataSourcesComponent, isStandalone: true, selector: "axp-designer-data-sources", ngImport: i0, template: "<axp-designer-drawer-content>\n <ax-title>{{ '@layout-designer:components.data-sources.title' | translate | async }}</ax-title>\n\n <ax-content header>\n <ax-button\n look=\"blank\"\n class=\"ax-sm\"\n [title]=\"('@layout-designer:components.data-sources.add' | translate | async) ?? ''\"\n (onClick)=\"handleAddClick()\"\n >\n <ax-icon class=\"fa-light fa-plus\"></ax-icon>\n </ax-button>\n </ax-content>\n\n <ax-content body>\n @if (store.sources().length) {\n <!-- ----- Form-local named lists ----- -->\n <ul class=\"axp-designer-drawer-list\">\n @for (item of store.sources(); track item.id) {\n <li class=\"flex items-center gap-1\">\n <i class=\"me-1 fa-solid fa-table\"></i>\n <span class=\"flex-1 truncate\">{{ item.name || ('@layout-designer:components.data-sources.untitled' | translate | async) }}</span>\n <ax-button\n look=\"blank\"\n class=\"ax-sm\"\n [title]=\"('@general:actions.edit.title' | translate | async) ?? ''\"\n (onClick)=\"handleEdit(item.id)\"\n >\n <ax-icon class=\"fa-light fa-pen\"></ax-icon>\n </ax-button>\n <ax-button\n look=\"blank\"\n class=\"ax-sm\"\n [title]=\"('@layout-designer:components.data-sources.delete' | translate | async) ?? ''\"\n (onClick)=\"handleRemove(item.id)\"\n >\n <ax-icon class=\"fa-light fa-trash\"></ax-icon>\n </ax-button>\n </li>\n }\n </ul>\n }\n <!-- ----- Empty local bag ----- -->\n @else {\n <axp-state-message\n icon=\"fa-light fa-database\"\n [title]=\"'@layout-designer:components.data-sources.empty-states.no-data-sources.title'\"\n [description]=\"'@layout-designer:components.data-sources.empty-states.no-data-sources.description'\"\n >\n </axp-state-message>\n }\n </ax-content>\n</axp-designer-drawer-content>\n", dependencies: [{ kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i2.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type: AXPLayoutDesignerDrawerContentComponent, selector: "axp-designer-drawer-content" }, { kind: "component", type: AXPStateMessageComponent, selector: "axp-state-message", inputs: ["mode", "icon", "title", "description", "titleParams", "descriptionParams", "look"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: i4.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
2235
2819
|
}
|
|
2236
2820
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPDesignerDataSourcesComponent, decorators: [{
|
|
2237
2821
|
type: Component,
|
|
2238
2822
|
args: [{ selector: 'axp-designer-data-sources', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
2823
|
+
AsyncPipe,
|
|
2239
2824
|
AXDecoratorModule,
|
|
2240
2825
|
AXButtonModule,
|
|
2826
|
+
AXTranslationModule,
|
|
2241
2827
|
AXPLayoutDesignerDrawerContentComponent,
|
|
2242
|
-
AXPStateMessageComponent
|
|
2243
|
-
], template: "<axp-designer-drawer-content>\n <ax-title>
|
|
2828
|
+
AXPStateMessageComponent,
|
|
2829
|
+
], template: "<axp-designer-drawer-content>\n <ax-title>{{ '@layout-designer:components.data-sources.title' | translate | async }}</ax-title>\n\n <ax-content header>\n <ax-button\n look=\"blank\"\n class=\"ax-sm\"\n [title]=\"('@layout-designer:components.data-sources.add' | translate | async) ?? ''\"\n (onClick)=\"handleAddClick()\"\n >\n <ax-icon class=\"fa-light fa-plus\"></ax-icon>\n </ax-button>\n </ax-content>\n\n <ax-content body>\n @if (store.sources().length) {\n <!-- ----- Form-local named lists ----- -->\n <ul class=\"axp-designer-drawer-list\">\n @for (item of store.sources(); track item.id) {\n <li class=\"flex items-center gap-1\">\n <i class=\"me-1 fa-solid fa-table\"></i>\n <span class=\"flex-1 truncate\">{{ item.name || ('@layout-designer:components.data-sources.untitled' | translate | async) }}</span>\n <ax-button\n look=\"blank\"\n class=\"ax-sm\"\n [title]=\"('@general:actions.edit.title' | translate | async) ?? ''\"\n (onClick)=\"handleEdit(item.id)\"\n >\n <ax-icon class=\"fa-light fa-pen\"></ax-icon>\n </ax-button>\n <ax-button\n look=\"blank\"\n class=\"ax-sm\"\n [title]=\"('@layout-designer:components.data-sources.delete' | translate | async) ?? ''\"\n (onClick)=\"handleRemove(item.id)\"\n >\n <ax-icon class=\"fa-light fa-trash\"></ax-icon>\n </ax-button>\n </li>\n }\n </ul>\n }\n <!-- ----- Empty local bag ----- -->\n @else {\n <axp-state-message\n icon=\"fa-light fa-database\"\n [title]=\"'@layout-designer:components.data-sources.empty-states.no-data-sources.title'\"\n [description]=\"'@layout-designer:components.data-sources.empty-states.no-data-sources.description'\"\n >\n </axp-state-message>\n }\n </ax-content>\n</axp-designer-drawer-content>\n" }]
|
|
2244
2830
|
}] });
|
|
2245
2831
|
|
|
2246
2832
|
class AXPDesignerHistoryComponent {
|
|
@@ -2248,7 +2834,7 @@ class AXPDesignerHistoryComponent {
|
|
|
2248
2834
|
this.service = inject(AXPDesignerService);
|
|
2249
2835
|
}
|
|
2250
2836
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPDesignerHistoryComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2251
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPDesignerHistoryComponent, isStandalone: true, selector: "axp-designer-history", ngImport: i0, template: "<axp-designer-drawer-content>\n <ax-title>History</ax-title>\n\n <ax-content header>\n <ax-button look=\"blank\" class=\"ax-sm\">\n <ax-icon class=\"fa-light fa-ellipsis\"></ax-icon>\n <ax-dropdown-panel class=\"ax-sm\">\n <ax-button-item-list>\n <ax-button-item text=\"Clear\" name=\"add\" (onClick)=\"service.clearHistory()\"> </ax-button-item>\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-button>\n </ax-content>\n\n <ax-content body>\n @if (service.history().length) {\n <ul class=\"axp-designer-drawer-list\">\n @for (step of service.history(); track $index) {\n <li\n (click)=\"service.navigateTo($index)\"\n [class.italic]=\"step.isFuture\"\n [class.text-neutral-400]=\"step.isFuture\"\n [class.state-selected]=\"step.isCurrent\"\n >\n <i class=\"me-1\" [ngClass]=\"step.icon\"></i>\n {{ step.description }}\n </li>\n }\n </ul>\n } @else {\n <axp-state-message\n icon=\"fa-light fa-history\"\n [title]=\"'@layout-designer:components.history.empty-states.no-changes.title'\"\n [description]=\"'@layout-designer:components.history.empty-states.no-changes.description'\"\n >\n </axp-state-message>\n }\n </ax-content>\n</axp-designer-drawer-content>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i2.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "component", type: i2.AXButtonItemComponent, selector: "ax-button-item", inputs: ["color", "disabled", "text", "selected", "divided", "data", "name"], outputs: ["onClick", "onFocus", "onBlur", "disabledChange"] }, { kind: "component", type: i2.AXButtonItemListComponent, selector: "ax-button-item-list", inputs: ["items", "closeParentOnClick", "lockOnLoading"], outputs: ["onItemClick"] }, { kind: "ngmodule", type: AXDropdownModule }, { kind: "component", type: i4.AXDropdownPanelComponent, selector: "ax-dropdown-panel", inputs: ["isOpen", "fitParent", "dropdownWidth", "position", "placement", "_target", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "component", type: AXPLayoutDesignerDrawerContentComponent, selector: "axp-designer-drawer-content" }, { kind: "component", type: AXPStateMessageComponent, selector: "axp-state-message", inputs: ["mode", "icon", "title", "description", "titleParams", "descriptionParams", "look"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
2837
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPDesignerHistoryComponent, isStandalone: true, selector: "axp-designer-history", ngImport: i0, template: "<axp-designer-drawer-content>\n <ax-title>History</ax-title>\n\n <ax-content header>\n <ax-button look=\"blank\" class=\"ax-sm\">\n <ax-icon class=\"fa-light fa-ellipsis\"></ax-icon>\n <ax-dropdown-panel class=\"ax-sm\">\n <ax-button-item-list>\n <ax-button-item text=\"Clear\" name=\"add\" (onClick)=\"service.clearHistory()\"> </ax-button-item>\n </ax-button-item-list>\n </ax-dropdown-panel>\n </ax-button>\n </ax-content>\n\n <ax-content body>\n @if (service.history().length) {\n <ul class=\"axp-designer-drawer-list\">\n @for (step of service.history(); track $index) {\n <li\n (click)=\"service.navigateTo($index)\"\n [class.italic]=\"step.isFuture\"\n [class.text-neutral-400]=\"step.isFuture\"\n [class.state-selected]=\"step.isCurrent\"\n >\n <i class=\"me-1\" [ngClass]=\"step.icon\"></i>\n {{ step.description }}\n </li>\n }\n </ul>\n } @else {\n <axp-state-message\n icon=\"fa-light fa-history\"\n [title]=\"'@layout-designer:components.history.empty-states.no-changes.title'\"\n [description]=\"'@layout-designer:components.history.empty-states.no-changes.description'\"\n >\n </axp-state-message>\n }\n </ax-content>\n</axp-designer-drawer-content>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i2.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "component", type: i2.AXButtonItemComponent, selector: "ax-button-item", inputs: ["color", "disabled", "text", "selected", "divided", "data", "name"], outputs: ["onClick", "onFocus", "onBlur", "disabledChange"] }, { kind: "component", type: i2.AXButtonItemListComponent, selector: "ax-button-item-list", inputs: ["items", "closeParentOnClick", "lockOnLoading"], outputs: ["onItemClick"] }, { kind: "ngmodule", type: AXDropdownModule }, { kind: "component", type: i4$1.AXDropdownPanelComponent, selector: "ax-dropdown-panel", inputs: ["isOpen", "fitParent", "dropdownWidth", "position", "placement", "_target", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "component", type: AXPLayoutDesignerDrawerContentComponent, selector: "axp-designer-drawer-content" }, { kind: "component", type: AXPStateMessageComponent, selector: "axp-state-message", inputs: ["mode", "icon", "title", "description", "titleParams", "descriptionParams", "look"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
2252
2838
|
}
|
|
2253
2839
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPDesignerHistoryComponent, decorators: [{
|
|
2254
2840
|
type: Component,
|
|
@@ -2263,8 +2849,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
2263
2849
|
}] });
|
|
2264
2850
|
|
|
2265
2851
|
class AXPDesignerOutlineComponent {
|
|
2852
|
+
//#endregion
|
|
2853
|
+
//#region ----- Lifecycle -----
|
|
2266
2854
|
constructor() {
|
|
2855
|
+
//#region ----- Services & Dependencies -----
|
|
2267
2856
|
this.service = inject(AXPDesignerService);
|
|
2857
|
+
this.contextMenu = viewChild('outlineContextMenu', /* @ts-ignore */
|
|
2858
|
+
...(ngDevMode ? [{ debugName: "contextMenu" }] : /* istanbul ignore next */ []));
|
|
2859
|
+
//#endregion
|
|
2860
|
+
//#region ----- State Signals -----
|
|
2268
2861
|
this.collapsedStates = new Map();
|
|
2269
2862
|
this.root = signal(this.getTree(), /* @ts-ignore */
|
|
2270
2863
|
...(ngDevMode ? [{ debugName: "root" }] : /* istanbul ignore next */ []));
|
|
@@ -2272,6 +2865,8 @@ class AXPDesignerOutlineComponent {
|
|
|
2272
2865
|
this.root.update((c) => ({ ...this.getTree() }));
|
|
2273
2866
|
});
|
|
2274
2867
|
}
|
|
2868
|
+
//#endregion
|
|
2869
|
+
//#region ----- Tree -----
|
|
2275
2870
|
getTree() {
|
|
2276
2871
|
return {
|
|
2277
2872
|
type: AXPWidgetsCatalog.document,
|
|
@@ -2279,64 +2874,209 @@ class AXPDesignerOutlineComponent {
|
|
|
2279
2874
|
};
|
|
2280
2875
|
}
|
|
2281
2876
|
toggleCollapse(node) {
|
|
2282
|
-
// Toggle the current state or set to true if undefined
|
|
2283
2877
|
this.collapsedStates.set(node, !this.collapsedStates.get(node));
|
|
2284
2878
|
}
|
|
2285
2879
|
isCollapsed(node) {
|
|
2286
|
-
// Return the collapsed state, default is false (expanded)
|
|
2287
2880
|
return !!this.collapsedStates.get(node);
|
|
2288
2881
|
}
|
|
2289
2882
|
getConfig(node) {
|
|
2290
2883
|
return get(node, '__meta__.config');
|
|
2291
2884
|
}
|
|
2885
|
+
/** Solid, type-colored icon so outline rows stay scannable on a dark drawer. */
|
|
2886
|
+
getOutlineIconClass(config) {
|
|
2887
|
+
const icon = (config?.icon ?? 'fa-solid fa-cube')
|
|
2888
|
+
.replace(/\bfa-light\b/g, 'fa-solid')
|
|
2889
|
+
.replace(/\bfa-regular\b/g, 'fa-solid');
|
|
2890
|
+
return `${icon} ${this.getOutlineIconColor(config)}`;
|
|
2891
|
+
}
|
|
2892
|
+
getOutlineIconColor(config) {
|
|
2893
|
+
switch (config?.type) {
|
|
2894
|
+
case 'container':
|
|
2895
|
+
return 'text-primary';
|
|
2896
|
+
case 'editor':
|
|
2897
|
+
return 'text-success';
|
|
2898
|
+
case 'action':
|
|
2899
|
+
return 'text-warning';
|
|
2900
|
+
case 'view':
|
|
2901
|
+
return 'text-secondary';
|
|
2902
|
+
case 'filter':
|
|
2903
|
+
return 'text-primary';
|
|
2904
|
+
case 'validation':
|
|
2905
|
+
return 'text-danger';
|
|
2906
|
+
case 'dashboard':
|
|
2907
|
+
return 'text-warning';
|
|
2908
|
+
default:
|
|
2909
|
+
return 'text-primary';
|
|
2910
|
+
}
|
|
2911
|
+
}
|
|
2912
|
+
/** Caption, text-block content, or the widget type title. Type-slug names stay off this string. */
|
|
2913
|
+
getOutlineTitle(node) {
|
|
2914
|
+
return this.readOutlineCaption(node) ?? this.getConfig(node)?.title ?? node.type ?? '';
|
|
2915
|
+
}
|
|
2916
|
+
/** Plain captions render as-is. Type titles and multi-language captions go through translate. */
|
|
2917
|
+
usesOutlineTranslation(title) {
|
|
2918
|
+
return typeof title !== 'string' || title.startsWith('@');
|
|
2919
|
+
}
|
|
2920
|
+
outlinePlainTitle(title) {
|
|
2921
|
+
return typeof title === 'string' ? title : '';
|
|
2922
|
+
}
|
|
2923
|
+
/** Field names such as `txtlocation`. Generated slugs (`text-block-layout2`, `page`) stay off the row. */
|
|
2924
|
+
getOutlineNameSuffix(node) {
|
|
2925
|
+
const name = typeof node.name === 'string' ? node.name.trim() : '';
|
|
2926
|
+
if (!name || this.isGeneratedWidgetName(node.type, name)) {
|
|
2927
|
+
return '';
|
|
2928
|
+
}
|
|
2929
|
+
return ` : ${name}`;
|
|
2930
|
+
}
|
|
2931
|
+
/** Full row text, plus the generated name when the visible label hides it. */
|
|
2932
|
+
outlineTooltip(node, title, suffix) {
|
|
2933
|
+
const visible = `${title ?? ''}${suffix}`.trim();
|
|
2934
|
+
const name = typeof node.name === 'string' ? node.name.trim() : '';
|
|
2935
|
+
if (name && !visible.includes(name)) {
|
|
2936
|
+
return visible ? `${visible} (${name})` : name;
|
|
2937
|
+
}
|
|
2938
|
+
return visible;
|
|
2939
|
+
}
|
|
2940
|
+
readOutlineCaption(node) {
|
|
2941
|
+
const options = node.options;
|
|
2942
|
+
if (!options || typeof options !== 'object' || Array.isArray(options)) {
|
|
2943
|
+
return undefined;
|
|
2944
|
+
}
|
|
2945
|
+
const record = options;
|
|
2946
|
+
const caption = record['label'] ?? record['title'] ?? record['caption'] ?? record['text'];
|
|
2947
|
+
if (typeof caption === 'string' && caption.trim()) {
|
|
2948
|
+
return caption.trim();
|
|
2949
|
+
}
|
|
2950
|
+
if (caption && typeof caption === 'object' && !Array.isArray(caption)) {
|
|
2951
|
+
return caption;
|
|
2952
|
+
}
|
|
2953
|
+
if (node.type !== 'text-block-layout' || typeof record['content'] !== 'string') {
|
|
2954
|
+
return undefined;
|
|
2955
|
+
}
|
|
2956
|
+
const plain = this.stripOutlineHtml(record['content']).replace(/\s+/g, ' ').trim();
|
|
2957
|
+
return plain || undefined;
|
|
2958
|
+
}
|
|
2959
|
+
isGeneratedWidgetName(type, name) {
|
|
2960
|
+
const widgetType = (type ?? '').trim();
|
|
2961
|
+
if (this.matchesTypeSlug(name, widgetType)) {
|
|
2962
|
+
return true;
|
|
2963
|
+
}
|
|
2964
|
+
const shortType = widgetType.replace(/-layout$/, '');
|
|
2965
|
+
return shortType !== widgetType && this.matchesTypeSlug(name, shortType);
|
|
2966
|
+
}
|
|
2967
|
+
matchesTypeSlug(name, base) {
|
|
2968
|
+
if (!base) {
|
|
2969
|
+
return false;
|
|
2970
|
+
}
|
|
2971
|
+
if (name === base) {
|
|
2972
|
+
return true;
|
|
2973
|
+
}
|
|
2974
|
+
if (!name.startsWith(base)) {
|
|
2975
|
+
return false;
|
|
2976
|
+
}
|
|
2977
|
+
return /^[0-9]+$/.test(name.slice(base.length));
|
|
2978
|
+
}
|
|
2979
|
+
stripOutlineHtml(value) {
|
|
2980
|
+
return value
|
|
2981
|
+
.replace(/<br\s*\/?>/gi, ' ')
|
|
2982
|
+
.replace(/<[^>]+>/g, ' ')
|
|
2983
|
+
.replace(/ /gi, ' ')
|
|
2984
|
+
.replace(/&/gi, '&')
|
|
2985
|
+
.replace(/</gi, '<')
|
|
2986
|
+
.replace(/>/gi, '>');
|
|
2987
|
+
}
|
|
2988
|
+
//#endregion
|
|
2989
|
+
//#region ----- Event Handlers -----
|
|
2292
2990
|
handleClick(e, node) {
|
|
2293
2991
|
e.stopPropagation();
|
|
2294
2992
|
this.service.select({ widget: node });
|
|
2295
2993
|
}
|
|
2296
2994
|
handleToggleClick(event, item) {
|
|
2297
|
-
event.stopPropagation();
|
|
2995
|
+
event.stopPropagation();
|
|
2298
2996
|
this.toggleCollapse(item);
|
|
2299
2997
|
}
|
|
2300
2998
|
handleMouseOver(e, node) {
|
|
2301
2999
|
e.stopPropagation();
|
|
2302
3000
|
this.service.focus({ widget: node });
|
|
2303
3001
|
}
|
|
3002
|
+
handleContextMenu(event, node) {
|
|
3003
|
+
event.preventDefault();
|
|
3004
|
+
event.stopPropagation();
|
|
3005
|
+
this.service.select({ widget: node });
|
|
3006
|
+
const menu = this.contextMenu();
|
|
3007
|
+
if (!menu) {
|
|
3008
|
+
return;
|
|
3009
|
+
}
|
|
3010
|
+
const instance = this.service.getWidgetInstance(node);
|
|
3011
|
+
const items = this.service.getContextMenuItemsForNode(node, true);
|
|
3012
|
+
this.bindMenuData(items, instance, node);
|
|
3013
|
+
const targetElement = event.currentTarget instanceof HTMLElement ? event.currentTarget : undefined;
|
|
3014
|
+
menu.showAt({ x: event.clientX, y: event.clientY }, targetElement, {
|
|
3015
|
+
sender: menu,
|
|
3016
|
+
canceled: false,
|
|
3017
|
+
targetElement,
|
|
3018
|
+
items,
|
|
3019
|
+
});
|
|
3020
|
+
}
|
|
3021
|
+
async handleContextMenuItemClick(e) {
|
|
3022
|
+
if (e.item.name) {
|
|
3023
|
+
const instance = get(e.item.data, 'instance');
|
|
3024
|
+
const node = get(e.item.data, 'node');
|
|
3025
|
+
await this.service.executeCommand({ instance, node, name: e.item.name });
|
|
3026
|
+
}
|
|
3027
|
+
}
|
|
3028
|
+
//#endregion
|
|
3029
|
+
//#region ----- Context Menu -----
|
|
3030
|
+
bindMenuData(items, instance, node) {
|
|
3031
|
+
items.forEach((item) => {
|
|
3032
|
+
item.data = { ...(item.data ?? {}), instance, node };
|
|
3033
|
+
if (item.items) {
|
|
3034
|
+
this.bindMenuData(item.items, instance, node);
|
|
3035
|
+
}
|
|
3036
|
+
});
|
|
3037
|
+
}
|
|
2304
3038
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPDesignerOutlineComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2305
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPDesignerOutlineComponent, isStandalone: true, selector: "axp-designer-outline", ngImport: i0, template: "<axp-designer-drawer-content>\n <ax-title>
|
|
3039
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPDesignerOutlineComponent, isStandalone: true, selector: "axp-designer-outline", viewQueries: [{ propertyName: "contextMenu", first: true, predicate: ["outlineContextMenu"], descendants: true, isSignal: true }], ngImport: i0, template: "<axp-designer-drawer-content>\n <ax-title>{{ '@layout-designer:components.outline.title' | translate | async }}</ax-title>\n\n <ax-content body>\n @if (root().children?.length) {\n <!-- ----- Outline tree of the current page ----- -->\n <ul class=\"space-y-1 p-1 text-sm\">\n @for (node of root().children; track $index) {\n <ng-container [ngTemplateOutlet]=\"sideMenu\" [ngTemplateOutletContext]=\"{ $implicit: node }\"></ng-container>\n }\n </ul>\n <ng-template #sideMenu let-item>\n <li (click)=\"handleClick($event, item)\" (mouseover)=\"handleMouseOver($event, item)\">\n <div [class.darker-surface]=\"item === service.selectedNode()\" class=\"flex flex-row items-center gap-1 cursor-pointer transition duration-150 ease-in-out hover:dark-surface py-1 px-2 rounded-sm\" (contextmenu)=\"handleContextMenu($event, item)\">\n <span class=\"w-3 shrink-0 flex items-center justify-center\">\n <!--->\n <!-- ----- Collapse / expand when this node has children ----- -->\n @if (item.children?.length) {\n <i class=\"fa-solid fa-xs opacity-60\" [class.fa-chevron-right]=\"isCollapsed(item)\" (click)=\"handleToggleClick($event, item)\" [class.fa-chevron-down]=\"!isCollapsed(item)\"></i>\n }\n </span>\n @let config = getConfig(item);\n <span class=\"w-4 shrink-0 flex items-center justify-center\">\n <!--->\n <!-- ----- Widget icon from config, colored by widget type ----- -->\n @if (config?.icon) {\n <i [ngClass]=\"getOutlineIconClass(config)\"></i>\n }\n </span>\n @let title = getOutlineTitle(item);\n @let suffix = getOutlineNameSuffix(item);\n <!--------------------------------------------------------------->\n <!-- ----- Translate type titles; plain captions and text-block content stay as stored ----- -->\n @if (usesOutlineTranslation(title)) {\n @let translated = (title | translate | async) ?? '';\n <span class=\"truncate flex-1 pe-2\" [attr.title]=\"outlineTooltip(item, translated, suffix)\">{{ translated }}{{ suffix }}</span>\n }\n <!-- ----- Plain caption or stripped text-block content ----- -->\n @else {\n <span class=\"truncate flex-1 pe-2\" [attr.title]=\"outlineTooltip(item, outlinePlainTitle(title), suffix)\">{{ outlinePlainTitle(title) }}{{ suffix }}</span>\n }\n </div>\n <!--->\n <!-- ----- Nested outline children ----- -->\n @if (item.children?.length && !isCollapsed(item)) {\n <ul class=\"space-y-1 ps-3 text-sm\">\n @for (child of item.children; track child) {\n <ng-container [ngTemplateOutlet]=\"sideMenu\" [ngTemplateOutletContext]=\"{ $implicit: child }\"></ng-container>\n }\n </ul>\n }\n </li>\n </ng-template>\n }\n <!-- ----- Empty outline when the page has no widgets ----- -->\n @else {\n <axp-state-message icon=\"fa-light fa-shapes\" [title]=\"'@layout-designer:components.outline.empty-states.no-widgets.title'\" [description]=\"'@layout-designer:components.outline.empty-states.no-widgets.description'\"></axp-state-message>\n }\n </ax-content>\n</axp-designer-drawer-content>\n\n<!-- Opened from each outline row; same commands as the canvas widget menu. -->\n<ax-context-menu class=\"ax-dark\" #outlineContextMenu [orientation]=\"'vertical'\" [closeOn]=\"'leave'\" (onItemClick)=\"handleContextMenuItemClick($event)\"></ax-context-menu>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i1.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: AXMenuModule }, { kind: "component", type: i2$2.AXContextMenuComponent, selector: "ax-context-menu", inputs: ["orientation", "openOn", "closeOn", "closeOnRouteChange", "items", "target"], outputs: ["onItemClick", "onOpening", "onClose"] }, { kind: "component", type: AXPLayoutDesignerDrawerContentComponent, selector: "axp-designer-drawer-content" }, { kind: "component", type: AXPStateMessageComponent, selector: "axp-state-message", inputs: ["mode", "icon", "title", "description", "titleParams", "descriptionParams", "look"] }, { kind: "pipe", type: i1$2.AsyncPipe, name: "async" }, { kind: "pipe", type: i4.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
2306
3040
|
}
|
|
2307
3041
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPDesignerOutlineComponent, decorators: [{
|
|
2308
3042
|
type: Component,
|
|
2309
3043
|
args: [{ selector: 'axp-designer-outline', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
2310
3044
|
CommonModule,
|
|
2311
3045
|
AXDecoratorModule,
|
|
3046
|
+
AXTranslationModule,
|
|
3047
|
+
AXMenuModule,
|
|
2312
3048
|
AXPLayoutDesignerDrawerContentComponent,
|
|
2313
|
-
AXPStateMessageComponent
|
|
2314
|
-
], template: "<axp-designer-drawer-content>\n <ax-title>
|
|
2315
|
-
}], ctorParameters: () => [] });
|
|
3049
|
+
AXPStateMessageComponent,
|
|
3050
|
+
], template: "<axp-designer-drawer-content>\n <ax-title>{{ '@layout-designer:components.outline.title' | translate | async }}</ax-title>\n\n <ax-content body>\n @if (root().children?.length) {\n <!-- ----- Outline tree of the current page ----- -->\n <ul class=\"space-y-1 p-1 text-sm\">\n @for (node of root().children; track $index) {\n <ng-container [ngTemplateOutlet]=\"sideMenu\" [ngTemplateOutletContext]=\"{ $implicit: node }\"></ng-container>\n }\n </ul>\n <ng-template #sideMenu let-item>\n <li (click)=\"handleClick($event, item)\" (mouseover)=\"handleMouseOver($event, item)\">\n <div [class.darker-surface]=\"item === service.selectedNode()\" class=\"flex flex-row items-center gap-1 cursor-pointer transition duration-150 ease-in-out hover:dark-surface py-1 px-2 rounded-sm\" (contextmenu)=\"handleContextMenu($event, item)\">\n <span class=\"w-3 shrink-0 flex items-center justify-center\">\n <!--->\n <!-- ----- Collapse / expand when this node has children ----- -->\n @if (item.children?.length) {\n <i class=\"fa-solid fa-xs opacity-60\" [class.fa-chevron-right]=\"isCollapsed(item)\" (click)=\"handleToggleClick($event, item)\" [class.fa-chevron-down]=\"!isCollapsed(item)\"></i>\n }\n </span>\n @let config = getConfig(item);\n <span class=\"w-4 shrink-0 flex items-center justify-center\">\n <!--->\n <!-- ----- Widget icon from config, colored by widget type ----- -->\n @if (config?.icon) {\n <i [ngClass]=\"getOutlineIconClass(config)\"></i>\n }\n </span>\n @let title = getOutlineTitle(item);\n @let suffix = getOutlineNameSuffix(item);\n <!--------------------------------------------------------------->\n <!-- ----- Translate type titles; plain captions and text-block content stay as stored ----- -->\n @if (usesOutlineTranslation(title)) {\n @let translated = (title | translate | async) ?? '';\n <span class=\"truncate flex-1 pe-2\" [attr.title]=\"outlineTooltip(item, translated, suffix)\">{{ translated }}{{ suffix }}</span>\n }\n <!-- ----- Plain caption or stripped text-block content ----- -->\n @else {\n <span class=\"truncate flex-1 pe-2\" [attr.title]=\"outlineTooltip(item, outlinePlainTitle(title), suffix)\">{{ outlinePlainTitle(title) }}{{ suffix }}</span>\n }\n </div>\n <!--->\n <!-- ----- Nested outline children ----- -->\n @if (item.children?.length && !isCollapsed(item)) {\n <ul class=\"space-y-1 ps-3 text-sm\">\n @for (child of item.children; track child) {\n <ng-container [ngTemplateOutlet]=\"sideMenu\" [ngTemplateOutletContext]=\"{ $implicit: child }\"></ng-container>\n }\n </ul>\n }\n </li>\n </ng-template>\n }\n <!-- ----- Empty outline when the page has no widgets ----- -->\n @else {\n <axp-state-message icon=\"fa-light fa-shapes\" [title]=\"'@layout-designer:components.outline.empty-states.no-widgets.title'\" [description]=\"'@layout-designer:components.outline.empty-states.no-widgets.description'\"></axp-state-message>\n }\n </ax-content>\n</axp-designer-drawer-content>\n\n<!-- Opened from each outline row; same commands as the canvas widget menu. -->\n<ax-context-menu class=\"ax-dark\" #outlineContextMenu [orientation]=\"'vertical'\" [closeOn]=\"'leave'\" (onItemClick)=\"handleContextMenuItemClick($event)\"></ax-context-menu>\n" }]
|
|
3051
|
+
}], ctorParameters: () => [], propDecorators: { contextMenu: [{ type: i0.ViewChild, args: ['outlineContextMenu', { isSignal: true }] }] } });
|
|
2316
3052
|
|
|
2317
3053
|
class AXPDesignerPagesComponent {
|
|
2318
3054
|
constructor() {
|
|
2319
3055
|
this.service = inject(AXPDesignerService);
|
|
2320
3056
|
}
|
|
2321
3057
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPDesignerPagesComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2322
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPDesignerPagesComponent, isStandalone: true, selector: "axp-designer-pages", ngImport: i0, template: "<axp-designer-drawer-content
|
|
3058
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPDesignerPagesComponent, isStandalone: true, selector: "axp-designer-pages", ngImport: i0, template: "<axp-designer-drawer-content>\n <ax-title>{{ '@layout-designer:components.pages.title' | translate | async }}</ax-title>\n <ax-content header>\n <ax-button look=\"blank\" class=\"ax-sm\" (onClick)=\"service.addNewPage()\" [title]=\"'@layout-designer:components.pages.add' | translate | async\">\n <ax-icon class=\"fa-light fa-file-circle-plus\"></ax-icon>\n </ax-button>\n </ax-content>\n\n <ax-content body>\n @let count = service.document().children?.length ?? 0; @if(count) {\n <ul class=\"text-sm p-2 rounded ax-md space-y-1\">\n @for( page of service.document().children;track $index) {\n <li (click)=\"service.goToPage($index)\"\n class=\"cursor-pointer transition duration-150 ease-in-out hover:dark-surface py-1 px-2 rounded-sm group flex justify-between items-center\"\n [class.darker-surface]=\"$index == service.currentPageIndex()\">\n <div>\n <i class=\"fa-light fa-file me-1\"></i>\n {{ '@layout-designer:components.pages.page-n' | translate: { params: { n: $index + 1 } } | async }}\n </div>\n <div class=\"invisible group-hover:visible flex gap-2\">\n @if(count>1) {\n <i class=\"fa-light fa-trash hover:text-danger-500\" (click)=\"service.removePage($index)\"></i>\n }\n <i class=\"fa-light fa-clone hover:text-primary-500\" (click)=\"service.clonePage($index)\"></i>\n </div>\n </li>\n }\n </ul>\n } @else {\n <div class=\"axp-designer-drawer-empty\">{{ '@layout-designer:components.pages.empty' | translate | async }}</div>\n }\n </ax-content>\n</axp-designer-drawer-content>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXPWidgetCoreModule }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i2.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type: AXPLayoutDesignerDrawerContentComponent, selector: "axp-designer-drawer-content" }, { kind: "pipe", type: i1$2.AsyncPipe, name: "async" }, { kind: "pipe", type: i4.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
2323
3059
|
}
|
|
2324
3060
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPDesignerPagesComponent, decorators: [{
|
|
2325
3061
|
type: Component,
|
|
2326
3062
|
args: [{ selector: 'axp-designer-pages', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
3063
|
+
CommonModule,
|
|
2327
3064
|
AXPWidgetCoreModule,
|
|
2328
3065
|
AXDecoratorModule,
|
|
2329
3066
|
AXButtonModule,
|
|
3067
|
+
AXTranslationModule,
|
|
2330
3068
|
AXPLayoutDesignerDrawerContentComponent
|
|
2331
|
-
], template: "<axp-designer-drawer-content
|
|
3069
|
+
], template: "<axp-designer-drawer-content>\n <ax-title>{{ '@layout-designer:components.pages.title' | translate | async }}</ax-title>\n <ax-content header>\n <ax-button look=\"blank\" class=\"ax-sm\" (onClick)=\"service.addNewPage()\" [title]=\"'@layout-designer:components.pages.add' | translate | async\">\n <ax-icon class=\"fa-light fa-file-circle-plus\"></ax-icon>\n </ax-button>\n </ax-content>\n\n <ax-content body>\n @let count = service.document().children?.length ?? 0; @if(count) {\n <ul class=\"text-sm p-2 rounded ax-md space-y-1\">\n @for( page of service.document().children;track $index) {\n <li (click)=\"service.goToPage($index)\"\n class=\"cursor-pointer transition duration-150 ease-in-out hover:dark-surface py-1 px-2 rounded-sm group flex justify-between items-center\"\n [class.darker-surface]=\"$index == service.currentPageIndex()\">\n <div>\n <i class=\"fa-light fa-file me-1\"></i>\n {{ '@layout-designer:components.pages.page-n' | translate: { params: { n: $index + 1 } } | async }}\n </div>\n <div class=\"invisible group-hover:visible flex gap-2\">\n @if(count>1) {\n <i class=\"fa-light fa-trash hover:text-danger-500\" (click)=\"service.removePage($index)\"></i>\n }\n <i class=\"fa-light fa-clone hover:text-primary-500\" (click)=\"service.clonePage($index)\"></i>\n </div>\n </li>\n }\n </ul>\n } @else {\n <div class=\"axp-designer-drawer-empty\">{{ '@layout-designer:components.pages.empty' | translate | async }}</div>\n }\n </ax-content>\n</axp-designer-drawer-content>\n" }]
|
|
2332
3070
|
}] });
|
|
2333
3071
|
|
|
3072
|
+
//#region ---- Imports ----
|
|
3073
|
+
//#endregion
|
|
2334
3074
|
//#region ---- Hook keys ----
|
|
2335
3075
|
/**
|
|
2336
3076
|
* Distributed hooks for extending the layout designer header menu without coupling the designer library to feature modules.
|
|
2337
3077
|
*
|
|
2338
3078
|
* - {@link AXPLayoutDesignerHeaderMenuHookKeys.root}: top-level bar items (siblings of File, Edit, …).
|
|
2339
|
-
* - {@link AXPLayoutDesignerHeaderMenuHookKeys.submenu}: extra items inside a
|
|
3079
|
+
* - {@link AXPLayoutDesignerHeaderMenuHookKeys.submenu}: extra items inside a menu (`file`, `import`, `edit`, `run`, `help`).
|
|
2340
3080
|
*/
|
|
2341
3081
|
const AXPLayoutDesignerHeaderMenuHookKeys = {
|
|
2342
3082
|
root: 'layout-designer.header-menu.root',
|
|
@@ -2365,13 +3105,13 @@ class AXPDesignerHeaderMenuComponent {
|
|
|
2365
3105
|
this.registerDesignerKeyboardShortcuts();
|
|
2366
3106
|
}
|
|
2367
3107
|
async ngOnInit() {
|
|
2368
|
-
const rootPayload = await this.hooks.runAsync(AXPLayoutDesignerHeaderMenuHookKeys.root, { designer: this.service, items: [] });
|
|
3108
|
+
const rootPayload = await this.hooks.runAsync(AXPLayoutDesignerHeaderMenuHookKeys.root, { designer: this.service, owner: this.destroyRef, items: [] });
|
|
2369
3109
|
rootPayload.items.sort((a, b) => (a.priority ?? 0) - (b.priority ?? 0));
|
|
2370
3110
|
this.rootMenuContributions.set(await this.resolveMenuLabels(rootPayload.items));
|
|
2371
|
-
const parents = ['file', 'edit', 'run', 'help'];
|
|
3111
|
+
const parents = ['file', 'import', 'edit', 'run', 'help'];
|
|
2372
3112
|
const map = {};
|
|
2373
3113
|
for (const parentMenuId of parents) {
|
|
2374
|
-
const subPayload = await this.hooks.runAsync(AXPLayoutDesignerHeaderMenuHookKeys.submenu, { designer: this.service, parentMenuId, items: [] });
|
|
3114
|
+
const subPayload = await this.hooks.runAsync(AXPLayoutDesignerHeaderMenuHookKeys.submenu, { designer: this.service, owner: this.destroyRef, parentMenuId, items: [] });
|
|
2375
3115
|
subPayload.items.sort((a, b) => (a.priority ?? 0) - (b.priority ?? 0));
|
|
2376
3116
|
map[parentMenuId] = await this.resolveMenuLabels(subPayload.items);
|
|
2377
3117
|
}
|
|
@@ -2515,7 +3255,7 @@ class AXPDesignerHeaderMenuComponent {
|
|
|
2515
3255
|
when: () => this.service.canRedo(),
|
|
2516
3256
|
shortcuts: [
|
|
2517
3257
|
{
|
|
2518
|
-
keys: ['ctrl+y'],
|
|
3258
|
+
keys: ['ctrl+y', 'ctrl+shift+z'],
|
|
2519
3259
|
title: '@layout-designer:keyboard-shortcuts.redo',
|
|
2520
3260
|
group: '@layout-designer:keyboard-shortcuts.groups.edit',
|
|
2521
3261
|
handler: (event) => {
|
|
@@ -2585,11 +3325,11 @@ class AXPDesignerHeaderMenuComponent {
|
|
|
2585
3325
|
return event.target === document.body;
|
|
2586
3326
|
}
|
|
2587
3327
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPDesignerHeaderMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2588
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPDesignerHeaderMenuComponent, isStandalone: true, selector: "axp-designer-header-menu", ngImport: i0, template: "<ax-menu [openOn]=\"'hover'\" [hasArrow]=\"false\">\n <ax-menu-item>\n <ax-text>File</ax-text>\n <ax-menu-item (onClick)=\"service.new()\">\n <ax-text>New</ax-text>\n <ax-suffix>\n <ax-kbd look=\"blank\">\n <ax-kbd-item [keys]=\"shortcutKeys('shift+n')\"></ax-kbd-item>\n </ax-kbd>\n </ax-suffix>\n </ax-menu-item>\n <ax-divider></ax-divider>\n @if (service.canSave()) {\n <ng-container>\n <ax-menu-item (onClick)=\"service.save()\">\n <ax-text>Save</ax-text>\n <ax-suffix>\n <ax-kbd look=\"blank\">\n <ax-kbd-item [keys]=\"shortcutKeys('ctrl+s')\"></ax-kbd-item>\n </ax-kbd>\n </ax-suffix>\n </ax-menu-item>\n <ax-menu-item (onClick)=\"service.saveAs()\">\n <ax-text>Save As...</ax-text>\n <ax-suffix>\n <ax-kbd look=\"blank\">\n <ax-kbd-item [keys]=\"shortcutKeys('ctrl+shift+s')\"></ax-kbd-item>\n </ax-kbd>\n </ax-suffix>\n </ax-menu-item>\n <ax-divider></ax-divider>\n </ng-container>\n }\n <ax-menu-item>\n <ax-text>Export</ax-text>\n <ax-menu-item (onClick)=\"service.downloadJson()\">\n <ax-text>Download JSON</ax-text>\n </ax-menu-item>\n </ax-menu-item>\n <ax-menu-item>\n <ax-text>Import</ax-text>\n <ax-menu-item (onClick)=\"service.importJSon()\">\n <ax-text>Import JSON</ax-text>\n </ax-menu-item>\n </ax-menu-item>\n @for (item of submenuFor('file'); track item.id) {\n <ax-menu-item (onClick)=\"runMenuEntry(item)\">\n @if (item.iconClass) {\n <ax-prefix>\n <ax-icon>\n <i [class]=\"item.iconClass\"></i>\n </ax-icon>\n </ax-prefix>\n }\n @if (item.resolvedLabel) {\n <ax-text>{{ item.resolvedLabel }}</ax-text>\n }\n </ax-menu-item>\n }\n </ax-menu-item>\n <ax-menu-item>\n <ax-text>Edit</ax-text>\n <ax-menu-item [disabled]=\"!service.canUndo()\" (onClick)=\"service.undo()\">\n <ax-text>Undo</ax-text>\n <ax-prefix>\n <ax-icon>\n <i class=\"fa-solid fa-rotate-left\"></i>\n </ax-icon>\n </ax-prefix>\n <ax-suffix>\n <ax-kbd look=\"blank\">\n <ax-kbd-item [keys]=\"shortcutKeys('ctrl+z')\"></ax-kbd-item>\n </ax-kbd>\n </ax-suffix>\n </ax-menu-item>\n <ax-menu-item [disabled]=\"!service.canRedo()\" (onClick)=\"service.redo()\">\n <ax-text>Redo</ax-text>\n <ax-prefix>\n <ax-icon>\n <i class=\"fa-solid fa-rotate-right\"></i>\n </ax-icon>\n </ax-prefix>\n <ax-suffix>\n <ax-kbd look=\"blank\">\n <ax-kbd-item [keys]=\"shortcutKeys('ctrl+y')\"></ax-kbd-item>\n </ax-kbd>\n </ax-suffix>\n </ax-menu-item>\n <ax-divider></ax-divider>\n <ax-menu-item\n [disabled]=\"!service.canCutCopy()\"\n (onClick)=\"service.clone()\"\n >\n <ax-text>Clone</ax-text>\n <ax-prefix>\n <ax-icon>\n <i class=\"fa-solid fa-clone\"></i>\n </ax-icon>\n </ax-prefix>\n <ax-suffix>\n <ax-kbd look=\"blank\">\n <ax-kbd-item [keys]=\"shortcutKeys('ctrl+d')\"></ax-kbd-item>\n </ax-kbd>\n </ax-suffix>\n </ax-menu-item>\n <ax-menu-item [disabled]=\"!service.canCutCopy()\" (onClick)=\"service.cut()\">\n <ax-text>Cut</ax-text>\n <ax-prefix>\n <ax-icon>\n <i class=\"fa-solid fa-cut\"></i>\n </ax-icon>\n </ax-prefix>\n <ax-suffix>\n <ax-kbd look=\"blank\">\n <ax-kbd-item [keys]=\"shortcutKeys('ctrl+x')\"></ax-kbd-item>\n </ax-kbd>\n </ax-suffix>\n </ax-menu-item>\n <ax-menu-item [disabled]=\"!service.canCutCopy()\" (onClick)=\"service.copy()\">\n <ax-text>Copy</ax-text>\n <ax-prefix>\n <ax-icon>\n <i class=\"fa-solid fa-copy\"></i>\n </ax-icon>\n </ax-prefix>\n <ax-suffix>\n <ax-kbd look=\"blank\">\n <ax-kbd-item [keys]=\"shortcutKeys('ctrl+c')\"></ax-kbd-item>\n </ax-kbd>\n </ax-suffix>\n </ax-menu-item>\n <ax-menu-item [disabled]=\"!service.canPaste()\" (onClick)=\"service.paste()\">\n <ax-text>Paste</ax-text>\n <ax-prefix>\n <ax-icon>\n <i class=\"fa-solid fa-paste\"></i>\n </ax-icon>\n </ax-prefix>\n <ax-suffix>\n <ax-kbd look=\"blank\">\n <ax-kbd-item [keys]=\"shortcutKeys('ctrl+v')\"></ax-kbd-item>\n </ax-kbd>\n </ax-suffix>\n </ax-menu-item>\n <ax-divider></ax-divider>\n <ax-menu-item\n [disabled]=\"!service.canDelete()\"\n (onClick)=\"service.removeWidget()\"\n >\n <ax-text>Delete</ax-text>\n <ax-prefix>\n <ax-icon>\n <i class=\"fa-solid fa-trash\"></i>\n </ax-icon>\n </ax-prefix>\n <ax-suffix>\n <ax-kbd look=\"blank\">\n <ax-kbd-item [keys]=\"shortcutKeys('delete')\"></ax-kbd-item>\n </ax-kbd>\n </ax-suffix>\n </ax-menu-item>\n @for (item of submenuFor('edit'); track item.id) {\n <ax-menu-item (onClick)=\"runMenuEntry(item)\">\n @if (item.iconClass) {\n <ax-prefix>\n <ax-icon>\n <i [class]=\"item.iconClass\"></i>\n </ax-icon>\n </ax-prefix>\n }\n @if (item.resolvedLabel) {\n <ax-text>{{ item.resolvedLabel }}</ax-text>\n }\n </ax-menu-item>\n }\n </ax-menu-item>\n <ax-menu-item>\n <ax-text>Run</ax-text>\n <ax-menu-item (onClick)=\"service.openPreviewDialog()\">\n <ax-text>Preview</ax-text>\n <ax-prefix> </ax-prefix>\n <ax-suffix>\n <ax-kbd look=\"blank\">\n <ax-kbd-item [keys]=\"shortcutKeys('ctrl+r')\"></ax-kbd-item>\n </ax-kbd>\n </ax-suffix>\n </ax-menu-item>\n <ax-menu-item (onClick)=\"service.openPreviewWindow()\">\n <ax-text>Preview in seperate window</ax-text>\n <ax-prefix> </ax-prefix>\n <ax-suffix>\n <ax-kbd look=\"blank\">\n <ax-kbd-item [keys]=\"shortcutKeys('ctrl+shift+r')\"></ax-kbd-item>\n </ax-kbd>\n </ax-suffix>\n </ax-menu-item>\n @for (item of submenuFor('run'); track item.id) {\n <ax-menu-item (onClick)=\"runMenuEntry(item)\">\n @if (item.iconClass) {\n <ax-prefix>\n <ax-icon>\n <i [class]=\"item.iconClass\"></i>\n </ax-icon>\n </ax-prefix>\n }\n @if (item.resolvedLabel) {\n <ax-text>{{ item.resolvedLabel }}</ax-text>\n }\n </ax-menu-item>\n }\n </ax-menu-item>\n <ax-menu-item>\n <ax-text>Help</ax-text>\n <ax-menu-item>\n <ax-text>About</ax-text>\n </ax-menu-item>\n @for (item of submenuFor('help'); track item.id) {\n <ax-menu-item (onClick)=\"runMenuEntry(item)\">\n @if (item.iconClass) {\n <ax-prefix>\n <ax-icon>\n <i [class]=\"item.iconClass\"></i>\n </ax-icon>\n </ax-prefix>\n }\n @if (item.resolvedLabel) {\n <ax-text>{{ item.resolvedLabel }}</ax-text>\n }\n </ax-menu-item>\n }\n </ax-menu-item>\n @for (item of rootMenuContributions(); track item.id) {\n <ax-menu-item (onClick)=\"runMenuEntry(item)\">\n @if (item.iconClass) {\n <ax-prefix>\n <ax-icon>\n <i [class]=\"item.iconClass\"></i>\n </ax-icon>\n </ax-prefix>\n }\n @if (item.resolvedLabel) {\n <ax-text>{{ item.resolvedLabel }}</ax-text>\n }\n </ax-menu-item>\n }\n</ax-menu>\n", dependencies: [{ kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i1.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: "component", type: AXKBDComponent, selector: "ax-kbd", inputs: ["look"] }, { kind: "component", type: AXKBDItemComponent, selector: "ax-kbd-item", inputs: ["keys", "join", "look"], outputs: ["lookChange"] }, { kind: "ngmodule", type: AXMenuModule }, { kind: "component", type: i2$2.AXMenuItemComponent, selector: "ax-menu-item", inputs: ["subItems", "name", "data", "disabled", "color"], outputs: ["onClick"] }, { kind: "component", type: i2$2.AXMenuComponent, selector: "ax-menu", inputs: ["orientation", "openOn", "closeOn", "items", "hasArrow"], outputs: ["onItemClick"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
3328
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPDesignerHeaderMenuComponent, isStandalone: true, selector: "axp-designer-header-menu", ngImport: i0, template: "<ax-menu [openOn]=\"'hover'\" [hasArrow]=\"false\">\n <ax-menu-item>\n <ax-text>File</ax-text>\n <ax-menu-item (onClick)=\"service.new()\">\n <ax-text>New</ax-text>\n <ax-prefix>\n <ax-icon>\n <i class=\"fa-solid fa-file\"></i>\n </ax-icon>\n </ax-prefix>\n <ax-suffix>\n <ax-kbd look=\"blank\">\n <ax-kbd-item [keys]=\"shortcutKeys('shift+n')\"></ax-kbd-item>\n </ax-kbd>\n </ax-suffix>\n </ax-menu-item>\n <ax-divider></ax-divider>\n @if (service.canSave()) {\n <ng-container>\n <ax-menu-item (onClick)=\"service.save()\">\n <ax-text>Save</ax-text>\n <ax-prefix>\n <ax-icon>\n <i class=\"fa-solid fa-floppy-disk\"></i>\n </ax-icon>\n </ax-prefix>\n <ax-suffix>\n <ax-kbd look=\"blank\">\n <ax-kbd-item [keys]=\"shortcutKeys('ctrl+s')\"></ax-kbd-item>\n </ax-kbd>\n </ax-suffix>\n </ax-menu-item>\n <ax-menu-item (onClick)=\"service.saveAs()\">\n <ax-text>Save As...</ax-text>\n <ax-prefix>\n <ax-icon>\n <i class=\"fa-solid fa-file-pen\"></i>\n </ax-icon>\n </ax-prefix>\n <ax-suffix>\n <ax-kbd look=\"blank\">\n <ax-kbd-item [keys]=\"shortcutKeys('ctrl+shift+s')\"></ax-kbd-item>\n </ax-kbd>\n </ax-suffix>\n </ax-menu-item>\n <ax-divider></ax-divider>\n </ng-container>\n }\n <ax-menu-item>\n <ax-text>Export</ax-text>\n <ax-prefix>\n <ax-icon>\n <i class=\"fa-solid fa-file-export\"></i>\n </ax-icon>\n </ax-prefix>\n <ax-menu-item (onClick)=\"service.downloadJson()\">\n <ax-text>Download JSON</ax-text>\n <ax-prefix>\n <ax-icon>\n <i class=\"fa-solid fa-download\"></i>\n </ax-icon>\n </ax-prefix>\n </ax-menu-item>\n </ax-menu-item>\n <ax-menu-item>\n <ax-text>Import</ax-text>\n <ax-prefix>\n <ax-icon>\n <i class=\"fa-solid fa-file-import\"></i>\n </ax-icon>\n </ax-prefix>\n <ax-menu-item (onClick)=\"service.importJSon()\">\n <ax-text>Import JSON</ax-text>\n <ax-prefix>\n <ax-icon>\n <i class=\"fa-solid fa-upload\"></i>\n </ax-icon>\n </ax-prefix>\n </ax-menu-item>\n @for (item of submenuFor('import'); track item.id) {\n <ax-menu-item (onClick)=\"runMenuEntry(item)\">\n @if (item.iconClass) {\n <ax-prefix>\n <ax-icon>\n <i [class]=\"item.iconClass\"></i>\n </ax-icon>\n </ax-prefix>\n }\n @if (item.resolvedLabel) {\n <ax-text>{{ item.resolvedLabel }}</ax-text>\n }\n </ax-menu-item>\n }\n </ax-menu-item>\n @for (item of submenuFor('file'); track item.id) {\n <ax-menu-item (onClick)=\"runMenuEntry(item)\">\n @if (item.iconClass) {\n <ax-prefix>\n <ax-icon>\n <i [class]=\"item.iconClass\"></i>\n </ax-icon>\n </ax-prefix>\n }\n @if (item.resolvedLabel) {\n <ax-text>{{ item.resolvedLabel }}</ax-text>\n }\n </ax-menu-item>\n }\n </ax-menu-item>\n <ax-menu-item>\n <ax-text>Edit</ax-text>\n <ax-menu-item [disabled]=\"!service.canUndo()\" (onClick)=\"service.undo()\">\n <ax-text>Undo</ax-text>\n <ax-prefix>\n <ax-icon>\n <i class=\"fa-solid fa-undo\"></i>\n </ax-icon>\n </ax-prefix>\n <ax-suffix>\n <ax-kbd look=\"blank\">\n <ax-kbd-item [keys]=\"shortcutKeys('ctrl+z')\"></ax-kbd-item>\n </ax-kbd>\n </ax-suffix>\n </ax-menu-item>\n <ax-menu-item [disabled]=\"!service.canRedo()\" (onClick)=\"service.redo()\">\n <ax-text>Redo</ax-text>\n <ax-prefix>\n <ax-icon>\n <i class=\"fa-solid fa-rotate-right\"></i>\n </ax-icon>\n </ax-prefix>\n <ax-suffix>\n <ax-kbd look=\"blank\">\n <ax-kbd-item [keys]=\"shortcutKeys('ctrl+y')\"></ax-kbd-item>\n </ax-kbd>\n </ax-suffix>\n </ax-menu-item>\n <ax-divider></ax-divider>\n <ax-menu-item\n [disabled]=\"!service.canCutCopy()\"\n (onClick)=\"service.clone()\"\n >\n <ax-text>Clone</ax-text>\n <ax-prefix>\n <ax-icon>\n <i class=\"fa-solid fa-clone\"></i>\n </ax-icon>\n </ax-prefix>\n <ax-suffix>\n <ax-kbd look=\"blank\">\n <ax-kbd-item [keys]=\"shortcutKeys('ctrl+d')\"></ax-kbd-item>\n </ax-kbd>\n </ax-suffix>\n </ax-menu-item>\n <ax-menu-item [disabled]=\"!service.canCutCopy()\" (onClick)=\"service.cut()\">\n <ax-text>Cut</ax-text>\n <ax-prefix>\n <ax-icon>\n <i class=\"fa-solid fa-cut\"></i>\n </ax-icon>\n </ax-prefix>\n <ax-suffix>\n <ax-kbd look=\"blank\">\n <ax-kbd-item [keys]=\"shortcutKeys('ctrl+x')\"></ax-kbd-item>\n </ax-kbd>\n </ax-suffix>\n </ax-menu-item>\n <ax-menu-item [disabled]=\"!service.canCutCopy()\" (onClick)=\"service.copy()\">\n <ax-text>Copy</ax-text>\n <ax-prefix>\n <ax-icon>\n <i class=\"fa-solid fa-copy\"></i>\n </ax-icon>\n </ax-prefix>\n <ax-suffix>\n <ax-kbd look=\"blank\">\n <ax-kbd-item [keys]=\"shortcutKeys('ctrl+c')\"></ax-kbd-item>\n </ax-kbd>\n </ax-suffix>\n </ax-menu-item>\n <ax-menu-item [disabled]=\"!service.canPaste()\" (onClick)=\"service.paste()\">\n <ax-text>Paste</ax-text>\n <ax-prefix>\n <ax-icon>\n <i class=\"fa-solid fa-paste\"></i>\n </ax-icon>\n </ax-prefix>\n <ax-suffix>\n <ax-kbd look=\"blank\">\n <ax-kbd-item [keys]=\"shortcutKeys('ctrl+v')\"></ax-kbd-item>\n </ax-kbd>\n </ax-suffix>\n </ax-menu-item>\n <ax-divider></ax-divider>\n <ax-menu-item\n [disabled]=\"!service.canDelete()\"\n (onClick)=\"service.removeWidget()\"\n >\n <ax-text>Delete</ax-text>\n <ax-prefix>\n <ax-icon>\n <i class=\"fa-solid fa-trash\"></i>\n </ax-icon>\n </ax-prefix>\n <ax-suffix>\n <ax-kbd look=\"blank\">\n <ax-kbd-item [keys]=\"shortcutKeys('delete')\"></ax-kbd-item>\n </ax-kbd>\n </ax-suffix>\n </ax-menu-item>\n @for (item of submenuFor('edit'); track item.id) {\n <ax-menu-item (onClick)=\"runMenuEntry(item)\">\n @if (item.iconClass) {\n <ax-prefix>\n <ax-icon>\n <i [class]=\"item.iconClass\"></i>\n </ax-icon>\n </ax-prefix>\n }\n @if (item.resolvedLabel) {\n <ax-text>{{ item.resolvedLabel }}</ax-text>\n }\n </ax-menu-item>\n }\n </ax-menu-item>\n <ax-menu-item>\n <ax-text>Run</ax-text>\n <ax-menu-item (onClick)=\"service.openPreviewDialog()\">\n <ax-text>Preview</ax-text>\n <ax-prefix>\n <ax-icon>\n <i class=\"fa-solid fa-eye\"></i>\n </ax-icon>\n </ax-prefix>\n <ax-suffix>\n <ax-kbd look=\"blank\">\n <ax-kbd-item [keys]=\"shortcutKeys('ctrl+r')\"></ax-kbd-item>\n </ax-kbd>\n </ax-suffix>\n </ax-menu-item>\n <ax-menu-item (onClick)=\"service.openPreviewWindow()\">\n <ax-text>Preview in seperate window</ax-text>\n <ax-prefix>\n <ax-icon>\n <i class=\"fa-solid fa-window-restore\"></i>\n </ax-icon>\n </ax-prefix>\n <ax-suffix>\n <ax-kbd look=\"blank\">\n <ax-kbd-item [keys]=\"shortcutKeys('ctrl+shift+r')\"></ax-kbd-item>\n </ax-kbd>\n </ax-suffix>\n </ax-menu-item>\n @for (item of submenuFor('run'); track item.id) {\n <ax-menu-item (onClick)=\"runMenuEntry(item)\">\n @if (item.iconClass) {\n <ax-prefix>\n <ax-icon>\n <i [class]=\"item.iconClass\"></i>\n </ax-icon>\n </ax-prefix>\n }\n @if (item.resolvedLabel) {\n <ax-text>{{ item.resolvedLabel }}</ax-text>\n }\n </ax-menu-item>\n }\n </ax-menu-item>\n <ax-menu-item>\n <ax-text>Help</ax-text>\n @for (item of submenuFor('help'); track item.id) {\n <ax-menu-item (onClick)=\"runMenuEntry(item)\">\n @if (item.iconClass) {\n <ax-prefix>\n <ax-icon>\n <i [class]=\"item.iconClass\"></i>\n </ax-icon>\n </ax-prefix>\n }\n @if (item.resolvedLabel) {\n <ax-text>{{ item.resolvedLabel }}</ax-text>\n }\n </ax-menu-item>\n }\n <ax-divider></ax-divider>\n <ax-menu-item>\n <ax-text>About</ax-text>\n <ax-prefix>\n <ax-icon>\n <i class=\"fa-solid fa-circle-info\"></i>\n </ax-icon>\n </ax-prefix>\n </ax-menu-item>\n </ax-menu-item>\n @for (item of rootMenuContributions(); track item.id) {\n <ax-menu-item (onClick)=\"runMenuEntry(item)\">\n @if (item.iconClass) {\n <ax-prefix>\n <ax-icon>\n <i [class]=\"item.iconClass\"></i>\n </ax-icon>\n </ax-prefix>\n }\n @if (item.resolvedLabel) {\n <ax-text>{{ item.resolvedLabel }}</ax-text>\n }\n </ax-menu-item>\n }\n</ax-menu>\n", dependencies: [{ kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i1.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: "component", type: AXKBDComponent, selector: "ax-kbd", inputs: ["look"] }, { kind: "component", type: AXKBDItemComponent, selector: "ax-kbd-item", inputs: ["keys", "join", "look"], outputs: ["lookChange"] }, { kind: "ngmodule", type: AXMenuModule }, { kind: "component", type: i2$2.AXMenuItemComponent, selector: "ax-menu-item", inputs: ["subItems", "name", "data", "disabled", "color"], outputs: ["onClick"] }, { kind: "component", type: i2$2.AXMenuComponent, selector: "ax-menu", inputs: ["orientation", "openOn", "closeOn", "items", "hasArrow"], outputs: ["onItemClick"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2589
3329
|
}
|
|
2590
3330
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPDesignerHeaderMenuComponent, decorators: [{
|
|
2591
3331
|
type: Component,
|
|
2592
|
-
args: [{ imports: [AXDecoratorModule, AXKBDComponent, AXKBDItemComponent, AXMenuModule], selector: 'axp-designer-header-menu', changeDetection: ChangeDetectionStrategy.OnPush, template: "<ax-menu [openOn]=\"'hover'\" [hasArrow]=\"false\">\n <ax-menu-item>\n <ax-text>File</ax-text>\n <ax-menu-item (onClick)=\"service.new()\">\n <ax-text>New</ax-text>\n <ax-suffix>\n <ax-kbd look=\"blank\">\n <ax-kbd-item [keys]=\"shortcutKeys('shift+n')\"></ax-kbd-item>\n </ax-kbd>\n </ax-suffix>\n </ax-menu-item>\n <ax-divider></ax-divider>\n @if (service.canSave()) {\n <ng-container>\n <ax-menu-item (onClick)=\"service.save()\">\n <ax-text>Save</ax-text>\n <ax-suffix>\n <ax-kbd look=\"blank\">\n <ax-kbd-item [keys]=\"shortcutKeys('ctrl+s')\"></ax-kbd-item>\n </ax-kbd>\n </ax-suffix>\n </ax-menu-item>\n <ax-menu-item (onClick)=\"service.saveAs()\">\n <ax-text>Save As...</ax-text>\n <ax-suffix>\n <ax-kbd look=\"blank\">\n <ax-kbd-item [keys]=\"shortcutKeys('ctrl+shift+s')\"></ax-kbd-item>\n </ax-kbd>\n </ax-suffix>\n </ax-menu-item>\n <ax-divider></ax-divider>\n </ng-container>\n }\n <ax-menu-item>\n <ax-text>Export</ax-text>\n <ax-menu-item (onClick)=\"service.downloadJson()\">\n <ax-text>Download JSON</ax-text>\n </ax-menu-item>\n </ax-menu-item>\n <ax-menu-item>\n <ax-text>Import</ax-text>\n <ax-menu-item (onClick)=\"service.importJSon()\">\n <ax-text>Import JSON</ax-text>\n </ax-menu-item>\n </ax-menu-item>\n @for (item of submenuFor('file'); track item.id) {\n <ax-menu-item (onClick)=\"runMenuEntry(item)\">\n @if (item.iconClass) {\n <ax-prefix>\n <ax-icon>\n <i [class]=\"item.iconClass\"></i>\n </ax-icon>\n </ax-prefix>\n }\n @if (item.resolvedLabel) {\n <ax-text>{{ item.resolvedLabel }}</ax-text>\n }\n </ax-menu-item>\n }\n </ax-menu-item>\n <ax-menu-item>\n <ax-text>Edit</ax-text>\n <ax-menu-item [disabled]=\"!service.canUndo()\" (onClick)=\"service.undo()\">\n <ax-text>Undo</ax-text>\n <ax-prefix>\n <ax-icon>\n <i class=\"fa-solid fa-
|
|
3332
|
+
args: [{ imports: [AXDecoratorModule, AXKBDComponent, AXKBDItemComponent, AXMenuModule], selector: 'axp-designer-header-menu', changeDetection: ChangeDetectionStrategy.OnPush, template: "<ax-menu [openOn]=\"'hover'\" [hasArrow]=\"false\">\n <ax-menu-item>\n <ax-text>File</ax-text>\n <ax-menu-item (onClick)=\"service.new()\">\n <ax-text>New</ax-text>\n <ax-prefix>\n <ax-icon>\n <i class=\"fa-solid fa-file\"></i>\n </ax-icon>\n </ax-prefix>\n <ax-suffix>\n <ax-kbd look=\"blank\">\n <ax-kbd-item [keys]=\"shortcutKeys('shift+n')\"></ax-kbd-item>\n </ax-kbd>\n </ax-suffix>\n </ax-menu-item>\n <ax-divider></ax-divider>\n @if (service.canSave()) {\n <ng-container>\n <ax-menu-item (onClick)=\"service.save()\">\n <ax-text>Save</ax-text>\n <ax-prefix>\n <ax-icon>\n <i class=\"fa-solid fa-floppy-disk\"></i>\n </ax-icon>\n </ax-prefix>\n <ax-suffix>\n <ax-kbd look=\"blank\">\n <ax-kbd-item [keys]=\"shortcutKeys('ctrl+s')\"></ax-kbd-item>\n </ax-kbd>\n </ax-suffix>\n </ax-menu-item>\n <ax-menu-item (onClick)=\"service.saveAs()\">\n <ax-text>Save As...</ax-text>\n <ax-prefix>\n <ax-icon>\n <i class=\"fa-solid fa-file-pen\"></i>\n </ax-icon>\n </ax-prefix>\n <ax-suffix>\n <ax-kbd look=\"blank\">\n <ax-kbd-item [keys]=\"shortcutKeys('ctrl+shift+s')\"></ax-kbd-item>\n </ax-kbd>\n </ax-suffix>\n </ax-menu-item>\n <ax-divider></ax-divider>\n </ng-container>\n }\n <ax-menu-item>\n <ax-text>Export</ax-text>\n <ax-prefix>\n <ax-icon>\n <i class=\"fa-solid fa-file-export\"></i>\n </ax-icon>\n </ax-prefix>\n <ax-menu-item (onClick)=\"service.downloadJson()\">\n <ax-text>Download JSON</ax-text>\n <ax-prefix>\n <ax-icon>\n <i class=\"fa-solid fa-download\"></i>\n </ax-icon>\n </ax-prefix>\n </ax-menu-item>\n </ax-menu-item>\n <ax-menu-item>\n <ax-text>Import</ax-text>\n <ax-prefix>\n <ax-icon>\n <i class=\"fa-solid fa-file-import\"></i>\n </ax-icon>\n </ax-prefix>\n <ax-menu-item (onClick)=\"service.importJSon()\">\n <ax-text>Import JSON</ax-text>\n <ax-prefix>\n <ax-icon>\n <i class=\"fa-solid fa-upload\"></i>\n </ax-icon>\n </ax-prefix>\n </ax-menu-item>\n @for (item of submenuFor('import'); track item.id) {\n <ax-menu-item (onClick)=\"runMenuEntry(item)\">\n @if (item.iconClass) {\n <ax-prefix>\n <ax-icon>\n <i [class]=\"item.iconClass\"></i>\n </ax-icon>\n </ax-prefix>\n }\n @if (item.resolvedLabel) {\n <ax-text>{{ item.resolvedLabel }}</ax-text>\n }\n </ax-menu-item>\n }\n </ax-menu-item>\n @for (item of submenuFor('file'); track item.id) {\n <ax-menu-item (onClick)=\"runMenuEntry(item)\">\n @if (item.iconClass) {\n <ax-prefix>\n <ax-icon>\n <i [class]=\"item.iconClass\"></i>\n </ax-icon>\n </ax-prefix>\n }\n @if (item.resolvedLabel) {\n <ax-text>{{ item.resolvedLabel }}</ax-text>\n }\n </ax-menu-item>\n }\n </ax-menu-item>\n <ax-menu-item>\n <ax-text>Edit</ax-text>\n <ax-menu-item [disabled]=\"!service.canUndo()\" (onClick)=\"service.undo()\">\n <ax-text>Undo</ax-text>\n <ax-prefix>\n <ax-icon>\n <i class=\"fa-solid fa-undo\"></i>\n </ax-icon>\n </ax-prefix>\n <ax-suffix>\n <ax-kbd look=\"blank\">\n <ax-kbd-item [keys]=\"shortcutKeys('ctrl+z')\"></ax-kbd-item>\n </ax-kbd>\n </ax-suffix>\n </ax-menu-item>\n <ax-menu-item [disabled]=\"!service.canRedo()\" (onClick)=\"service.redo()\">\n <ax-text>Redo</ax-text>\n <ax-prefix>\n <ax-icon>\n <i class=\"fa-solid fa-rotate-right\"></i>\n </ax-icon>\n </ax-prefix>\n <ax-suffix>\n <ax-kbd look=\"blank\">\n <ax-kbd-item [keys]=\"shortcutKeys('ctrl+y')\"></ax-kbd-item>\n </ax-kbd>\n </ax-suffix>\n </ax-menu-item>\n <ax-divider></ax-divider>\n <ax-menu-item\n [disabled]=\"!service.canCutCopy()\"\n (onClick)=\"service.clone()\"\n >\n <ax-text>Clone</ax-text>\n <ax-prefix>\n <ax-icon>\n <i class=\"fa-solid fa-clone\"></i>\n </ax-icon>\n </ax-prefix>\n <ax-suffix>\n <ax-kbd look=\"blank\">\n <ax-kbd-item [keys]=\"shortcutKeys('ctrl+d')\"></ax-kbd-item>\n </ax-kbd>\n </ax-suffix>\n </ax-menu-item>\n <ax-menu-item [disabled]=\"!service.canCutCopy()\" (onClick)=\"service.cut()\">\n <ax-text>Cut</ax-text>\n <ax-prefix>\n <ax-icon>\n <i class=\"fa-solid fa-cut\"></i>\n </ax-icon>\n </ax-prefix>\n <ax-suffix>\n <ax-kbd look=\"blank\">\n <ax-kbd-item [keys]=\"shortcutKeys('ctrl+x')\"></ax-kbd-item>\n </ax-kbd>\n </ax-suffix>\n </ax-menu-item>\n <ax-menu-item [disabled]=\"!service.canCutCopy()\" (onClick)=\"service.copy()\">\n <ax-text>Copy</ax-text>\n <ax-prefix>\n <ax-icon>\n <i class=\"fa-solid fa-copy\"></i>\n </ax-icon>\n </ax-prefix>\n <ax-suffix>\n <ax-kbd look=\"blank\">\n <ax-kbd-item [keys]=\"shortcutKeys('ctrl+c')\"></ax-kbd-item>\n </ax-kbd>\n </ax-suffix>\n </ax-menu-item>\n <ax-menu-item [disabled]=\"!service.canPaste()\" (onClick)=\"service.paste()\">\n <ax-text>Paste</ax-text>\n <ax-prefix>\n <ax-icon>\n <i class=\"fa-solid fa-paste\"></i>\n </ax-icon>\n </ax-prefix>\n <ax-suffix>\n <ax-kbd look=\"blank\">\n <ax-kbd-item [keys]=\"shortcutKeys('ctrl+v')\"></ax-kbd-item>\n </ax-kbd>\n </ax-suffix>\n </ax-menu-item>\n <ax-divider></ax-divider>\n <ax-menu-item\n [disabled]=\"!service.canDelete()\"\n (onClick)=\"service.removeWidget()\"\n >\n <ax-text>Delete</ax-text>\n <ax-prefix>\n <ax-icon>\n <i class=\"fa-solid fa-trash\"></i>\n </ax-icon>\n </ax-prefix>\n <ax-suffix>\n <ax-kbd look=\"blank\">\n <ax-kbd-item [keys]=\"shortcutKeys('delete')\"></ax-kbd-item>\n </ax-kbd>\n </ax-suffix>\n </ax-menu-item>\n @for (item of submenuFor('edit'); track item.id) {\n <ax-menu-item (onClick)=\"runMenuEntry(item)\">\n @if (item.iconClass) {\n <ax-prefix>\n <ax-icon>\n <i [class]=\"item.iconClass\"></i>\n </ax-icon>\n </ax-prefix>\n }\n @if (item.resolvedLabel) {\n <ax-text>{{ item.resolvedLabel }}</ax-text>\n }\n </ax-menu-item>\n }\n </ax-menu-item>\n <ax-menu-item>\n <ax-text>Run</ax-text>\n <ax-menu-item (onClick)=\"service.openPreviewDialog()\">\n <ax-text>Preview</ax-text>\n <ax-prefix>\n <ax-icon>\n <i class=\"fa-solid fa-eye\"></i>\n </ax-icon>\n </ax-prefix>\n <ax-suffix>\n <ax-kbd look=\"blank\">\n <ax-kbd-item [keys]=\"shortcutKeys('ctrl+r')\"></ax-kbd-item>\n </ax-kbd>\n </ax-suffix>\n </ax-menu-item>\n <ax-menu-item (onClick)=\"service.openPreviewWindow()\">\n <ax-text>Preview in seperate window</ax-text>\n <ax-prefix>\n <ax-icon>\n <i class=\"fa-solid fa-window-restore\"></i>\n </ax-icon>\n </ax-prefix>\n <ax-suffix>\n <ax-kbd look=\"blank\">\n <ax-kbd-item [keys]=\"shortcutKeys('ctrl+shift+r')\"></ax-kbd-item>\n </ax-kbd>\n </ax-suffix>\n </ax-menu-item>\n @for (item of submenuFor('run'); track item.id) {\n <ax-menu-item (onClick)=\"runMenuEntry(item)\">\n @if (item.iconClass) {\n <ax-prefix>\n <ax-icon>\n <i [class]=\"item.iconClass\"></i>\n </ax-icon>\n </ax-prefix>\n }\n @if (item.resolvedLabel) {\n <ax-text>{{ item.resolvedLabel }}</ax-text>\n }\n </ax-menu-item>\n }\n </ax-menu-item>\n <ax-menu-item>\n <ax-text>Help</ax-text>\n @for (item of submenuFor('help'); track item.id) {\n <ax-menu-item (onClick)=\"runMenuEntry(item)\">\n @if (item.iconClass) {\n <ax-prefix>\n <ax-icon>\n <i [class]=\"item.iconClass\"></i>\n </ax-icon>\n </ax-prefix>\n }\n @if (item.resolvedLabel) {\n <ax-text>{{ item.resolvedLabel }}</ax-text>\n }\n </ax-menu-item>\n }\n <ax-divider></ax-divider>\n <ax-menu-item>\n <ax-text>About</ax-text>\n <ax-prefix>\n <ax-icon>\n <i class=\"fa-solid fa-circle-info\"></i>\n </ax-icon>\n </ax-prefix>\n </ax-menu-item>\n </ax-menu-item>\n @for (item of rootMenuContributions(); track item.id) {\n <ax-menu-item (onClick)=\"runMenuEntry(item)\">\n @if (item.iconClass) {\n <ax-prefix>\n <ax-icon>\n <i [class]=\"item.iconClass\"></i>\n </ax-icon>\n </ax-prefix>\n }\n @if (item.resolvedLabel) {\n <ax-text>{{ item.resolvedLabel }}</ax-text>\n }\n </ax-menu-item>\n }\n</ax-menu>\n" }]
|
|
2593
3333
|
}], ctorParameters: () => [] });
|
|
2594
3334
|
|
|
2595
3335
|
class AXPDesignerViewSizeToolbarComponent {
|
|
@@ -2634,31 +3374,115 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
2634
3374
|
}]
|
|
2635
3375
|
}], propDecorators: { size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }, { type: i0.Output, args: ["sizeChange"] }] } });
|
|
2636
3376
|
|
|
3377
|
+
//#region ----- Imports -----
|
|
3378
|
+
//#endregion
|
|
3379
|
+
//#region ----- Hook keys -----
|
|
3380
|
+
/**
|
|
3381
|
+
* Distributed hooks for extending the layout designer footer without coupling the designer library to feature modules.
|
|
3382
|
+
*
|
|
3383
|
+
* - {@link AXPLayoutDesignerFooterHookKeys.end}: icon actions at the trailing end of the footer (after breadcrumbs).
|
|
3384
|
+
*/
|
|
3385
|
+
const AXPLayoutDesignerFooterHookKeys = {
|
|
3386
|
+
end: 'layout-designer.footer.end',
|
|
3387
|
+
};
|
|
3388
|
+
//#endregion
|
|
3389
|
+
|
|
3390
|
+
//#region ----- Imports -----
|
|
3391
|
+
//#endregion
|
|
2637
3392
|
class AXPLayoutDesignerComponent {
|
|
3393
|
+
//#endregion
|
|
3394
|
+
//#region ----- Lifecycle -----
|
|
2638
3395
|
constructor() {
|
|
3396
|
+
//#region ----- Services & Dependencies -----
|
|
2639
3397
|
this.service = inject(AXPDesignerService);
|
|
3398
|
+
this.hooks = inject(AXPHookService);
|
|
3399
|
+
this.translationService = inject(AXTranslationService);
|
|
3400
|
+
this.destroyRef = inject(DestroyRef);
|
|
3401
|
+
//#endregion
|
|
3402
|
+
//#region ----- State Signals -----
|
|
3403
|
+
this.footerEndActions = signal([], /* @ts-ignore */
|
|
3404
|
+
...(ngDevMode ? [{ debugName: "footerEndActions" }] : /* istanbul ignore next */ []));
|
|
3405
|
+
//#endregion
|
|
3406
|
+
//#region ----- Inputs -----
|
|
2640
3407
|
this.id = input(/* @ts-ignore */
|
|
2641
3408
|
...(ngDevMode ? [undefined, { debugName: "id" }] : /* istanbul ignore next */ []));
|
|
2642
3409
|
this.strategy = input(/* @ts-ignore */
|
|
2643
3410
|
...(ngDevMode ? [undefined, { debugName: "strategy" }] : /* istanbul ignore next */ []));
|
|
3411
|
+
/** Host surface policy. Form Builder may omit this; the form profile is the default. */
|
|
3412
|
+
this.profile = input(AXP_FORM_DESIGNER_SURFACE_PROFILE, /* @ts-ignore */
|
|
3413
|
+
...(ngDevMode ? [{ debugName: "profile" }] : /* istanbul ignore next */ []));
|
|
3414
|
+
//#region ----- Computed Properties -----
|
|
3415
|
+
this.layoutProfileContext = computed(() => ({
|
|
3416
|
+
size: designerPreviewSizeToLayoutSize(this.service.size()),
|
|
3417
|
+
medium: 'screen',
|
|
3418
|
+
}), /* @ts-ignore */
|
|
3419
|
+
...(ngDevMode ? [{ debugName: "layoutProfileContext" }] : /* istanbul ignore next */ []));
|
|
2644
3420
|
this.nodeConfig = computed(() => this.service.selectedNode() ? get(this.service.selectedNode(), '__meta__.config') : null, /* @ts-ignore */
|
|
2645
3421
|
...(ngDevMode ? [{ debugName: "nodeConfig" }] : /* istanbul ignore next */ []));
|
|
3422
|
+
this.hasPagesDrawer = computed(() => this.hasDrawer('pages'), /* @ts-ignore */
|
|
3423
|
+
...(ngDevMode ? [{ debugName: "hasPagesDrawer" }] : /* istanbul ignore next */ []));
|
|
3424
|
+
this.hasDataSourcesDrawer = computed(() => this.hasDrawer('dataSources'), /* @ts-ignore */
|
|
3425
|
+
...(ngDevMode ? [{ debugName: "hasDataSourcesDrawer" }] : /* istanbul ignore next */ []));
|
|
3426
|
+
this.hasOutlineDrawer = computed(() => this.hasDrawer('outline'), /* @ts-ignore */
|
|
3427
|
+
...(ngDevMode ? [{ debugName: "hasOutlineDrawer" }] : /* istanbul ignore next */ []));
|
|
3428
|
+
this.hasHistoryDrawer = computed(() => this.hasDrawer('history'), /* @ts-ignore */
|
|
3429
|
+
...(ngDevMode ? [{ debugName: "hasHistoryDrawer" }] : /* istanbul ignore next */ []));
|
|
3430
|
+
this.hasPaletteDrawer = computed(() => this.hasDrawer('palette'), /* @ts-ignore */
|
|
3431
|
+
...(ngDevMode ? [{ debugName: "hasPaletteDrawer" }] : /* istanbul ignore next */ []));
|
|
3432
|
+
//#endregion
|
|
3433
|
+
this.designerDirection = 'ltr';
|
|
2646
3434
|
this.service.onUpdate.subscribe((e) => {
|
|
2647
3435
|
this.propertyViewer.update(e.values);
|
|
2648
3436
|
});
|
|
3437
|
+
effect(() => {
|
|
3438
|
+
this.service.surfaceProfile.set(this.profile());
|
|
3439
|
+
});
|
|
2649
3440
|
}
|
|
2650
3441
|
ngOnInit() {
|
|
2651
3442
|
if (this.id()) {
|
|
2652
3443
|
this.service.loadById(this.id(), { strategy: (this.strategy() ?? AXPTemplateLoadingStrategy.Connector) });
|
|
2653
3444
|
}
|
|
3445
|
+
void this.loadFooterEndActions();
|
|
3446
|
+
}
|
|
3447
|
+
//#region ----- Chrome -----
|
|
3448
|
+
hasDrawer(drawer) {
|
|
3449
|
+
return designerSurfaceHasDrawer(this.profile(), drawer);
|
|
2654
3450
|
}
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
3451
|
+
runFooterEndAction(entry) {
|
|
3452
|
+
void Promise.resolve(entry.run());
|
|
3453
|
+
}
|
|
3454
|
+
//#endregion
|
|
3455
|
+
//#region ----- Footer hooks -----
|
|
3456
|
+
async loadFooterEndActions() {
|
|
3457
|
+
const payload = await this.hooks.runAsync(AXPLayoutDesignerFooterHookKeys.end, { designer: this.service, owner: this.destroyRef, items: [] });
|
|
3458
|
+
payload.items.sort((a, b) => (a.priority ?? 0) - (b.priority ?? 0));
|
|
3459
|
+
this.footerEndActions.set(await Promise.all(payload.items.map(async (item) => ({
|
|
3460
|
+
...item,
|
|
3461
|
+
resolvedLabel: item.labelKey
|
|
3462
|
+
? await this.translationService.translateAsync(item.labelKey)
|
|
3463
|
+
: item.label,
|
|
3464
|
+
}))));
|
|
2659
3465
|
}
|
|
2660
3466
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPLayoutDesignerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2661
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.0.8", type: AXPLayoutDesignerComponent, isStandalone: true, selector: "axp-layout-designer", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, strategy: { classPropertyName: "strategy", publicName: "strategy", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "style": "this.__styles" } }, providers: [AXPDesignerService], viewQueries: [{ propertyName: "propertyViewer", first: true, predicate: AXPWidgetPropertyViewerComponent, descendants: true, static: true }], ngImport: i0, template: "<ax-drawer-container class=\"h-full w-full flex relative overflow-hidden\">\n <ax-content class=\"contents\">\n <!-- Toolbar Side -->\n <div\n class=\"min-w-10 bg-lightest border-e ax-sm flex flex-col items-center ax-dark\"\n >\n <div class=\"min-w-10 h-10 flex items-center justify-center border-b\">\n <img src=\"assets/images/brand/platform/platform-icon-light.svg\" class=\"w-6\" />\n </div>\n <div class=\"py-1\"></div>\n <div class=\"flex flex-col gap-2\">\n <!-- <ax-button look=\"blank\">\n <ax-icon class=\"fa-solid fa-puzzle text-sm\"> </ax-icon>\n </ax-button> -->\n <ax-button look=\"blank\" (onClick)=\"pages.toggle()\" title=\"Pages\">\n <ax-icon class=\"fa-solid fa-page text-sm\"> </ax-icon>\n </ax-button>\n <ax-button\n look=\"blank\"\n (onClick)=\"datasources.toggle()\"\n title=\"Data Sources\"\n >\n <ax-icon class=\"fa-solid fa-database text-sm\"> </ax-icon>\n </ax-button>\n <ax-button look=\"blank\" (onClick)=\"outline.toggle()\" title=\"Outline\">\n <ax-icon class=\"fa-solid fa-list-tree text-sm\"> </ax-icon>\n </ax-button>\n <ax-button look=\"blank\" (onClick)=\"history.toggle()\" title=\"History\">\n <ax-icon class=\"fa-solid fa-clock-rotate-left text-sm\"> </ax-icon>\n </ax-button>\n <!-- <ax-button look=\"blank\" title=\"Timeline\">\n <ax-icon class=\"fa-solid fa-diagram-sankey text-sm\"> </ax-icon>\n </ax-button> -->\n </div>\n </div>\n <!-- Main Side -->\n <div class=\"col-span-10 flex flex-col flex-1\">\n <!-- Header Toolbar -->\n <div class=\"h-10 bg-lightest border-b flex justify-between px-2 ax-dark\">\n <div class=\"flex flex-1 items-center text-white justify-start\">\n <axp-designer-header-menu></axp-designer-header-menu>\n </div>\n <div\n class=\"flex flex-1 flex-row gap-2 ax-sm items-center justify-center\"\n >\n <axp-designer-view-sizes\n [(size)]=\"service.size\"\n ></axp-designer-view-sizes>\n </div>\n <div class=\"flex flex-1 flex-row gap-2 ax-sm items-center justify-end\">\n <ax-dropdown-button\n mode=\"split\"\n look=\"solid\"\n text=\"Preview\"\n class=\"ax-sm\"\n (onClick)=\"service.openPreviewDialog()\"\n >\n <ax-button-item-list>\n <ax-button-item\n text=\"Open in new window\"\n (onClick)=\"service.openPreviewWindow()\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-regular fa-window-restore\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n </ax-button-item-list>\n </ax-dropdown-button>\n </div>\n </div>\n <!-- Board -->\n <ax-drawer-container class=\"w-full flex-1\">\n <!-- Pages -->\n <ax-drawer\n #pages\n location=\"start\"\n mode=\"push\"\n class=\"ax-dark bg-lightest\"\n >\n <ax-content>\n <axp-designer-pages></axp-designer-pages>\n </ax-content>\n </ax-drawer>\n <!-- Datasources -->\n <ax-drawer\n #datasources\n location=\"start\"\n mode=\"push\"\n class=\"ax-dark bg-lightest\"\n >\n <ax-content>\n <axp-designer-data-sources></axp-designer-data-sources>\n </ax-content>\n </ax-drawer>\n <!-- Outline Pnael -->\n <ax-drawer\n #outline\n location=\"start\"\n mode=\"push\"\n class=\"ax-dark bg-lightest\"\n >\n <ax-content>\n <axp-designer-outline></axp-designer-outline>\n </ax-content>\n </ax-drawer>\n <!-- History Pnael -->\n <ax-drawer\n #history\n location=\"start\"\n mode=\"push\"\n class=\"ax-dark bg-lightest\"\n >\n <ax-content>\n <axp-designer-history></axp-designer-history>\n </ax-content>\n </ax-drawer>\n <!-- Content of board -->\n <ax-content class=\"light-surface bg-lighter flex justify-center p-10\">\n <axp-designer-board class=\"rounded-lg bg-lightest shadow-md\">\n </axp-designer-board>\n </ax-content>\n </ax-drawer-container>\n <!-- Footer -->\n <div class=\"h-10 bg-lightest border-t flex items-center ax-dark\">\n <axp-designer-breadcrumbs class=\"border-default p-2 font-normal\">\n </axp-designer-breadcrumbs>\n </div>\n </div>\n </ax-content>\n <!-- Property Side -->\n <ax-drawer\n class=\"ax-dark axp-designer-prop-side\"\n location=\"end\"\n mode=\"push\"\n [collapsed]=\"false\"\n #pd\n >\n <ax-content class=\"flex flex-col h-full overflow-hidden\">\n <div\n class=\"flex flex-row w-full justify-between text-white px-4 border-b h-10\"\n >\n <div class=\"flex flex-row gap-2 items-center\">\n <i [ngClass]=\"$safeNavigationMigration(nodeConfig()?.icon)\"></i>\n <span class=\"font-semibold\">{{\n $safeNavigationMigration(nodeConfig()?.title) | translate | async\n }}</span>\n </div>\n </div>\n <axp-widget-property-viewer\n [mode]=\"'advanced'\"\n [widget]=\"service.selectedNode()!\"\n (onChanged)=\"\n service.update({ values: $event.values, mode: $event.mode })\n \"\n class=\"flex-1 overflow-auto\"\n >\n </axp-widget-property-viewer>\n </ax-content>\n </ax-drawer>\n</ax-drawer-container>\n", styles: ["@layer properties;axp-layout-designer .axp-designer-board{background-color:#fff;background-image:linear-gradient(45deg,#f0f0f0 25%,transparent 25%,transparent 75%,#f0f0f0 75%,#f0f0f0),linear-gradient(45deg,#f0f0f0 25%,#fff 25% 75%,#f0f0f0 75%,#f0f0f0);background-size:20px 20px;background-position:0 0,10px 10px;display:block;height:100%;width:100%;overflow:auto;background-color:rgba(var(--ax-sys-color-surface));padding:calc(var(--spacing, .25rem) * 3)}axp-layout-designer .axp-designer-board ax-drawer{background-color:var(--color-light);color:var(--color-on-light);border-color:var(--color-border-light)}axp-layout-designer .axp-designer-board.axp-state-design .widget-outline{outline-style:var(--tw-outline-style);outline-width:1px;outline-offset:2px;outline-color:var(--color-gray-300, oklch(87.2% .01 258.338));--tw-outline-style: dashed;outline-style:dashed}axp-layout-designer .axp-designer-board.axp-state-design .axp-widget-host{position:relative;cursor:pointer}axp-layout-designer .axp-designer-board.axp-state-design .axp-widget-host.axp-state-selected{outline-width:1px;outline-style:var(--tw-outline-style);outline-width:2px;outline-offset:1px;outline-color:var(--color-blue-400, oklch(70.7% .165 254.624))}axp-layout-designer .axp-designer-board.axp-state-design .axp-widget-host.axp-state-selected.widget-container{outline-offset:2px}axp-layout-designer .axp-designer-board.axp-state-design .axp-widget-host.axp-state-hover{outline-style:var(--tw-outline-style);outline-width:2px;outline-offset:2px;outline-color:var(--color-fuchsia-500, oklch(66.7% .295 322.15));--tw-outline-style: dashed;outline-style:dashed}axp-layout-designer .axp-designer-board.axp-state-design .axp-widget-host.axp-state-hover.axp-state-selected{outline-color:var(--color-blue-400, oklch(70.7% .165 254.624))}axp-layout-designer .axp-designer-board.axp-state-design .axp-widget-host.axp-state-hover.widget-container{outline-offset:4px}axp-layout-designer .axp-designer-board.axp-state-design .axp-widget-host .axp-widget-overlay{position:absolute;inset:0;z-index:2000;height:100%;width:100%}axp-layout-designer .axp-designer-board .axp-empty-space{display:flex;flex:1;cursor:default;align-items:center;justify-content:center;background-color:rgba(var(--ax-sys-color-primary-300));background-image:linear-gradient(135deg,rgba(var(--ax-sys-color-primary-300)) 10%,transparent 0,transparent 50%,rgba(var(--ax-sys-color-primary-300)) 0,rgba(var(--ax-sys-color-primary-300)) 60%,transparent 0,transparent);background-size:7.5px 7.5px;height:100%}@supports (color: color-mix(in lab,red,red)){axp-layout-designer .axp-designer-board .axp-empty-space{background-color:color-mix(in oklab,rgba(var(--ax-sys-color-primary-300)) 10%,transparent)}}@supports (color: color-mix(in lab,red,red)){axp-layout-designer .axp-designer-board .axp-empty-space{background-image:linear-gradient(135deg,color-mix(in oklab,rgba(var(--ax-sys-color-primary-300)) 50%,transparent) 10%,transparent 0,transparent 50%,color-mix(in oklab,rgba(var(--ax-sys-color-primary-300)) 50%,transparent) 0,color-mix(in oklab,rgba(var(--ax-sys-color-primary-300)) 50%,transparent) 60%,transparent 0,transparent)}}axp-layout-designer .axp-designer-board .axp-page-widget-header,axp-layout-designer .axp-designer-board .axp-page-widget-footer{filter:grayscale(100%);opacity:.5}:is(axp-layout-designer .axp-designer-board .axp-page-widget-header,axp-layout-designer .axp-designer-board .axp-page-widget-footer):hover{filter:grayscale(0);opacity:1}axp-layout-designer .axp-designer-board .axp-page-widget-header{margin-bottom:calc(var(--spacing, .25rem) * 2)}axp-layout-designer .axp-designer-board .axp-page-widget-footer{margin-top:calc(var(--spacing, .25rem) * 2)}axp-layout-designer .axp-designer-prop-side{width:calc(var(--spacing, .25rem) * 80);border-inline-start-style:var(--tw-border-style);border-inline-start-width:1px;background-color:var(--color-light);color:var(--color-on-light);border-color:var(--color-border-light)}axp-designer-drawer-content ul.axp-designer-drawer-list{padding:var(--spacing, .25rem);font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));color:var(--color-white, #fff)}:where(axp-designer-drawer-content ul.axp-designer-drawer-list>:not(:last-child)){--tw-space-y-reverse: 0;margin-block-start:calc(var(--spacing, .25rem) * var(--tw-space-y-reverse));margin-block-end:calc(var(--spacing, .25rem) * calc(1 - var(--tw-space-y-reverse)))}axp-designer-drawer-content ul.axp-designer-drawer-list li{cursor:pointer;border-radius:var(--radius-sm, .25rem);padding-inline:calc(var(--spacing, .25rem) * 2);padding-block:var(--spacing, .25rem);transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease, var(--default-transition-timing-function, cubic-bezier(.4, 0, .2, 1)));transition-duration:var(--tw-duration, var(--default-transition-duration, .15s));--tw-duration: .15s;transition-duration:.15s;--tw-ease: var(--ease-in-out, cubic-bezier(.4, 0, .2, 1));transition-timing-function:var(--ease-in-out, cubic-bezier(.4, 0, .2, 1))}axp-designer-drawer-content ul.axp-designer-drawer-list li:hover:not(.axp-designer-drawer-list){background-color:var(--color-gray-700, oklch(37.3% .034 259.733))}axp-designer-drawer-content ul.axp-designer-drawer-list li.state-selected{background-color:var(--color-neutral-700, oklch(37.1% 0 none))}axp-designer-drawer-content .axp-designer-drawer-empty{display:flex;align-items:center;justify-content:center;padding:calc(var(--spacing, .25rem) * 4);color:var(--color-gray-300, oklch(87.2% .01 258.338))}@property --tw-outline-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-space-y-reverse{syntax: \"*\"; inherits: false; initial-value: 0;}@property --tw-duration{syntax: \"*\"; inherits: false;}@property --tw-ease{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-outline-style: solid;--tw-border-style: solid;--tw-space-y-reverse: 0;--tw-duration: initial;--tw-ease: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: AXPWidgetCoreModule }, { kind: "component", type: AXPDesignerBoardComponent, selector: "axp-designer-board" }, { kind: "component", type: AXPWidgetPropertyViewerComponent, selector: "axp-widget-property-viewer", inputs: ["widget", "mode"], outputs: ["onChanged"] }, { kind: "component", type: AXPDesignerBreadcrumbsComponent, selector: "axp-designer-breadcrumbs" }, { kind: "component", type: AXPDesignerOutlineComponent, selector: "axp-designer-outline" }, { kind: "component", type: AXPDesignerHeaderMenuComponent, selector: "axp-designer-header-menu" }, { kind: "component", type: AXPDesignerHistoryComponent, selector: "axp-designer-history" }, { kind: "component", type: AXPDesignerDataSourcesComponent, selector: "axp-designer-data-sources" }, { kind: "component", type: AXPDesignerPagesComponent, selector: "axp-designer-pages" }, { kind: "component", type: AXPDesignerViewSizeToolbarComponent, selector: "axp-designer-view-sizes", inputs: ["size"], outputs: ["sizeChange"] }, { kind: "ngmodule", type: AXTabsModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i2.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "component", type: i2.AXButtonItemComponent, selector: "ax-button-item", inputs: ["color", "disabled", "text", "selected", "divided", "data", "name"], outputs: ["onClick", "onFocus", "onBlur", "disabledChange"] }, { kind: "component", type: i2.AXButtonItemListComponent, selector: "ax-button-item-list", inputs: ["items", "closeParentOnClick", "lockOnLoading"], outputs: ["onItemClick"] }, { kind: "ngmodule", type: AXDrawerModule }, { kind: "component", type: i3.AXDrawerComponent, selector: "ax-drawer", inputs: ["location", "showBackdrop", "mode", "transition", "closeOnBackdropClick", "backdropClass", "collapsed", "singleOpenMode"], outputs: ["onBackdropClick", "collapsedStateChanged"] }, { kind: "component", type: i3.AXDrawerContainerComponent, selector: "ax-drawer-container" }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i1.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: AXMenuModule }, { kind: "ngmodule", type: AXButtonGroupModule }, { kind: "ngmodule", type: AXDropdownModule }, { kind: "ngmodule", type: AXDropdownButtonModule }, { kind: "component", type: i5$1.AXDropdownButtonComponent, selector: "ax-dropdown-button", inputs: ["disabled", "size", "text", "color", "look", "type", "mode"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "lookChange", "colorChange", "disabledChange"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i1$2.AsyncPipe, name: "async" }, { kind: "pipe", type: i8.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.Eager, encapsulation: i0.ViewEncapsulation.None }); }
|
|
3467
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPLayoutDesignerComponent, isStandalone: true, selector: "axp-layout-designer", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, strategy: { classPropertyName: "strategy", publicName: "strategy", isSignal: true, isRequired: false, transformFunction: null }, profile: { classPropertyName: "profile", publicName: "profile", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "style.direction": "this.designerDirection" } }, providers: [
|
|
3468
|
+
AXPDesignerService,
|
|
3469
|
+
CommandManager,
|
|
3470
|
+
{
|
|
3471
|
+
provide: AXP_LOCAL_DATA_SOURCE_STORE,
|
|
3472
|
+
useFactory: (svc) => svc.toLocalDataSourceStore(),
|
|
3473
|
+
deps: [AXPDesignerService],
|
|
3474
|
+
},
|
|
3475
|
+
{
|
|
3476
|
+
provide: AXP_LAYOUT_PROFILE,
|
|
3477
|
+
useFactory: () => {
|
|
3478
|
+
const service = inject(AXPDesignerService);
|
|
3479
|
+
return computed(() => ({
|
|
3480
|
+
size: designerPreviewSizeToLayoutSize(service.size()),
|
|
3481
|
+
medium: 'screen',
|
|
3482
|
+
}));
|
|
3483
|
+
},
|
|
3484
|
+
},
|
|
3485
|
+
], viewQueries: [{ propertyName: "propertyViewer", first: true, predicate: AXPWidgetPropertyViewerComponent, descendants: true, static: true }], ngImport: i0, template: "<ax-drawer-container class=\"h-full w-full flex relative overflow-hidden\">\n <ax-content class=\"contents\">\n <!-- Toolbar Side -->\n <div\n class=\"ax-dark min-w-10 lightest-surface border-e ax-sm flex flex-col items-center\"\n >\n <div class=\"min-w-10 h-10 flex items-center justify-center border-b\">\n <axp-logo logoKey=\"platform\" appearance=\"onDark\" format=\"icon\" [size]=\"24\"></axp-logo>\n </div>\n <div class=\"py-1\"></div>\n <div class=\"flex flex-col gap-2\">\n <!-- ----- Palette opens the widget picker when the surface has no dedicated drawer ----- -->\n @if (hasPaletteDrawer()) {\n <ax-button\n look=\"blank\"\n (onClick)=\"service.showPicker()\"\n [title]=\"('@layout-designer:components.palette.title' | translate | async) ?? ''\"\n >\n <ax-icon class=\"fa-solid fa-puzzle text-sm\"> </ax-icon>\n </ax-button>\n }\n <!-- ----- Pages drawer toggle ----- -->\n @if (hasPagesDrawer()) {\n <ax-button\n look=\"blank\"\n (onClick)=\"pages.toggle()\"\n [title]=\"('@layout-designer:components.pages.title' | translate | async) ?? ''\"\n >\n <ax-icon class=\"fa-solid fa-page text-sm\"> </ax-icon>\n </ax-button>\n }\n <!-- ----- Data sources drawer toggle ----- -->\n @if (hasDataSourcesDrawer()) {\n <ax-button\n look=\"blank\"\n (onClick)=\"datasources.toggle()\"\n [title]=\"('@layout-designer:components.data-sources.title' | translate | async) ?? ''\"\n >\n <ax-icon class=\"fa-solid fa-database text-sm\"> </ax-icon>\n </ax-button>\n }\n <!-- ----- Outline drawer toggle ----- -->\n @if (hasOutlineDrawer()) {\n <ax-button\n look=\"blank\"\n (onClick)=\"outline.toggle()\"\n [title]=\"('@layout-designer:components.outline.title' | translate | async) ?? ''\"\n >\n <ax-icon class=\"fa-solid fa-list-tree text-sm\"> </ax-icon>\n </ax-button>\n }\n <!-- ----- History drawer toggle ----- -->\n @if (hasHistoryDrawer()) {\n <ax-button\n look=\"blank\"\n (onClick)=\"history.toggle()\"\n [title]=\"('@layout-designer:components.history.title' | translate | async) ?? ''\"\n >\n <ax-icon class=\"fa-solid fa-clock-rotate-left text-sm\"> </ax-icon>\n </ax-button>\n }\n </div>\n </div>\n <!-- Main Side -->\n <div class=\"col-span-10 flex flex-col flex-1\">\n <!-- Header Toolbar -->\n <div class=\"ax-dark h-10 lightest-surface border-b flex justify-between px-2\">\n <div class=\"flex flex-1 items-center justify-start text-on-lightest\">\n <axp-designer-header-menu></axp-designer-header-menu>\n </div>\n <div\n class=\"flex flex-1 flex-row gap-2 ax-sm items-center justify-center\"\n >\n <axp-designer-view-sizes\n [(size)]=\"service.size\"\n ></axp-designer-view-sizes>\n </div>\n <div class=\"flex flex-1 flex-row gap-2 ax-sm items-center justify-end\">\n <ax-dropdown-button\n mode=\"split\"\n look=\"solid\"\n [text]=\"('@layout-designer:keyboard-shortcuts.preview' | translate | async) ?? ''\"\n class=\"ax-sm\"\n (onClick)=\"service.openPreviewDialog()\"\n >\n <ax-button-item-list>\n <ax-button-item\n [text]=\"('@layout-designer:keyboard-shortcuts.preview-window' | translate | async) ?? ''\"\n (onClick)=\"service.openPreviewWindow()\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-regular fa-window-restore\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n </ax-button-item-list>\n </ax-dropdown-button>\n </div>\n </div>\n <!-- Board -->\n <ax-drawer-container class=\"w-full flex-1\">\n <!-- ----- Pages drawer (rail button is profile-gated; panel stays mounted for #pages) ----- -->\n <ax-drawer\n #pages\n location=\"start\"\n mode=\"push\"\n class=\"ax-dark lightest-surface\"\n >\n <ax-content>\n <axp-designer-pages></axp-designer-pages>\n </ax-content>\n </ax-drawer>\n <!-- ----- Data sources drawer ----- -->\n <ax-drawer\n #datasources\n location=\"start\"\n mode=\"push\"\n class=\"ax-dark lightest-surface\"\n >\n <ax-content>\n <axp-designer-data-sources></axp-designer-data-sources>\n </ax-content>\n </ax-drawer>\n <!-- ----- Outline drawer ----- -->\n <ax-drawer\n #outline\n location=\"start\"\n mode=\"push\"\n class=\"ax-dark lightest-surface\"\n >\n <ax-content>\n <axp-designer-outline></axp-designer-outline>\n </ax-content>\n </ax-drawer>\n <!-- ----- History drawer ----- -->\n <ax-drawer\n #history\n location=\"start\"\n mode=\"push\"\n class=\"ax-dark lightest-surface\"\n >\n <ax-content>\n <axp-designer-history></axp-designer-history>\n </ax-content>\n </ax-drawer>\n <!-- Content of board -->\n <ax-content class=\"ax-light lighter-surface axp-designer-canvas flex h-full min-h-0 items-start justify-center overflow-auto p-10\">\n <axp-designer-board class=\"rounded-lg lightest-surface shadow-md\">\n </axp-designer-board>\n </ax-content>\n </ax-drawer-container>\n <!-- Footer -->\n <div class=\"ax-dark h-10 lightest-surface border-t flex items-center text-on-lightest\">\n <axp-designer-breadcrumbs class=\"border-default p-2 font-normal min-w-0 flex-1\">\n </axp-designer-breadcrumbs>\n <!-- ----- Hook-contributed actions at the footer end ----- -->\n @if (footerEndActions().length) {\n <div class=\"ms-auto flex items-center gap-1 pe-2\">\n @for (item of footerEndActions(); track item.id) {\n <ax-button\n class=\"ax-sm\"\n look=\"blank\"\n [iconOnly]=\"true\"\n [title]=\"item.resolvedLabel ?? ''\"\n (onClick)=\"runFooterEndAction(item)\"\n >\n @if (item.iconClass) {\n <ax-icon>\n <i [class]=\"item.iconClass\"></i>\n </ax-icon>\n }\n </ax-button>\n }\n </div>\n }\n </div>\n </div>\n </ax-content>\n <!-- Property Side -->\n <ax-drawer\n class=\"ax-dark axp-designer-prop-side lightest-surface\"\n location=\"end\"\n mode=\"push\"\n [collapsed]=\"false\"\n #pd\n >\n <ax-content class=\"flex flex-col h-full overflow-hidden\">\n <div\n class=\"flex flex-row w-full justify-between px-4 border-b h-10 text-on-lightest\"\n >\n <div class=\"flex flex-row gap-2 items-center\">\n <i [ngClass]=\"$safeNavigationMigration(nodeConfig()?.icon)\"></i>\n <span class=\"font-semibold\">{{\n $safeNavigationMigration(nodeConfig()?.title) | translate | async\n }}</span>\n </div>\n </div>\n <axp-widget-property-viewer\n [mode]=\"'advanced'\"\n [bindingExpressionEditorMode]=\"'popup'\"\n [widget]=\"service.selectedNode()!\"\n [layoutProfile]=\"layoutProfileContext()\"\n (onChanged)=\"service.applyPropertyPanelChange($event)\"\n (pointerdown)=\"service.armPropertyPanelHistory()\"\n (focusin)=\"service.armPropertyPanelHistory()\"\n class=\"flex-1 overflow-auto\"\n >\n </axp-widget-property-viewer>\n </ax-content>\n </ax-drawer>\n</ax-drawer-container>\n", styles: ["@layer properties;axp-layout-designer .axp-designer-board{display:block;min-height:100%;width:100%;overflow:auto;background-color:var(--color-lightest);color:var(--color-on-lightest);border-color:var(--color-border-lightest);padding:calc(var(--spacing, .25rem) * 3);background-image:linear-gradient(45deg,rgb(var(--ax-sys-color-light-surface)) 25%,transparent 25%,transparent 75%,rgb(var(--ax-sys-color-light-surface)) 75%,rgb(var(--ax-sys-color-light-surface))),linear-gradient(45deg,rgb(var(--ax-sys-color-light-surface)) 25%,rgb(var(--ax-sys-color-lightest-surface)) 25% 75%,rgb(var(--ax-sys-color-light-surface)) 75%,rgb(var(--ax-sys-color-light-surface)));background-size:20px 20px;background-position:0 0,10px 10px}axp-layout-designer .axp-designer-board.axp-state-design .widget-outline,axp-layout-designer .axp-designer-board.axp-state-design .ax-widget-outline{outline-style:var(--tw-outline-style);outline-width:1px;outline-offset:2px;outline-color:rgba(var(--ax-sys-color-border-light-surface));--tw-outline-style: dashed;outline-style:dashed}axp-layout-designer .axp-designer-board.axp-state-design .axp-widget-host{position:relative;cursor:pointer}axp-layout-designer .axp-designer-board.axp-state-design .axp-widget-host.axp-state-selected{outline-width:1px;outline-style:var(--tw-outline-style);outline-width:2px;outline-offset:1px;outline-color:rgba(var(--ax-sys-color-primary-400))}axp-layout-designer .axp-designer-board.axp-state-design .axp-widget-host.axp-state-selected.widget-container,axp-layout-designer .axp-designer-board.axp-state-design .axp-widget-host.axp-state-selected.ax-widget-container{outline-offset:2px}axp-layout-designer .axp-designer-board.axp-state-design .axp-widget-host.axp-state-hover{outline-style:var(--tw-outline-style);outline-width:2px;outline-offset:2px;outline-color:rgba(var(--ax-sys-color-accent1-500));--tw-outline-style: dashed;outline-style:dashed}axp-layout-designer .axp-designer-board.axp-state-design .axp-widget-host.axp-state-hover.axp-state-selected{outline-color:rgba(var(--ax-sys-color-primary-400))}axp-layout-designer .axp-designer-board.axp-state-design .axp-widget-host.axp-state-hover.widget-container,axp-layout-designer .axp-designer-board.axp-state-design .axp-widget-host.axp-state-hover.ax-widget-container{outline-offset:4px}axp-layout-designer .axp-designer-board.axp-state-design .axp-widget-host .axp-widget-overlay{position:absolute;inset:0;z-index:2000;height:100%;width:100%}axp-layout-designer .axp-designer-board .axp-empty-space{display:flex;flex:1;cursor:default;align-items:center;justify-content:center;background-color:color-mix(in srgb,rgba(var(--ax-sys-color-primary-300)) 10%,transparent);background-image:linear-gradient(135deg,color-mix(in srgb,rgba(var(--ax-sys-color-primary-300)) 50%,transparent) 10%,transparent 0,transparent 50%,color-mix(in srgb,rgba(var(--ax-sys-color-primary-300)) 50%,transparent) 0,color-mix(in srgb,rgba(var(--ax-sys-color-primary-300)) 50%,transparent) 60%,transparent 0,transparent);background-size:7.5px 7.5px;height:100%}@supports (color: color-mix(in lab,red,red)){axp-layout-designer .axp-designer-board .axp-empty-space{background-color:color-mix(in srgb,var(--color-primary-300) 10%,transparent)}}@supports (color: color-mix(in lab,red,red)){axp-layout-designer .axp-designer-board .axp-empty-space{background-image:linear-gradient(135deg,color-mix(in srgb,var(--color-primary-300) 50%,transparent) 10%,transparent 0,transparent 50%,color-mix(in srgb,var(--color-primary-300) 50%,transparent) 0,color-mix(in srgb,var(--color-primary-300) 50%,transparent) 60%,transparent 0,transparent)}}axp-layout-designer .axp-designer-board .axp-page-widget-header,axp-layout-designer .axp-designer-board .axp-page-widget-footer{filter:grayscale(100%);opacity:.5}:is(axp-layout-designer .axp-designer-board .axp-page-widget-header,axp-layout-designer .axp-designer-board .axp-page-widget-footer):hover{filter:grayscale(0);opacity:1}axp-layout-designer .axp-designer-board .axp-page-widget-header{margin-bottom:calc(var(--spacing, .25rem) * 2)}axp-layout-designer .axp-designer-board .axp-page-widget-footer{margin-top:calc(var(--spacing, .25rem) * 2)}axp-layout-designer .axp-designer-prop-side{width:calc(var(--spacing, .25rem) * 80);border-inline-start-style:var(--tw-border-style);border-inline-start-width:1px}axp-designer-drawer-content ul.axp-designer-drawer-list{padding:var(--spacing, .25rem);font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));color:rgba(var(--ax-sys-color-on-lightest-surface))}:where(axp-designer-drawer-content ul.axp-designer-drawer-list>:not(:last-child)){--tw-space-y-reverse: 0;margin-block-start:calc(var(--spacing, .25rem) * var(--tw-space-y-reverse));margin-block-end:calc(var(--spacing, .25rem) * calc(1 - var(--tw-space-y-reverse)))}axp-designer-drawer-content ul.axp-designer-drawer-list li{cursor:pointer;border-radius:var(--radius-sm, .25rem);padding-inline:calc(var(--spacing, .25rem) * 2);padding-block:var(--spacing, .25rem);transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease, var(--default-transition-timing-function, cubic-bezier(.4, 0, .2, 1)));transition-duration:var(--tw-duration, var(--default-transition-duration, .15s));--tw-duration: .15s;transition-duration:.15s;--tw-ease: var(--ease-in-out, cubic-bezier(.4, 0, .2, 1));transition-timing-function:var(--ease-in-out, cubic-bezier(.4, 0, .2, 1))}axp-designer-drawer-content ul.axp-designer-drawer-list li:hover:not(.axp-designer-drawer-list){background-color:var(--color-dark);color:var(--color-on-dark);border-color:var(--color-border-dark)}axp-designer-drawer-content ul.axp-designer-drawer-list li.state-selected{background-color:var(--color-darker);color:var(--color-on-darker);border-color:var(--color-border-darker)}axp-designer-drawer-content .axp-designer-drawer-empty{display:flex;align-items:center;justify-content:center;padding:calc(var(--spacing, .25rem) * 4);color:rgba(var(--ax-sys-color-on-lightest-surface));opacity:70%}@property --tw-outline-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-space-y-reverse{syntax: \"*\"; inherits: false; initial-value: 0;}@property --tw-duration{syntax: \"*\"; inherits: false;}@property --tw-ease{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-outline-style: solid;--tw-border-style: solid;--tw-space-y-reverse: 0;--tw-duration: initial;--tw-ease: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: AXPWidgetCoreModule }, { kind: "component", type: AXPDesignerBoardComponent, selector: "axp-designer-board" }, { kind: "component", type: AXPWidgetPropertyViewerComponent, selector: "axp-widget-property-viewer", inputs: ["widget", "mode", "layoutProfile", "bindingExpressionEditorMode"], outputs: ["onChanged"] }, { kind: "component", type: AXPDesignerBreadcrumbsComponent, selector: "axp-designer-breadcrumbs" }, { kind: "component", type: AXPDesignerOutlineComponent, selector: "axp-designer-outline" }, { kind: "component", type: AXPDesignerHeaderMenuComponent, selector: "axp-designer-header-menu" }, { kind: "component", type: AXPDesignerHistoryComponent, selector: "axp-designer-history" }, { kind: "component", type: AXPDesignerDataSourcesComponent, selector: "axp-designer-data-sources" }, { kind: "component", type: AXPDesignerPagesComponent, selector: "axp-designer-pages" }, { kind: "component", type: AXPDesignerViewSizeToolbarComponent, selector: "axp-designer-view-sizes", inputs: ["size"], outputs: ["sizeChange"] }, { kind: "ngmodule", type: AXTabsModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i2.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "component", type: i2.AXButtonItemComponent, selector: "ax-button-item", inputs: ["color", "disabled", "text", "selected", "divided", "data", "name"], outputs: ["onClick", "onFocus", "onBlur", "disabledChange"] }, { kind: "component", type: i2.AXButtonItemListComponent, selector: "ax-button-item-list", inputs: ["items", "closeParentOnClick", "lockOnLoading"], outputs: ["onItemClick"] }, { kind: "ngmodule", type: AXDrawerModule }, { kind: "component", type: i3.AXDrawerComponent, selector: "ax-drawer", inputs: ["location", "showBackdrop", "mode", "transition", "closeOnBackdropClick", "backdropClass", "collapsed", "singleOpenMode"], outputs: ["onBackdropClick", "collapsedStateChanged"] }, { kind: "component", type: i3.AXDrawerContainerComponent, selector: "ax-drawer-container" }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i1.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: AXMenuModule }, { kind: "ngmodule", type: AXButtonGroupModule }, { kind: "ngmodule", type: AXDropdownModule }, { kind: "ngmodule", type: AXDropdownButtonModule }, { kind: "component", type: i5$1.AXDropdownButtonComponent, selector: "ax-dropdown-button", inputs: ["disabled", "size", "text", "color", "look", "type", "mode"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "lookChange", "colorChange", "disabledChange"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type: AXPLogoComponent, selector: "axp-logo", inputs: ["logoKey", "appearance", "size", "format"] }, { kind: "pipe", type: i1$2.AsyncPipe, name: "async" }, { kind: "pipe", type: i4.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.Eager, encapsulation: i0.ViewEncapsulation.None }); }
|
|
2662
3486
|
}
|
|
2663
3487
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPLayoutDesignerComponent, decorators: [{
|
|
2664
3488
|
type: Component,
|
|
@@ -2683,18 +3507,56 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
2683
3507
|
AXDropdownModule,
|
|
2684
3508
|
AXDropdownButtonModule,
|
|
2685
3509
|
AXTranslationModule,
|
|
2686
|
-
], changeDetection: ChangeDetectionStrategy.Eager, providers: [AXPDesignerService], template: "<ax-drawer-container class=\"h-full w-full flex relative overflow-hidden\">\n <ax-content class=\"contents\">\n <!-- Toolbar Side -->\n <div\n class=\"min-w-10 bg-lightest border-e ax-sm flex flex-col items-center ax-dark\"\n >\n <div class=\"min-w-10 h-10 flex items-center justify-center border-b\">\n <img src=\"assets/images/brand/platform/platform-icon-light.svg\" class=\"w-6\" />\n </div>\n <div class=\"py-1\"></div>\n <div class=\"flex flex-col gap-2\">\n <!-- <ax-button look=\"blank\">\n <ax-icon class=\"fa-solid fa-puzzle text-sm\"> </ax-icon>\n </ax-button> -->\n <ax-button look=\"blank\" (onClick)=\"pages.toggle()\" title=\"Pages\">\n <ax-icon class=\"fa-solid fa-page text-sm\"> </ax-icon>\n </ax-button>\n <ax-button\n look=\"blank\"\n (onClick)=\"datasources.toggle()\"\n title=\"Data Sources\"\n >\n <ax-icon class=\"fa-solid fa-database text-sm\"> </ax-icon>\n </ax-button>\n <ax-button look=\"blank\" (onClick)=\"outline.toggle()\" title=\"Outline\">\n <ax-icon class=\"fa-solid fa-list-tree text-sm\"> </ax-icon>\n </ax-button>\n <ax-button look=\"blank\" (onClick)=\"history.toggle()\" title=\"History\">\n <ax-icon class=\"fa-solid fa-clock-rotate-left text-sm\"> </ax-icon>\n </ax-button>\n <!-- <ax-button look=\"blank\" title=\"Timeline\">\n <ax-icon class=\"fa-solid fa-diagram-sankey text-sm\"> </ax-icon>\n </ax-button> -->\n </div>\n </div>\n <!-- Main Side -->\n <div class=\"col-span-10 flex flex-col flex-1\">\n <!-- Header Toolbar -->\n <div class=\"h-10 bg-lightest border-b flex justify-between px-2 ax-dark\">\n <div class=\"flex flex-1 items-center text-white justify-start\">\n <axp-designer-header-menu></axp-designer-header-menu>\n </div>\n <div\n class=\"flex flex-1 flex-row gap-2 ax-sm items-center justify-center\"\n >\n <axp-designer-view-sizes\n [(size)]=\"service.size\"\n ></axp-designer-view-sizes>\n </div>\n <div class=\"flex flex-1 flex-row gap-2 ax-sm items-center justify-end\">\n <ax-dropdown-button\n mode=\"split\"\n look=\"solid\"\n text=\"Preview\"\n class=\"ax-sm\"\n (onClick)=\"service.openPreviewDialog()\"\n >\n <ax-button-item-list>\n <ax-button-item\n text=\"Open in new window\"\n (onClick)=\"service.openPreviewWindow()\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-regular fa-window-restore\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n </ax-button-item-list>\n </ax-dropdown-button>\n </div>\n </div>\n <!-- Board -->\n <ax-drawer-container class=\"w-full flex-1\">\n <!-- Pages -->\n <ax-drawer\n #pages\n location=\"start\"\n mode=\"push\"\n class=\"ax-dark bg-lightest\"\n >\n <ax-content>\n <axp-designer-pages></axp-designer-pages>\n </ax-content>\n </ax-drawer>\n <!-- Datasources -->\n <ax-drawer\n #datasources\n location=\"start\"\n mode=\"push\"\n class=\"ax-dark bg-lightest\"\n >\n <ax-content>\n <axp-designer-data-sources></axp-designer-data-sources>\n </ax-content>\n </ax-drawer>\n <!-- Outline Pnael -->\n <ax-drawer\n #outline\n location=\"start\"\n mode=\"push\"\n class=\"ax-dark bg-lightest\"\n >\n <ax-content>\n <axp-designer-outline></axp-designer-outline>\n </ax-content>\n </ax-drawer>\n <!-- History Pnael -->\n <ax-drawer\n #history\n location=\"start\"\n mode=\"push\"\n class=\"ax-dark bg-lightest\"\n >\n <ax-content>\n <axp-designer-history></axp-designer-history>\n </ax-content>\n </ax-drawer>\n <!-- Content of board -->\n <ax-content class=\"light-surface bg-lighter flex justify-center p-10\">\n <axp-designer-board class=\"rounded-lg bg-lightest shadow-md\">\n </axp-designer-board>\n </ax-content>\n </ax-drawer-container>\n <!-- Footer -->\n <div class=\"h-10 bg-lightest border-t flex items-center ax-dark\">\n <axp-designer-breadcrumbs class=\"border-default p-2 font-normal\">\n </axp-designer-breadcrumbs>\n </div>\n </div>\n </ax-content>\n <!-- Property Side -->\n <ax-drawer\n class=\"ax-dark axp-designer-prop-side\"\n location=\"end\"\n mode=\"push\"\n [collapsed]=\"false\"\n #pd\n >\n <ax-content class=\"flex flex-col h-full overflow-hidden\">\n <div\n class=\"flex flex-row w-full justify-between text-white px-4 border-b h-10\"\n >\n <div class=\"flex flex-row gap-2 items-center\">\n <i [ngClass]=\"$safeNavigationMigration(nodeConfig()?.icon)\"></i>\n <span class=\"font-semibold\">{{\n $safeNavigationMigration(nodeConfig()?.title) | translate | async\n }}</span>\n </div>\n </div>\n <axp-widget-property-viewer\n [mode]=\"'advanced'\"\n [widget]=\"service.selectedNode()!\"\n (onChanged)=\"\n service.update({ values: $event.values, mode: $event.mode })\n \"\n class=\"flex-1 overflow-auto\"\n >\n </axp-widget-property-viewer>\n </ax-content>\n </ax-drawer>\n</ax-drawer-container>\n", styles: ["@layer properties;axp-layout-designer .axp-designer-board{background-color:#fff;background-image:linear-gradient(45deg,#f0f0f0 25%,transparent 25%,transparent 75%,#f0f0f0 75%,#f0f0f0),linear-gradient(45deg,#f0f0f0 25%,#fff 25% 75%,#f0f0f0 75%,#f0f0f0);background-size:20px 20px;background-position:0 0,10px 10px;display:block;height:100%;width:100%;overflow:auto;background-color:rgba(var(--ax-sys-color-surface));padding:calc(var(--spacing, .25rem) * 3)}axp-layout-designer .axp-designer-board ax-drawer{background-color:var(--color-light);color:var(--color-on-light);border-color:var(--color-border-light)}axp-layout-designer .axp-designer-board.axp-state-design .widget-outline{outline-style:var(--tw-outline-style);outline-width:1px;outline-offset:2px;outline-color:var(--color-gray-300, oklch(87.2% .01 258.338));--tw-outline-style: dashed;outline-style:dashed}axp-layout-designer .axp-designer-board.axp-state-design .axp-widget-host{position:relative;cursor:pointer}axp-layout-designer .axp-designer-board.axp-state-design .axp-widget-host.axp-state-selected{outline-width:1px;outline-style:var(--tw-outline-style);outline-width:2px;outline-offset:1px;outline-color:var(--color-blue-400, oklch(70.7% .165 254.624))}axp-layout-designer .axp-designer-board.axp-state-design .axp-widget-host.axp-state-selected.widget-container{outline-offset:2px}axp-layout-designer .axp-designer-board.axp-state-design .axp-widget-host.axp-state-hover{outline-style:var(--tw-outline-style);outline-width:2px;outline-offset:2px;outline-color:var(--color-fuchsia-500, oklch(66.7% .295 322.15));--tw-outline-style: dashed;outline-style:dashed}axp-layout-designer .axp-designer-board.axp-state-design .axp-widget-host.axp-state-hover.axp-state-selected{outline-color:var(--color-blue-400, oklch(70.7% .165 254.624))}axp-layout-designer .axp-designer-board.axp-state-design .axp-widget-host.axp-state-hover.widget-container{outline-offset:4px}axp-layout-designer .axp-designer-board.axp-state-design .axp-widget-host .axp-widget-overlay{position:absolute;inset:0;z-index:2000;height:100%;width:100%}axp-layout-designer .axp-designer-board .axp-empty-space{display:flex;flex:1;cursor:default;align-items:center;justify-content:center;background-color:rgba(var(--ax-sys-color-primary-300));background-image:linear-gradient(135deg,rgba(var(--ax-sys-color-primary-300)) 10%,transparent 0,transparent 50%,rgba(var(--ax-sys-color-primary-300)) 0,rgba(var(--ax-sys-color-primary-300)) 60%,transparent 0,transparent);background-size:7.5px 7.5px;height:100%}@supports (color: color-mix(in lab,red,red)){axp-layout-designer .axp-designer-board .axp-empty-space{background-color:color-mix(in oklab,rgba(var(--ax-sys-color-primary-300)) 10%,transparent)}}@supports (color: color-mix(in lab,red,red)){axp-layout-designer .axp-designer-board .axp-empty-space{background-image:linear-gradient(135deg,color-mix(in oklab,rgba(var(--ax-sys-color-primary-300)) 50%,transparent) 10%,transparent 0,transparent 50%,color-mix(in oklab,rgba(var(--ax-sys-color-primary-300)) 50%,transparent) 0,color-mix(in oklab,rgba(var(--ax-sys-color-primary-300)) 50%,transparent) 60%,transparent 0,transparent)}}axp-layout-designer .axp-designer-board .axp-page-widget-header,axp-layout-designer .axp-designer-board .axp-page-widget-footer{filter:grayscale(100%);opacity:.5}:is(axp-layout-designer .axp-designer-board .axp-page-widget-header,axp-layout-designer .axp-designer-board .axp-page-widget-footer):hover{filter:grayscale(0);opacity:1}axp-layout-designer .axp-designer-board .axp-page-widget-header{margin-bottom:calc(var(--spacing, .25rem) * 2)}axp-layout-designer .axp-designer-board .axp-page-widget-footer{margin-top:calc(var(--spacing, .25rem) * 2)}axp-layout-designer .axp-designer-prop-side{width:calc(var(--spacing, .25rem) * 80);border-inline-start-style:var(--tw-border-style);border-inline-start-width:1px;background-color:var(--color-light);color:var(--color-on-light);border-color:var(--color-border-light)}axp-designer-drawer-content ul.axp-designer-drawer-list{padding:var(--spacing, .25rem);font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));color:var(--color-white, #fff)}:where(axp-designer-drawer-content ul.axp-designer-drawer-list>:not(:last-child)){--tw-space-y-reverse: 0;margin-block-start:calc(var(--spacing, .25rem) * var(--tw-space-y-reverse));margin-block-end:calc(var(--spacing, .25rem) * calc(1 - var(--tw-space-y-reverse)))}axp-designer-drawer-content ul.axp-designer-drawer-list li{cursor:pointer;border-radius:var(--radius-sm, .25rem);padding-inline:calc(var(--spacing, .25rem) * 2);padding-block:var(--spacing, .25rem);transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease, var(--default-transition-timing-function, cubic-bezier(.4, 0, .2, 1)));transition-duration:var(--tw-duration, var(--default-transition-duration, .15s));--tw-duration: .15s;transition-duration:.15s;--tw-ease: var(--ease-in-out, cubic-bezier(.4, 0, .2, 1));transition-timing-function:var(--ease-in-out, cubic-bezier(.4, 0, .2, 1))}axp-designer-drawer-content ul.axp-designer-drawer-list li:hover:not(.axp-designer-drawer-list){background-color:var(--color-gray-700, oklch(37.3% .034 259.733))}axp-designer-drawer-content ul.axp-designer-drawer-list li.state-selected{background-color:var(--color-neutral-700, oklch(37.1% 0 none))}axp-designer-drawer-content .axp-designer-drawer-empty{display:flex;align-items:center;justify-content:center;padding:calc(var(--spacing, .25rem) * 4);color:var(--color-gray-300, oklch(87.2% .01 258.338))}@property --tw-outline-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-space-y-reverse{syntax: \"*\"; inherits: false; initial-value: 0;}@property --tw-duration{syntax: \"*\"; inherits: false;}@property --tw-ease{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-outline-style: solid;--tw-border-style: solid;--tw-space-y-reverse: 0;--tw-duration: initial;--tw-ease: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
|
|
2687
|
-
|
|
3510
|
+
AXPLogoComponent,
|
|
3511
|
+
], changeDetection: ChangeDetectionStrategy.Eager, providers: [
|
|
3512
|
+
AXPDesignerService,
|
|
3513
|
+
CommandManager,
|
|
3514
|
+
{
|
|
3515
|
+
provide: AXP_LOCAL_DATA_SOURCE_STORE,
|
|
3516
|
+
useFactory: (svc) => svc.toLocalDataSourceStore(),
|
|
3517
|
+
deps: [AXPDesignerService],
|
|
3518
|
+
},
|
|
3519
|
+
{
|
|
3520
|
+
provide: AXP_LAYOUT_PROFILE,
|
|
3521
|
+
useFactory: () => {
|
|
3522
|
+
const service = inject(AXPDesignerService);
|
|
3523
|
+
return computed(() => ({
|
|
3524
|
+
size: designerPreviewSizeToLayoutSize(service.size()),
|
|
3525
|
+
medium: 'screen',
|
|
3526
|
+
}));
|
|
3527
|
+
},
|
|
3528
|
+
},
|
|
3529
|
+
], template: "<ax-drawer-container class=\"h-full w-full flex relative overflow-hidden\">\n <ax-content class=\"contents\">\n <!-- Toolbar Side -->\n <div\n class=\"ax-dark min-w-10 lightest-surface border-e ax-sm flex flex-col items-center\"\n >\n <div class=\"min-w-10 h-10 flex items-center justify-center border-b\">\n <axp-logo logoKey=\"platform\" appearance=\"onDark\" format=\"icon\" [size]=\"24\"></axp-logo>\n </div>\n <div class=\"py-1\"></div>\n <div class=\"flex flex-col gap-2\">\n <!-- ----- Palette opens the widget picker when the surface has no dedicated drawer ----- -->\n @if (hasPaletteDrawer()) {\n <ax-button\n look=\"blank\"\n (onClick)=\"service.showPicker()\"\n [title]=\"('@layout-designer:components.palette.title' | translate | async) ?? ''\"\n >\n <ax-icon class=\"fa-solid fa-puzzle text-sm\"> </ax-icon>\n </ax-button>\n }\n <!-- ----- Pages drawer toggle ----- -->\n @if (hasPagesDrawer()) {\n <ax-button\n look=\"blank\"\n (onClick)=\"pages.toggle()\"\n [title]=\"('@layout-designer:components.pages.title' | translate | async) ?? ''\"\n >\n <ax-icon class=\"fa-solid fa-page text-sm\"> </ax-icon>\n </ax-button>\n }\n <!-- ----- Data sources drawer toggle ----- -->\n @if (hasDataSourcesDrawer()) {\n <ax-button\n look=\"blank\"\n (onClick)=\"datasources.toggle()\"\n [title]=\"('@layout-designer:components.data-sources.title' | translate | async) ?? ''\"\n >\n <ax-icon class=\"fa-solid fa-database text-sm\"> </ax-icon>\n </ax-button>\n }\n <!-- ----- Outline drawer toggle ----- -->\n @if (hasOutlineDrawer()) {\n <ax-button\n look=\"blank\"\n (onClick)=\"outline.toggle()\"\n [title]=\"('@layout-designer:components.outline.title' | translate | async) ?? ''\"\n >\n <ax-icon class=\"fa-solid fa-list-tree text-sm\"> </ax-icon>\n </ax-button>\n }\n <!-- ----- History drawer toggle ----- -->\n @if (hasHistoryDrawer()) {\n <ax-button\n look=\"blank\"\n (onClick)=\"history.toggle()\"\n [title]=\"('@layout-designer:components.history.title' | translate | async) ?? ''\"\n >\n <ax-icon class=\"fa-solid fa-clock-rotate-left text-sm\"> </ax-icon>\n </ax-button>\n }\n </div>\n </div>\n <!-- Main Side -->\n <div class=\"col-span-10 flex flex-col flex-1\">\n <!-- Header Toolbar -->\n <div class=\"ax-dark h-10 lightest-surface border-b flex justify-between px-2\">\n <div class=\"flex flex-1 items-center justify-start text-on-lightest\">\n <axp-designer-header-menu></axp-designer-header-menu>\n </div>\n <div\n class=\"flex flex-1 flex-row gap-2 ax-sm items-center justify-center\"\n >\n <axp-designer-view-sizes\n [(size)]=\"service.size\"\n ></axp-designer-view-sizes>\n </div>\n <div class=\"flex flex-1 flex-row gap-2 ax-sm items-center justify-end\">\n <ax-dropdown-button\n mode=\"split\"\n look=\"solid\"\n [text]=\"('@layout-designer:keyboard-shortcuts.preview' | translate | async) ?? ''\"\n class=\"ax-sm\"\n (onClick)=\"service.openPreviewDialog()\"\n >\n <ax-button-item-list>\n <ax-button-item\n [text]=\"('@layout-designer:keyboard-shortcuts.preview-window' | translate | async) ?? ''\"\n (onClick)=\"service.openPreviewWindow()\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-regular fa-window-restore\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n </ax-button-item-list>\n </ax-dropdown-button>\n </div>\n </div>\n <!-- Board -->\n <ax-drawer-container class=\"w-full flex-1\">\n <!-- ----- Pages drawer (rail button is profile-gated; panel stays mounted for #pages) ----- -->\n <ax-drawer\n #pages\n location=\"start\"\n mode=\"push\"\n class=\"ax-dark lightest-surface\"\n >\n <ax-content>\n <axp-designer-pages></axp-designer-pages>\n </ax-content>\n </ax-drawer>\n <!-- ----- Data sources drawer ----- -->\n <ax-drawer\n #datasources\n location=\"start\"\n mode=\"push\"\n class=\"ax-dark lightest-surface\"\n >\n <ax-content>\n <axp-designer-data-sources></axp-designer-data-sources>\n </ax-content>\n </ax-drawer>\n <!-- ----- Outline drawer ----- -->\n <ax-drawer\n #outline\n location=\"start\"\n mode=\"push\"\n class=\"ax-dark lightest-surface\"\n >\n <ax-content>\n <axp-designer-outline></axp-designer-outline>\n </ax-content>\n </ax-drawer>\n <!-- ----- History drawer ----- -->\n <ax-drawer\n #history\n location=\"start\"\n mode=\"push\"\n class=\"ax-dark lightest-surface\"\n >\n <ax-content>\n <axp-designer-history></axp-designer-history>\n </ax-content>\n </ax-drawer>\n <!-- Content of board -->\n <ax-content class=\"ax-light lighter-surface axp-designer-canvas flex h-full min-h-0 items-start justify-center overflow-auto p-10\">\n <axp-designer-board class=\"rounded-lg lightest-surface shadow-md\">\n </axp-designer-board>\n </ax-content>\n </ax-drawer-container>\n <!-- Footer -->\n <div class=\"ax-dark h-10 lightest-surface border-t flex items-center text-on-lightest\">\n <axp-designer-breadcrumbs class=\"border-default p-2 font-normal min-w-0 flex-1\">\n </axp-designer-breadcrumbs>\n <!-- ----- Hook-contributed actions at the footer end ----- -->\n @if (footerEndActions().length) {\n <div class=\"ms-auto flex items-center gap-1 pe-2\">\n @for (item of footerEndActions(); track item.id) {\n <ax-button\n class=\"ax-sm\"\n look=\"blank\"\n [iconOnly]=\"true\"\n [title]=\"item.resolvedLabel ?? ''\"\n (onClick)=\"runFooterEndAction(item)\"\n >\n @if (item.iconClass) {\n <ax-icon>\n <i [class]=\"item.iconClass\"></i>\n </ax-icon>\n }\n </ax-button>\n }\n </div>\n }\n </div>\n </div>\n </ax-content>\n <!-- Property Side -->\n <ax-drawer\n class=\"ax-dark axp-designer-prop-side lightest-surface\"\n location=\"end\"\n mode=\"push\"\n [collapsed]=\"false\"\n #pd\n >\n <ax-content class=\"flex flex-col h-full overflow-hidden\">\n <div\n class=\"flex flex-row w-full justify-between px-4 border-b h-10 text-on-lightest\"\n >\n <div class=\"flex flex-row gap-2 items-center\">\n <i [ngClass]=\"$safeNavigationMigration(nodeConfig()?.icon)\"></i>\n <span class=\"font-semibold\">{{\n $safeNavigationMigration(nodeConfig()?.title) | translate | async\n }}</span>\n </div>\n </div>\n <axp-widget-property-viewer\n [mode]=\"'advanced'\"\n [bindingExpressionEditorMode]=\"'popup'\"\n [widget]=\"service.selectedNode()!\"\n [layoutProfile]=\"layoutProfileContext()\"\n (onChanged)=\"service.applyPropertyPanelChange($event)\"\n (pointerdown)=\"service.armPropertyPanelHistory()\"\n (focusin)=\"service.armPropertyPanelHistory()\"\n class=\"flex-1 overflow-auto\"\n >\n </axp-widget-property-viewer>\n </ax-content>\n </ax-drawer>\n</ax-drawer-container>\n", styles: ["@layer properties;axp-layout-designer .axp-designer-board{display:block;min-height:100%;width:100%;overflow:auto;background-color:var(--color-lightest);color:var(--color-on-lightest);border-color:var(--color-border-lightest);padding:calc(var(--spacing, .25rem) * 3);background-image:linear-gradient(45deg,rgb(var(--ax-sys-color-light-surface)) 25%,transparent 25%,transparent 75%,rgb(var(--ax-sys-color-light-surface)) 75%,rgb(var(--ax-sys-color-light-surface))),linear-gradient(45deg,rgb(var(--ax-sys-color-light-surface)) 25%,rgb(var(--ax-sys-color-lightest-surface)) 25% 75%,rgb(var(--ax-sys-color-light-surface)) 75%,rgb(var(--ax-sys-color-light-surface)));background-size:20px 20px;background-position:0 0,10px 10px}axp-layout-designer .axp-designer-board.axp-state-design .widget-outline,axp-layout-designer .axp-designer-board.axp-state-design .ax-widget-outline{outline-style:var(--tw-outline-style);outline-width:1px;outline-offset:2px;outline-color:rgba(var(--ax-sys-color-border-light-surface));--tw-outline-style: dashed;outline-style:dashed}axp-layout-designer .axp-designer-board.axp-state-design .axp-widget-host{position:relative;cursor:pointer}axp-layout-designer .axp-designer-board.axp-state-design .axp-widget-host.axp-state-selected{outline-width:1px;outline-style:var(--tw-outline-style);outline-width:2px;outline-offset:1px;outline-color:rgba(var(--ax-sys-color-primary-400))}axp-layout-designer .axp-designer-board.axp-state-design .axp-widget-host.axp-state-selected.widget-container,axp-layout-designer .axp-designer-board.axp-state-design .axp-widget-host.axp-state-selected.ax-widget-container{outline-offset:2px}axp-layout-designer .axp-designer-board.axp-state-design .axp-widget-host.axp-state-hover{outline-style:var(--tw-outline-style);outline-width:2px;outline-offset:2px;outline-color:rgba(var(--ax-sys-color-accent1-500));--tw-outline-style: dashed;outline-style:dashed}axp-layout-designer .axp-designer-board.axp-state-design .axp-widget-host.axp-state-hover.axp-state-selected{outline-color:rgba(var(--ax-sys-color-primary-400))}axp-layout-designer .axp-designer-board.axp-state-design .axp-widget-host.axp-state-hover.widget-container,axp-layout-designer .axp-designer-board.axp-state-design .axp-widget-host.axp-state-hover.ax-widget-container{outline-offset:4px}axp-layout-designer .axp-designer-board.axp-state-design .axp-widget-host .axp-widget-overlay{position:absolute;inset:0;z-index:2000;height:100%;width:100%}axp-layout-designer .axp-designer-board .axp-empty-space{display:flex;flex:1;cursor:default;align-items:center;justify-content:center;background-color:color-mix(in srgb,rgba(var(--ax-sys-color-primary-300)) 10%,transparent);background-image:linear-gradient(135deg,color-mix(in srgb,rgba(var(--ax-sys-color-primary-300)) 50%,transparent) 10%,transparent 0,transparent 50%,color-mix(in srgb,rgba(var(--ax-sys-color-primary-300)) 50%,transparent) 0,color-mix(in srgb,rgba(var(--ax-sys-color-primary-300)) 50%,transparent) 60%,transparent 0,transparent);background-size:7.5px 7.5px;height:100%}@supports (color: color-mix(in lab,red,red)){axp-layout-designer .axp-designer-board .axp-empty-space{background-color:color-mix(in srgb,var(--color-primary-300) 10%,transparent)}}@supports (color: color-mix(in lab,red,red)){axp-layout-designer .axp-designer-board .axp-empty-space{background-image:linear-gradient(135deg,color-mix(in srgb,var(--color-primary-300) 50%,transparent) 10%,transparent 0,transparent 50%,color-mix(in srgb,var(--color-primary-300) 50%,transparent) 0,color-mix(in srgb,var(--color-primary-300) 50%,transparent) 60%,transparent 0,transparent)}}axp-layout-designer .axp-designer-board .axp-page-widget-header,axp-layout-designer .axp-designer-board .axp-page-widget-footer{filter:grayscale(100%);opacity:.5}:is(axp-layout-designer .axp-designer-board .axp-page-widget-header,axp-layout-designer .axp-designer-board .axp-page-widget-footer):hover{filter:grayscale(0);opacity:1}axp-layout-designer .axp-designer-board .axp-page-widget-header{margin-bottom:calc(var(--spacing, .25rem) * 2)}axp-layout-designer .axp-designer-board .axp-page-widget-footer{margin-top:calc(var(--spacing, .25rem) * 2)}axp-layout-designer .axp-designer-prop-side{width:calc(var(--spacing, .25rem) * 80);border-inline-start-style:var(--tw-border-style);border-inline-start-width:1px}axp-designer-drawer-content ul.axp-designer-drawer-list{padding:var(--spacing, .25rem);font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));color:rgba(var(--ax-sys-color-on-lightest-surface))}:where(axp-designer-drawer-content ul.axp-designer-drawer-list>:not(:last-child)){--tw-space-y-reverse: 0;margin-block-start:calc(var(--spacing, .25rem) * var(--tw-space-y-reverse));margin-block-end:calc(var(--spacing, .25rem) * calc(1 - var(--tw-space-y-reverse)))}axp-designer-drawer-content ul.axp-designer-drawer-list li{cursor:pointer;border-radius:var(--radius-sm, .25rem);padding-inline:calc(var(--spacing, .25rem) * 2);padding-block:var(--spacing, .25rem);transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease, var(--default-transition-timing-function, cubic-bezier(.4, 0, .2, 1)));transition-duration:var(--tw-duration, var(--default-transition-duration, .15s));--tw-duration: .15s;transition-duration:.15s;--tw-ease: var(--ease-in-out, cubic-bezier(.4, 0, .2, 1));transition-timing-function:var(--ease-in-out, cubic-bezier(.4, 0, .2, 1))}axp-designer-drawer-content ul.axp-designer-drawer-list li:hover:not(.axp-designer-drawer-list){background-color:var(--color-dark);color:var(--color-on-dark);border-color:var(--color-border-dark)}axp-designer-drawer-content ul.axp-designer-drawer-list li.state-selected{background-color:var(--color-darker);color:var(--color-on-darker);border-color:var(--color-border-darker)}axp-designer-drawer-content .axp-designer-drawer-empty{display:flex;align-items:center;justify-content:center;padding:calc(var(--spacing, .25rem) * 4);color:rgba(var(--ax-sys-color-on-lightest-surface));opacity:70%}@property --tw-outline-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-space-y-reverse{syntax: \"*\"; inherits: false; initial-value: 0;}@property --tw-duration{syntax: \"*\"; inherits: false;}@property --tw-ease{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-outline-style: solid;--tw-border-style: solid;--tw-space-y-reverse: 0;--tw-duration: initial;--tw-ease: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
|
|
3530
|
+
}], ctorParameters: () => [], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], strategy: [{ type: i0.Input, args: [{ isSignal: true, alias: "strategy", required: false }] }], profile: [{ type: i0.Input, args: [{ isSignal: true, alias: "profile", required: false }] }], propertyViewer: [{
|
|
2688
3531
|
type: ViewChild,
|
|
2689
3532
|
args: [AXPWidgetPropertyViewerComponent, { static: true }]
|
|
2690
|
-
}],
|
|
3533
|
+
}], designerDirection: [{
|
|
2691
3534
|
type: HostBinding,
|
|
2692
|
-
args: ['style']
|
|
3535
|
+
args: ['style.direction']
|
|
2693
3536
|
}] } });
|
|
2694
3537
|
|
|
3538
|
+
//#endregion
|
|
3539
|
+
|
|
2695
3540
|
class AXPLayoutDesignerPreviewViewerComponent {
|
|
3541
|
+
get(id) {
|
|
3542
|
+
return this.sources().find((row) => row.id === id);
|
|
3543
|
+
}
|
|
3544
|
+
create(name) {
|
|
3545
|
+
return { id: '', name, items: [] };
|
|
3546
|
+
}
|
|
3547
|
+
update() {
|
|
3548
|
+
return;
|
|
3549
|
+
}
|
|
3550
|
+
remove() {
|
|
3551
|
+
return;
|
|
3552
|
+
}
|
|
3553
|
+
get __class() {
|
|
3554
|
+
return 'block w-full min-h-full';
|
|
3555
|
+
}
|
|
2696
3556
|
constructor() {
|
|
2697
3557
|
this.context = {};
|
|
3558
|
+
this.initialDocument = input(null, /* @ts-ignore */
|
|
3559
|
+
...(ngDevMode ? [{ debugName: "initialDocument" }] : /* istanbul ignore next */ []));
|
|
2698
3560
|
this.document = signal({ type: AXPWidgetsCatalog.document }, /* @ts-ignore */
|
|
2699
3561
|
...(ngDevMode ? [{ debugName: "document" }] : /* istanbul ignore next */ []));
|
|
2700
3562
|
this.currentPageIndex = signal(0, /* @ts-ignore */
|
|
@@ -2702,22 +3564,24 @@ class AXPLayoutDesignerPreviewViewerComponent {
|
|
|
2702
3564
|
this.connector = inject(AXPDesignerConnector);
|
|
2703
3565
|
this.eventService = inject(AXPBroadcastEventService);
|
|
2704
3566
|
this.unsubscriber = inject(AXUnsubscriber);
|
|
3567
|
+
this.sources = computed(() => readLocalDataSourcesFromNode(this.document()), /* @ts-ignore */
|
|
3568
|
+
...(ngDevMode ? [{ debugName: "sources" }] : /* istanbul ignore next */ []));
|
|
2705
3569
|
this.currentPage = computed(() => {
|
|
2706
3570
|
return (this.document().children?.[this.currentPageIndex()] ?? { type: AXPWidgetsCatalog.pageLayout });
|
|
2707
3571
|
}, /* @ts-ignore */
|
|
2708
3572
|
...(ngDevMode ? [{ debugName: "currentPage" }] : /* istanbul ignore next */ []));
|
|
3573
|
+
const seeded = readDesignerPreviewDocument();
|
|
3574
|
+
if (seeded) {
|
|
3575
|
+
this.document.set(seeded);
|
|
3576
|
+
}
|
|
2709
3577
|
this.eventService
|
|
2710
3578
|
.listen(AXPDesignerMessageKeys.Preview)
|
|
2711
3579
|
.pipe(this.unsubscriber.takeUntilDestroy)
|
|
2712
3580
|
.subscribe((event) => {
|
|
2713
|
-
this.document
|
|
3581
|
+
if (event.data?.document && !isEqual(this.document(), event.data.document)) {
|
|
3582
|
+
this.document.set(event.data.document);
|
|
3583
|
+
}
|
|
2714
3584
|
});
|
|
2715
|
-
//
|
|
2716
|
-
if (document.body.parentElement) {
|
|
2717
|
-
document.body.parentElement.classList.remove('ax-dark');
|
|
2718
|
-
document.body.parentElement.style.backgroundColor = 'unset';
|
|
2719
|
-
document.body.style.backgroundColor = 'unset';
|
|
2720
|
-
}
|
|
2721
3585
|
}
|
|
2722
3586
|
ngAfterViewInit() {
|
|
2723
3587
|
this.eventService.publish(AXPDesignerMessageKeys.Loaded);
|
|
@@ -2730,7 +3594,10 @@ class AXPLayoutDesignerPreviewViewerComponent {
|
|
|
2730
3594
|
this.eventService.unsubscribe(AXPDesignerMessageKeys.Preview);
|
|
2731
3595
|
}
|
|
2732
3596
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPLayoutDesignerPreviewViewerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2733
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
3597
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.0.8", type: AXPLayoutDesignerPreviewViewerComponent, isStandalone: true, selector: "axp-layout-builder-viewer", inputs: { initialDocument: { classPropertyName: "initialDocument", publicName: "initialDocument", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "this.__class" } }, providers: [
|
|
3598
|
+
AXUnsubscriber,
|
|
3599
|
+
{ provide: AXP_LOCAL_DATA_SOURCE_STORE, useExisting: AXPLayoutDesignerPreviewViewerComponent },
|
|
3600
|
+
], ngImport: i0, template: `
|
|
2734
3601
|
<axp-widgets-container [context]="context" (onContextChanged)="handleContextChanged($event)">
|
|
2735
3602
|
<ng-container axp-widget-renderer [node]="currentPage()" [mode]="'edit'"></ng-container>
|
|
2736
3603
|
</axp-widgets-container>
|
|
@@ -2748,16 +3615,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
2748
3615
|
encapsulation: ViewEncapsulation.None,
|
|
2749
3616
|
imports: [AXPWidgetCoreModule],
|
|
2750
3617
|
changeDetection: ChangeDetectionStrategy.Eager,
|
|
2751
|
-
providers: [
|
|
3618
|
+
providers: [
|
|
3619
|
+
AXUnsubscriber,
|
|
3620
|
+
{ provide: AXP_LOCAL_DATA_SOURCE_STORE, useExisting: AXPLayoutDesignerPreviewViewerComponent },
|
|
3621
|
+
],
|
|
2752
3622
|
}]
|
|
2753
|
-
}], ctorParameters: () => [] }
|
|
3623
|
+
}], ctorParameters: () => [], propDecorators: { initialDocument: [{ type: i0.Input, args: [{ isSignal: true, alias: "initialDocument", required: false }] }], __class: [{
|
|
3624
|
+
type: HostBinding,
|
|
3625
|
+
args: ['class']
|
|
3626
|
+
}] } });
|
|
2754
3627
|
|
|
2755
3628
|
class AXPLayoutDesignerPreviewFrameComponent {
|
|
2756
3629
|
constructor() {
|
|
2757
3630
|
this.size = input('xl', /* @ts-ignore */
|
|
2758
3631
|
...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
2759
3632
|
this.width = computed(() => {
|
|
2760
|
-
;
|
|
2761
3633
|
switch (this.size()) {
|
|
2762
3634
|
case 'sm':
|
|
2763
3635
|
return '340px';
|
|
@@ -2765,39 +3637,34 @@ class AXPLayoutDesignerPreviewFrameComponent {
|
|
|
2765
3637
|
case 'lg':
|
|
2766
3638
|
return '768px';
|
|
2767
3639
|
default:
|
|
2768
|
-
return '
|
|
3640
|
+
return '1280px';
|
|
2769
3641
|
}
|
|
2770
3642
|
}, /* @ts-ignore */
|
|
2771
3643
|
...(ngDevMode ? [{ debugName: "width" }] : /* istanbul ignore next */ []));
|
|
2772
3644
|
}
|
|
2773
3645
|
get __class() {
|
|
2774
|
-
|
|
2775
|
-
cls['flex'] = true;
|
|
2776
|
-
cls['flex-col'] = true;
|
|
2777
|
-
cls['h-full'] = true;
|
|
2778
|
-
cls['W-full'] = true;
|
|
2779
|
-
cls['lg:p-20'] = true;
|
|
2780
|
-
cls['bg-[#f3f3fe]'] = true;
|
|
2781
|
-
cls['w-full'] = true;
|
|
2782
|
-
cls['items-center'] = true;
|
|
2783
|
-
cls['overflow-auto'] = true;
|
|
2784
|
-
return cls;
|
|
3646
|
+
return 'lighter-surface flex flex-col h-full w-full items-center overflow-auto p-6';
|
|
2785
3647
|
}
|
|
2786
3648
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPLayoutDesignerPreviewFrameComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2787
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.0.8", type: AXPLayoutDesignerPreviewFrameComponent, isStandalone: true, selector: "axp-layout-preview-frame", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "this.__class" } },
|
|
3649
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.0.8", type: AXPLayoutDesignerPreviewFrameComponent, isStandalone: true, selector: "axp-layout-preview-frame", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "this.__class" } }, providers: [
|
|
3650
|
+
{
|
|
3651
|
+
provide: AXP_LAYOUT_PROFILE,
|
|
3652
|
+
useFactory: () => {
|
|
3653
|
+
const frame = inject(AXPLayoutDesignerPreviewFrameComponent);
|
|
3654
|
+
return computed(() => ({
|
|
3655
|
+
size: designerPreviewSizeToLayoutSize(frame.size()),
|
|
3656
|
+
medium: 'screen',
|
|
3657
|
+
}));
|
|
3658
|
+
},
|
|
3659
|
+
},
|
|
3660
|
+
], ngImport: i0, template: `
|
|
2788
3661
|
<div
|
|
2789
|
-
class="
|
|
2790
|
-
[style.width]="width()"
|
|
2791
|
-
style="max-width: 1280px;"
|
|
3662
|
+
class="lightest-surface min-h-full w-full shrink-0 rounded-lg shadow-md p-4"
|
|
3663
|
+
[style.max-width]="width()"
|
|
2792
3664
|
>
|
|
2793
|
-
<
|
|
2794
|
-
class="w-full h-full bg-transparent"
|
|
2795
|
-
[frameBorder]="0"
|
|
2796
|
-
[src]="'/forms/viewer' | safe : 'resourceUrl'"
|
|
2797
|
-
>
|
|
2798
|
-
</iframe>
|
|
3665
|
+
<axp-layout-builder-viewer></axp-layout-builder-viewer>
|
|
2799
3666
|
</div>
|
|
2800
|
-
`, isInline: true, dependencies: [{ kind: "
|
|
3667
|
+
`, isInline: true, dependencies: [{ kind: "component", type: AXPLayoutDesignerPreviewViewerComponent, selector: "axp-layout-builder-viewer", inputs: ["initialDocument"] }], changeDetection: i0.ChangeDetectionStrategy.Eager, encapsulation: i0.ViewEncapsulation.None }); }
|
|
2801
3668
|
}
|
|
2802
3669
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPLayoutDesignerPreviewFrameComponent, decorators: [{
|
|
2803
3670
|
type: Component,
|
|
@@ -2805,21 +3672,27 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
2805
3672
|
selector: 'axp-layout-preview-frame',
|
|
2806
3673
|
template: `
|
|
2807
3674
|
<div
|
|
2808
|
-
class="
|
|
2809
|
-
[style.width]="width()"
|
|
2810
|
-
style="max-width: 1280px;"
|
|
3675
|
+
class="lightest-surface min-h-full w-full shrink-0 rounded-lg shadow-md p-4"
|
|
3676
|
+
[style.max-width]="width()"
|
|
2811
3677
|
>
|
|
2812
|
-
<
|
|
2813
|
-
class="w-full h-full bg-transparent"
|
|
2814
|
-
[frameBorder]="0"
|
|
2815
|
-
[src]="'/forms/viewer' | safe : 'resourceUrl'"
|
|
2816
|
-
>
|
|
2817
|
-
</iframe>
|
|
3678
|
+
<axp-layout-builder-viewer></axp-layout-builder-viewer>
|
|
2818
3679
|
</div>
|
|
2819
3680
|
`,
|
|
2820
3681
|
encapsulation: ViewEncapsulation.None,
|
|
2821
3682
|
changeDetection: ChangeDetectionStrategy.Eager,
|
|
2822
|
-
imports: [
|
|
3683
|
+
imports: [AXPLayoutDesignerPreviewViewerComponent],
|
|
3684
|
+
providers: [
|
|
3685
|
+
{
|
|
3686
|
+
provide: AXP_LAYOUT_PROFILE,
|
|
3687
|
+
useFactory: () => {
|
|
3688
|
+
const frame = inject(AXPLayoutDesignerPreviewFrameComponent);
|
|
3689
|
+
return computed(() => ({
|
|
3690
|
+
size: designerPreviewSizeToLayoutSize(frame.size()),
|
|
3691
|
+
medium: 'screen',
|
|
3692
|
+
}));
|
|
3693
|
+
},
|
|
3694
|
+
},
|
|
3695
|
+
],
|
|
2823
3696
|
}]
|
|
2824
3697
|
}], propDecorators: { size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], __class: [{
|
|
2825
3698
|
type: HostBinding,
|
|
@@ -2871,7 +3744,7 @@ class AXPLayoutDesignerPreviewComponent extends AXBasePageComponent {
|
|
|
2871
3744
|
await this.settings.scope(AXPPlatformScope.User).set(this.jsonSettingsKey, !value);
|
|
2872
3745
|
}
|
|
2873
3746
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPLayoutDesignerPreviewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2874
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPLayoutDesignerPreviewComponent, isStandalone: true, selector: "axp-layout-preview", usesInheritance: true, ngImport: i0, template: "<ax-drawer-container class=\"ax-dark h-full w-full flex relative overflow-hidden\">\n <ax-content>\n <div class=\"ax-dark flex flex-col h-full relative
|
|
3747
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXPLayoutDesignerPreviewComponent, isStandalone: true, selector: "axp-layout-preview", usesInheritance: true, ngImport: i0, template: "<ax-drawer-container class=\"ax-dark h-full w-full flex relative overflow-hidden\">\n <ax-content>\n <div class=\"ax-dark flex flex-col h-full relative\">\n <div class=\"flex items-center justify-between h-12 lightest-surface shadow ax-sm px-2\">\n <div class=\"flex flex-1 w-16 justify-start\">\n <ax-button look=\"blank\" [text]=\"'@layout-designer:preview.back' | translate | async\" (onClick)=\"handleCloseButton()\">\n <ax-prefix>\n <ax-icon class=\"fa-regular fa-chevron-left\"></ax-icon>\n </ax-prefix>\n </ax-button>\n </div>\n <div class=\"flex flex-1 flex-row gap-2 ax-sm items-center justify-center\">\n <axp-designer-view-sizes [(size)]=\"size\"></axp-designer-view-sizes>\n </div>\n <div class=\"flex flex-1 w-16 justify-end\">\n @if (isDialogWindow) {\n <ax-button look=\"blank\" [title]=\"'@layout-designer:keyboard-shortcuts.preview-window' | translate | async\" (onClick)=\"handlePreviewWindow()\">\n <ax-prefix>\n <ax-icon class=\"fa-regular fa-window-restore\"></ax-icon>\n </ax-prefix>\n </ax-button>\n }\n <ax-button look=\"blank\" (onClick)=\"jsonView.toggle()\">\n <ax-prefix>\n <ax-icon class=\"fa-regular fa-list-tree\"></ax-icon>\n </ax-prefix>\n </ax-button>\n </div>\n </div>\n\n <div class=\"ax-light lighter-surface flex flex-1 justify-center overflow-auto min-h-0\">\n <axp-layout-preview-frame [size]=\"size()\"></axp-layout-preview-frame>\n </div>\n </div>\n </ax-content>\n <ax-drawer class=\"ax-dark w-1/3 border-s\" location=\"end\" mode=\"push\" #jsonView>\n <ax-content>\n <div class=\"ax-dark flex flex-col h-full relative\">\n <div class=\"flex items-center justify-between h-12 lightest-surface border-b shadow ax-sm px-2\">\n <div class=\"flex flex-1 w-16 justify-start\">\n <span class=\"font-semibold text-on-lightest\">{{ '@layout-designer:preview.form-data' | translate | async }}</span>\n </div>\n <div class=\"flex flex-1 flex-row gap-2 ax-sm items-center justify-center\"></div>\n <div class=\"flex flex-1 w-16 justify-end\">\n <ax-button look=\"blank\" (onClick)=\"handleCopyJson()\">\n <ax-prefix>\n <ax-icon class=\"fa-regular fa-copy\"></ax-icon>\n </ax-prefix>\n </ax-button>\n </div>\n </div>\n <div class=\"px-6\">\n <ax-json-viewer [json]=\"context()\"></ax-json-viewer>\n </div>\n </div>\n </ax-content>\n </ax-drawer>\n</ax-drawer-container>\n", styles: ["/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i2.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXButtonGroupModule }, { kind: "ngmodule", type: AXDrawerModule }, { kind: "component", type: i3.AXDrawerComponent, selector: "ax-drawer", inputs: ["location", "showBackdrop", "mode", "transition", "closeOnBackdropClick", "backdropClass", "collapsed", "singleOpenMode"], outputs: ["onBackdropClick", "collapsedStateChanged"] }, { kind: "component", type: i3.AXDrawerContainerComponent, selector: "ax-drawer-container" }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i1.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: AXJsonViewerModule }, { kind: "component", type: i4$2.JsonViewerComponent, selector: "ax-json-viewer", inputs: ["json"] }, { kind: "ngmodule", type: CommonModule }, { kind: "component", type: AXPLayoutDesignerPreviewFrameComponent, selector: "axp-layout-preview-frame", inputs: ["size"] }, { kind: "component", type: AXPDesignerViewSizeToolbarComponent, selector: "axp-designer-view-sizes", inputs: ["size"], outputs: ["sizeChange"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i1$2.AsyncPipe, name: "async" }, { kind: "pipe", type: i4.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.Eager, encapsulation: i0.ViewEncapsulation.None }); }
|
|
2875
3748
|
}
|
|
2876
3749
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPLayoutDesignerPreviewComponent, decorators: [{
|
|
2877
3750
|
type: Component,
|
|
@@ -2881,9 +3754,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
2881
3754
|
AXDrawerModule,
|
|
2882
3755
|
AXDecoratorModule,
|
|
2883
3756
|
AXJsonViewerModule,
|
|
3757
|
+
CommonModule,
|
|
2884
3758
|
AXPLayoutDesignerPreviewFrameComponent,
|
|
2885
|
-
AXPDesignerViewSizeToolbarComponent
|
|
2886
|
-
|
|
3759
|
+
AXPDesignerViewSizeToolbarComponent,
|
|
3760
|
+
AXTranslationModule,
|
|
3761
|
+
], template: "<ax-drawer-container class=\"ax-dark h-full w-full flex relative overflow-hidden\">\n <ax-content>\n <div class=\"ax-dark flex flex-col h-full relative\">\n <div class=\"flex items-center justify-between h-12 lightest-surface shadow ax-sm px-2\">\n <div class=\"flex flex-1 w-16 justify-start\">\n <ax-button look=\"blank\" [text]=\"'@layout-designer:preview.back' | translate | async\" (onClick)=\"handleCloseButton()\">\n <ax-prefix>\n <ax-icon class=\"fa-regular fa-chevron-left\"></ax-icon>\n </ax-prefix>\n </ax-button>\n </div>\n <div class=\"flex flex-1 flex-row gap-2 ax-sm items-center justify-center\">\n <axp-designer-view-sizes [(size)]=\"size\"></axp-designer-view-sizes>\n </div>\n <div class=\"flex flex-1 w-16 justify-end\">\n @if (isDialogWindow) {\n <ax-button look=\"blank\" [title]=\"'@layout-designer:keyboard-shortcuts.preview-window' | translate | async\" (onClick)=\"handlePreviewWindow()\">\n <ax-prefix>\n <ax-icon class=\"fa-regular fa-window-restore\"></ax-icon>\n </ax-prefix>\n </ax-button>\n }\n <ax-button look=\"blank\" (onClick)=\"jsonView.toggle()\">\n <ax-prefix>\n <ax-icon class=\"fa-regular fa-list-tree\"></ax-icon>\n </ax-prefix>\n </ax-button>\n </div>\n </div>\n\n <div class=\"ax-light lighter-surface flex flex-1 justify-center overflow-auto min-h-0\">\n <axp-layout-preview-frame [size]=\"size()\"></axp-layout-preview-frame>\n </div>\n </div>\n </ax-content>\n <ax-drawer class=\"ax-dark w-1/3 border-s\" location=\"end\" mode=\"push\" #jsonView>\n <ax-content>\n <div class=\"ax-dark flex flex-col h-full relative\">\n <div class=\"flex items-center justify-between h-12 lightest-surface border-b shadow ax-sm px-2\">\n <div class=\"flex flex-1 w-16 justify-start\">\n <span class=\"font-semibold text-on-lightest\">{{ '@layout-designer:preview.form-data' | translate | async }}</span>\n </div>\n <div class=\"flex flex-1 flex-row gap-2 ax-sm items-center justify-center\"></div>\n <div class=\"flex flex-1 w-16 justify-end\">\n <ax-button look=\"blank\" (onClick)=\"handleCopyJson()\">\n <ax-prefix>\n <ax-icon class=\"fa-regular fa-copy\"></ax-icon>\n </ax-prefix>\n </ax-button>\n </div>\n </div>\n <div class=\"px-6\">\n <ax-json-viewer [json]=\"context()\"></ax-json-viewer>\n </div>\n </div>\n </ax-content>\n </ax-drawer>\n</ax-drawer-container>\n", styles: ["/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
|
|
2887
3762
|
}], ctorParameters: () => [] });
|
|
2888
3763
|
|
|
2889
3764
|
var preview_component = /*#__PURE__*/Object.freeze({
|
|
@@ -2895,5 +3770,5 @@ var preview_component = /*#__PURE__*/Object.freeze({
|
|
|
2895
3770
|
* Generated bundle index. Do not edit.
|
|
2896
3771
|
*/
|
|
2897
3772
|
|
|
2898
|
-
export { AXPDesignerAddWidgetButtonComponent, AXPDesignerAddWidgetLineButtonComponent, AXPDesignerAddWidgetMiniButtonComponent, AXPDesignerConnector, AXPDesignerFlexDrawerComponent, AXPDesignerGridDrawerComponent, AXPDesignerMessageKeys, AXPDesignerModes, AXPDesignerService, AXPDesignerWidgetPickerComponent, AXPLayoutDesignerComponent, AXPLayoutDesignerHeaderMenuHookKeys, AXPLayoutDesignerPreviewComponent, AXPLayoutDesignerPreviewViewerComponent, AXPTemplateLoadingStrategy, AXPWidgetDesignerRendererDirective, AXPWidgetPickerService, AXP_DESIGNER_ADD_WIDGET_MENU, AXP_DESIGNER_CLONE_MENU, AXP_DESIGNER_COPY_MENU, AXP_DESIGNER_CUT_MENU, AXP_DESIGNER_DELETE_WIDGET_MENU, AXP_DESIGNER_PASTE_MENU, AXP_DESIGNER_SAVE_AS_WIDGET_MENU, AXP_DESIGNER_SELECT_WIDGET_MENU, AXP_WIDGET_PICKER_TAB_CONTEXT, cloneWidgetMenu };
|
|
3773
|
+
export { AXPDesignerAddWidgetButtonComponent, AXPDesignerAddWidgetLineButtonComponent, AXPDesignerAddWidgetMiniButtonComponent, AXPDesignerConnector, AXPDesignerFlexDrawerComponent, AXPDesignerGridDrawerComponent, AXPDesignerMessageKeys, AXPDesignerModes, AXPDesignerService, AXPDesignerWidgetPickerComponent, AXPLayoutDesignerComponent, AXPLayoutDesignerFooterHookKeys, AXPLayoutDesignerHeaderMenuHookKeys, AXPLayoutDesignerPreviewComponent, AXPLayoutDesignerPreviewViewerComponent, AXPTemplateLoadingStrategy, AXPWidgetDesignerRendererDirective, AXPWidgetPickerService, AXP_DESIGNER_ADD_WIDGET_MENU, AXP_DESIGNER_CLONE_MENU, AXP_DESIGNER_COPY_MENU, AXP_DESIGNER_CUT_MENU, AXP_DESIGNER_DELETE_WIDGET_MENU, AXP_DESIGNER_PASTE_MENU, AXP_DESIGNER_SAVE_AS_WIDGET_MENU, AXP_DESIGNER_SELECT_WIDGET_MENU, AXP_FORM_DESIGNER_SURFACE_PROFILE, AXP_PAGE_DESIGNER_SURFACE_PROFILE, AXP_WIDGET_DESIGNER_SURFACE_PROFILE, AXP_WIDGET_PICKER_TAB_CONTEXT, cloneWidgetMenu, designerSurfaceHasDrawer, widgetMatchesDesignerSurface };
|
|
2899
3774
|
//# sourceMappingURL=acorex-platform-framework-client-layout-designer.mjs.map
|