@acorex/platform 21.0.0-next.3 → 21.0.0-next.34
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 +295 -45
- package/fesm2022/acorex-platform-auth.mjs.map +1 -1
- package/fesm2022/{acorex-platform-common-common-settings.provider-zhqNP3xb.mjs → acorex-platform-common-common-settings.provider-G9XcXXOG.mjs} +60 -4
- package/fesm2022/acorex-platform-common-common-settings.provider-G9XcXXOG.mjs.map +1 -0
- package/fesm2022/acorex-platform-common.mjs +960 -319
- package/fesm2022/acorex-platform-common.mjs.map +1 -1
- package/fesm2022/acorex-platform-core.mjs +1352 -832
- package/fesm2022/acorex-platform-core.mjs.map +1 -1
- package/fesm2022/acorex-platform-domain.mjs +554 -826
- package/fesm2022/acorex-platform-domain.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-builder.mjs +530 -154
- package/fesm2022/acorex-platform-layout-builder.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-components-binding-expression-editor-popup.component-CXEdvDTf.mjs +121 -0
- package/fesm2022/acorex-platform-layout-components-binding-expression-editor-popup.component-CXEdvDTf.mjs.map +1 -0
- package/fesm2022/acorex-platform-layout-components.mjs +5969 -2347
- package/fesm2022/acorex-platform-layout-components.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-designer.mjs +169 -154
- package/fesm2022/acorex-platform-layout-designer.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-entity.mjs +15380 -9274
- package/fesm2022/acorex-platform-layout-entity.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-views.mjs +393 -110
- package/fesm2022/acorex-platform-layout-views.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-widget-core.mjs +511 -450
- package/fesm2022/acorex-platform-layout-widget-core.mjs.map +1 -1
- package/fesm2022/{acorex-platform-layout-widgets-button-widget-designer.component-C3VoBb_b.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-CxrsI6Hn.mjs → acorex-platform-layout-widgets-file-list-popup.component-9uCkMxcc.mjs} +39 -16
- package/fesm2022/acorex-platform-layout-widgets-file-list-popup.component-9uCkMxcc.mjs.map +1 -0
- package/fesm2022/{acorex-platform-layout-widgets-image-preview.popup-V31OpYah.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-BtZMBxYp.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-BGQqY5Mw.mjs +111 -0
- package/fesm2022/acorex-platform-layout-widgets-repeater-widget-column.component-BGQqY5Mw.mjs.map +1 -0
- package/fesm2022/{acorex-platform-layout-widgets-tabular-data-edit-popup.component-Ck7-wpT2.mjs → acorex-platform-layout-widgets-tabular-data-edit-popup.component-DmzNTYiS.mjs} +6 -6
- 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-y8vjUiVs.mjs → acorex-platform-layout-widgets-tabular-data-view-popup.component-BNG_588B.mjs} +5 -5
- 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-Df1BFkSa.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 +7865 -4026
- 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 +220 -169
- package/fesm2022/acorex-platform-runtime.mjs.map +1 -1
- package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-Cvvr4HnL.mjs +160 -0
- package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-Cvvr4HnL.mjs.map +1 -0
- package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-TYoLN1Jq.mjs +120 -0
- package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-TYoLN1Jq.mjs.map +1 -0
- package/fesm2022/{acorex-platform-themes-default-entity-master-single-view.component-eMBby9k4.mjs → acorex-platform-themes-default-entity-master-single-view.component-C2z5Lq9y.mjs} +18 -25
- package/fesm2022/acorex-platform-themes-default-entity-master-single-view.component-C2z5Lq9y.mjs.map +1 -0
- package/fesm2022/{acorex-platform-themes-default-error-401.component-cfREo88K.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-CdCV5ZoA.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 +1717 -66
- package/fesm2022/acorex-platform-themes-default.mjs.map +1 -1
- package/fesm2022/{acorex-platform-themes-shared-icon-chooser-column.component-C0EpfU2k.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-9W52W6Nu.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.map +1 -1
- package/fesm2022/{acorex-platform-themes-shared-theme-color-chooser-column.component-DTnfRy5f.mjs → acorex-platform-themes-shared-theme-color-chooser-column.component-CHfrTtol.mjs} +11 -11
- package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-column.component-CHfrTtol.mjs.map +1 -0
- package/fesm2022/{acorex-platform-themes-shared-theme-color-chooser-view.component-DY0JtT1v.mjs → acorex-platform-themes-shared-theme-color-chooser-view.component-BSmvnUVq.mjs} +9 -9
- package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-view.component-BSmvnUVq.mjs.map +1 -0
- package/fesm2022/acorex-platform-themes-shared.mjs +563 -561
- package/fesm2022/acorex-platform-themes-shared.mjs.map +1 -1
- package/fesm2022/acorex-platform-workflow.mjs +1735 -1750
- 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} +247 -10
- package/{common/index.d.ts → types/acorex-platform-common.d.ts} +492 -31
- package/{core/index.d.ts → types/acorex-platform-core.d.ts} +606 -392
- package/{domain/index.d.ts → types/acorex-platform-domain.d.ts} +719 -413
- package/{layout/builder/index.d.ts → types/acorex-platform-layout-builder.d.ts} +128 -56
- package/types/acorex-platform-layout-components.d.ts +2927 -0
- package/{layout/designer/index.d.ts → types/acorex-platform-layout-designer.d.ts} +9 -3
- package/{layout/entity/index.d.ts → types/acorex-platform-layout-entity.d.ts} +1133 -237
- package/{layout/views/index.d.ts → types/acorex-platform-layout-views.d.ts} +90 -31
- package/{layout/widget-core/index.d.ts → types/acorex-platform-layout-widget-core.d.ts} +206 -102
- package/{layout/widgets/index.d.ts → types/acorex-platform-layout-widgets.d.ts} +942 -137
- package/{native/index.d.ts → types/acorex-platform-native.d.ts} +0 -7
- package/{runtime/index.d.ts → types/acorex-platform-runtime.d.ts} +237 -74
- package/{themes/default/index.d.ts → types/acorex-platform-themes-default.d.ts} +113 -5
- package/{themes/shared/index.d.ts → types/acorex-platform-themes-shared.d.ts} +1 -1
- package/types/acorex-platform-workflow.d.ts +1806 -0
- package/fesm2022/acorex-platform-common-common-settings.provider-zhqNP3xb.mjs.map +0 -1
- package/fesm2022/acorex-platform-layout-widgets-button-widget-designer.component-C3VoBb_b.mjs.map +0 -1
- package/fesm2022/acorex-platform-layout-widgets-file-list-popup.component-CxrsI6Hn.mjs.map +0 -1
- package/fesm2022/acorex-platform-layout-widgets-image-preview.popup-V31OpYah.mjs.map +0 -1
- package/fesm2022/acorex-platform-layout-widgets-page-widget-designer.component-BtZMBxYp.mjs.map +0 -1
- package/fesm2022/acorex-platform-layout-widgets-tabular-data-edit-popup.component-Ck7-wpT2.mjs.map +0 -1
- package/fesm2022/acorex-platform-layout-widgets-tabular-data-view-popup.component-y8vjUiVs.mjs.map +0 -1
- package/fesm2022/acorex-platform-layout-widgets-text-block-widget-designer.component-Df1BFkSa.mjs.map +0 -1
- package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-VIGuU5M4.mjs +0 -157
- package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-VIGuU5M4.mjs.map +0 -1
- package/fesm2022/acorex-platform-themes-default-entity-master-list-view.component-DyDa_hyd.mjs +0 -1542
- package/fesm2022/acorex-platform-themes-default-entity-master-list-view.component-DyDa_hyd.mjs.map +0 -1
- package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-Ua3ZA5hk.mjs +0 -101
- package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-Ua3ZA5hk.mjs.map +0 -1
- package/fesm2022/acorex-platform-themes-default-entity-master-single-view.component-eMBby9k4.mjs.map +0 -1
- package/fesm2022/acorex-platform-themes-default-error-401.component-cfREo88K.mjs.map +0 -1
- package/fesm2022/acorex-platform-themes-default-error-404.component-CdCV5ZoA.mjs.map +0 -1
- package/fesm2022/acorex-platform-themes-default-error-offline.component-E7SzBcAt.mjs +0 -19
- package/fesm2022/acorex-platform-themes-default-error-offline.component-E7SzBcAt.mjs.map +0 -1
- package/fesm2022/acorex-platform-themes-shared-icon-chooser-column.component-C0EpfU2k.mjs.map +0 -1
- package/fesm2022/acorex-platform-themes-shared-icon-chooser-view.component-9W52W6Nu.mjs.map +0 -1
- package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-column.component-DTnfRy5f.mjs.map +0 -1
- package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-view.component-DY0JtT1v.mjs.map +0 -1
- package/layout/components/index.d.ts +0 -1669
- package/workflow/index.d.ts +0 -2443
- /package/{index.d.ts → types/acorex-platform.d.ts} +0 -0
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import * as
|
|
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
|
|
4
|
+
import { Injectable, inject, input, model, signal, effect, output, viewChild, ChangeDetectionStrategy, Component, NgModule, EventEmitter, Output } from '@angular/core';
|
|
5
|
+
import { provideCommandSetups } from '@acorex/platform/runtime';
|
|
5
6
|
import { AXPopupService } from '@acorex/components/popup';
|
|
7
|
+
import * as i1 from '@acorex/platform/layout/widget-core';
|
|
8
|
+
import { AXPWidgetSerializationHelper, AXPWidgetContainerComponent, AXPPageStatus, AXPWidgetCoreModule, AXPWidgetRegistryService } from '@acorex/platform/layout/widget-core';
|
|
6
9
|
import { cloneDeep, isNil, set, isEqual } from 'lodash-es';
|
|
7
10
|
import * as i2 from '@acorex/components/form';
|
|
8
11
|
import { AXFormComponent, AXFormModule } from '@acorex/components/form';
|
|
9
|
-
import * as i1 from '@acorex/platform/layout/widget-core';
|
|
10
|
-
import { AXPWidgetContainerComponent, AXPPageStatus, AXPWidgetCoreModule } from '@acorex/platform/layout/widget-core';
|
|
11
12
|
import { Subject, debounceTime, distinctUntilChanged, startWith } from 'rxjs';
|
|
12
13
|
import * as i1$1 from '@acorex/components/button';
|
|
13
14
|
import { AXButtonModule } from '@acorex/components/button';
|
|
@@ -16,9 +17,11 @@ import { AXDecoratorModule } from '@acorex/components/decorators';
|
|
|
16
17
|
import * as i3 from '@acorex/components/loading';
|
|
17
18
|
import { AXLoadingModule } from '@acorex/components/loading';
|
|
18
19
|
import { AXBasePageComponent } from '@acorex/components/page';
|
|
19
|
-
import * as
|
|
20
|
-
import { AXTranslationModule } from '@acorex/core/translation';
|
|
21
|
-
import
|
|
20
|
+
import * as i6 from '@acorex/core/translation';
|
|
21
|
+
import { AXTranslationModule, AXTranslationService } from '@acorex/core/translation';
|
|
22
|
+
import * as i4 from '@acorex/platform/core';
|
|
23
|
+
import { AXPExpressionEvaluatorService, AXPComponentSlotModule, AXPContextStore, AXPMultiLanguageStringResolverService } from '@acorex/platform/core';
|
|
24
|
+
import { AXP_ENTITY_DEFINITION_CRUD_SERVICE } from '@acorex/platform/domain';
|
|
22
25
|
|
|
23
26
|
class AXPLayoutConversionService {
|
|
24
27
|
constructor() {
|
|
@@ -222,9 +225,16 @@ class AXPLayoutConversionService {
|
|
|
222
225
|
const keyParts = [];
|
|
223
226
|
keyParts.push(`groups:${formDefinition.groups.length}`);
|
|
224
227
|
formDefinition.groups.forEach((group, groupIndex) => {
|
|
225
|
-
|
|
228
|
+
// Include group.mode so view vs edit (or mixed) layouts do not share a cached widget tree.
|
|
229
|
+
const groupModePart = group.mode ?? '_';
|
|
230
|
+
keyParts.push(`g${groupIndex}:${group.name}:${group.parameters.length}:${groupModePart}`);
|
|
231
|
+
keyParts.push(`gL${groupIndex}:${JSON.stringify(group.title ?? null)}:${JSON.stringify(group.description ?? null)}`);
|
|
226
232
|
group.parameters.forEach((param, paramIndex) => {
|
|
227
|
-
|
|
233
|
+
// Field mode must be part of the key; otherwise metadata forms that only differ by
|
|
234
|
+
// view/edit (same paths and widget types) incorrectly reuse the first cached tree.
|
|
235
|
+
const fieldModePart = param.mode ?? '_';
|
|
236
|
+
keyParts.push(`p${groupIndex}.${paramIndex}:${param.path}:${param.widget.type}:${fieldModePart}`);
|
|
237
|
+
keyParts.push(`pL${groupIndex}.${paramIndex}:${JSON.stringify(param.title ?? null)}:${JSON.stringify(param.description ?? null)}:${JSON.stringify(param.badge ?? null)}`);
|
|
228
238
|
});
|
|
229
239
|
});
|
|
230
240
|
if (formDefinition.mode) {
|
|
@@ -285,10 +295,10 @@ class AXPLayoutConversionService {
|
|
|
285
295
|
}
|
|
286
296
|
return Math.abs(hash).toString(36); // Convert to base36 for shorter string
|
|
287
297
|
}
|
|
288
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
289
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
298
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPLayoutConversionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
299
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPLayoutConversionService, providedIn: 'root' }); }
|
|
290
300
|
}
|
|
291
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
301
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPLayoutConversionService, decorators: [{
|
|
292
302
|
type: Injectable,
|
|
293
303
|
args: [{
|
|
294
304
|
providedIn: 'root',
|
|
@@ -361,17 +371,13 @@ function collectDefaultValues(node, context = {}, isTopLevel = true) {
|
|
|
361
371
|
const result = isTopLevel ? cloneDeep(context) : context;
|
|
362
372
|
// Check if this node has a defaultValue and a path
|
|
363
373
|
// Note: We check for both node.defaultValue and also look in node.options.defaultValue as fallback
|
|
364
|
-
const defaultValue = node.defaultValue !== undefined
|
|
365
|
-
? node.defaultValue
|
|
366
|
-
: node.options?.defaultValue;
|
|
374
|
+
const defaultValue = node.defaultValue !== undefined ? node.defaultValue : node.options?.defaultValue;
|
|
367
375
|
if (defaultValue !== undefined && !isNil(defaultValue) && node.path) {
|
|
368
376
|
// Check if path exists in context using lodash get equivalent check
|
|
369
377
|
const currentValue = getNestedValue(result, node.path);
|
|
370
378
|
if (currentValue === undefined) {
|
|
371
379
|
// Clone the defaultValue to avoid reference issues (especially for Date objects)
|
|
372
|
-
const clonedValue = defaultValue instanceof Date
|
|
373
|
-
? new Date(defaultValue.getTime())
|
|
374
|
-
: cloneDeep(defaultValue);
|
|
380
|
+
const clonedValue = defaultValue instanceof Date ? new Date(defaultValue.getTime()) : cloneDeep(defaultValue);
|
|
375
381
|
set(result, node.path, clonedValue);
|
|
376
382
|
}
|
|
377
383
|
}
|
|
@@ -409,10 +415,10 @@ class AXPLayoutBuilderService {
|
|
|
409
415
|
create() {
|
|
410
416
|
return new LayoutBuilder(this.popupService);
|
|
411
417
|
}
|
|
412
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
413
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
418
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPLayoutBuilderService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
419
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPLayoutBuilderService, providedIn: 'root' }); }
|
|
414
420
|
}
|
|
415
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
421
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPLayoutBuilderService, decorators: [{
|
|
416
422
|
type: Injectable,
|
|
417
423
|
args: [{
|
|
418
424
|
providedIn: 'root',
|
|
@@ -527,6 +533,15 @@ class LayoutBuilder {
|
|
|
527
533
|
mode: this.root.mode,
|
|
528
534
|
};
|
|
529
535
|
}
|
|
536
|
+
/**
|
|
537
|
+
* Converts the built widget node to JSON string
|
|
538
|
+
* @param options - Serialization options
|
|
539
|
+
* @returns JSON string representation of the widget node
|
|
540
|
+
*/
|
|
541
|
+
toJson(options) {
|
|
542
|
+
const node = this.build();
|
|
543
|
+
return AXPWidgetSerializationHelper.toJson(node, options);
|
|
544
|
+
}
|
|
530
545
|
}
|
|
531
546
|
//#endregion
|
|
532
547
|
//#region ---- Container Builder Implementation ----
|
|
@@ -585,6 +600,7 @@ class BaseContainerBuilder {
|
|
|
585
600
|
'number-editor',
|
|
586
601
|
'select-editor',
|
|
587
602
|
'lookup-editor',
|
|
603
|
+
'entity-definition-provider-editor',
|
|
588
604
|
'selection-list-editor',
|
|
589
605
|
'date-time-editor',
|
|
590
606
|
'toggle-editor',
|
|
@@ -687,24 +703,30 @@ class BaseContainerMixin extends BaseContainerBuilder {
|
|
|
687
703
|
class LayoutContainerMixin extends BaseContainerMixin {
|
|
688
704
|
layout(value) {
|
|
689
705
|
// Map layout intent to grid item sizing so containers like `form-field`
|
|
690
|
-
// can span multiple columns inside grid/fieldset layouts.
|
|
706
|
+
// can span multiple columns/rows inside grid/fieldset layouts.
|
|
691
707
|
if (!this.containerState.options)
|
|
692
708
|
this.containerState.options = {};
|
|
693
709
|
if (typeof value === 'number') {
|
|
694
|
-
// Direct numeric shorthand → colSpan
|
|
695
710
|
this.containerState.options.colSpan = value;
|
|
696
711
|
}
|
|
697
712
|
else if (value) {
|
|
698
|
-
// Try to extract a reasonable colSpan from breakpoint positions
|
|
699
713
|
const positions = value.positions;
|
|
700
714
|
if (positions) {
|
|
701
|
-
const
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
715
|
+
const placement = positions?.lg ?? positions?.xl ?? positions?.xxl ?? positions?.md ?? positions?.sm;
|
|
716
|
+
if (placement) {
|
|
717
|
+
const opts = this.containerState.options;
|
|
718
|
+
if (placement.colSpan != null)
|
|
719
|
+
opts.colSpan = placement.colSpan;
|
|
720
|
+
if (placement.colStart != null)
|
|
721
|
+
opts.colStart = placement.colStart;
|
|
722
|
+
if (placement.colEnd != null)
|
|
723
|
+
opts.colEnd = placement.colEnd;
|
|
724
|
+
if (placement.rowSpan != null)
|
|
725
|
+
opts.rowSpan = placement.rowSpan;
|
|
726
|
+
if (placement.rowStart != null)
|
|
727
|
+
opts.rowStart = placement.rowStart;
|
|
728
|
+
if (placement.rowEnd != null)
|
|
729
|
+
opts.rowEnd = placement.rowEnd;
|
|
708
730
|
}
|
|
709
731
|
}
|
|
710
732
|
}
|
|
@@ -923,6 +945,7 @@ class WidgetContainerMixin extends ChildContainerMixin {
|
|
|
923
945
|
'number-editor',
|
|
924
946
|
'select-editor',
|
|
925
947
|
'lookup-editor',
|
|
948
|
+
'entity-definition-provider-editor',
|
|
926
949
|
'selection-list-editor',
|
|
927
950
|
'date-time-editor',
|
|
928
951
|
'toggle-editor',
|
|
@@ -978,6 +1001,34 @@ class FlexContainerBuilder extends WidgetContainerMixin {
|
|
|
978
1001
|
* Grid Container Builder - Liskov Substitution Principle
|
|
979
1002
|
* Extends WidgetContainerMixin to inherit all common functionality
|
|
980
1003
|
*/
|
|
1004
|
+
/**
|
|
1005
|
+
* Extracts flat grid-item options from AXPGridLayoutOptions for grid-item-layout widget.
|
|
1006
|
+
* Uses first available breakpoint (lg, xl, md, sm).
|
|
1007
|
+
*/
|
|
1008
|
+
function toGridItemOptions(layoutOptions) {
|
|
1009
|
+
if (!layoutOptions?.positions)
|
|
1010
|
+
return { colSpan: 12 };
|
|
1011
|
+
const positions = layoutOptions.positions;
|
|
1012
|
+
const placement = positions['lg'] ?? positions['xl'] ?? positions['xxl'] ?? positions['md'] ?? positions['sm'];
|
|
1013
|
+
if (!placement)
|
|
1014
|
+
return { colSpan: 12 };
|
|
1015
|
+
const opts = {};
|
|
1016
|
+
if (placement['colSpan'] != null)
|
|
1017
|
+
opts['colSpan'] = placement['colSpan'];
|
|
1018
|
+
if (placement['colStart'] != null)
|
|
1019
|
+
opts['colStart'] = placement['colStart'];
|
|
1020
|
+
if (placement['colEnd'] != null)
|
|
1021
|
+
opts['colEnd'] = placement['colEnd'];
|
|
1022
|
+
if (placement['rowSpan'] != null)
|
|
1023
|
+
opts['rowSpan'] = placement['rowSpan'];
|
|
1024
|
+
if (placement['rowStart'] != null)
|
|
1025
|
+
opts['rowStart'] = placement['rowStart'];
|
|
1026
|
+
if (placement['rowEnd'] != null)
|
|
1027
|
+
opts['rowEnd'] = placement['rowEnd'];
|
|
1028
|
+
if (Object.keys(opts).length === 0)
|
|
1029
|
+
opts['colSpan'] = 12;
|
|
1030
|
+
return opts;
|
|
1031
|
+
}
|
|
981
1032
|
class GridContainerBuilder extends WidgetContainerMixin {
|
|
982
1033
|
constructor() {
|
|
983
1034
|
super('grid-layout');
|
|
@@ -986,6 +1037,21 @@ class GridContainerBuilder extends WidgetContainerMixin {
|
|
|
986
1037
|
this.containerState.options = { ...this.containerState.options, ...options };
|
|
987
1038
|
return this;
|
|
988
1039
|
}
|
|
1040
|
+
item(layoutOptions, delegate) {
|
|
1041
|
+
const fieldset = new FieldsetContainerBuilder();
|
|
1042
|
+
fieldset.withInheritanceContext(this.inheritanceContext);
|
|
1043
|
+
delegate(fieldset);
|
|
1044
|
+
const fieldsetNode = fieldset.build();
|
|
1045
|
+
const gridItemOptions = toGridItemOptions(layoutOptions);
|
|
1046
|
+
const gridItemNode = {
|
|
1047
|
+
type: 'grid-item-layout',
|
|
1048
|
+
options: gridItemOptions,
|
|
1049
|
+
children: [fieldsetNode],
|
|
1050
|
+
};
|
|
1051
|
+
this.ensureChildren();
|
|
1052
|
+
this.containerState.children.push(gridItemNode);
|
|
1053
|
+
return this;
|
|
1054
|
+
}
|
|
989
1055
|
// Individual fluent methods for Grid
|
|
990
1056
|
setColumns(columns) {
|
|
991
1057
|
return this.setOptions({ grid: { default: { columns } } });
|
|
@@ -1155,10 +1221,34 @@ class FormFieldBuilder extends LayoutContainerMixin {
|
|
|
1155
1221
|
child.type(type);
|
|
1156
1222
|
child.name(finalName);
|
|
1157
1223
|
child.path(widgetPath);
|
|
1158
|
-
//
|
|
1159
|
-
const { name: _, ...cleanOptions } = (options || {});
|
|
1224
|
+
// Extract extended properties from options (triggers, meta, valueTransforms, mode, visible, defaultValue)
|
|
1225
|
+
const { name: _, triggers, meta, valueTransforms, mode: extendedMode, visible: extendedVisible, defaultValue: extendedDefaultValue, children: extendedChildren, ...cleanOptions } = (options || {});
|
|
1160
1226
|
child.withInheritanceContext(this.inheritanceContext);
|
|
1161
1227
|
child.options(cleanOptions);
|
|
1228
|
+
// Apply extended properties if provided
|
|
1229
|
+
if (extendedMode !== undefined) {
|
|
1230
|
+
child.mode(extendedMode);
|
|
1231
|
+
}
|
|
1232
|
+
if (extendedVisible !== undefined) {
|
|
1233
|
+
child.visible(extendedVisible);
|
|
1234
|
+
}
|
|
1235
|
+
if (extendedDefaultValue !== undefined) {
|
|
1236
|
+
child.defaultValue(extendedDefaultValue);
|
|
1237
|
+
}
|
|
1238
|
+
// Set triggers, meta, and valueTransforms directly on widgetState
|
|
1239
|
+
// These are part of AXPWidgetNode but not handled by WidgetBuilder methods
|
|
1240
|
+
if (triggers !== undefined) {
|
|
1241
|
+
child.widgetState.triggers = triggers;
|
|
1242
|
+
}
|
|
1243
|
+
if (meta !== undefined) {
|
|
1244
|
+
child.widgetState.meta = meta;
|
|
1245
|
+
}
|
|
1246
|
+
if (valueTransforms !== undefined) {
|
|
1247
|
+
child.widgetState.valueTransforms = valueTransforms;
|
|
1248
|
+
}
|
|
1249
|
+
if (extendedChildren !== undefined) {
|
|
1250
|
+
child.widgetState.children = extendedChildren;
|
|
1251
|
+
}
|
|
1162
1252
|
// IMPORTANT: Store the widget builder, don't build it yet!
|
|
1163
1253
|
// This allows properties set after this method (like disabled, readonly) to be applied
|
|
1164
1254
|
this.childWidget = child;
|
|
@@ -1452,6 +1542,10 @@ class DialogContainerBuilder {
|
|
|
1452
1542
|
}
|
|
1453
1543
|
return this;
|
|
1454
1544
|
}
|
|
1545
|
+
onAction(handler) {
|
|
1546
|
+
(this.dialogState.dialogOptions ??= {}).onAction = handler;
|
|
1547
|
+
return this;
|
|
1548
|
+
}
|
|
1455
1549
|
addCustomAction(action) {
|
|
1456
1550
|
// Add to actions based on position
|
|
1457
1551
|
const position = action.position || 'suffix';
|
|
@@ -1500,14 +1594,16 @@ class DialogContainerBuilder {
|
|
|
1500
1594
|
const { AXPDialogRendererComponent } = await Promise.resolve().then(function () { return dialogRenderer_component; });
|
|
1501
1595
|
// Collect default values from widget tree and merge into initial context
|
|
1502
1596
|
const initialContext = this.dialogState.dialogOptions?.context || {};
|
|
1597
|
+
//TODO remove using collectDefaultValues and use initialContext directly for now:
|
|
1503
1598
|
const contextWithDefaults = collectDefaultValues(dialogNode, initialContext);
|
|
1504
1599
|
// Create dialog configuration
|
|
1505
1600
|
const dialogConfig = {
|
|
1506
1601
|
title: this.dialogState.dialogOptions?.title || '',
|
|
1507
1602
|
message: this.dialogState.dialogOptions?.message,
|
|
1508
|
-
context:
|
|
1603
|
+
context: initialContext,
|
|
1509
1604
|
definition: dialogNode,
|
|
1510
1605
|
actions: this.dialogState.actions,
|
|
1606
|
+
onAction: this.dialogState.dialogOptions?.onAction,
|
|
1511
1607
|
};
|
|
1512
1608
|
// The Promise resolves when user clicks an action button
|
|
1513
1609
|
return new Promise(async (resolve) => {
|
|
@@ -1520,7 +1616,6 @@ class DialogContainerBuilder {
|
|
|
1520
1616
|
data: {
|
|
1521
1617
|
config: dialogConfig,
|
|
1522
1618
|
callBack: (result) => {
|
|
1523
|
-
// Resolve with the dialog reference when user clicks an action
|
|
1524
1619
|
resolve(result);
|
|
1525
1620
|
},
|
|
1526
1621
|
},
|
|
@@ -1539,6 +1634,7 @@ class WidgetBuilder {
|
|
|
1539
1634
|
this.widgetState = {
|
|
1540
1635
|
type: 'widget',
|
|
1541
1636
|
options: {},
|
|
1637
|
+
children: [],
|
|
1542
1638
|
};
|
|
1543
1639
|
this.inheritanceContext = {};
|
|
1544
1640
|
if (name) {
|
|
@@ -1602,6 +1698,7 @@ class WidgetBuilder {
|
|
|
1602
1698
|
this.widgetState.options = {};
|
|
1603
1699
|
}
|
|
1604
1700
|
this.widgetState.options['visible'] = condition;
|
|
1701
|
+
this.widgetState.visible = condition;
|
|
1605
1702
|
this.inheritanceContext.visible = condition;
|
|
1606
1703
|
return this;
|
|
1607
1704
|
}
|
|
@@ -1633,6 +1730,10 @@ class WidgetBuilder {
|
|
|
1633
1730
|
this.inheritanceContext.direction = direction;
|
|
1634
1731
|
return this;
|
|
1635
1732
|
}
|
|
1733
|
+
children(children) {
|
|
1734
|
+
this.widgetState.children = children;
|
|
1735
|
+
return this;
|
|
1736
|
+
}
|
|
1636
1737
|
// Inheritance context methods
|
|
1637
1738
|
withInheritanceContext(context) {
|
|
1638
1739
|
this.inheritanceContext = mergeInheritanceContext(context);
|
|
@@ -1656,6 +1757,7 @@ class WidgetBuilder {
|
|
|
1656
1757
|
}
|
|
1657
1758
|
if (resolved.visible !== undefined) {
|
|
1658
1759
|
this.widgetState.options['visible'] = resolved.visible;
|
|
1760
|
+
this.widgetState.visible = resolved.visible;
|
|
1659
1761
|
}
|
|
1660
1762
|
if (context.defaultValue !== undefined) {
|
|
1661
1763
|
this.widgetState.defaultValue = context.defaultValue;
|
|
@@ -1666,14 +1768,29 @@ class WidgetBuilder {
|
|
|
1666
1768
|
return { ...this.inheritanceContext };
|
|
1667
1769
|
}
|
|
1668
1770
|
build() {
|
|
1669
|
-
|
|
1771
|
+
const node = {
|
|
1670
1772
|
name: this.widgetState.name,
|
|
1671
1773
|
type: this.widgetState.type,
|
|
1672
1774
|
options: this.widgetState.options,
|
|
1673
1775
|
mode: this.widgetState.mode,
|
|
1674
1776
|
path: this.widgetState.path,
|
|
1675
1777
|
defaultValue: this.widgetState.defaultValue,
|
|
1778
|
+
children: this.widgetState.children,
|
|
1676
1779
|
};
|
|
1780
|
+
// Add extended properties if they exist
|
|
1781
|
+
if (this.widgetState.triggers !== undefined) {
|
|
1782
|
+
node.triggers = this.widgetState.triggers;
|
|
1783
|
+
}
|
|
1784
|
+
if (this.widgetState.meta !== undefined) {
|
|
1785
|
+
node.meta = this.widgetState.meta;
|
|
1786
|
+
}
|
|
1787
|
+
if (this.widgetState.valueTransforms !== undefined) {
|
|
1788
|
+
node.valueTransforms = this.widgetState.valueTransforms;
|
|
1789
|
+
}
|
|
1790
|
+
if (this.widgetState.visible !== undefined) {
|
|
1791
|
+
node.visible = this.widgetState.visible;
|
|
1792
|
+
}
|
|
1793
|
+
return node;
|
|
1677
1794
|
}
|
|
1678
1795
|
}
|
|
1679
1796
|
//#region ---- Action Builder Implementation ----
|
|
@@ -1687,7 +1804,6 @@ class ActionBuilder {
|
|
|
1687
1804
|
}
|
|
1688
1805
|
this.dialogBuilder['dialogState'].actions.footer.suffix.push({
|
|
1689
1806
|
title: text || '@general:actions.cancel.title',
|
|
1690
|
-
icon: 'fa-times',
|
|
1691
1807
|
color: 'default',
|
|
1692
1808
|
command: { name: 'cancel' },
|
|
1693
1809
|
});
|
|
@@ -1699,17 +1815,25 @@ class ActionBuilder {
|
|
|
1699
1815
|
}
|
|
1700
1816
|
this.dialogBuilder['dialogState'].actions.footer.suffix.push({
|
|
1701
1817
|
title: text || '@general:actions.submit.title',
|
|
1702
|
-
icon: 'fa-check',
|
|
1703
1818
|
color: 'primary',
|
|
1704
1819
|
command: { name: 'submit', options: { validate: true } },
|
|
1705
1820
|
});
|
|
1706
1821
|
return this;
|
|
1707
1822
|
}
|
|
1708
1823
|
custom(action) {
|
|
1709
|
-
|
|
1710
|
-
|
|
1824
|
+
const position = action.position ?? 'suffix';
|
|
1825
|
+
if (position === 'prefix') {
|
|
1826
|
+
if (!this.dialogBuilder['dialogState'].actions.footer.prefix) {
|
|
1827
|
+
this.dialogBuilder['dialogState'].actions.footer.prefix = [];
|
|
1828
|
+
}
|
|
1829
|
+
this.dialogBuilder['dialogState'].actions.footer.prefix.push(action);
|
|
1830
|
+
}
|
|
1831
|
+
else {
|
|
1832
|
+
if (!this.dialogBuilder['dialogState'].actions.footer.suffix) {
|
|
1833
|
+
this.dialogBuilder['dialogState'].actions.footer.suffix = [];
|
|
1834
|
+
}
|
|
1835
|
+
this.dialogBuilder['dialogState'].actions.footer.suffix.push(action);
|
|
1711
1836
|
}
|
|
1712
|
-
this.dialogBuilder['dialogState'].actions.footer.suffix.push(action);
|
|
1713
1837
|
return this;
|
|
1714
1838
|
}
|
|
1715
1839
|
}
|
|
@@ -1858,22 +1982,22 @@ class AXPLayoutRendererComponent {
|
|
|
1858
1982
|
/**
|
|
1859
1983
|
* Form definition containing groups and fields OR widget tree
|
|
1860
1984
|
*/
|
|
1861
|
-
this.layout = input.required(...(ngDevMode ? [{ debugName: "layout" }] : []));
|
|
1985
|
+
this.layout = input.required(...(ngDevMode ? [{ debugName: "layout" }] : /* istanbul ignore next */ []));
|
|
1862
1986
|
/**
|
|
1863
1987
|
* Form context/model data
|
|
1864
1988
|
*/
|
|
1865
|
-
this.context = model({}, ...(ngDevMode ? [{ debugName: "context" }] : []));
|
|
1989
|
+
this.context = model({}, ...(ngDevMode ? [{ debugName: "context" }] : /* istanbul ignore next */ []));
|
|
1866
1990
|
/**
|
|
1867
1991
|
* Form appearance and density styling (normal, compact, spacious)
|
|
1868
1992
|
*/
|
|
1869
|
-
this.look = input('fieldset', ...(ngDevMode ? [{ debugName: "look" }] : []));
|
|
1993
|
+
this.look = input('fieldset', ...(ngDevMode ? [{ debugName: "look" }] : /* istanbul ignore next */ []));
|
|
1870
1994
|
/**
|
|
1871
1995
|
* Default form mode. Can be overridden by section/group and field.
|
|
1872
1996
|
*/
|
|
1873
|
-
this.mode = input('edit', ...(ngDevMode ? [{ debugName: "mode" }] : []));
|
|
1997
|
+
this.mode = input('edit', ...(ngDevMode ? [{ debugName: "mode" }] : /* istanbul ignore next */ []));
|
|
1874
1998
|
//#endregion
|
|
1875
1999
|
//#region ---- Widget Tree Conversion ----
|
|
1876
|
-
this.widgetTree = signal(null, ...(ngDevMode ? [{ debugName: "widgetTree" }] : []));
|
|
2000
|
+
this.widgetTree = signal(null, ...(ngDevMode ? [{ debugName: "widgetTree" }] : /* istanbul ignore next */ []));
|
|
1877
2001
|
/**
|
|
1878
2002
|
* Convert layout data to widget tree when inputs change
|
|
1879
2003
|
*/
|
|
@@ -1898,7 +2022,7 @@ class AXPLayoutRendererComponent {
|
|
|
1898
2022
|
if (!isEqual(prev, tree)) {
|
|
1899
2023
|
this.widgetTree.set(tree);
|
|
1900
2024
|
}
|
|
1901
|
-
}, ...(ngDevMode ? [{ debugName: "conversionEffect" }] : []));
|
|
2025
|
+
}, ...(ngDevMode ? [{ debugName: "conversionEffect" }] : /* istanbul ignore next */ []));
|
|
1902
2026
|
//#endregion
|
|
1903
2027
|
//#region ---- Outputs ----
|
|
1904
2028
|
/**
|
|
@@ -1911,12 +2035,12 @@ class AXPLayoutRendererComponent {
|
|
|
1911
2035
|
this.validityChange = output();
|
|
1912
2036
|
//#endregion
|
|
1913
2037
|
//#region ---- Properties ----
|
|
1914
|
-
this.form = viewChild(AXFormComponent, ...(ngDevMode ? [{ debugName: "form" }] : []));
|
|
1915
|
-
this.container = viewChild(AXPWidgetContainerComponent, ...(ngDevMode ? [{ debugName: "container" }] : []));
|
|
2038
|
+
this.form = viewChild(AXFormComponent, ...(ngDevMode ? [{ debugName: "form" }] : /* istanbul ignore next */ []));
|
|
2039
|
+
this.container = viewChild(AXPWidgetContainerComponent, ...(ngDevMode ? [{ debugName: "container" }] : /* istanbul ignore next */ []));
|
|
1916
2040
|
/**
|
|
1917
2041
|
* Internal context signal for reactivity
|
|
1918
2042
|
*/
|
|
1919
|
-
this.internalContext = signal({}, ...(ngDevMode ? [{ debugName: "internalContext" }] : []));
|
|
2043
|
+
this.internalContext = signal({}, ...(ngDevMode ? [{ debugName: "internalContext" }] : /* istanbul ignore next */ []));
|
|
1920
2044
|
/**
|
|
1921
2045
|
* Initial context for reset functionality
|
|
1922
2046
|
*/
|
|
@@ -1929,7 +2053,7 @@ class AXPLayoutRendererComponent {
|
|
|
1929
2053
|
this.#contextSyncEffect = effect(() => {
|
|
1930
2054
|
const ctx = this.context() ?? {};
|
|
1931
2055
|
this.contextUpdateSubject.next(ctx);
|
|
1932
|
-
}, ...(ngDevMode ? [{ debugName: "#contextSyncEffect" }] : []));
|
|
2056
|
+
}, ...(ngDevMode ? [{ debugName: "#contextSyncEffect" }] : /* istanbul ignore next */ []));
|
|
1933
2057
|
/**
|
|
1934
2058
|
* Effect to handle widget tree status changes
|
|
1935
2059
|
*/
|
|
@@ -1938,7 +2062,7 @@ class AXPLayoutRendererComponent {
|
|
|
1938
2062
|
if (widgetTree) {
|
|
1939
2063
|
this.container()?.builderService.setStatus(AXPPageStatus.Rendered);
|
|
1940
2064
|
}
|
|
1941
|
-
}, ...(ngDevMode ? [{ debugName: "#widgetStatusEffect" }] : []));
|
|
2065
|
+
}, ...(ngDevMode ? [{ debugName: "#widgetStatusEffect" }] : /* istanbul ignore next */ []));
|
|
1942
2066
|
}
|
|
1943
2067
|
//#endregion
|
|
1944
2068
|
//#region ---- Lifecycle Methods ----
|
|
@@ -2078,8 +2202,8 @@ class AXPLayoutRendererComponent {
|
|
|
2078
2202
|
isWidgetNode(data) {
|
|
2079
2203
|
return data && typeof data === 'object' && 'type' in data && typeof data.type === 'string';
|
|
2080
2204
|
}
|
|
2081
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2082
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
2205
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPLayoutRendererComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2206
|
+
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: `
|
|
2083
2207
|
<ax-form>
|
|
2084
2208
|
<axp-widgets-container [context]="internalContext()" (onContextChanged)="handleContextChanged($event)">
|
|
2085
2209
|
@if (widgetTree()) {
|
|
@@ -2087,11 +2211,11 @@ class AXPLayoutRendererComponent {
|
|
|
2087
2211
|
}
|
|
2088
2212
|
</axp-widgets-container>
|
|
2089
2213
|
</ax-form>
|
|
2090
|
-
`, isInline: true, styles: [":host{display:block;width:100%}\n"], dependencies: [{ kind: "ngmodule", type:
|
|
2214
|
+
`, 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 }); }
|
|
2091
2215
|
}
|
|
2092
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2216
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPLayoutRendererComponent, decorators: [{
|
|
2093
2217
|
type: Component,
|
|
2094
|
-
args: [{ selector: 'axp-layout-renderer', standalone: true, imports: [
|
|
2218
|
+
args: [{ selector: 'axp-layout-renderer', standalone: true, imports: [AXPWidgetCoreModule, AXFormModule], changeDetection: ChangeDetectionStrategy.OnPush, template: `
|
|
2095
2219
|
<ax-form>
|
|
2096
2220
|
<axp-widgets-container [context]="internalContext()" (onContextChanged)="handleContextChanged($event)">
|
|
2097
2221
|
@if (widgetTree()) {
|
|
@@ -2102,16 +2226,35 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
|
|
|
2102
2226
|
`, styles: [":host{display:block;width:100%}\n"] }]
|
|
2103
2227
|
}], 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 }] }] } });
|
|
2104
2228
|
|
|
2229
|
+
/** Registration key for {@link AXPPreviewWidgetFieldCommand}; lives alone so `LayoutBuilderModule` can reference it without static-importing the command implementation. */
|
|
2230
|
+
const AXP_PREVIEW_WIDGET_FIELD_COMMAND_KEY = 'Widget:Preview';
|
|
2231
|
+
|
|
2105
2232
|
class LayoutBuilderModule {
|
|
2106
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2107
|
-
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "
|
|
2108
|
-
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "
|
|
2233
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: LayoutBuilderModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
2234
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.9", ngImport: i0, type: LayoutBuilderModule, imports: [CommonModule, AXPLayoutRendererComponent], exports: [AXPLayoutRendererComponent] }); }
|
|
2235
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: LayoutBuilderModule, providers: [
|
|
2236
|
+
AXPLayoutBuilderService,
|
|
2237
|
+
provideCommandSetups([
|
|
2238
|
+
{
|
|
2239
|
+
key: AXP_PREVIEW_WIDGET_FIELD_COMMAND_KEY,
|
|
2240
|
+
command: () => Promise.resolve().then(function () { return previewWidgetField_command; }).then((c) => c.AXPPreviewWidgetFieldCommand),
|
|
2241
|
+
},
|
|
2242
|
+
]),
|
|
2243
|
+
], imports: [CommonModule, AXPLayoutRendererComponent] }); }
|
|
2109
2244
|
}
|
|
2110
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2245
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: LayoutBuilderModule, decorators: [{
|
|
2111
2246
|
type: NgModule,
|
|
2112
2247
|
args: [{
|
|
2113
2248
|
imports: [CommonModule, AXPLayoutRendererComponent],
|
|
2114
|
-
providers: [
|
|
2249
|
+
providers: [
|
|
2250
|
+
AXPLayoutBuilderService,
|
|
2251
|
+
provideCommandSetups([
|
|
2252
|
+
{
|
|
2253
|
+
key: AXP_PREVIEW_WIDGET_FIELD_COMMAND_KEY,
|
|
2254
|
+
command: () => Promise.resolve().then(function () { return previewWidgetField_command; }).then((c) => c.AXPPreviewWidgetFieldCommand),
|
|
2255
|
+
},
|
|
2256
|
+
]),
|
|
2257
|
+
],
|
|
2115
2258
|
exports: [AXPLayoutRendererComponent],
|
|
2116
2259
|
}]
|
|
2117
2260
|
}] });
|
|
@@ -2123,17 +2266,17 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
|
|
|
2123
2266
|
super(...arguments);
|
|
2124
2267
|
this.result = new EventEmitter();
|
|
2125
2268
|
this.expressionEvaluator = inject(AXPExpressionEvaluatorService);
|
|
2126
|
-
this.context = signal({}, ...(ngDevMode ? [{ debugName: "context" }] : []));
|
|
2269
|
+
this.context = signal({}, ...(ngDevMode ? [{ debugName: "context" }] : /* istanbul ignore next */ []));
|
|
2127
2270
|
// This will be set by the popup service automatically - same as dynamic-dialog
|
|
2128
2271
|
this.callBack = () => { };
|
|
2129
|
-
this.isDialogLoading = signal(false, ...(ngDevMode ? [{ debugName: "isDialogLoading" }] : []));
|
|
2272
|
+
this.isDialogLoading = signal(false, ...(ngDevMode ? [{ debugName: "isDialogLoading" }] : /* istanbul ignore next */ []));
|
|
2130
2273
|
// Aggregated actions for footer rendering
|
|
2131
|
-
this.footerPrefix = signal([], ...(ngDevMode ? [{ debugName: "footerPrefix" }] : []));
|
|
2132
|
-
this.footerSuffix = signal([], ...(ngDevMode ? [{ debugName: "footerSuffix" }] : []));
|
|
2274
|
+
this.footerPrefix = signal([], ...(ngDevMode ? [{ debugName: "footerPrefix" }] : /* istanbul ignore next */ []));
|
|
2275
|
+
this.footerSuffix = signal([], ...(ngDevMode ? [{ debugName: "footerSuffix" }] : /* istanbul ignore next */ []));
|
|
2133
2276
|
//#endregion
|
|
2134
2277
|
//#region ---- View Accessors ----
|
|
2135
2278
|
// Access the internal layout renderer to reach the widgets container injector
|
|
2136
|
-
this.layoutRenderer = viewChild(AXPLayoutRendererComponent, ...(ngDevMode ? [{ debugName: "layoutRenderer" }] : []));
|
|
2279
|
+
this.layoutRenderer = viewChild(AXPLayoutRendererComponent, ...(ngDevMode ? [{ debugName: "layoutRenderer" }] : /* istanbul ignore next */ []));
|
|
2137
2280
|
this.#eff = effect(() => {
|
|
2138
2281
|
let count = 0;
|
|
2139
2282
|
this.aggregateAndEvaluateActions();
|
|
@@ -2141,10 +2284,10 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
|
|
|
2141
2284
|
const renderer = this.layoutRenderer();
|
|
2142
2285
|
const container = renderer?.getContainer();
|
|
2143
2286
|
this.widgetCoreService = container?.builderService ?? null;
|
|
2144
|
-
count = this.widgetCoreService
|
|
2287
|
+
count = this.widgetCoreService?.registeredWidgetsCount();
|
|
2145
2288
|
}
|
|
2146
2289
|
else {
|
|
2147
|
-
count = this.widgetCoreService
|
|
2290
|
+
count = this.widgetCoreService?.registeredWidgetsCount();
|
|
2148
2291
|
// Clear existing timer
|
|
2149
2292
|
if (this.debounceTimer) {
|
|
2150
2293
|
clearTimeout(this.debounceTimer);
|
|
@@ -2154,12 +2297,11 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
|
|
|
2154
2297
|
this.aggregateAndEvaluateActions();
|
|
2155
2298
|
}, 200);
|
|
2156
2299
|
}
|
|
2157
|
-
}, ...(ngDevMode ? [{ debugName: "#eff" }] : []));
|
|
2300
|
+
}, ...(ngDevMode ? [{ debugName: "#eff" }] : /* istanbul ignore next */ []));
|
|
2158
2301
|
}
|
|
2159
2302
|
//#endregion
|
|
2160
2303
|
//#region ---- Lifecycle ----
|
|
2161
2304
|
ngOnInit() {
|
|
2162
|
-
// Initialize context with provided context
|
|
2163
2305
|
this.context.set(this.config?.context || {});
|
|
2164
2306
|
}
|
|
2165
2307
|
#eff;
|
|
@@ -2185,14 +2327,14 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
|
|
|
2185
2327
|
return this.isDialogLoading();
|
|
2186
2328
|
}
|
|
2187
2329
|
async executeAction(action) {
|
|
2188
|
-
const cmd = action.command;
|
|
2330
|
+
const cmd = this.resolveActionCommandName(action.command);
|
|
2189
2331
|
if (cmd !== 'cancel') {
|
|
2190
2332
|
const isValid = await this.layoutRenderer()?.validate();
|
|
2191
2333
|
if (!isValid?.result) {
|
|
2192
2334
|
return;
|
|
2193
2335
|
}
|
|
2194
2336
|
}
|
|
2195
|
-
if (
|
|
2337
|
+
if (cmd?.startsWith('widget:')) {
|
|
2196
2338
|
const parsed = this.parseWidgetCommand(cmd);
|
|
2197
2339
|
if (parsed.widgetName && parsed.action) {
|
|
2198
2340
|
await this.executeWidgetApi(parsed.widgetName, parsed.action);
|
|
@@ -2200,16 +2342,39 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
|
|
|
2200
2342
|
return;
|
|
2201
2343
|
}
|
|
2202
2344
|
}
|
|
2345
|
+
const context = this.context();
|
|
2346
|
+
const onAction = this.config?.onAction;
|
|
2347
|
+
if (onAction) {
|
|
2348
|
+
const dialogRef = {
|
|
2349
|
+
close: (res) => this.close(res),
|
|
2350
|
+
context: () => this.context(),
|
|
2351
|
+
action: () => action.command ?? undefined,
|
|
2352
|
+
setLoading: (loading) => this.isDialogLoading.set(loading),
|
|
2353
|
+
};
|
|
2354
|
+
try {
|
|
2355
|
+
this.isDialogLoading.set(true);
|
|
2356
|
+
const result = await Promise.resolve(onAction(dialogRef));
|
|
2357
|
+
this.callBack(result);
|
|
2358
|
+
this.close(result);
|
|
2359
|
+
}
|
|
2360
|
+
catch {
|
|
2361
|
+
// Handler threw: stay open for retry, actions remain clickable
|
|
2362
|
+
}
|
|
2363
|
+
finally {
|
|
2364
|
+
this.isDialogLoading.set(false);
|
|
2365
|
+
}
|
|
2366
|
+
return;
|
|
2367
|
+
}
|
|
2203
2368
|
// Fallback: treat as regular dialog action (cancel/confirm/custom)
|
|
2204
|
-
const result = { context
|
|
2369
|
+
const result = { context, action: cmd };
|
|
2205
2370
|
this.dialogResult = result;
|
|
2206
2371
|
if (this.data) {
|
|
2207
2372
|
this.data.context = result.context;
|
|
2208
2373
|
this.data.action = result.action;
|
|
2209
2374
|
}
|
|
2210
2375
|
this.callBack({
|
|
2211
|
-
close: (
|
|
2212
|
-
this.close(
|
|
2376
|
+
close: (res) => {
|
|
2377
|
+
this.close(res);
|
|
2213
2378
|
},
|
|
2214
2379
|
context: () => this.context(),
|
|
2215
2380
|
action: () => result.action,
|
|
@@ -2217,6 +2382,20 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
|
|
|
2217
2382
|
this.isDialogLoading.set(loading);
|
|
2218
2383
|
},
|
|
2219
2384
|
});
|
|
2385
|
+
// Without `onAction`, only the configured cancel action dismisses the dialog (not submit/custom).
|
|
2386
|
+
if (cmd === 'cancel') {
|
|
2387
|
+
await this.close(result);
|
|
2388
|
+
}
|
|
2389
|
+
}
|
|
2390
|
+
/** Resolves footer/widget action command to a string (e.g. `cancel`, `submit`, `widget:...`). */
|
|
2391
|
+
resolveActionCommandName(command) {
|
|
2392
|
+
if (typeof command === 'string') {
|
|
2393
|
+
return command;
|
|
2394
|
+
}
|
|
2395
|
+
if (command && typeof command === 'object' && 'name' in command) {
|
|
2396
|
+
return command.name;
|
|
2397
|
+
}
|
|
2398
|
+
return undefined;
|
|
2220
2399
|
}
|
|
2221
2400
|
parseWidgetCommand(cmd) {
|
|
2222
2401
|
// Expected 'widget:<widgetName>.<action>'
|
|
@@ -2343,8 +2522,9 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
|
|
|
2343
2522
|
return undefined;
|
|
2344
2523
|
}
|
|
2345
2524
|
}
|
|
2346
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2347
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
2525
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPDialogRendererComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
2526
|
+
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: `
|
|
2527
|
+
<axp-component-slot name="dialog-header" [context]="context()"></axp-component-slot>
|
|
2348
2528
|
<div class="ax-p-4">
|
|
2349
2529
|
<axp-layout-renderer
|
|
2350
2530
|
[layout]="config.definition"
|
|
@@ -2355,46 +2535,52 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
|
|
|
2355
2535
|
</axp-layout-renderer>
|
|
2356
2536
|
</div>
|
|
2357
2537
|
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
}
|
|
2373
|
-
</ax-prefix>
|
|
2374
|
-
<ax-suffix>
|
|
2375
|
-
@for (action of footerSuffixActions(); track $index) {
|
|
2376
|
-
<ax-button
|
|
2377
|
-
[disabled]="action.disabled || isSubmitting()"
|
|
2378
|
-
[text]="(action.title | translate | async)!"
|
|
2379
|
-
[look]="'solid'"
|
|
2380
|
-
[color]="action.color"
|
|
2381
|
-
(onClick)="executeAction(action)"
|
|
2382
|
-
>
|
|
2383
|
-
@if (isFormLoading()) {
|
|
2384
|
-
<ax-loading></ax-loading>
|
|
2385
|
-
}
|
|
2386
|
-
@if (action.icon) {
|
|
2538
|
+
<!-- Custom footer slot: if it has content, default footer is hidden -->
|
|
2539
|
+
<axp-component-slot name="dialog-footer" #footerSlot="slot" [context]="context()"></axp-component-slot>
|
|
2540
|
+
@if (footerSlot.isEmpty()) {
|
|
2541
|
+
<ax-footer>
|
|
2542
|
+
<ax-prefix>
|
|
2543
|
+
<axp-component-slot name="dialog-footer-prefix" [context]="context()"></axp-component-slot>
|
|
2544
|
+
@for (action of footerPrefixActions(); track $index) {
|
|
2545
|
+
<ax-button
|
|
2546
|
+
[disabled]="action.disabled || isFormLoading()"
|
|
2547
|
+
[text]="(action.title | translate | async)!"
|
|
2548
|
+
[look]="'outline'"
|
|
2549
|
+
[color]="action.color"
|
|
2550
|
+
(onClick)="executeAction(action)"
|
|
2551
|
+
>
|
|
2387
2552
|
<ax-prefix>
|
|
2388
|
-
<
|
|
2553
|
+
<i class="{{ action.icon }}"></i>
|
|
2389
2554
|
</ax-prefix>
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2555
|
+
</ax-button>
|
|
2556
|
+
}
|
|
2557
|
+
</ax-prefix>
|
|
2558
|
+
<ax-suffix>
|
|
2559
|
+
@for (action of footerSuffixActions(); track $index) {
|
|
2560
|
+
<ax-button
|
|
2561
|
+
[disabled]="action.disabled || isSubmitting()"
|
|
2562
|
+
[text]="(action.title | translate | async)!"
|
|
2563
|
+
[look]="'solid'"
|
|
2564
|
+
[color]="action.color"
|
|
2565
|
+
(onClick)="executeAction(action)"
|
|
2566
|
+
>
|
|
2567
|
+
@if (isFormLoading()) {
|
|
2568
|
+
<ax-loading></ax-loading>
|
|
2569
|
+
}
|
|
2570
|
+
@if (action.icon) {
|
|
2571
|
+
<ax-prefix>
|
|
2572
|
+
<ax-icon icon="{{ action.icon }}"></ax-icon>
|
|
2573
|
+
</ax-prefix>
|
|
2574
|
+
}
|
|
2575
|
+
</ax-button>
|
|
2576
|
+
}
|
|
2577
|
+
<axp-component-slot name="dialog-footer-suffix" [context]="context()"></axp-component-slot>
|
|
2578
|
+
</ax-suffix>
|
|
2579
|
+
</ax-footer>
|
|
2580
|
+
}
|
|
2581
|
+
`, 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 }); }
|
|
2396
2582
|
}
|
|
2397
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2583
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPDialogRendererComponent, decorators: [{
|
|
2398
2584
|
type: Component,
|
|
2399
2585
|
args: [{
|
|
2400
2586
|
selector: 'axp-dialog-renderer',
|
|
@@ -2406,8 +2592,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
|
|
|
2406
2592
|
AXDecoratorModule,
|
|
2407
2593
|
AXLoadingModule,
|
|
2408
2594
|
AXTranslationModule,
|
|
2595
|
+
AXPComponentSlotModule,
|
|
2409
2596
|
],
|
|
2597
|
+
providers: [AXPContextStore],
|
|
2598
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
2410
2599
|
template: `
|
|
2600
|
+
<axp-component-slot name="dialog-header" [context]="context()"></axp-component-slot>
|
|
2411
2601
|
<div class="ax-p-4">
|
|
2412
2602
|
<axp-layout-renderer
|
|
2413
2603
|
[layout]="config.definition"
|
|
@@ -2418,48 +2608,52 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
|
|
|
2418
2608
|
</axp-layout-renderer>
|
|
2419
2609
|
</div>
|
|
2420
2610
|
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
}
|
|
2436
|
-
</ax-prefix>
|
|
2437
|
-
<ax-suffix>
|
|
2438
|
-
@for (action of footerSuffixActions(); track $index) {
|
|
2439
|
-
<ax-button
|
|
2440
|
-
[disabled]="action.disabled || isSubmitting()"
|
|
2441
|
-
[text]="(action.title | translate | async)!"
|
|
2442
|
-
[look]="'solid'"
|
|
2443
|
-
[color]="action.color"
|
|
2444
|
-
(onClick)="executeAction(action)"
|
|
2445
|
-
>
|
|
2446
|
-
@if (isFormLoading()) {
|
|
2447
|
-
<ax-loading></ax-loading>
|
|
2448
|
-
}
|
|
2449
|
-
@if (action.icon) {
|
|
2611
|
+
<!-- Custom footer slot: if it has content, default footer is hidden -->
|
|
2612
|
+
<axp-component-slot name="dialog-footer" #footerSlot="slot" [context]="context()"></axp-component-slot>
|
|
2613
|
+
@if (footerSlot.isEmpty()) {
|
|
2614
|
+
<ax-footer>
|
|
2615
|
+
<ax-prefix>
|
|
2616
|
+
<axp-component-slot name="dialog-footer-prefix" [context]="context()"></axp-component-slot>
|
|
2617
|
+
@for (action of footerPrefixActions(); track $index) {
|
|
2618
|
+
<ax-button
|
|
2619
|
+
[disabled]="action.disabled || isFormLoading()"
|
|
2620
|
+
[text]="(action.title | translate | async)!"
|
|
2621
|
+
[look]="'outline'"
|
|
2622
|
+
[color]="action.color"
|
|
2623
|
+
(onClick)="executeAction(action)"
|
|
2624
|
+
>
|
|
2450
2625
|
<ax-prefix>
|
|
2451
|
-
<
|
|
2626
|
+
<i class="{{ action.icon }}"></i>
|
|
2452
2627
|
</ax-prefix>
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2628
|
+
</ax-button>
|
|
2629
|
+
}
|
|
2630
|
+
</ax-prefix>
|
|
2631
|
+
<ax-suffix>
|
|
2632
|
+
@for (action of footerSuffixActions(); track $index) {
|
|
2633
|
+
<ax-button
|
|
2634
|
+
[disabled]="action.disabled || isSubmitting()"
|
|
2635
|
+
[text]="(action.title | translate | async)!"
|
|
2636
|
+
[look]="'solid'"
|
|
2637
|
+
[color]="action.color"
|
|
2638
|
+
(onClick)="executeAction(action)"
|
|
2639
|
+
>
|
|
2640
|
+
@if (isFormLoading()) {
|
|
2641
|
+
<ax-loading></ax-loading>
|
|
2642
|
+
}
|
|
2643
|
+
@if (action.icon) {
|
|
2644
|
+
<ax-prefix>
|
|
2645
|
+
<ax-icon icon="{{ action.icon }}"></ax-icon>
|
|
2646
|
+
</ax-prefix>
|
|
2647
|
+
}
|
|
2648
|
+
</ax-button>
|
|
2649
|
+
}
|
|
2650
|
+
<axp-component-slot name="dialog-footer-suffix" [context]="context()"></axp-component-slot>
|
|
2651
|
+
</ax-suffix>
|
|
2652
|
+
</ax-footer>
|
|
2653
|
+
}
|
|
2458
2654
|
`,
|
|
2459
2655
|
}]
|
|
2460
|
-
}], propDecorators: {
|
|
2461
|
-
type: Input
|
|
2462
|
-
}], result: [{
|
|
2656
|
+
}], propDecorators: { result: [{
|
|
2463
2657
|
type: Output
|
|
2464
2658
|
}], layoutRenderer: [{ type: i0.ViewChild, args: [i0.forwardRef(() => AXPLayoutRendererComponent), { isSignal: true }] }] } });
|
|
2465
2659
|
|
|
@@ -2468,9 +2662,191 @@ var dialogRenderer_component = /*#__PURE__*/Object.freeze({
|
|
|
2468
2662
|
AXPDialogRendererComponent: AXPDialogRendererComponent
|
|
2469
2663
|
});
|
|
2470
2664
|
|
|
2665
|
+
//#region ---- Imports ----
|
|
2666
|
+
/**
|
|
2667
|
+
* `customWidget` only forwards keys from its options bag into the built node via `addSingleWidget`.
|
|
2668
|
+
* Designer / configurator persist `defaultValue` (and other extended fields) on the widget node root;
|
|
2669
|
+
* spreading `options` alone drops them, so preview never applied defaults.
|
|
2670
|
+
*/
|
|
2671
|
+
/**
|
|
2672
|
+
* Widget options are sometimes persisted with an extra nesting (`options.options`) when context
|
|
2673
|
+
* was merged incorrectly. Flatten so list/data-source resolution sees `dataSource` at the top level.
|
|
2674
|
+
*/
|
|
2675
|
+
function optionsBagForPreview(node) {
|
|
2676
|
+
const raw = (node.options ?? {});
|
|
2677
|
+
const inner = raw['options'];
|
|
2678
|
+
if (inner !== undefined && typeof inner === 'object' && !Array.isArray(inner)) {
|
|
2679
|
+
const { options: _nested, ...rest } = raw;
|
|
2680
|
+
return { ...rest, ...inner };
|
|
2681
|
+
}
|
|
2682
|
+
return { ...raw };
|
|
2683
|
+
}
|
|
2684
|
+
function extendedNodePropsForPreview(node) {
|
|
2685
|
+
const out = {};
|
|
2686
|
+
if (node.defaultValue !== undefined) {
|
|
2687
|
+
out['defaultValue'] = node.defaultValue;
|
|
2688
|
+
}
|
|
2689
|
+
if (node.triggers !== undefined) {
|
|
2690
|
+
out['triggers'] = node.triggers;
|
|
2691
|
+
}
|
|
2692
|
+
if (node.meta !== undefined) {
|
|
2693
|
+
out['meta'] = node.meta;
|
|
2694
|
+
}
|
|
2695
|
+
if (node.valueTransforms !== undefined) {
|
|
2696
|
+
out['valueTransforms'] = node.valueTransforms;
|
|
2697
|
+
}
|
|
2698
|
+
if (node.visible !== undefined) {
|
|
2699
|
+
out['visible'] = node.visible;
|
|
2700
|
+
}
|
|
2701
|
+
if (node.mode !== undefined) {
|
|
2702
|
+
out['mode'] = node.mode;
|
|
2703
|
+
}
|
|
2704
|
+
if (node.children !== undefined) {
|
|
2705
|
+
out['children'] = node.children;
|
|
2706
|
+
}
|
|
2707
|
+
return out;
|
|
2708
|
+
}
|
|
2709
|
+
//#endregion
|
|
2710
|
+
//#region ---- Command ----
|
|
2711
|
+
/**
|
|
2712
|
+
* Opens a dialog that previews a widget configuration (same behavior as the preview button on
|
|
2713
|
+
* `axp-widget-field-configurator`). Invoked from that component and from entity list actions.
|
|
2714
|
+
*/
|
|
2715
|
+
class AXPPreviewWidgetFieldCommand {
|
|
2716
|
+
constructor() {
|
|
2717
|
+
this.formBuilderService = inject(AXPLayoutBuilderService);
|
|
2718
|
+
this.widgetRegistry = inject(AXPWidgetRegistryService);
|
|
2719
|
+
this.translationService = inject(AXTranslationService);
|
|
2720
|
+
this.mlResolver = inject(AXPMultiLanguageStringResolverService);
|
|
2721
|
+
this.crudService = inject(AXP_ENTITY_DEFINITION_CRUD_SERVICE, { optional: true });
|
|
2722
|
+
}
|
|
2723
|
+
async execute(input) {
|
|
2724
|
+
try {
|
|
2725
|
+
const merged = this.mergeInvocation(input);
|
|
2726
|
+
const currentWidget = this.normalizeWidget(merged['widget'] ?? merged['interface']);
|
|
2727
|
+
if (!currentWidget?.type) {
|
|
2728
|
+
return {
|
|
2729
|
+
success: false,
|
|
2730
|
+
message: { text: (await this.translationService.translateAsync('@general:messages.invalid-data')) || 'Invalid data' },
|
|
2731
|
+
};
|
|
2732
|
+
}
|
|
2733
|
+
const fieldName = String(merged['fieldName'] ?? merged['name'] ?? 'Field');
|
|
2734
|
+
const rawTitle = (merged['fieldTitle'] ?? merged['title']);
|
|
2735
|
+
const fieldTitleLabel = this.resolveFieldTitleLabel(rawTitle, fieldName);
|
|
2736
|
+
const dialogTitle = (await this.resolveWidgetDisplayTitle(currentWidget.type)) ||
|
|
2737
|
+
currentWidget.type ||
|
|
2738
|
+
fieldTitleLabel;
|
|
2739
|
+
const previewWidgetOptions = {
|
|
2740
|
+
...optionsBagForPreview(currentWidget),
|
|
2741
|
+
name: fieldName,
|
|
2742
|
+
...extendedNodePropsForPreview(currentWidget),
|
|
2743
|
+
};
|
|
2744
|
+
const dialogOutcome = await this.formBuilderService
|
|
2745
|
+
.create()
|
|
2746
|
+
.dialog((dialog) => {
|
|
2747
|
+
dialog
|
|
2748
|
+
.setTitle(dialogTitle)
|
|
2749
|
+
.setSize('md')
|
|
2750
|
+
.setCloseButton(true)
|
|
2751
|
+
.setContext({})
|
|
2752
|
+
.content((layoutBuilder) => {
|
|
2753
|
+
layoutBuilder.formField(fieldTitleLabel, (formField) => {
|
|
2754
|
+
formField.customWidget(currentWidget.type, previewWidgetOptions);
|
|
2755
|
+
});
|
|
2756
|
+
})
|
|
2757
|
+
.setActions((actions) => actions.cancel('@general:actions.close.title'));
|
|
2758
|
+
})
|
|
2759
|
+
.show();
|
|
2760
|
+
const cancelled = this.isCancelDialogOutcome(dialogOutcome);
|
|
2761
|
+
return {
|
|
2762
|
+
success: !cancelled,
|
|
2763
|
+
message: { text: '' },
|
|
2764
|
+
};
|
|
2765
|
+
}
|
|
2766
|
+
catch (error) {
|
|
2767
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
2768
|
+
return {
|
|
2769
|
+
success: false,
|
|
2770
|
+
message: { text: message },
|
|
2771
|
+
};
|
|
2772
|
+
}
|
|
2773
|
+
}
|
|
2774
|
+
mergeInvocation(input) {
|
|
2775
|
+
const contextOptions = input.__context__?.options;
|
|
2776
|
+
const ctxData = input.__context__?.data;
|
|
2777
|
+
const { __context__: _ctx, ...rest } = input;
|
|
2778
|
+
return {
|
|
2779
|
+
...(ctxData ?? {}),
|
|
2780
|
+
...(contextOptions ?? {}),
|
|
2781
|
+
...rest,
|
|
2782
|
+
};
|
|
2783
|
+
}
|
|
2784
|
+
normalizeWidget(raw) {
|
|
2785
|
+
if (raw == null)
|
|
2786
|
+
return null;
|
|
2787
|
+
if (typeof raw === 'string') {
|
|
2788
|
+
const t = raw.trim();
|
|
2789
|
+
return t ? { type: t, options: {} } : null;
|
|
2790
|
+
}
|
|
2791
|
+
if (typeof raw === 'object' && !Array.isArray(raw) && 'type' in raw) {
|
|
2792
|
+
const w = raw;
|
|
2793
|
+
return w.type ? cloneDeep(w) : null;
|
|
2794
|
+
}
|
|
2795
|
+
return null;
|
|
2796
|
+
}
|
|
2797
|
+
resolveFieldTitleLabel(raw, fallback) {
|
|
2798
|
+
let source = fallback;
|
|
2799
|
+
if (raw !== undefined && raw !== null) {
|
|
2800
|
+
if (typeof raw === 'string') {
|
|
2801
|
+
if (raw.trim() !== '') {
|
|
2802
|
+
source = raw;
|
|
2803
|
+
}
|
|
2804
|
+
}
|
|
2805
|
+
else if (typeof raw === 'object' && !Array.isArray(raw) && Object.keys(raw).length > 0) {
|
|
2806
|
+
source = raw;
|
|
2807
|
+
}
|
|
2808
|
+
}
|
|
2809
|
+
return this.mlResolver.resolve(source);
|
|
2810
|
+
}
|
|
2811
|
+
isCancelDialogOutcome(outcome) {
|
|
2812
|
+
if (outcome == null) {
|
|
2813
|
+
return false;
|
|
2814
|
+
}
|
|
2815
|
+
const ref = outcome;
|
|
2816
|
+
if (typeof ref.action !== 'function') {
|
|
2817
|
+
return false;
|
|
2818
|
+
}
|
|
2819
|
+
return ref.action() === 'cancel';
|
|
2820
|
+
}
|
|
2821
|
+
async resolveWidgetDisplayTitle(widgetType) {
|
|
2822
|
+
const crud = this.crudService;
|
|
2823
|
+
if (crud) {
|
|
2824
|
+
const interfaces = await crud.listInterfaces();
|
|
2825
|
+
const iface = interfaces.find((d) => d.name === widgetType);
|
|
2826
|
+
return iface?.title ?? iface?.name;
|
|
2827
|
+
}
|
|
2828
|
+
const config = this.widgetRegistry.getOptional(widgetType);
|
|
2829
|
+
if (!config) {
|
|
2830
|
+
return undefined;
|
|
2831
|
+
}
|
|
2832
|
+
const resolved = this.mlResolver.resolve(config.title);
|
|
2833
|
+
return resolved || undefined;
|
|
2834
|
+
}
|
|
2835
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPPreviewWidgetFieldCommand, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
2836
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPPreviewWidgetFieldCommand }); }
|
|
2837
|
+
}
|
|
2838
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPPreviewWidgetFieldCommand, decorators: [{
|
|
2839
|
+
type: Injectable
|
|
2840
|
+
}] });
|
|
2841
|
+
|
|
2842
|
+
var previewWidgetField_command = /*#__PURE__*/Object.freeze({
|
|
2843
|
+
__proto__: null,
|
|
2844
|
+
AXPPreviewWidgetFieldCommand: AXPPreviewWidgetFieldCommand
|
|
2845
|
+
});
|
|
2846
|
+
|
|
2471
2847
|
/**
|
|
2472
2848
|
* Generated bundle index. Do not edit.
|
|
2473
2849
|
*/
|
|
2474
2850
|
|
|
2475
|
-
export { AXPDialogRendererComponent, AXPLayoutBuilderService, AXPLayoutConversionService, AXPLayoutRendererComponent, LayoutBuilderModule };
|
|
2851
|
+
export { AXPDialogRendererComponent, AXPLayoutBuilderService, AXPLayoutConversionService, AXPLayoutRendererComponent, AXPPreviewWidgetFieldCommand, AXP_PREVIEW_WIDGET_FIELD_COMMAND_KEY, LayoutBuilderModule };
|
|
2476
2852
|
//# sourceMappingURL=acorex-platform-layout-builder.mjs.map
|