@acorex/platform 20.8.9 → 20.8.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/acorex-platform-auth.mjs +125 -27
- package/fesm2022/acorex-platform-auth.mjs.map +1 -1
- package/fesm2022/{acorex-platform-common-common-settings.provider-DVvuLUfF.mjs → acorex-platform-common-common-settings.provider-Bi1RYif5.mjs} +30 -32
- package/fesm2022/acorex-platform-common-common-settings.provider-Bi1RYif5.mjs.map +1 -0
- package/fesm2022/acorex-platform-common.mjs +711 -205
- package/fesm2022/acorex-platform-common.mjs.map +1 -1
- package/fesm2022/acorex-platform-core.mjs +420 -127
- package/fesm2022/acorex-platform-core.mjs.map +1 -1
- package/fesm2022/acorex-platform-domain.mjs +557 -826
- package/fesm2022/acorex-platform-domain.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-builder.mjs +634 -114
- package/fesm2022/acorex-platform-layout-builder.mjs.map +1 -1
- package/fesm2022/{acorex-platform-layout-components-binding-expression-editor-popup.component-CSxCnzwU.mjs → acorex-platform-layout-components-binding-expression-editor-popup.component-CXEdvDTf.mjs} +9 -9
- package/fesm2022/acorex-platform-layout-components-binding-expression-editor-popup.component-CXEdvDTf.mjs.map +1 -0
- package/fesm2022/acorex-platform-layout-components.mjs +3365 -880
- package/fesm2022/acorex-platform-layout-components.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-designer.mjs +456 -204
- package/fesm2022/acorex-platform-layout-designer.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-entity.mjs +18667 -14048
- package/fesm2022/acorex-platform-layout-entity.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-views.mjs +413 -171
- package/fesm2022/acorex-platform-layout-views.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-widget-core.mjs +507 -441
- package/fesm2022/acorex-platform-layout-widget-core.mjs.map +1 -1
- package/fesm2022/{acorex-platform-layout-widgets-button-widget-designer.component-CPBzE96V.mjs → acorex-platform-layout-widgets-button-widget-designer.component-Dy7jF-oD.mjs} +10 -10
- package/fesm2022/acorex-platform-layout-widgets-button-widget-designer.component-Dy7jF-oD.mjs.map +1 -0
- package/fesm2022/{acorex-platform-layout-widgets-file-list-popup.component-Dtv6U3df.mjs → acorex-platform-layout-widgets-file-list-popup.component-CDYAGBku.mjs} +21 -76
- package/fesm2022/acorex-platform-layout-widgets-file-list-popup.component-CDYAGBku.mjs.map +1 -0
- package/fesm2022/{acorex-platform-layout-widgets-image-preview.popup-QxJfswhK.mjs → acorex-platform-layout-widgets-image-preview.popup-C_EPAvCU.mjs} +6 -7
- package/fesm2022/acorex-platform-layout-widgets-image-preview.popup-C_EPAvCU.mjs.map +1 -0
- package/fesm2022/{acorex-platform-layout-widgets-page-widget-designer.component-CVdssZBD.mjs → acorex-platform-layout-widgets-page-widget-designer.component-D10yO28c.mjs} +12 -12
- package/fesm2022/acorex-platform-layout-widgets-page-widget-designer.component-D10yO28c.mjs.map +1 -0
- package/fesm2022/acorex-platform-layout-widgets-repeater-widget-column.component-BGO75IMz.mjs +116 -0
- package/fesm2022/acorex-platform-layout-widgets-repeater-widget-column.component-BGO75IMz.mjs.map +1 -0
- package/fesm2022/{acorex-platform-layout-widgets-tabular-data-edit-popup.component-DVaZN9QN.mjs → acorex-platform-layout-widgets-tabular-data-edit-popup.component-DmzNTYiS.mjs} +5 -5
- package/fesm2022/acorex-platform-layout-widgets-tabular-data-edit-popup.component-DmzNTYiS.mjs.map +1 -0
- package/fesm2022/{acorex-platform-layout-widgets-tabular-data-view-popup.component-DPGHgXa6.mjs → acorex-platform-layout-widgets-tabular-data-view-popup.component-BNG_588B.mjs} +4 -4
- package/fesm2022/acorex-platform-layout-widgets-tabular-data-view-popup.component-BNG_588B.mjs.map +1 -0
- package/fesm2022/{acorex-platform-layout-widgets-text-block-widget-designer.component-CdiNW691.mjs → acorex-platform-layout-widgets-text-block-widget-designer.component-Vo4fWHtX.mjs} +6 -6
- package/fesm2022/acorex-platform-layout-widgets-text-block-widget-designer.component-Vo4fWHtX.mjs.map +1 -0
- package/fesm2022/acorex-platform-layout-widgets.mjs +6578 -4314
- package/fesm2022/acorex-platform-layout-widgets.mjs.map +1 -1
- package/fesm2022/acorex-platform-native.mjs +8 -7
- package/fesm2022/acorex-platform-native.mjs.map +1 -1
- package/fesm2022/acorex-platform-runtime.mjs +391 -166
- package/fesm2022/acorex-platform-runtime.mjs.map +1 -1
- package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-Cx1lLUaR.mjs +160 -0
- package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-Cx1lLUaR.mjs.map +1 -0
- package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-AOrcgjDF.mjs +120 -0
- package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-AOrcgjDF.mjs.map +1 -0
- package/fesm2022/{acorex-platform-themes-default-entity-master-single-view.component-rGsMVAZj.mjs → acorex-platform-themes-default-entity-master-single-view.component-BfCeUU5F.mjs} +16 -23
- package/fesm2022/acorex-platform-themes-default-entity-master-single-view.component-BfCeUU5F.mjs.map +1 -0
- package/fesm2022/{acorex-platform-themes-default-error-401.component-53VB-PS_.mjs → acorex-platform-themes-default-error-401.component-C7EYJzSr.mjs} +4 -4
- package/fesm2022/acorex-platform-themes-default-error-401.component-C7EYJzSr.mjs.map +1 -0
- package/fesm2022/{acorex-platform-themes-default-error-404.component-DVF9soT5.mjs → acorex-platform-themes-default-error-404.component-7MVLMwIa.mjs} +4 -4
- package/fesm2022/acorex-platform-themes-default-error-404.component-7MVLMwIa.mjs.map +1 -0
- package/fesm2022/acorex-platform-themes-default-error-offline.component-DR6G8gPC.mjs +19 -0
- package/fesm2022/acorex-platform-themes-default-error-offline.component-DR6G8gPC.mjs.map +1 -0
- package/fesm2022/acorex-platform-themes-default.mjs +1784 -61
- package/fesm2022/acorex-platform-themes-default.mjs.map +1 -1
- package/fesm2022/{acorex-platform-themes-shared-icon-chooser-column.component-TJ9PWHMY.mjs → acorex-platform-themes-shared-icon-chooser-column.component-CqkWJYdv.mjs} +6 -6
- package/fesm2022/acorex-platform-themes-shared-icon-chooser-column.component-CqkWJYdv.mjs.map +1 -0
- package/fesm2022/{acorex-platform-themes-shared-icon-chooser-view.component-BHcKkIx0.mjs → acorex-platform-themes-shared-icon-chooser-view.component-BOTuLdWN.mjs} +6 -6
- package/fesm2022/acorex-platform-themes-shared-icon-chooser-view.component-BOTuLdWN.mjs.map +1 -0
- package/fesm2022/{acorex-platform-themes-shared-settings.provider-DSs1o1M6.mjs → acorex-platform-themes-shared-settings.provider-DK6R87Lf.mjs} +24 -25
- package/fesm2022/acorex-platform-themes-shared-settings.provider-DK6R87Lf.mjs.map +1 -0
- package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-column.component-D566Kdvy.mjs +94 -0
- package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-column.component-D566Kdvy.mjs.map +1 -0
- package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-view.component-D7-rCGl7.mjs +86 -0
- package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-view.component-D7-rCGl7.mjs.map +1 -0
- package/fesm2022/acorex-platform-themes-shared.mjs +408 -305
- package/fesm2022/acorex-platform-themes-shared.mjs.map +1 -1
- package/fesm2022/acorex-platform-workflow.mjs +359 -100
- package/fesm2022/acorex-platform-workflow.mjs.map +1 -1
- package/fesm2022/acorex-platform.mjs.map +1 -1
- package/package.json +31 -31
- package/{auth/index.d.ts → types/acorex-platform-auth.d.ts} +14 -2
- package/{common/index.d.ts → types/acorex-platform-common.d.ts} +302 -30
- package/{core/index.d.ts → types/acorex-platform-core.d.ts} +188 -44
- package/{domain/index.d.ts → types/acorex-platform-domain.d.ts} +744 -412
- package/{layout/builder/index.d.ts → types/acorex-platform-layout-builder.d.ts} +160 -38
- package/{layout/components/index.d.ts → types/acorex-platform-layout-components.d.ts} +854 -125
- package/{layout/designer/index.d.ts → types/acorex-platform-layout-designer.d.ts} +96 -18
- package/{layout/entity/index.d.ts → types/acorex-platform-layout-entity.d.ts} +848 -63
- package/{layout/views/index.d.ts → types/acorex-platform-layout-views.d.ts} +80 -47
- package/{layout/widget-core/index.d.ts → types/acorex-platform-layout-widget-core.d.ts} +274 -197
- package/{layout/widgets/index.d.ts → types/acorex-platform-layout-widgets.d.ts} +608 -122
- package/{native/index.d.ts → types/acorex-platform-native.d.ts} +0 -7
- package/types/acorex-platform-runtime.d.ts +571 -0
- package/{themes/default/index.d.ts → types/acorex-platform-themes-default.d.ts} +113 -4
- package/{themes/shared/index.d.ts → types/acorex-platform-themes-shared.d.ts} +5 -4
- package/{workflow/index.d.ts → types/acorex-platform-workflow.d.ts} +162 -81
- package/fesm2022/acorex-platform-common-common-settings.provider-DVvuLUfF.mjs.map +0 -1
- package/fesm2022/acorex-platform-layout-components-binding-expression-editor-popup.component-CSxCnzwU.mjs.map +0 -1
- package/fesm2022/acorex-platform-layout-widgets-button-widget-designer.component-CPBzE96V.mjs.map +0 -1
- package/fesm2022/acorex-platform-layout-widgets-file-list-popup.component-Dtv6U3df.mjs.map +0 -1
- package/fesm2022/acorex-platform-layout-widgets-image-preview.popup-QxJfswhK.mjs.map +0 -1
- package/fesm2022/acorex-platform-layout-widgets-page-widget-designer.component-CVdssZBD.mjs.map +0 -1
- package/fesm2022/acorex-platform-layout-widgets-repeater-widget-column.component-BCxE0RTB.mjs +0 -111
- package/fesm2022/acorex-platform-layout-widgets-repeater-widget-column.component-BCxE0RTB.mjs.map +0 -1
- package/fesm2022/acorex-platform-layout-widgets-tabular-data-edit-popup.component-DVaZN9QN.mjs.map +0 -1
- package/fesm2022/acorex-platform-layout-widgets-tabular-data-view-popup.component-DPGHgXa6.mjs.map +0 -1
- package/fesm2022/acorex-platform-layout-widgets-text-block-widget-designer.component-CdiNW691.mjs.map +0 -1
- package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-D4hU2SCE.mjs +0 -160
- package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-D4hU2SCE.mjs.map +0 -1
- package/fesm2022/acorex-platform-themes-default-entity-master-list-view.component-D2CtNrSn.mjs +0 -1716
- package/fesm2022/acorex-platform-themes-default-entity-master-list-view.component-D2CtNrSn.mjs.map +0 -1
- package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-BVTklnzs.mjs +0 -120
- package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-BVTklnzs.mjs.map +0 -1
- package/fesm2022/acorex-platform-themes-default-entity-master-single-view.component-rGsMVAZj.mjs.map +0 -1
- package/fesm2022/acorex-platform-themes-default-error-401.component-53VB-PS_.mjs.map +0 -1
- package/fesm2022/acorex-platform-themes-default-error-404.component-DVF9soT5.mjs.map +0 -1
- package/fesm2022/acorex-platform-themes-default-error-offline.component-CwNNHzZn.mjs +0 -19
- package/fesm2022/acorex-platform-themes-default-error-offline.component-CwNNHzZn.mjs.map +0 -1
- package/fesm2022/acorex-platform-themes-shared-icon-chooser-column.component-TJ9PWHMY.mjs.map +0 -1
- package/fesm2022/acorex-platform-themes-shared-icon-chooser-view.component-BHcKkIx0.mjs.map +0 -1
- package/fesm2022/acorex-platform-themes-shared-settings.provider-DSs1o1M6.mjs.map +0 -1
- package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-column.component-BUPs84MI.mjs +0 -65
- package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-column.component-BUPs84MI.mjs.map +0 -1
- package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-view.component-BotknoHn.mjs +0 -64
- package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-view.component-BotknoHn.mjs.map +0 -1
- package/runtime/index.d.ts +0 -307
- /package/{index.d.ts → types/acorex-platform.d.ts} +0 -0
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import * as i5 from '@angular/common';
|
|
2
2
|
import { CommonModule } from '@angular/common';
|
|
3
3
|
import * as i0 from '@angular/core';
|
|
4
|
-
import { Injectable, inject, input, model, signal, effect, output, viewChild, ChangeDetectionStrategy, Component, NgModule, EventEmitter, Output } from '@angular/core';
|
|
4
|
+
import { Injectable, inject, input, model, signal, computed, effect, output, viewChild, ChangeDetectionStrategy, Component, NgModule, EventEmitter, Output } from '@angular/core';
|
|
5
|
+
import { provideCommandSetups, AXPCommandService } from '@acorex/platform/runtime';
|
|
5
6
|
import { AXPopupService } from '@acorex/components/popup';
|
|
7
|
+
import * as i4 from '@acorex/platform/core';
|
|
8
|
+
import { AXPHookService, AXPExpressionEvaluatorService, AXPComponentSlotModule, AXPContextStore } from '@acorex/platform/core';
|
|
6
9
|
import * as i1 from '@acorex/platform/layout/widget-core';
|
|
7
|
-
import { AXPWidgetSerializationHelper, AXPWidgetContainerComponent, AXPPageStatus, AXPWidgetCoreModule } from '@acorex/platform/layout/widget-core';
|
|
8
|
-
import { cloneDeep, isNil, set, isEqual } from 'lodash-es';
|
|
10
|
+
import { AXPWidgetSerializationHelper, AXPWidgetContainerComponent, AXPPageStatus, AXPWidgetCoreModule, AXPWidgetRegistryService } from '@acorex/platform/layout/widget-core';
|
|
11
|
+
import { cloneDeep, isNil, set, isEqual, merge } from 'lodash-es';
|
|
9
12
|
import * as i2 from '@acorex/components/form';
|
|
10
13
|
import { AXFormComponent, AXFormModule } from '@acorex/components/form';
|
|
11
14
|
import { Subject, debounceTime, distinctUntilChanged, startWith } from 'rxjs';
|
|
@@ -17,9 +20,35 @@ import * as i3 from '@acorex/components/loading';
|
|
|
17
20
|
import { AXLoadingModule } from '@acorex/components/loading';
|
|
18
21
|
import { AXBasePageComponent } from '@acorex/components/page';
|
|
19
22
|
import * as i6 from '@acorex/core/translation';
|
|
20
|
-
import { AXTranslationModule } from '@acorex/core/translation';
|
|
21
|
-
import
|
|
22
|
-
|
|
23
|
+
import { AXTranslationModule, AXTranslationService } from '@acorex/core/translation';
|
|
24
|
+
import { AXP_ENTITY_DEFINITION_CRUD_SERVICE } from '@acorex/platform/domain';
|
|
25
|
+
|
|
26
|
+
//#region ---- Imports ----
|
|
27
|
+
//#endregion
|
|
28
|
+
//#region ---- Before open ----
|
|
29
|
+
/**
|
|
30
|
+
* Runs after dialog options and context are prepared and **before** footer customization and popup open.
|
|
31
|
+
* Listeners may mutate {@link AXPLayoutBuilderDialogBeforeOpenPayload.context} by reference.
|
|
32
|
+
*/
|
|
33
|
+
const AXP_LAYOUT_BUILDER_DIALOG_BEFORE_OPEN_HOOK_KEY = 'layout-builder.dialog.before-open';
|
|
34
|
+
//#endregion
|
|
35
|
+
//#region ---- Footer actions ----
|
|
36
|
+
/**
|
|
37
|
+
* Runs after builder-defined footer actions exist and **before** the dialog opens.
|
|
38
|
+
* Listeners receive the live `actions.footer.prefix` / `suffix` arrays (same references as the dialog)
|
|
39
|
+
* so they may push, splice, filter, or replace items. They may also mutate {@link AXPLayoutBuilderDialogFooterPayload.context} by reference.
|
|
40
|
+
*/
|
|
41
|
+
const AXP_LAYOUT_BUILDER_DIALOG_CONFIG_HOOK_KEY = 'layout-builder.dialog.config';
|
|
42
|
+
//#endregion
|
|
43
|
+
//#region ---- Context updates (after open) ----
|
|
44
|
+
/**
|
|
45
|
+
* Runs whenever the dialog layout builder context changes (debounced upstream), **after** the popup is visible.
|
|
46
|
+
* Use for side effects that depend on live context (for example values updated by widgets after render).
|
|
47
|
+
* Payload mirrors `AXPDialogRendererComponent` semantics: {@link AXPLayoutBuilderDialogContextChangedPayload.getContext},
|
|
48
|
+
* {@link AXPLayoutBuilderDialogContextChangedPayload.patchContext}, and optional loading state.
|
|
49
|
+
*/
|
|
50
|
+
const AXP_LAYOUT_BUILDER_DIALOG_CONTEXT_CHANGED_HOOK_KEY = 'layout-builder.dialog.context-changed';
|
|
51
|
+
//#endregion
|
|
23
52
|
|
|
24
53
|
class AXPLayoutConversionService {
|
|
25
54
|
constructor() {
|
|
@@ -159,6 +188,10 @@ class AXPLayoutConversionService {
|
|
|
159
188
|
if (!editorWidget.mode) {
|
|
160
189
|
editorWidget.mode = fieldMode;
|
|
161
190
|
}
|
|
191
|
+
const hintOpts = field.description != null &&
|
|
192
|
+
(typeof field.description !== 'string' || field.description.trim().length > 0)
|
|
193
|
+
? { hint: field.description, hintDisplayMode: 'note' }
|
|
194
|
+
: {};
|
|
162
195
|
return {
|
|
163
196
|
type: 'form-field',
|
|
164
197
|
name: field.path,
|
|
@@ -166,8 +199,8 @@ class AXPLayoutConversionService {
|
|
|
166
199
|
options: {
|
|
167
200
|
label: field.title,
|
|
168
201
|
badge: field.badge,
|
|
169
|
-
description: field.description,
|
|
170
202
|
showLabel: true,
|
|
203
|
+
...hintOpts,
|
|
171
204
|
},
|
|
172
205
|
children: [editorWidget], // The editor widget becomes a child of form-field
|
|
173
206
|
};
|
|
@@ -210,7 +243,7 @@ class AXPLayoutConversionService {
|
|
|
210
243
|
path: formFieldNode.name || editorWidget.name || `field-${Date.now()}`,
|
|
211
244
|
title: formFieldNode.options?.['label'],
|
|
212
245
|
badge: formFieldNode.options?.['badge'],
|
|
213
|
-
description: formFieldNode.options?.['
|
|
246
|
+
description: formFieldNode.options?.['hint'],
|
|
214
247
|
widget: editorWidget,
|
|
215
248
|
mode: formFieldNode.mode,
|
|
216
249
|
};
|
|
@@ -223,9 +256,16 @@ class AXPLayoutConversionService {
|
|
|
223
256
|
const keyParts = [];
|
|
224
257
|
keyParts.push(`groups:${formDefinition.groups.length}`);
|
|
225
258
|
formDefinition.groups.forEach((group, groupIndex) => {
|
|
226
|
-
|
|
259
|
+
// Include group.mode so view vs edit (or mixed) layouts do not share a cached widget tree.
|
|
260
|
+
const groupModePart = group.mode ?? '_';
|
|
261
|
+
keyParts.push(`g${groupIndex}:${group.name}:${group.parameters.length}:${groupModePart}`);
|
|
262
|
+
keyParts.push(`gL${groupIndex}:${JSON.stringify(group.title ?? null)}:${JSON.stringify(group.description ?? null)}`);
|
|
227
263
|
group.parameters.forEach((param, paramIndex) => {
|
|
228
|
-
|
|
264
|
+
// Field mode must be part of the key; otherwise metadata forms that only differ by
|
|
265
|
+
// view/edit (same paths and widget types) incorrectly reuse the first cached tree.
|
|
266
|
+
const fieldModePart = param.mode ?? '_';
|
|
267
|
+
keyParts.push(`p${groupIndex}.${paramIndex}:${param.path}:${param.widget.type}:${fieldModePart}`);
|
|
268
|
+
keyParts.push(`pL${groupIndex}.${paramIndex}:${JSON.stringify(param.title ?? null)}:${JSON.stringify(param.description ?? null)}:${JSON.stringify(param.badge ?? null)}`);
|
|
229
269
|
});
|
|
230
270
|
});
|
|
231
271
|
if (formDefinition.mode) {
|
|
@@ -286,10 +326,10 @@ class AXPLayoutConversionService {
|
|
|
286
326
|
}
|
|
287
327
|
return Math.abs(hash).toString(36); // Convert to base36 for shorter string
|
|
288
328
|
}
|
|
289
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
290
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
329
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPLayoutConversionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
330
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPLayoutConversionService, providedIn: 'root' }); }
|
|
291
331
|
}
|
|
292
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
332
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPLayoutConversionService, decorators: [{
|
|
293
333
|
type: Injectable,
|
|
294
334
|
args: [{
|
|
295
335
|
providedIn: 'root',
|
|
@@ -399,17 +439,18 @@ function getNestedValue(obj, path) {
|
|
|
399
439
|
class AXPLayoutBuilderService {
|
|
400
440
|
constructor() {
|
|
401
441
|
this.popupService = inject(AXPopupService);
|
|
442
|
+
this.hookService = inject(AXPHookService, { optional: true }) ?? undefined;
|
|
402
443
|
}
|
|
403
444
|
/**
|
|
404
445
|
* Create a new layout builder
|
|
405
446
|
*/
|
|
406
447
|
create() {
|
|
407
|
-
return new LayoutBuilder(this.popupService);
|
|
448
|
+
return new LayoutBuilder(this.popupService, this.hookService);
|
|
408
449
|
}
|
|
409
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
410
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
450
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPLayoutBuilderService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
451
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPLayoutBuilderService, providedIn: 'root' }); }
|
|
411
452
|
}
|
|
412
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
453
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPLayoutBuilderService, decorators: [{
|
|
413
454
|
type: Injectable,
|
|
414
455
|
args: [{
|
|
415
456
|
providedIn: 'root',
|
|
@@ -422,8 +463,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
422
463
|
* Open/Closed: Extensible through container delegates
|
|
423
464
|
*/
|
|
424
465
|
class LayoutBuilder {
|
|
425
|
-
constructor(popupService) {
|
|
466
|
+
constructor(popupService, hookService) {
|
|
426
467
|
this.popupService = popupService;
|
|
468
|
+
this.hookService = hookService;
|
|
427
469
|
this.root = {
|
|
428
470
|
children: [],
|
|
429
471
|
mode: 'edit',
|
|
@@ -493,7 +535,7 @@ class LayoutBuilder {
|
|
|
493
535
|
if (!this.popupService) {
|
|
494
536
|
throw new Error('LayoutBuilder requires AXPopupService to create dialogs. Please inject it in the service constructor.');
|
|
495
537
|
}
|
|
496
|
-
const container = new DialogContainerBuilder(this.popupService);
|
|
538
|
+
const container = new DialogContainerBuilder(this.popupService, this.hookService);
|
|
497
539
|
if (delegate) {
|
|
498
540
|
delegate(container);
|
|
499
541
|
}
|
|
@@ -518,11 +560,21 @@ class LayoutBuilder {
|
|
|
518
560
|
return this;
|
|
519
561
|
}
|
|
520
562
|
build() {
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
mode:
|
|
563
|
+
const r = this.root;
|
|
564
|
+
const node = {
|
|
565
|
+
type: r.type,
|
|
566
|
+
...(r.mode !== undefined ? { mode: r.mode } : {}),
|
|
567
|
+
...(r.children !== undefined ? { children: r.children } : {}),
|
|
568
|
+
...(r.options !== undefined ? { options: r.options } : {}),
|
|
569
|
+
...(r.name !== undefined ? { name: r.name } : {}),
|
|
570
|
+
...(r.path !== undefined ? { path: r.path } : {}),
|
|
571
|
+
...(r.visible !== undefined ? { visible: r.visible } : {}),
|
|
572
|
+
...(r.defaultValue !== undefined ? { defaultValue: r.defaultValue } : {}),
|
|
573
|
+
...(r.triggers !== undefined ? { triggers: r.triggers } : {}),
|
|
574
|
+
...(r.meta !== undefined ? { meta: r.meta } : {}),
|
|
575
|
+
...(r.valueTransforms !== undefined ? { valueTransforms: r.valueTransforms } : {}),
|
|
525
576
|
};
|
|
577
|
+
return node;
|
|
526
578
|
}
|
|
527
579
|
/**
|
|
528
580
|
* Converts the built widget node to JSON string
|
|
@@ -591,6 +643,7 @@ class BaseContainerBuilder {
|
|
|
591
643
|
'number-editor',
|
|
592
644
|
'select-editor',
|
|
593
645
|
'lookup-editor',
|
|
646
|
+
'entity-definition-provider-editor',
|
|
594
647
|
'selection-list-editor',
|
|
595
648
|
'date-time-editor',
|
|
596
649
|
'toggle-editor',
|
|
@@ -693,32 +746,30 @@ class BaseContainerMixin extends BaseContainerBuilder {
|
|
|
693
746
|
class LayoutContainerMixin extends BaseContainerMixin {
|
|
694
747
|
layout(value) {
|
|
695
748
|
// Map layout intent to grid item sizing so containers like `form-field`
|
|
696
|
-
// can span multiple columns inside grid/fieldset layouts.
|
|
749
|
+
// can span multiple columns/rows inside grid/fieldset layouts.
|
|
697
750
|
if (!this.containerState.options)
|
|
698
751
|
this.containerState.options = {};
|
|
699
752
|
if (typeof value === 'number') {
|
|
700
|
-
// Direct numeric shorthand → colSpan
|
|
701
753
|
this.containerState.options.colSpan = value;
|
|
702
754
|
}
|
|
703
755
|
else if (value) {
|
|
704
|
-
// Try to extract grid positioning from breakpoint positions
|
|
705
756
|
const positions = value.positions;
|
|
706
757
|
if (positions) {
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
if (
|
|
711
|
-
|
|
712
|
-
if (
|
|
713
|
-
|
|
714
|
-
if (
|
|
715
|
-
|
|
716
|
-
if (
|
|
717
|
-
|
|
718
|
-
if (
|
|
719
|
-
|
|
720
|
-
if (
|
|
721
|
-
|
|
758
|
+
const placement = positions?.lg ?? positions?.xl ?? positions?.xxl ?? positions?.md ?? positions?.sm;
|
|
759
|
+
if (placement) {
|
|
760
|
+
const opts = this.containerState.options;
|
|
761
|
+
if (placement.colSpan != null)
|
|
762
|
+
opts.colSpan = placement.colSpan;
|
|
763
|
+
if (placement.colStart != null)
|
|
764
|
+
opts.colStart = placement.colStart;
|
|
765
|
+
if (placement.colEnd != null)
|
|
766
|
+
opts.colEnd = placement.colEnd;
|
|
767
|
+
if (placement.rowSpan != null)
|
|
768
|
+
opts.rowSpan = placement.rowSpan;
|
|
769
|
+
if (placement.rowStart != null)
|
|
770
|
+
opts.rowStart = placement.rowStart;
|
|
771
|
+
if (placement.rowEnd != null)
|
|
772
|
+
opts.rowEnd = placement.rowEnd;
|
|
722
773
|
}
|
|
723
774
|
}
|
|
724
775
|
}
|
|
@@ -937,6 +988,7 @@ class WidgetContainerMixin extends ChildContainerMixin {
|
|
|
937
988
|
'number-editor',
|
|
938
989
|
'select-editor',
|
|
939
990
|
'lookup-editor',
|
|
991
|
+
'entity-definition-provider-editor',
|
|
940
992
|
'selection-list-editor',
|
|
941
993
|
'date-time-editor',
|
|
942
994
|
'toggle-editor',
|
|
@@ -992,12 +1044,73 @@ class FlexContainerBuilder extends WidgetContainerMixin {
|
|
|
992
1044
|
* Grid Container Builder - Liskov Substitution Principle
|
|
993
1045
|
* Extends WidgetContainerMixin to inherit all common functionality
|
|
994
1046
|
*/
|
|
1047
|
+
/**
|
|
1048
|
+
* Extracts flat grid-item options from AXPGridLayoutOptions for grid-item-layout widget.
|
|
1049
|
+
* Uses first available breakpoint (lg, xl, md, sm).
|
|
1050
|
+
*/
|
|
1051
|
+
/**
|
|
1052
|
+
* Deep-merges grid breakpoint buckets so sequential fluent calls (e.g. setColumns then setGap)
|
|
1053
|
+
* do not wipe sibling keys under options.grid.default.
|
|
1054
|
+
*/
|
|
1055
|
+
function mergeAXPGridContainerOptions(prev, patch) {
|
|
1056
|
+
const next = { ...(prev ?? {}), ...patch };
|
|
1057
|
+
if (prev?.grid?.default || patch.grid?.default) {
|
|
1058
|
+
next.grid = {
|
|
1059
|
+
...(prev?.grid ?? {}),
|
|
1060
|
+
...(patch.grid ?? {}),
|
|
1061
|
+
default: {
|
|
1062
|
+
...(prev?.grid?.default ?? {}),
|
|
1063
|
+
...(patch.grid?.default ?? {}),
|
|
1064
|
+
},
|
|
1065
|
+
};
|
|
1066
|
+
}
|
|
1067
|
+
return next;
|
|
1068
|
+
}
|
|
1069
|
+
function toGridItemOptions(layoutOptions) {
|
|
1070
|
+
if (!layoutOptions?.positions)
|
|
1071
|
+
return { colSpan: 12 };
|
|
1072
|
+
const positions = layoutOptions.positions;
|
|
1073
|
+
const placement = positions['lg'] ?? positions['xl'] ?? positions['xxl'] ?? positions['md'] ?? positions['sm'];
|
|
1074
|
+
if (!placement)
|
|
1075
|
+
return { colSpan: 12 };
|
|
1076
|
+
const opts = {};
|
|
1077
|
+
if (placement['colSpan'] != null)
|
|
1078
|
+
opts['colSpan'] = placement['colSpan'];
|
|
1079
|
+
if (placement['colStart'] != null)
|
|
1080
|
+
opts['colStart'] = placement['colStart'];
|
|
1081
|
+
if (placement['colEnd'] != null)
|
|
1082
|
+
opts['colEnd'] = placement['colEnd'];
|
|
1083
|
+
if (placement['rowSpan'] != null)
|
|
1084
|
+
opts['rowSpan'] = placement['rowSpan'];
|
|
1085
|
+
if (placement['rowStart'] != null)
|
|
1086
|
+
opts['rowStart'] = placement['rowStart'];
|
|
1087
|
+
if (placement['rowEnd'] != null)
|
|
1088
|
+
opts['rowEnd'] = placement['rowEnd'];
|
|
1089
|
+
if (Object.keys(opts).length === 0)
|
|
1090
|
+
opts['colSpan'] = 12;
|
|
1091
|
+
return opts;
|
|
1092
|
+
}
|
|
995
1093
|
class GridContainerBuilder extends WidgetContainerMixin {
|
|
996
1094
|
constructor() {
|
|
997
1095
|
super('grid-layout');
|
|
998
1096
|
}
|
|
999
1097
|
setOptions(options) {
|
|
1000
|
-
this.containerState.options =
|
|
1098
|
+
this.containerState.options = mergeAXPGridContainerOptions(this.containerState.options, options);
|
|
1099
|
+
return this;
|
|
1100
|
+
}
|
|
1101
|
+
item(layoutOptions, delegate) {
|
|
1102
|
+
const fieldset = new FieldsetContainerBuilder();
|
|
1103
|
+
fieldset.withInheritanceContext(this.inheritanceContext);
|
|
1104
|
+
delegate(fieldset);
|
|
1105
|
+
const fieldsetNode = fieldset.build();
|
|
1106
|
+
const gridItemOptions = toGridItemOptions(layoutOptions);
|
|
1107
|
+
const gridItemNode = {
|
|
1108
|
+
type: 'grid-item-layout',
|
|
1109
|
+
options: gridItemOptions,
|
|
1110
|
+
children: [fieldsetNode],
|
|
1111
|
+
};
|
|
1112
|
+
this.ensureChildren();
|
|
1113
|
+
this.containerState.children.push(gridItemNode);
|
|
1001
1114
|
return this;
|
|
1002
1115
|
}
|
|
1003
1116
|
// Individual fluent methods for Grid
|
|
@@ -1428,7 +1541,7 @@ class ListWidgetBuilder extends WidgetContainerMixin {
|
|
|
1428
1541
|
* Uses composition instead of inheritance for cleaner separation
|
|
1429
1542
|
*/
|
|
1430
1543
|
class DialogContainerBuilder {
|
|
1431
|
-
constructor(popupService) {
|
|
1544
|
+
constructor(popupService, hookService) {
|
|
1432
1545
|
this.dialogState = {
|
|
1433
1546
|
type: 'flex-layout', // This will be overridden when content layout exists
|
|
1434
1547
|
children: [],
|
|
@@ -1451,6 +1564,7 @@ class DialogContainerBuilder {
|
|
|
1451
1564
|
else {
|
|
1452
1565
|
this.popupService = inject(AXPopupService);
|
|
1453
1566
|
}
|
|
1567
|
+
this.hookService = hookService ?? inject(AXPHookService, { optional: true }) ?? undefined;
|
|
1454
1568
|
}
|
|
1455
1569
|
setOptions(options) {
|
|
1456
1570
|
this.dialogState.dialogOptions = { ...this.dialogState.dialogOptions, ...options };
|
|
@@ -1491,7 +1605,12 @@ class DialogContainerBuilder {
|
|
|
1491
1605
|
return this;
|
|
1492
1606
|
}
|
|
1493
1607
|
onAction(handler) {
|
|
1494
|
-
|
|
1608
|
+
this.dialogState.dialogOptions ??= {
|
|
1609
|
+
title: '',
|
|
1610
|
+
size: 'md',
|
|
1611
|
+
closeButton: false,
|
|
1612
|
+
};
|
|
1613
|
+
this.dialogState.dialogOptions.onAction = handler;
|
|
1495
1614
|
return this;
|
|
1496
1615
|
}
|
|
1497
1616
|
addCustomAction(action) {
|
|
@@ -1540,22 +1659,42 @@ class DialogContainerBuilder {
|
|
|
1540
1659
|
const dialogNode = this.build();
|
|
1541
1660
|
// Import the dialog renderer component dynamically
|
|
1542
1661
|
const { AXPDialogRendererComponent } = await Promise.resolve().then(function () { return dialogRenderer_component; });
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1662
|
+
this.dialogState.dialogOptions ??= {};
|
|
1663
|
+
if (this.dialogState.dialogOptions.context == null || typeof this.dialogState.dialogOptions.context !== 'object') {
|
|
1664
|
+
this.dialogState.dialogOptions.context = {};
|
|
1665
|
+
}
|
|
1666
|
+
const initialContext = this.dialogState.dialogOptions.context;
|
|
1667
|
+
this.dialogState.actions ??= { footer: { prefix: [], suffix: [] } };
|
|
1668
|
+
this.dialogState.actions.footer ??= { prefix: [], suffix: [] };
|
|
1669
|
+
this.dialogState.actions.footer.prefix ??= [];
|
|
1670
|
+
this.dialogState.actions.footer.suffix ??= [];
|
|
1671
|
+
const hookService = this.hookService;
|
|
1672
|
+
if (hookService) {
|
|
1673
|
+
const beforePayload = {
|
|
1674
|
+
context: initialContext,
|
|
1675
|
+
dialogOptions: this.dialogState.dialogOptions,
|
|
1676
|
+
};
|
|
1677
|
+
await hookService.runAsync(AXP_LAYOUT_BUILDER_DIALOG_BEFORE_OPEN_HOOK_KEY, beforePayload);
|
|
1678
|
+
}
|
|
1547
1679
|
// Create dialog configuration
|
|
1548
1680
|
const dialogConfig = {
|
|
1549
1681
|
title: this.dialogState.dialogOptions?.title || '',
|
|
1550
|
-
|
|
1682
|
+
//TODO: why we need message?
|
|
1683
|
+
//message: this.dialogState.dialogOptions?.message,
|
|
1551
1684
|
context: initialContext,
|
|
1552
1685
|
definition: dialogNode,
|
|
1686
|
+
metadata: this.dialogState.dialogOptions.metadata,
|
|
1553
1687
|
actions: this.dialogState.actions,
|
|
1554
1688
|
onAction: this.dialogState.dialogOptions?.onAction,
|
|
1555
1689
|
};
|
|
1690
|
+
//
|
|
1691
|
+
if (hookService) {
|
|
1692
|
+
await hookService.runAsync(AXP_LAYOUT_BUILDER_DIALOG_CONFIG_HOOK_KEY, dialogConfig);
|
|
1693
|
+
}
|
|
1556
1694
|
// The Promise resolves when user clicks an action button
|
|
1557
1695
|
return new Promise(async (resolve) => {
|
|
1558
|
-
|
|
1696
|
+
let flag = false;
|
|
1697
|
+
await this.popupService.open(AXPDialogRendererComponent, {
|
|
1559
1698
|
title: dialogConfig.title,
|
|
1560
1699
|
size: this.dialogState.dialogOptions?.size || 'md',
|
|
1561
1700
|
closeButton: this.dialogState.dialogOptions?.closeButton || false,
|
|
@@ -1564,10 +1703,14 @@ class DialogContainerBuilder {
|
|
|
1564
1703
|
data: {
|
|
1565
1704
|
config: dialogConfig,
|
|
1566
1705
|
callBack: (result) => {
|
|
1706
|
+
flag = true;
|
|
1567
1707
|
resolve(result);
|
|
1568
1708
|
},
|
|
1569
1709
|
},
|
|
1570
1710
|
});
|
|
1711
|
+
if (!flag) {
|
|
1712
|
+
resolve({ success: false });
|
|
1713
|
+
}
|
|
1571
1714
|
});
|
|
1572
1715
|
}
|
|
1573
1716
|
}
|
|
@@ -1769,10 +1912,19 @@ class ActionBuilder {
|
|
|
1769
1912
|
return this;
|
|
1770
1913
|
}
|
|
1771
1914
|
custom(action) {
|
|
1772
|
-
|
|
1773
|
-
|
|
1915
|
+
const position = action.position ?? 'suffix';
|
|
1916
|
+
if (position === 'prefix') {
|
|
1917
|
+
if (!this.dialogBuilder['dialogState'].actions.footer.prefix) {
|
|
1918
|
+
this.dialogBuilder['dialogState'].actions.footer.prefix = [];
|
|
1919
|
+
}
|
|
1920
|
+
this.dialogBuilder['dialogState'].actions.footer.prefix.push(action);
|
|
1921
|
+
}
|
|
1922
|
+
else {
|
|
1923
|
+
if (!this.dialogBuilder['dialogState'].actions.footer.suffix) {
|
|
1924
|
+
this.dialogBuilder['dialogState'].actions.footer.suffix = [];
|
|
1925
|
+
}
|
|
1926
|
+
this.dialogBuilder['dialogState'].actions.footer.suffix.push(action);
|
|
1774
1927
|
}
|
|
1775
|
-
this.dialogBuilder['dialogState'].actions.footer.suffix.push(action);
|
|
1776
1928
|
return this;
|
|
1777
1929
|
}
|
|
1778
1930
|
}
|
|
@@ -1921,22 +2073,27 @@ class AXPLayoutRendererComponent {
|
|
|
1921
2073
|
/**
|
|
1922
2074
|
* Form definition containing groups and fields OR widget tree
|
|
1923
2075
|
*/
|
|
1924
|
-
this.layout = input.required(...(ngDevMode ? [{ debugName: "layout" }] : []));
|
|
2076
|
+
this.layout = input.required(...(ngDevMode ? [{ debugName: "layout" }] : /* istanbul ignore next */ []));
|
|
1925
2077
|
/**
|
|
1926
2078
|
* Form context/model data
|
|
1927
2079
|
*/
|
|
1928
|
-
this.context = model({}, ...(ngDevMode ? [{ debugName: "context" }] : []));
|
|
2080
|
+
this.context = model({}, ...(ngDevMode ? [{ debugName: "context" }] : /* istanbul ignore next */ []));
|
|
1929
2081
|
/**
|
|
1930
2082
|
* Form appearance and density styling (normal, compact, spacious)
|
|
1931
2083
|
*/
|
|
1932
|
-
this.look = input('fieldset', ...(ngDevMode ? [{ debugName: "look" }] : []));
|
|
2084
|
+
this.look = input('fieldset', ...(ngDevMode ? [{ debugName: "look" }] : /* istanbul ignore next */ []));
|
|
1933
2085
|
/**
|
|
1934
2086
|
* Default form mode. Can be overridden by section/group and field.
|
|
1935
2087
|
*/
|
|
1936
|
-
this.mode = input('edit', ...(ngDevMode ? [{ debugName: "mode" }] : []));
|
|
2088
|
+
this.mode = input('edit', ...(ngDevMode ? [{ debugName: "mode" }] : /* istanbul ignore next */ []));
|
|
1937
2089
|
//#endregion
|
|
1938
2090
|
//#region ---- Widget Tree Conversion ----
|
|
1939
|
-
this.widgetTree = signal(null, ...(ngDevMode ? [{ debugName: "widgetTree" }] : []));
|
|
2091
|
+
this.widgetTree = signal(null, ...(ngDevMode ? [{ debugName: "widgetTree" }] : /* istanbul ignore next */ []));
|
|
2092
|
+
/**
|
|
2093
|
+
* Prefer explicit {@link AXPWidgetNode.mode} on the root node (e.g. dialog flex `mode('view')`)
|
|
2094
|
+
* so nested widgets resolve view vs edit correctly; fall back to the layout `mode` input.
|
|
2095
|
+
*/
|
|
2096
|
+
this.effectiveRenderMode = computed(() => this.widgetTree()?.mode ?? this.mode(), ...(ngDevMode ? [{ debugName: "effectiveRenderMode" }] : /* istanbul ignore next */ []));
|
|
1940
2097
|
/**
|
|
1941
2098
|
* Convert layout data to widget tree when inputs change
|
|
1942
2099
|
*/
|
|
@@ -1961,7 +2118,7 @@ class AXPLayoutRendererComponent {
|
|
|
1961
2118
|
if (!isEqual(prev, tree)) {
|
|
1962
2119
|
this.widgetTree.set(tree);
|
|
1963
2120
|
}
|
|
1964
|
-
}, ...(ngDevMode ? [{ debugName: "conversionEffect" }] : []));
|
|
2121
|
+
}, ...(ngDevMode ? [{ debugName: "conversionEffect" }] : /* istanbul ignore next */ []));
|
|
1965
2122
|
//#endregion
|
|
1966
2123
|
//#region ---- Outputs ----
|
|
1967
2124
|
/**
|
|
@@ -1974,12 +2131,12 @@ class AXPLayoutRendererComponent {
|
|
|
1974
2131
|
this.validityChange = output();
|
|
1975
2132
|
//#endregion
|
|
1976
2133
|
//#region ---- Properties ----
|
|
1977
|
-
this.form = viewChild(AXFormComponent, ...(ngDevMode ? [{ debugName: "form" }] : []));
|
|
1978
|
-
this.container = viewChild(AXPWidgetContainerComponent, ...(ngDevMode ? [{ debugName: "container" }] : []));
|
|
2134
|
+
this.form = viewChild(AXFormComponent, ...(ngDevMode ? [{ debugName: "form" }] : /* istanbul ignore next */ []));
|
|
2135
|
+
this.container = viewChild(AXPWidgetContainerComponent, ...(ngDevMode ? [{ debugName: "container" }] : /* istanbul ignore next */ []));
|
|
1979
2136
|
/**
|
|
1980
2137
|
* Internal context signal for reactivity
|
|
1981
2138
|
*/
|
|
1982
|
-
this.internalContext = signal({}, ...(ngDevMode ? [{ debugName: "internalContext" }] : []));
|
|
2139
|
+
this.internalContext = signal({}, ...(ngDevMode ? [{ debugName: "internalContext" }] : /* istanbul ignore next */ []));
|
|
1983
2140
|
/**
|
|
1984
2141
|
* Initial context for reset functionality
|
|
1985
2142
|
*/
|
|
@@ -1992,7 +2149,7 @@ class AXPLayoutRendererComponent {
|
|
|
1992
2149
|
this.#contextSyncEffect = effect(() => {
|
|
1993
2150
|
const ctx = this.context() ?? {};
|
|
1994
2151
|
this.contextUpdateSubject.next(ctx);
|
|
1995
|
-
}, ...(ngDevMode ? [{ debugName: "#contextSyncEffect" }] : []));
|
|
2152
|
+
}, ...(ngDevMode ? [{ debugName: "#contextSyncEffect" }] : /* istanbul ignore next */ []));
|
|
1996
2153
|
/**
|
|
1997
2154
|
* Effect to handle widget tree status changes
|
|
1998
2155
|
*/
|
|
@@ -2001,7 +2158,7 @@ class AXPLayoutRendererComponent {
|
|
|
2001
2158
|
if (widgetTree) {
|
|
2002
2159
|
this.container()?.builderService.setStatus(AXPPageStatus.Rendered);
|
|
2003
2160
|
}
|
|
2004
|
-
}, ...(ngDevMode ? [{ debugName: "#widgetStatusEffect" }] : []));
|
|
2161
|
+
}, ...(ngDevMode ? [{ debugName: "#widgetStatusEffect" }] : /* istanbul ignore next */ []));
|
|
2005
2162
|
}
|
|
2006
2163
|
//#endregion
|
|
2007
2164
|
//#region ---- Lifecycle Methods ----
|
|
@@ -2141,40 +2298,67 @@ class AXPLayoutRendererComponent {
|
|
|
2141
2298
|
isWidgetNode(data) {
|
|
2142
2299
|
return data && typeof data === 'object' && 'type' in data && typeof data.type === 'string';
|
|
2143
2300
|
}
|
|
2144
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2145
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
2301
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPLayoutRendererComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2302
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPLayoutRendererComponent, isStandalone: true, selector: "axp-layout-renderer", inputs: { layout: { classPropertyName: "layout", publicName: "layout", isSignal: true, isRequired: true, transformFunction: null }, context: { classPropertyName: "context", publicName: "context", isSignal: true, isRequired: false, transformFunction: null }, look: { classPropertyName: "look", publicName: "look", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { context: "contextChange", contextInitiated: "contextInitiated", validityChange: "validityChange" }, viewQueries: [{ propertyName: "form", first: true, predicate: AXFormComponent, descendants: true, isSignal: true }, { propertyName: "container", first: true, predicate: AXPWidgetContainerComponent, descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
2146
2303
|
<ax-form>
|
|
2147
2304
|
<axp-widgets-container [context]="internalContext()" (onContextChanged)="handleContextChanged($event)">
|
|
2148
2305
|
@if (widgetTree()) {
|
|
2149
|
-
<ng-container
|
|
2306
|
+
<ng-container
|
|
2307
|
+
axp-widget-renderer
|
|
2308
|
+
[node]="widgetTree()!"
|
|
2309
|
+
[mode]="effectiveRenderMode()"
|
|
2310
|
+
></ng-container>
|
|
2150
2311
|
}
|
|
2151
2312
|
</axp-widgets-container>
|
|
2152
2313
|
</ax-form>
|
|
2153
|
-
`, isInline: true, styles: [":host{display:block;width:100%}\n"], dependencies: [{ kind: "ngmodule", type:
|
|
2314
|
+
`, isInline: true, styles: [":host{display:block;width:100%}\n"], dependencies: [{ kind: "ngmodule", type: AXPWidgetCoreModule }, { kind: "component", type: i1.AXPWidgetContainerComponent, selector: "axp-widgets-container", inputs: ["context", "functions"], outputs: ["onContextChanged"] }, { kind: "directive", type: i1.AXPWidgetRendererDirective, selector: "[axp-widget-renderer]", inputs: ["parentNode", "index", "mode", "node"], outputs: ["onOptionsChanged", "onValueChanged", "onLoad"], exportAs: ["widgetRenderer"] }, { kind: "ngmodule", type: AXFormModule }, { kind: "component", type: i2.AXFormComponent, selector: "ax-form", inputs: ["disabled", "readonly", "labelMode", "look", "messageStyle", "updateOn", "inUserInteractionActive"], outputs: ["onValidate", "updateOnChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2154
2315
|
}
|
|
2155
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2316
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPLayoutRendererComponent, decorators: [{
|
|
2156
2317
|
type: Component,
|
|
2157
|
-
args: [{ selector: 'axp-layout-renderer', standalone: true, imports: [
|
|
2318
|
+
args: [{ selector: 'axp-layout-renderer', standalone: true, imports: [AXPWidgetCoreModule, AXFormModule], changeDetection: ChangeDetectionStrategy.OnPush, template: `
|
|
2158
2319
|
<ax-form>
|
|
2159
2320
|
<axp-widgets-container [context]="internalContext()" (onContextChanged)="handleContextChanged($event)">
|
|
2160
2321
|
@if (widgetTree()) {
|
|
2161
|
-
<ng-container
|
|
2322
|
+
<ng-container
|
|
2323
|
+
axp-widget-renderer
|
|
2324
|
+
[node]="widgetTree()!"
|
|
2325
|
+
[mode]="effectiveRenderMode()"
|
|
2326
|
+
></ng-container>
|
|
2162
2327
|
}
|
|
2163
2328
|
</axp-widgets-container>
|
|
2164
2329
|
</ax-form>
|
|
2165
2330
|
`, styles: [":host{display:block;width:100%}\n"] }]
|
|
2166
2331
|
}], propDecorators: { layout: [{ type: i0.Input, args: [{ isSignal: true, alias: "layout", required: true }] }], context: [{ type: i0.Input, args: [{ isSignal: true, alias: "context", required: false }] }, { type: i0.Output, args: ["contextChange"] }], look: [{ type: i0.Input, args: [{ isSignal: true, alias: "look", required: false }] }], mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], contextInitiated: [{ type: i0.Output, args: ["contextInitiated"] }], validityChange: [{ type: i0.Output, args: ["validityChange"] }], form: [{ type: i0.ViewChild, args: [i0.forwardRef(() => AXFormComponent), { isSignal: true }] }], container: [{ type: i0.ViewChild, args: [i0.forwardRef(() => AXPWidgetContainerComponent), { isSignal: true }] }] } });
|
|
2167
2332
|
|
|
2333
|
+
/** Registration key for {@link AXPPreviewWidgetFieldCommand}; lives alone so `LayoutBuilderModule` can reference it without static-importing the command implementation. */
|
|
2334
|
+
const AXP_PREVIEW_WIDGET_FIELD_COMMAND_KEY = 'Widget:Preview';
|
|
2335
|
+
|
|
2168
2336
|
class LayoutBuilderModule {
|
|
2169
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2170
|
-
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "
|
|
2171
|
-
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "
|
|
2337
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: LayoutBuilderModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
2338
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.9", ngImport: i0, type: LayoutBuilderModule, imports: [CommonModule, AXPLayoutRendererComponent], exports: [AXPLayoutRendererComponent] }); }
|
|
2339
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: LayoutBuilderModule, providers: [
|
|
2340
|
+
AXPLayoutBuilderService,
|
|
2341
|
+
provideCommandSetups([
|
|
2342
|
+
{
|
|
2343
|
+
key: AXP_PREVIEW_WIDGET_FIELD_COMMAND_KEY,
|
|
2344
|
+
command: () => Promise.resolve().then(function () { return previewWidgetField_command; }).then((c) => c.AXPPreviewWidgetFieldCommand),
|
|
2345
|
+
},
|
|
2346
|
+
]),
|
|
2347
|
+
], imports: [CommonModule, AXPLayoutRendererComponent] }); }
|
|
2172
2348
|
}
|
|
2173
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2349
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: LayoutBuilderModule, decorators: [{
|
|
2174
2350
|
type: NgModule,
|
|
2175
2351
|
args: [{
|
|
2176
2352
|
imports: [CommonModule, AXPLayoutRendererComponent],
|
|
2177
|
-
providers: [
|
|
2353
|
+
providers: [
|
|
2354
|
+
AXPLayoutBuilderService,
|
|
2355
|
+
provideCommandSetups([
|
|
2356
|
+
{
|
|
2357
|
+
key: AXP_PREVIEW_WIDGET_FIELD_COMMAND_KEY,
|
|
2358
|
+
command: () => Promise.resolve().then(function () { return previewWidgetField_command; }).then((c) => c.AXPPreviewWidgetFieldCommand),
|
|
2359
|
+
},
|
|
2360
|
+
]),
|
|
2361
|
+
],
|
|
2178
2362
|
exports: [AXPLayoutRendererComponent],
|
|
2179
2363
|
}]
|
|
2180
2364
|
}] });
|
|
@@ -2186,17 +2370,25 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
|
|
|
2186
2370
|
super(...arguments);
|
|
2187
2371
|
this.result = new EventEmitter();
|
|
2188
2372
|
this.expressionEvaluator = inject(AXPExpressionEvaluatorService);
|
|
2189
|
-
this.
|
|
2373
|
+
this.commandService = inject(AXPCommandService);
|
|
2374
|
+
this.hookService = inject(AXPHookService, { optional: true });
|
|
2375
|
+
this.context = signal({}, ...(ngDevMode ? [{ debugName: "context" }] : /* istanbul ignore next */ []));
|
|
2190
2376
|
// This will be set by the popup service automatically - same as dynamic-dialog
|
|
2191
2377
|
this.callBack = () => { };
|
|
2192
|
-
this.isDialogLoading = signal(false, ...(ngDevMode ? [{ debugName: "isDialogLoading" }] : []));
|
|
2378
|
+
this.isDialogLoading = signal(false, ...(ngDevMode ? [{ debugName: "isDialogLoading" }] : /* istanbul ignore next */ []));
|
|
2193
2379
|
// Aggregated actions for footer rendering
|
|
2194
|
-
this.footerPrefix = signal([], ...(ngDevMode ? [{ debugName: "footerPrefix" }] : []));
|
|
2195
|
-
this.footerSuffix = signal([], ...(ngDevMode ? [{ debugName: "footerSuffix" }] : []));
|
|
2380
|
+
this.footerPrefix = signal([], ...(ngDevMode ? [{ debugName: "footerPrefix" }] : /* istanbul ignore next */ []));
|
|
2381
|
+
this.footerSuffix = signal([], ...(ngDevMode ? [{ debugName: "footerSuffix" }] : /* istanbul ignore next */ []));
|
|
2382
|
+
/**
|
|
2383
|
+
* Correlate layout context snapshots for distributed hooks (`layout-builder.dialog.context-changed`).
|
|
2384
|
+
*/
|
|
2385
|
+
this.contextChangedHooksSessionKey = typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function'
|
|
2386
|
+
? crypto.randomUUID()
|
|
2387
|
+
: `layout-dialog-ctx-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
2196
2388
|
//#endregion
|
|
2197
2389
|
//#region ---- View Accessors ----
|
|
2198
2390
|
// Access the internal layout renderer to reach the widgets container injector
|
|
2199
|
-
this.layoutRenderer = viewChild(AXPLayoutRendererComponent, ...(ngDevMode ? [{ debugName: "layoutRenderer" }] : []));
|
|
2391
|
+
this.layoutRenderer = viewChild(AXPLayoutRendererComponent, ...(ngDevMode ? [{ debugName: "layoutRenderer" }] : /* istanbul ignore next */ []));
|
|
2200
2392
|
this.#eff = effect(() => {
|
|
2201
2393
|
let count = 0;
|
|
2202
2394
|
this.aggregateAndEvaluateActions();
|
|
@@ -2217,22 +2409,48 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
|
|
|
2217
2409
|
this.aggregateAndEvaluateActions();
|
|
2218
2410
|
}, 200);
|
|
2219
2411
|
}
|
|
2220
|
-
}, ...(ngDevMode ? [{ debugName: "#eff" }] : []));
|
|
2412
|
+
}, ...(ngDevMode ? [{ debugName: "#eff" }] : /* istanbul ignore next */ []));
|
|
2221
2413
|
}
|
|
2222
2414
|
//#endregion
|
|
2223
2415
|
//#region ---- Lifecycle ----
|
|
2224
2416
|
ngOnInit() {
|
|
2225
2417
|
this.context.set(this.config?.context || {});
|
|
2418
|
+
void this.invokeLayoutContextChangedHooks();
|
|
2226
2419
|
}
|
|
2227
2420
|
#eff;
|
|
2228
2421
|
//#endregion
|
|
2229
2422
|
handleContextChanged(event) {
|
|
2230
2423
|
this.context.set(event);
|
|
2231
2424
|
this.aggregateAndEvaluateActions();
|
|
2425
|
+
void this.invokeLayoutContextChangedHooks();
|
|
2232
2426
|
}
|
|
2233
2427
|
handleContextInitiated(event) {
|
|
2234
2428
|
this.context.set(event);
|
|
2235
2429
|
this.aggregateAndEvaluateActions();
|
|
2430
|
+
void this.invokeLayoutContextChangedHooks();
|
|
2431
|
+
}
|
|
2432
|
+
async invokeLayoutContextChangedHooks() {
|
|
2433
|
+
const meta = this.config?.metadata;
|
|
2434
|
+
if (!this.hookService) {
|
|
2435
|
+
return;
|
|
2436
|
+
}
|
|
2437
|
+
const payload = {
|
|
2438
|
+
sessionKey: this.contextChangedHooksSessionKey,
|
|
2439
|
+
getContext: () => (this.context() ?? {}),
|
|
2440
|
+
metadata: meta,
|
|
2441
|
+
patchContext: (partial) => {
|
|
2442
|
+
const merged = merge({}, this.context(), partial);
|
|
2443
|
+
this.context.set(merged);
|
|
2444
|
+
this.layoutRenderer()?.updateContext(merged);
|
|
2445
|
+
},
|
|
2446
|
+
setLoading: (loading) => this.isDialogLoading.set(loading),
|
|
2447
|
+
};
|
|
2448
|
+
try {
|
|
2449
|
+
await this.hookService.runAsync(AXP_LAYOUT_BUILDER_DIALOG_CONTEXT_CHANGED_HOOK_KEY, payload);
|
|
2450
|
+
}
|
|
2451
|
+
catch {
|
|
2452
|
+
// Hook providers are best-effort; avoid breaking the dialog lifecycle.
|
|
2453
|
+
}
|
|
2236
2454
|
}
|
|
2237
2455
|
footerPrefixActions() {
|
|
2238
2456
|
return this.footerPrefix();
|
|
@@ -2247,35 +2465,53 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
|
|
|
2247
2465
|
return this.isDialogLoading();
|
|
2248
2466
|
}
|
|
2249
2467
|
async executeAction(action) {
|
|
2250
|
-
const cmd = action.command;
|
|
2251
|
-
if (cmd
|
|
2468
|
+
const cmd = this.resolveActionCommandName(action.command);
|
|
2469
|
+
if (this.shouldValidateBeforeAction(cmd)) {
|
|
2252
2470
|
const isValid = await this.layoutRenderer()?.validate();
|
|
2253
2471
|
if (!isValid?.result) {
|
|
2254
2472
|
return;
|
|
2255
2473
|
}
|
|
2256
2474
|
}
|
|
2257
|
-
|
|
2475
|
+
//TODO: matin, why we need this? maybe we can remove it?
|
|
2476
|
+
if (cmd?.startsWith('widget:')) {
|
|
2258
2477
|
const parsed = this.parseWidgetCommand(cmd);
|
|
2259
2478
|
if (parsed.widgetName && parsed.action) {
|
|
2260
|
-
await this.
|
|
2479
|
+
await this.invokeWidget(parsed.widgetName, parsed.action, {});
|
|
2261
2480
|
await this.aggregateAndEvaluateActions();
|
|
2262
2481
|
return;
|
|
2263
2482
|
}
|
|
2264
2483
|
}
|
|
2484
|
+
if (cmd && this.commandService.exists(cmd)) {
|
|
2485
|
+
const dialogRef = this.createDialogRef(cmd);
|
|
2486
|
+
const integration = (this.config.metadata ?? {});
|
|
2487
|
+
try {
|
|
2488
|
+
const cmdResult = await this.commandService.execute(cmd, { dialogRef, integration });
|
|
2489
|
+
if (!cmdResult?.success) {
|
|
2490
|
+
return;
|
|
2491
|
+
}
|
|
2492
|
+
if (this.shouldKeepDialogOpenAfterCommandResult(cmdResult)) {
|
|
2493
|
+
return;
|
|
2494
|
+
}
|
|
2495
|
+
this.callBack(cmdResult);
|
|
2496
|
+
await this.closeWithOptionalSkipValidate(cmdResult);
|
|
2497
|
+
}
|
|
2498
|
+
catch (error) {
|
|
2499
|
+
console.error('Error executing action', cmd, error);
|
|
2500
|
+
}
|
|
2501
|
+
return;
|
|
2502
|
+
}
|
|
2265
2503
|
const context = this.context();
|
|
2266
2504
|
const onAction = this.config?.onAction;
|
|
2267
2505
|
if (onAction) {
|
|
2268
|
-
const dialogRef =
|
|
2269
|
-
close: (res) => this.close(res),
|
|
2270
|
-
context: () => this.context(),
|
|
2271
|
-
action: () => cmd ?? undefined,
|
|
2272
|
-
setLoading: (loading) => this.isDialogLoading.set(loading),
|
|
2273
|
-
};
|
|
2506
|
+
const dialogRef = this.createDialogRef(cmd);
|
|
2274
2507
|
try {
|
|
2275
2508
|
this.isDialogLoading.set(true);
|
|
2276
2509
|
const result = await Promise.resolve(onAction(dialogRef));
|
|
2510
|
+
if (this.shouldKeepDialogOpenAfterCommandResult(result)) {
|
|
2511
|
+
return;
|
|
2512
|
+
}
|
|
2277
2513
|
this.callBack(result);
|
|
2278
|
-
this.
|
|
2514
|
+
await this.closeWithOptionalSkipValidate(result);
|
|
2279
2515
|
}
|
|
2280
2516
|
catch {
|
|
2281
2517
|
// Handler threw: stay open for retry, actions remain clickable
|
|
@@ -2293,15 +2529,74 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
|
|
|
2293
2529
|
this.data.action = result.action;
|
|
2294
2530
|
}
|
|
2295
2531
|
this.callBack({
|
|
2532
|
+
...this.createDialogRef(cmd),
|
|
2533
|
+
action: () => result.action,
|
|
2534
|
+
});
|
|
2535
|
+
// Without `onAction`, only the configured cancel action dismisses the dialog (not submit/custom).
|
|
2536
|
+
if (cmd === 'cancel') {
|
|
2537
|
+
await this.close(result);
|
|
2538
|
+
}
|
|
2539
|
+
}
|
|
2540
|
+
/** Whether the layout form should be validated before running this footer command. */
|
|
2541
|
+
shouldValidateBeforeAction(cmd) {
|
|
2542
|
+
if (!cmd || cmd === 'cancel' || cmd === 'entity-form-done') {
|
|
2543
|
+
return false;
|
|
2544
|
+
}
|
|
2545
|
+
if (cmd.startsWith('widget:')) {
|
|
2546
|
+
return false;
|
|
2547
|
+
}
|
|
2548
|
+
if (this.commandService.exists(cmd)) {
|
|
2549
|
+
return false;
|
|
2550
|
+
}
|
|
2551
|
+
return true;
|
|
2552
|
+
}
|
|
2553
|
+
/** True when a footer handler or command result asks to leave the dialog open (`keepDialogOpen` on the result or `result.data`). */
|
|
2554
|
+
shouldKeepDialogOpenAfterCommandResult(result) {
|
|
2555
|
+
if (!result || typeof result !== 'object') {
|
|
2556
|
+
return false;
|
|
2557
|
+
}
|
|
2558
|
+
const top = result;
|
|
2559
|
+
if (top.keepDialogOpen === true) {
|
|
2560
|
+
return true;
|
|
2561
|
+
}
|
|
2562
|
+
if (top.data != null && typeof top.data === 'object' && 'keepDialogOpen' in top.data) {
|
|
2563
|
+
return top.data.keepDialogOpen === true;
|
|
2564
|
+
}
|
|
2565
|
+
return false;
|
|
2566
|
+
}
|
|
2567
|
+
createDialogRef(actionCmd) {
|
|
2568
|
+
return {
|
|
2296
2569
|
close: (res) => {
|
|
2297
|
-
this.
|
|
2570
|
+
void this.closeWithOptionalSkipValidate(res);
|
|
2298
2571
|
},
|
|
2299
2572
|
context: () => this.context(),
|
|
2300
|
-
action: () =>
|
|
2301
|
-
setLoading: (loading) =>
|
|
2302
|
-
|
|
2573
|
+
action: () => actionCmd,
|
|
2574
|
+
setLoading: (loading) => this.isDialogLoading.set(loading),
|
|
2575
|
+
patchContext: (partial) => {
|
|
2576
|
+
const merged = merge({}, this.context(), partial);
|
|
2577
|
+
this.context.set(merged);
|
|
2578
|
+
this.layoutRenderer()?.updateContext(merged);
|
|
2303
2579
|
},
|
|
2304
|
-
|
|
2580
|
+
invokeWidget: (widgetName, method, opts) => this.invokeWidget(widgetName, method, opts ?? {}),
|
|
2581
|
+
};
|
|
2582
|
+
}
|
|
2583
|
+
async closeWithOptionalSkipValidate(result) {
|
|
2584
|
+
if (result && typeof result === 'object' && result.skipValidate) {
|
|
2585
|
+
this.result.emit(result);
|
|
2586
|
+
await super.close(result);
|
|
2587
|
+
return;
|
|
2588
|
+
}
|
|
2589
|
+
await this.close(result);
|
|
2590
|
+
}
|
|
2591
|
+
/** Resolves footer/widget action command to a string (e.g. `cancel`, `submit`, `widget:...`). */
|
|
2592
|
+
resolveActionCommandName(command) {
|
|
2593
|
+
if (typeof command === 'string') {
|
|
2594
|
+
return command;
|
|
2595
|
+
}
|
|
2596
|
+
if (command && typeof command === 'object' && 'name' in command) {
|
|
2597
|
+
return command.name;
|
|
2598
|
+
}
|
|
2599
|
+
return undefined;
|
|
2305
2600
|
}
|
|
2306
2601
|
parseWidgetCommand(cmd) {
|
|
2307
2602
|
// Expected 'widget:<widgetName>.<action>'
|
|
@@ -2313,7 +2608,7 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
|
|
|
2313
2608
|
return {};
|
|
2314
2609
|
return { widgetName: rest.slice(0, dot), action: rest.slice(dot + 1) };
|
|
2315
2610
|
}
|
|
2316
|
-
async
|
|
2611
|
+
async invokeWidget(widgetName, apiMethod, opts) {
|
|
2317
2612
|
if (!this.widgetCoreService)
|
|
2318
2613
|
return;
|
|
2319
2614
|
try {
|
|
@@ -2323,16 +2618,20 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
|
|
|
2323
2618
|
if (typeof fn === 'function') {
|
|
2324
2619
|
await Promise.resolve(fn({
|
|
2325
2620
|
close: (result) => {
|
|
2326
|
-
this.
|
|
2621
|
+
void this.closeWithOptionalSkipValidate(result);
|
|
2327
2622
|
},
|
|
2328
2623
|
context: () => this.context(),
|
|
2329
2624
|
setLoading: (loading) => {
|
|
2330
|
-
this.isDialogLoading.set(loading);
|
|
2625
|
+
(opts.setLoading ?? ((v) => this.isDialogLoading.set(v)))(loading);
|
|
2331
2626
|
},
|
|
2332
2627
|
}));
|
|
2628
|
+
// Footer predicates (e.g. wizard step) must refresh when the widget advances outside executeAction (e.g. dialogRef.invokeWidget after entity-form continue).
|
|
2629
|
+
await this.aggregateAndEvaluateActions();
|
|
2333
2630
|
}
|
|
2334
2631
|
}
|
|
2335
|
-
catch {
|
|
2632
|
+
catch {
|
|
2633
|
+
//
|
|
2634
|
+
}
|
|
2336
2635
|
}
|
|
2337
2636
|
async close(result) {
|
|
2338
2637
|
if (result) {
|
|
@@ -2382,6 +2681,7 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
|
|
|
2382
2681
|
zone: 'footer',
|
|
2383
2682
|
placement,
|
|
2384
2683
|
scope: a.scope,
|
|
2684
|
+
predicateApiWidgetName: a.predicateApiWidgetName,
|
|
2385
2685
|
});
|
|
2386
2686
|
const prefix = (footer?.prefix || []).map((a) => mapOne(a, 'prefix'));
|
|
2387
2687
|
const suffix = (footer?.suffix || []).map((a) => mapOne(a, 'suffix'));
|
|
@@ -2391,16 +2691,18 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
|
|
|
2391
2691
|
const out = [];
|
|
2392
2692
|
for (const a of actions) {
|
|
2393
2693
|
const parsed = typeof a.command === 'string' ? this.parseWidgetCommand(a.command) : {};
|
|
2394
|
-
const
|
|
2694
|
+
const widgetNameForApi = parsed.widgetName ?? a.predicateApiWidgetName;
|
|
2695
|
+
const api = widgetNameForApi ? await this.resolveApi(widgetNameForApi) : undefined;
|
|
2395
2696
|
const scope = {
|
|
2396
2697
|
api,
|
|
2397
|
-
widget: { name:
|
|
2698
|
+
widget: { name: widgetNameForApi },
|
|
2398
2699
|
dialog: { context: this.context() },
|
|
2399
2700
|
context: this.context(),
|
|
2400
2701
|
};
|
|
2401
2702
|
const disabled = await this.evalBool(a.disabled, scope);
|
|
2402
2703
|
const hidden = await this.evalBool(a.hidden, scope);
|
|
2403
|
-
|
|
2704
|
+
const resolvedTitle = (await this.evalActionTitle(a.title, scope)) ?? a.title;
|
|
2705
|
+
out.push({ ...a, disabled, hidden, title: resolvedTitle });
|
|
2404
2706
|
}
|
|
2405
2707
|
return out;
|
|
2406
2708
|
}
|
|
@@ -2418,6 +2720,25 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
|
|
|
2418
2720
|
}
|
|
2419
2721
|
return value;
|
|
2420
2722
|
}
|
|
2723
|
+
/** Resolves footer action title when it contains {{ ... }} (e.g. wizard labels from dialog context). */
|
|
2724
|
+
async evalActionTitle(value, scope) {
|
|
2725
|
+
if (value == null || typeof value !== 'string' || !value.includes('{{')) {
|
|
2726
|
+
return value;
|
|
2727
|
+
}
|
|
2728
|
+
try {
|
|
2729
|
+
const result = await this.expressionEvaluator.evaluate(value, scope);
|
|
2730
|
+
if (typeof result === 'string' && result.length > 0) {
|
|
2731
|
+
return result;
|
|
2732
|
+
}
|
|
2733
|
+
if (result != null && result !== false) {
|
|
2734
|
+
return String(result);
|
|
2735
|
+
}
|
|
2736
|
+
}
|
|
2737
|
+
catch {
|
|
2738
|
+
//
|
|
2739
|
+
}
|
|
2740
|
+
return value;
|
|
2741
|
+
}
|
|
2421
2742
|
async resolveApi(widgetName) {
|
|
2422
2743
|
try {
|
|
2423
2744
|
await this.widgetCoreService?.waitForWidget(widgetName, 2000);
|
|
@@ -2428,10 +2749,13 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
|
|
|
2428
2749
|
return undefined;
|
|
2429
2750
|
}
|
|
2430
2751
|
}
|
|
2431
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2432
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
2752
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPDialogRendererComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
2753
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPDialogRendererComponent, isStandalone: true, selector: "axp-dialog-renderer", outputs: { result: "result" }, providers: [AXPContextStore], viewQueries: [{ propertyName: "layoutRenderer", first: true, predicate: AXPLayoutRendererComponent, descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: `
|
|
2433
2754
|
<axp-component-slot name="dialog-header" [context]="context()"></axp-component-slot>
|
|
2434
2755
|
<div class="ax-p-4">
|
|
2756
|
+
<!-- @if (config.message) {
|
|
2757
|
+
<p class="ax-mb-4 ax-leading-relaxed">{{ config.message | translate | async }}</p>
|
|
2758
|
+
} -->
|
|
2435
2759
|
<axp-layout-renderer
|
|
2436
2760
|
[layout]="config.definition"
|
|
2437
2761
|
[context]="context()"
|
|
@@ -2455,8 +2779,13 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
|
|
|
2455
2779
|
[color]="action.color"
|
|
2456
2780
|
(onClick)="executeAction(action)"
|
|
2457
2781
|
>
|
|
2782
|
+
@if (isFormLoading()) {
|
|
2783
|
+
<ax-loading></ax-loading>
|
|
2784
|
+
}
|
|
2458
2785
|
<ax-prefix>
|
|
2459
|
-
|
|
2786
|
+
@if (action.icon) {
|
|
2787
|
+
<ax-icon [icon]="action.icon"></ax-icon>
|
|
2788
|
+
}
|
|
2460
2789
|
</ax-prefix>
|
|
2461
2790
|
</ax-button>
|
|
2462
2791
|
}
|
|
@@ -2475,7 +2804,7 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
|
|
|
2475
2804
|
}
|
|
2476
2805
|
@if (action.icon) {
|
|
2477
2806
|
<ax-prefix>
|
|
2478
|
-
<ax-icon icon="
|
|
2807
|
+
<ax-icon [icon]="action.icon"></ax-icon>
|
|
2479
2808
|
</ax-prefix>
|
|
2480
2809
|
}
|
|
2481
2810
|
</ax-button>
|
|
@@ -2484,9 +2813,9 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
|
|
|
2484
2813
|
</ax-suffix>
|
|
2485
2814
|
</ax-footer>
|
|
2486
2815
|
}
|
|
2487
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: AXPLayoutRendererComponent, selector: "axp-layout-renderer", inputs: ["layout", "context", "look", "mode"], outputs: ["contextChange", "contextInitiated", "validityChange"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1$1.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i2$1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXLoadingModule }, { kind: "component", type: i3.AXLoadingComponent, selector: "ax-loading", inputs: ["visible", "type", "context"], outputs: ["visibleChange"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: AXPComponentSlotModule }, { kind: "directive", type: i4.AXPComponentSlotDirective, selector: "axp-component-slot", inputs: ["name", "host", "context"], exportAs: ["slot"] }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.AXTranslatorPipe, name: "translate" }] }); }
|
|
2816
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: AXPLayoutRendererComponent, selector: "axp-layout-renderer", inputs: ["layout", "context", "look", "mode"], outputs: ["contextChange", "contextInitiated", "validityChange"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1$1.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i2$1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXLoadingModule }, { kind: "component", type: i3.AXLoadingComponent, selector: "ax-loading", inputs: ["visible", "type", "context"], outputs: ["visibleChange"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: AXPComponentSlotModule }, { kind: "directive", type: i4.AXPComponentSlotDirective, selector: "axp-component-slot", inputs: ["name", "host", "context"], exportAs: ["slot"] }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2488
2817
|
}
|
|
2489
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2818
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPDialogRendererComponent, decorators: [{
|
|
2490
2819
|
type: Component,
|
|
2491
2820
|
args: [{
|
|
2492
2821
|
selector: 'axp-dialog-renderer',
|
|
@@ -2500,9 +2829,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
2500
2829
|
AXTranslationModule,
|
|
2501
2830
|
AXPComponentSlotModule,
|
|
2502
2831
|
],
|
|
2832
|
+
providers: [AXPContextStore],
|
|
2833
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
2503
2834
|
template: `
|
|
2504
2835
|
<axp-component-slot name="dialog-header" [context]="context()"></axp-component-slot>
|
|
2505
2836
|
<div class="ax-p-4">
|
|
2837
|
+
<!-- @if (config.message) {
|
|
2838
|
+
<p class="ax-mb-4 ax-leading-relaxed">{{ config.message | translate | async }}</p>
|
|
2839
|
+
} -->
|
|
2506
2840
|
<axp-layout-renderer
|
|
2507
2841
|
[layout]="config.definition"
|
|
2508
2842
|
[context]="context()"
|
|
@@ -2526,8 +2860,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
2526
2860
|
[color]="action.color"
|
|
2527
2861
|
(onClick)="executeAction(action)"
|
|
2528
2862
|
>
|
|
2863
|
+
@if (isFormLoading()) {
|
|
2864
|
+
<ax-loading></ax-loading>
|
|
2865
|
+
}
|
|
2529
2866
|
<ax-prefix>
|
|
2530
|
-
|
|
2867
|
+
@if (action.icon) {
|
|
2868
|
+
<ax-icon [icon]="action.icon"></ax-icon>
|
|
2869
|
+
}
|
|
2531
2870
|
</ax-prefix>
|
|
2532
2871
|
</ax-button>
|
|
2533
2872
|
}
|
|
@@ -2546,7 +2885,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
2546
2885
|
}
|
|
2547
2886
|
@if (action.icon) {
|
|
2548
2887
|
<ax-prefix>
|
|
2549
|
-
<ax-icon icon="
|
|
2888
|
+
<ax-icon [icon]="action.icon"></ax-icon>
|
|
2550
2889
|
</ax-prefix>
|
|
2551
2890
|
}
|
|
2552
2891
|
</ax-button>
|
|
@@ -2566,9 +2905,190 @@ var dialogRenderer_component = /*#__PURE__*/Object.freeze({
|
|
|
2566
2905
|
AXPDialogRendererComponent: AXPDialogRendererComponent
|
|
2567
2906
|
});
|
|
2568
2907
|
|
|
2908
|
+
//#region ---- Imports ----
|
|
2909
|
+
/**
|
|
2910
|
+
* `customWidget` only forwards keys from its options bag into the built node via `addSingleWidget`.
|
|
2911
|
+
* Designer / configurator persist `defaultValue` (and other extended fields) on the widget node root;
|
|
2912
|
+
* spreading `options` alone drops them, so preview never applied defaults.
|
|
2913
|
+
*/
|
|
2914
|
+
/**
|
|
2915
|
+
* Widget options are sometimes persisted with an extra nesting (`options.options`) when context
|
|
2916
|
+
* was merged incorrectly. Flatten so list/data-source resolution sees `dataSource` at the top level.
|
|
2917
|
+
*/
|
|
2918
|
+
function optionsBagForPreview(node) {
|
|
2919
|
+
const raw = (node.options ?? {});
|
|
2920
|
+
const inner = raw['options'];
|
|
2921
|
+
if (inner !== undefined && typeof inner === 'object' && !Array.isArray(inner)) {
|
|
2922
|
+
const { options: _nested, ...rest } = raw;
|
|
2923
|
+
return { ...rest, ...inner };
|
|
2924
|
+
}
|
|
2925
|
+
return { ...raw };
|
|
2926
|
+
}
|
|
2927
|
+
function extendedNodePropsForPreview(node) {
|
|
2928
|
+
const out = {};
|
|
2929
|
+
if (node.defaultValue !== undefined) {
|
|
2930
|
+
out['defaultValue'] = node.defaultValue;
|
|
2931
|
+
}
|
|
2932
|
+
if (node.triggers !== undefined) {
|
|
2933
|
+
out['triggers'] = node.triggers;
|
|
2934
|
+
}
|
|
2935
|
+
if (node.meta !== undefined) {
|
|
2936
|
+
out['meta'] = node.meta;
|
|
2937
|
+
}
|
|
2938
|
+
if (node.valueTransforms !== undefined) {
|
|
2939
|
+
out['valueTransforms'] = node.valueTransforms;
|
|
2940
|
+
}
|
|
2941
|
+
if (node.visible !== undefined) {
|
|
2942
|
+
out['visible'] = node.visible;
|
|
2943
|
+
}
|
|
2944
|
+
if (node.mode !== undefined) {
|
|
2945
|
+
out['mode'] = node.mode;
|
|
2946
|
+
}
|
|
2947
|
+
if (node.children !== undefined) {
|
|
2948
|
+
out['children'] = node.children;
|
|
2949
|
+
}
|
|
2950
|
+
return out;
|
|
2951
|
+
}
|
|
2952
|
+
//#endregion
|
|
2953
|
+
//#region ---- Command ----
|
|
2954
|
+
/**
|
|
2955
|
+
* Opens a dialog that previews a widget configuration (same behavior as the preview button on
|
|
2956
|
+
* `axp-widget-field-configurator`). Invoked from that component and from entity list actions.
|
|
2957
|
+
*/
|
|
2958
|
+
class AXPPreviewWidgetFieldCommand {
|
|
2959
|
+
constructor() {
|
|
2960
|
+
this.formBuilderService = inject(AXPLayoutBuilderService);
|
|
2961
|
+
this.widgetRegistry = inject(AXPWidgetRegistryService);
|
|
2962
|
+
this.translationService = inject(AXTranslationService);
|
|
2963
|
+
this.crudService = inject(AXP_ENTITY_DEFINITION_CRUD_SERVICE, { optional: true });
|
|
2964
|
+
}
|
|
2965
|
+
async execute(input) {
|
|
2966
|
+
try {
|
|
2967
|
+
const merged = this.mergeInvocation(input);
|
|
2968
|
+
const currentWidget = this.normalizeWidget(merged['widget'] ?? merged['interface']);
|
|
2969
|
+
if (!currentWidget?.type) {
|
|
2970
|
+
return {
|
|
2971
|
+
success: false,
|
|
2972
|
+
message: {
|
|
2973
|
+
text: (await this.translationService.translateAsync('@general:messages.invalid-data')) || 'Invalid data',
|
|
2974
|
+
},
|
|
2975
|
+
};
|
|
2976
|
+
}
|
|
2977
|
+
const fieldName = String(merged['fieldName'] ?? merged['name'] ?? 'Field');
|
|
2978
|
+
const rawTitle = (merged['fieldTitle'] ?? merged['title']);
|
|
2979
|
+
const fieldTitleLabel = this.resolveFieldTitleLabel(rawTitle, fieldName);
|
|
2980
|
+
const dialogTitle = (await this.resolveWidgetDisplayTitle(currentWidget.type)) || currentWidget.type || fieldTitleLabel;
|
|
2981
|
+
const previewWidgetOptions = {
|
|
2982
|
+
...optionsBagForPreview(currentWidget),
|
|
2983
|
+
name: fieldName,
|
|
2984
|
+
...extendedNodePropsForPreview(currentWidget),
|
|
2985
|
+
};
|
|
2986
|
+
const dialogOutcome = await this.formBuilderService
|
|
2987
|
+
.create()
|
|
2988
|
+
.dialog((dialog) => {
|
|
2989
|
+
dialog
|
|
2990
|
+
.setTitle(dialogTitle)
|
|
2991
|
+
.setSize('md')
|
|
2992
|
+
.setCloseButton(true)
|
|
2993
|
+
.setContext({})
|
|
2994
|
+
.content((layoutBuilder) => {
|
|
2995
|
+
layoutBuilder.formField(fieldTitleLabel, (formField) => {
|
|
2996
|
+
formField.customWidget(currentWidget.type, previewWidgetOptions);
|
|
2997
|
+
});
|
|
2998
|
+
})
|
|
2999
|
+
.setActions((actions) => actions.cancel('@general:actions.close.title'));
|
|
3000
|
+
})
|
|
3001
|
+
.show();
|
|
3002
|
+
const cancelled = this.isCancelDialogOutcome(dialogOutcome);
|
|
3003
|
+
return {
|
|
3004
|
+
success: !cancelled,
|
|
3005
|
+
message: { text: '' },
|
|
3006
|
+
};
|
|
3007
|
+
}
|
|
3008
|
+
catch (error) {
|
|
3009
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
3010
|
+
return {
|
|
3011
|
+
success: false,
|
|
3012
|
+
message: { text: message },
|
|
3013
|
+
};
|
|
3014
|
+
}
|
|
3015
|
+
}
|
|
3016
|
+
mergeInvocation(input) {
|
|
3017
|
+
const contextOptions = input.__context__?.options;
|
|
3018
|
+
const ctxData = input.__context__?.data;
|
|
3019
|
+
const { __context__: _ctx, ...rest } = input;
|
|
3020
|
+
return {
|
|
3021
|
+
...(ctxData ?? {}),
|
|
3022
|
+
...(contextOptions ?? {}),
|
|
3023
|
+
...rest,
|
|
3024
|
+
};
|
|
3025
|
+
}
|
|
3026
|
+
normalizeWidget(raw) {
|
|
3027
|
+
if (raw == null)
|
|
3028
|
+
return null;
|
|
3029
|
+
if (typeof raw === 'string') {
|
|
3030
|
+
const t = raw.trim();
|
|
3031
|
+
return t ? { type: t, options: {} } : null;
|
|
3032
|
+
}
|
|
3033
|
+
if (typeof raw === 'object' && !Array.isArray(raw) && 'type' in raw) {
|
|
3034
|
+
const w = raw;
|
|
3035
|
+
return w.type ? cloneDeep(w) : null;
|
|
3036
|
+
}
|
|
3037
|
+
return null;
|
|
3038
|
+
}
|
|
3039
|
+
resolveFieldTitleLabel(raw, fallback) {
|
|
3040
|
+
let source = fallback;
|
|
3041
|
+
if (raw !== undefined && raw !== null) {
|
|
3042
|
+
if (typeof raw === 'string') {
|
|
3043
|
+
if (raw.trim() !== '') {
|
|
3044
|
+
source = raw;
|
|
3045
|
+
}
|
|
3046
|
+
}
|
|
3047
|
+
else if (typeof raw === 'object' && !Array.isArray(raw) && Object.keys(raw).length > 0) {
|
|
3048
|
+
source = raw;
|
|
3049
|
+
}
|
|
3050
|
+
}
|
|
3051
|
+
return this.translationService.resolve(source);
|
|
3052
|
+
}
|
|
3053
|
+
isCancelDialogOutcome(outcome) {
|
|
3054
|
+
if (outcome == null) {
|
|
3055
|
+
return false;
|
|
3056
|
+
}
|
|
3057
|
+
const ref = outcome;
|
|
3058
|
+
if (typeof ref.action !== 'function') {
|
|
3059
|
+
return false;
|
|
3060
|
+
}
|
|
3061
|
+
return ref.action() === 'cancel';
|
|
3062
|
+
}
|
|
3063
|
+
async resolveWidgetDisplayTitle(widgetType) {
|
|
3064
|
+
const crud = this.crudService;
|
|
3065
|
+
if (crud) {
|
|
3066
|
+
const interfaces = await crud.listInterfaces();
|
|
3067
|
+
const iface = interfaces.find((d) => d.name === widgetType);
|
|
3068
|
+
return iface?.title ?? iface?.name;
|
|
3069
|
+
}
|
|
3070
|
+
const config = this.widgetRegistry.getOptional(widgetType);
|
|
3071
|
+
if (!config) {
|
|
3072
|
+
return undefined;
|
|
3073
|
+
}
|
|
3074
|
+
const resolved = this.translationService.resolve(config.title);
|
|
3075
|
+
return resolved || undefined;
|
|
3076
|
+
}
|
|
3077
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPPreviewWidgetFieldCommand, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
3078
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPPreviewWidgetFieldCommand }); }
|
|
3079
|
+
}
|
|
3080
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPPreviewWidgetFieldCommand, decorators: [{
|
|
3081
|
+
type: Injectable
|
|
3082
|
+
}] });
|
|
3083
|
+
|
|
3084
|
+
var previewWidgetField_command = /*#__PURE__*/Object.freeze({
|
|
3085
|
+
__proto__: null,
|
|
3086
|
+
AXPPreviewWidgetFieldCommand: AXPPreviewWidgetFieldCommand
|
|
3087
|
+
});
|
|
3088
|
+
|
|
2569
3089
|
/**
|
|
2570
3090
|
* Generated bundle index. Do not edit.
|
|
2571
3091
|
*/
|
|
2572
3092
|
|
|
2573
|
-
export { AXPDialogRendererComponent, AXPLayoutBuilderService, AXPLayoutConversionService, AXPLayoutRendererComponent, LayoutBuilderModule };
|
|
3093
|
+
export { AXPDialogRendererComponent, AXPLayoutBuilderService, AXPLayoutConversionService, AXPLayoutRendererComponent, AXPPreviewWidgetFieldCommand, AXP_LAYOUT_BUILDER_DIALOG_BEFORE_OPEN_HOOK_KEY, AXP_LAYOUT_BUILDER_DIALOG_CONFIG_HOOK_KEY, AXP_LAYOUT_BUILDER_DIALOG_CONTEXT_CHANGED_HOOK_KEY, AXP_PREVIEW_WIDGET_FIELD_COMMAND_KEY, LayoutBuilderModule };
|
|
2574
3094
|
//# sourceMappingURL=acorex-platform-layout-builder.mjs.map
|