@acorex/platform 21.0.0-next.39 → 21.0.0-next.41
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-common.mjs +6 -2
- package/fesm2022/acorex-platform-common.mjs.map +1 -1
- package/fesm2022/acorex-platform-core.mjs +8 -1
- package/fesm2022/acorex-platform-core.mjs.map +1 -1
- package/fesm2022/acorex-platform-domain.mjs +3 -0
- package/fesm2022/acorex-platform-domain.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-builder.mjs +137 -34
- package/fesm2022/acorex-platform-layout-builder.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-components.mjs +25 -13
- package/fesm2022/acorex-platform-layout-components.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-designer.mjs +261 -58
- package/fesm2022/acorex-platform-layout-designer.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-entity.mjs +1583 -632
- package/fesm2022/acorex-platform-layout-entity.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-widget-core.mjs +169 -85
- package/fesm2022/acorex-platform-layout-widget-core.mjs.map +1 -1
- package/fesm2022/{acorex-platform-layout-widgets-repeater-widget-column.component-BGQqY5Mw.mjs → acorex-platform-layout-widgets-repeater-widget-column.component-BGO75IMz.mjs} +9 -4
- package/fesm2022/acorex-platform-layout-widgets-repeater-widget-column.component-BGO75IMz.mjs.map +1 -0
- package/fesm2022/acorex-platform-layout-widgets.mjs +1053 -409
- package/fesm2022/acorex-platform-layout-widgets.mjs.map +1 -1
- package/fesm2022/acorex-platform-runtime.mjs +120 -9
- package/fesm2022/acorex-platform-runtime.mjs.map +1 -1
- package/fesm2022/{acorex-platform-themes-default-entity-master-create-view.component-Cvvr4HnL.mjs → acorex-platform-themes-default-entity-master-create-view.component-Cx1lLUaR.mjs} +3 -3
- 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-TYoLN1Jq.mjs → acorex-platform-themes-default-entity-master-modify-view.component-AOrcgjDF.mjs} +3 -3
- 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-C2z5Lq9y.mjs → acorex-platform-themes-default-entity-master-single-view.component-BfCeUU5F.mjs} +3 -3
- package/fesm2022/acorex-platform-themes-default-entity-master-single-view.component-BfCeUU5F.mjs.map +1 -0
- package/fesm2022/acorex-platform-themes-default.mjs +10 -10
- package/fesm2022/acorex-platform-themes-default.mjs.map +1 -1
- package/fesm2022/{acorex-platform-themes-shared-settings.provider-DSs1o1M6.mjs → acorex-platform-themes-shared-settings.provider-D13QB3Hr.mjs} +2 -2
- package/fesm2022/acorex-platform-themes-shared-settings.provider-D13QB3Hr.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-BSmvnUVq.mjs → acorex-platform-themes-shared-theme-color-chooser-view.component-D7-rCGl7.mjs} +38 -16
- package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-view.component-D7-rCGl7.mjs.map +1 -0
- package/fesm2022/acorex-platform-themes-shared.mjs +183 -84
- package/fesm2022/acorex-platform-themes-shared.mjs.map +1 -1
- package/fesm2022/acorex-platform-workflow.mjs +52 -11
- package/fesm2022/acorex-platform-workflow.mjs.map +1 -1
- package/package.json +1 -1
- package/types/acorex-platform-common.d.ts +14 -10
- package/types/acorex-platform-core.d.ts +13 -2
- package/types/acorex-platform-domain.d.ts +28 -2
- package/types/acorex-platform-layout-builder.d.ts +61 -29
- package/types/acorex-platform-layout-designer.d.ts +88 -16
- package/types/acorex-platform-layout-entity.d.ts +190 -15
- package/types/acorex-platform-layout-widget-core.d.ts +81 -71
- package/types/acorex-platform-layout-widgets.d.ts +131 -54
- package/types/acorex-platform-runtime.d.ts +156 -61
- package/types/acorex-platform-workflow.d.ts +37 -2
- package/fesm2022/acorex-platform-layout-widgets-repeater-widget-column.component-BGQqY5Mw.mjs.map +0 -1
- package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-Cvvr4HnL.mjs.map +0 -1
- package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-TYoLN1Jq.mjs.map +0 -1
- package/fesm2022/acorex-platform-themes-default-entity-master-single-view.component-C2z5Lq9y.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-CHfrTtol.mjs +0 -65
- package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-column.component-CHfrTtol.mjs.map +0 -1
- package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-view.component-BSmvnUVq.mjs.map +0 -1
|
@@ -1,12 +1,12 @@
|
|
|
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
5
|
import { provideCommandSetups } from '@acorex/platform/runtime';
|
|
6
6
|
import { AXPopupService } from '@acorex/components/popup';
|
|
7
7
|
import * as i1 from '@acorex/platform/layout/widget-core';
|
|
8
8
|
import { AXPWidgetSerializationHelper, AXPWidgetContainerComponent, AXPPageStatus, AXPWidgetCoreModule, AXPWidgetRegistryService } from '@acorex/platform/layout/widget-core';
|
|
9
|
-
import { cloneDeep, isNil, set, isEqual } from 'lodash-es';
|
|
9
|
+
import { cloneDeep, isNil, set, isEqual, merge } from 'lodash-es';
|
|
10
10
|
import * as i2 from '@acorex/components/form';
|
|
11
11
|
import { AXFormComponent, AXFormModule } from '@acorex/components/form';
|
|
12
12
|
import { Subject, debounceTime, distinctUntilChanged, startWith } from 'rxjs';
|
|
@@ -161,6 +161,10 @@ class AXPLayoutConversionService {
|
|
|
161
161
|
if (!editorWidget.mode) {
|
|
162
162
|
editorWidget.mode = fieldMode;
|
|
163
163
|
}
|
|
164
|
+
const hintOpts = field.description != null &&
|
|
165
|
+
(typeof field.description !== 'string' || field.description.trim().length > 0)
|
|
166
|
+
? { hint: field.description, hintDisplayMode: 'note' }
|
|
167
|
+
: {};
|
|
164
168
|
return {
|
|
165
169
|
type: 'form-field',
|
|
166
170
|
name: field.path,
|
|
@@ -168,8 +172,8 @@ class AXPLayoutConversionService {
|
|
|
168
172
|
options: {
|
|
169
173
|
label: field.title,
|
|
170
174
|
badge: field.badge,
|
|
171
|
-
description: field.description,
|
|
172
175
|
showLabel: true,
|
|
176
|
+
...hintOpts,
|
|
173
177
|
},
|
|
174
178
|
children: [editorWidget], // The editor widget becomes a child of form-field
|
|
175
179
|
};
|
|
@@ -212,7 +216,7 @@ class AXPLayoutConversionService {
|
|
|
212
216
|
path: formFieldNode.name || editorWidget.name || `field-${Date.now()}`,
|
|
213
217
|
title: formFieldNode.options?.['label'],
|
|
214
218
|
badge: formFieldNode.options?.['badge'],
|
|
215
|
-
description: formFieldNode.options?.['
|
|
219
|
+
description: formFieldNode.options?.['hint'],
|
|
216
220
|
widget: editorWidget,
|
|
217
221
|
mode: formFieldNode.mode,
|
|
218
222
|
};
|
|
@@ -527,11 +531,21 @@ class LayoutBuilder {
|
|
|
527
531
|
return this;
|
|
528
532
|
}
|
|
529
533
|
build() {
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
mode:
|
|
534
|
+
const r = this.root;
|
|
535
|
+
const node = {
|
|
536
|
+
type: r.type,
|
|
537
|
+
...(r.mode !== undefined ? { mode: r.mode } : {}),
|
|
538
|
+
...(r.children !== undefined ? { children: r.children } : {}),
|
|
539
|
+
...(r.options !== undefined ? { options: r.options } : {}),
|
|
540
|
+
...(r.name !== undefined ? { name: r.name } : {}),
|
|
541
|
+
...(r.path !== undefined ? { path: r.path } : {}),
|
|
542
|
+
...(r.visible !== undefined ? { visible: r.visible } : {}),
|
|
543
|
+
...(r.defaultValue !== undefined ? { defaultValue: r.defaultValue } : {}),
|
|
544
|
+
...(r.triggers !== undefined ? { triggers: r.triggers } : {}),
|
|
545
|
+
...(r.meta !== undefined ? { meta: r.meta } : {}),
|
|
546
|
+
...(r.valueTransforms !== undefined ? { valueTransforms: r.valueTransforms } : {}),
|
|
534
547
|
};
|
|
548
|
+
return node;
|
|
535
549
|
}
|
|
536
550
|
/**
|
|
537
551
|
* Converts the built widget node to JSON string
|
|
@@ -1005,6 +1019,24 @@ class FlexContainerBuilder extends WidgetContainerMixin {
|
|
|
1005
1019
|
* Extracts flat grid-item options from AXPGridLayoutOptions for grid-item-layout widget.
|
|
1006
1020
|
* Uses first available breakpoint (lg, xl, md, sm).
|
|
1007
1021
|
*/
|
|
1022
|
+
/**
|
|
1023
|
+
* Deep-merges grid breakpoint buckets so sequential fluent calls (e.g. setColumns then setGap)
|
|
1024
|
+
* do not wipe sibling keys under options.grid.default.
|
|
1025
|
+
*/
|
|
1026
|
+
function mergeAXPGridContainerOptions(prev, patch) {
|
|
1027
|
+
const next = { ...(prev ?? {}), ...patch };
|
|
1028
|
+
if (prev?.grid?.default || patch.grid?.default) {
|
|
1029
|
+
next.grid = {
|
|
1030
|
+
...(prev?.grid ?? {}),
|
|
1031
|
+
...(patch.grid ?? {}),
|
|
1032
|
+
default: {
|
|
1033
|
+
...(prev?.grid?.default ?? {}),
|
|
1034
|
+
...(patch.grid?.default ?? {}),
|
|
1035
|
+
},
|
|
1036
|
+
};
|
|
1037
|
+
}
|
|
1038
|
+
return next;
|
|
1039
|
+
}
|
|
1008
1040
|
function toGridItemOptions(layoutOptions) {
|
|
1009
1041
|
if (!layoutOptions?.positions)
|
|
1010
1042
|
return { colSpan: 12 };
|
|
@@ -1034,7 +1066,7 @@ class GridContainerBuilder extends WidgetContainerMixin {
|
|
|
1034
1066
|
super('grid-layout');
|
|
1035
1067
|
}
|
|
1036
1068
|
setOptions(options) {
|
|
1037
|
-
this.containerState.options =
|
|
1069
|
+
this.containerState.options = mergeAXPGridContainerOptions(this.containerState.options, options);
|
|
1038
1070
|
return this;
|
|
1039
1071
|
}
|
|
1040
1072
|
item(layoutOptions, delegate) {
|
|
@@ -1998,6 +2030,11 @@ class AXPLayoutRendererComponent {
|
|
|
1998
2030
|
//#endregion
|
|
1999
2031
|
//#region ---- Widget Tree Conversion ----
|
|
2000
2032
|
this.widgetTree = signal(null, ...(ngDevMode ? [{ debugName: "widgetTree" }] : /* istanbul ignore next */ []));
|
|
2033
|
+
/**
|
|
2034
|
+
* Prefer explicit {@link AXPWidgetNode.mode} on the root node (e.g. dialog flex `mode('view')`)
|
|
2035
|
+
* so nested widgets resolve view vs edit correctly; fall back to the layout `mode` input.
|
|
2036
|
+
*/
|
|
2037
|
+
this.effectiveRenderMode = computed(() => this.widgetTree()?.mode ?? this.mode(), ...(ngDevMode ? [{ debugName: "effectiveRenderMode" }] : /* istanbul ignore next */ []));
|
|
2001
2038
|
/**
|
|
2002
2039
|
* Convert layout data to widget tree when inputs change
|
|
2003
2040
|
*/
|
|
@@ -2207,7 +2244,11 @@ class AXPLayoutRendererComponent {
|
|
|
2207
2244
|
<ax-form>
|
|
2208
2245
|
<axp-widgets-container [context]="internalContext()" (onContextChanged)="handleContextChanged($event)">
|
|
2209
2246
|
@if (widgetTree()) {
|
|
2210
|
-
<ng-container
|
|
2247
|
+
<ng-container
|
|
2248
|
+
axp-widget-renderer
|
|
2249
|
+
[node]="widgetTree()!"
|
|
2250
|
+
[mode]="effectiveRenderMode()"
|
|
2251
|
+
></ng-container>
|
|
2211
2252
|
}
|
|
2212
2253
|
</axp-widgets-container>
|
|
2213
2254
|
</ax-form>
|
|
@@ -2219,7 +2260,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
2219
2260
|
<ax-form>
|
|
2220
2261
|
<axp-widgets-container [context]="internalContext()" (onContextChanged)="handleContextChanged($event)">
|
|
2221
2262
|
@if (widgetTree()) {
|
|
2222
|
-
<ng-container
|
|
2263
|
+
<ng-container
|
|
2264
|
+
axp-widget-renderer
|
|
2265
|
+
[node]="widgetTree()!"
|
|
2266
|
+
[mode]="effectiveRenderMode()"
|
|
2267
|
+
></ng-container>
|
|
2223
2268
|
}
|
|
2224
2269
|
</axp-widgets-container>
|
|
2225
2270
|
</ax-form>
|
|
@@ -2328,7 +2373,7 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
|
|
|
2328
2373
|
}
|
|
2329
2374
|
async executeAction(action) {
|
|
2330
2375
|
const cmd = this.resolveActionCommandName(action.command);
|
|
2331
|
-
if (cmd
|
|
2376
|
+
if (this.shouldValidateBeforeAction(cmd)) {
|
|
2332
2377
|
const isValid = await this.layoutRenderer()?.validate();
|
|
2333
2378
|
if (!isValid?.result) {
|
|
2334
2379
|
return;
|
|
@@ -2337,7 +2382,7 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
|
|
|
2337
2382
|
if (cmd?.startsWith('widget:')) {
|
|
2338
2383
|
const parsed = this.parseWidgetCommand(cmd);
|
|
2339
2384
|
if (parsed.widgetName && parsed.action) {
|
|
2340
|
-
await this.
|
|
2385
|
+
await this.invokeWidget(parsed.widgetName, parsed.action, {});
|
|
2341
2386
|
await this.aggregateAndEvaluateActions();
|
|
2342
2387
|
return;
|
|
2343
2388
|
}
|
|
@@ -2345,17 +2390,15 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
|
|
|
2345
2390
|
const context = this.context();
|
|
2346
2391
|
const onAction = this.config?.onAction;
|
|
2347
2392
|
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
|
-
};
|
|
2393
|
+
const dialogRef = this.createDialogRef(cmd);
|
|
2354
2394
|
try {
|
|
2355
2395
|
this.isDialogLoading.set(true);
|
|
2356
2396
|
const result = await Promise.resolve(onAction(dialogRef));
|
|
2397
|
+
if (result && typeof result === 'object' && result.keepDialogOpen) {
|
|
2398
|
+
return;
|
|
2399
|
+
}
|
|
2357
2400
|
this.callBack(result);
|
|
2358
|
-
this.
|
|
2401
|
+
await this.closeWithOptionalSkipValidate(result);
|
|
2359
2402
|
}
|
|
2360
2403
|
catch {
|
|
2361
2404
|
// Handler threw: stay open for retry, actions remain clickable
|
|
@@ -2373,20 +2416,48 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
|
|
|
2373
2416
|
this.data.action = result.action;
|
|
2374
2417
|
}
|
|
2375
2418
|
this.callBack({
|
|
2376
|
-
|
|
2377
|
-
this.close(res);
|
|
2378
|
-
},
|
|
2379
|
-
context: () => this.context(),
|
|
2419
|
+
...this.createDialogRef(cmd),
|
|
2380
2420
|
action: () => result.action,
|
|
2381
|
-
setLoading: (loading) => {
|
|
2382
|
-
this.isDialogLoading.set(loading);
|
|
2383
|
-
},
|
|
2384
2421
|
});
|
|
2385
2422
|
// Without `onAction`, only the configured cancel action dismisses the dialog (not submit/custom).
|
|
2386
2423
|
if (cmd === 'cancel') {
|
|
2387
2424
|
await this.close(result);
|
|
2388
2425
|
}
|
|
2389
2426
|
}
|
|
2427
|
+
/** Whether the layout form should be validated before running this footer command. */
|
|
2428
|
+
shouldValidateBeforeAction(cmd) {
|
|
2429
|
+
if (!cmd || cmd === 'cancel' || cmd === 'entity-form-done') {
|
|
2430
|
+
return false;
|
|
2431
|
+
}
|
|
2432
|
+
if (cmd.startsWith('widget:')) {
|
|
2433
|
+
return false;
|
|
2434
|
+
}
|
|
2435
|
+
return true;
|
|
2436
|
+
}
|
|
2437
|
+
createDialogRef(actionCmd) {
|
|
2438
|
+
return {
|
|
2439
|
+
close: (res) => {
|
|
2440
|
+
void this.closeWithOptionalSkipValidate(res);
|
|
2441
|
+
},
|
|
2442
|
+
context: () => this.context(),
|
|
2443
|
+
action: () => actionCmd,
|
|
2444
|
+
setLoading: (loading) => this.isDialogLoading.set(loading),
|
|
2445
|
+
patchContext: (partial) => {
|
|
2446
|
+
const merged = merge({}, this.context(), partial);
|
|
2447
|
+
this.context.set(merged);
|
|
2448
|
+
this.layoutRenderer()?.updateContext(merged);
|
|
2449
|
+
},
|
|
2450
|
+
invokeWidget: (widgetName, method, opts) => this.invokeWidget(widgetName, method, opts ?? {}),
|
|
2451
|
+
};
|
|
2452
|
+
}
|
|
2453
|
+
async closeWithOptionalSkipValidate(result) {
|
|
2454
|
+
if (result && typeof result === 'object' && result.skipValidate) {
|
|
2455
|
+
this.result.emit(result);
|
|
2456
|
+
await super.close(result);
|
|
2457
|
+
return;
|
|
2458
|
+
}
|
|
2459
|
+
await this.close(result);
|
|
2460
|
+
}
|
|
2390
2461
|
/** Resolves footer/widget action command to a string (e.g. `cancel`, `submit`, `widget:...`). */
|
|
2391
2462
|
resolveActionCommandName(command) {
|
|
2392
2463
|
if (typeof command === 'string') {
|
|
@@ -2407,7 +2478,7 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
|
|
|
2407
2478
|
return {};
|
|
2408
2479
|
return { widgetName: rest.slice(0, dot), action: rest.slice(dot + 1) };
|
|
2409
2480
|
}
|
|
2410
|
-
async
|
|
2481
|
+
async invokeWidget(widgetName, apiMethod, opts) {
|
|
2411
2482
|
if (!this.widgetCoreService)
|
|
2412
2483
|
return;
|
|
2413
2484
|
try {
|
|
@@ -2417,16 +2488,20 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
|
|
|
2417
2488
|
if (typeof fn === 'function') {
|
|
2418
2489
|
await Promise.resolve(fn({
|
|
2419
2490
|
close: (result) => {
|
|
2420
|
-
this.
|
|
2491
|
+
void this.closeWithOptionalSkipValidate(result);
|
|
2421
2492
|
},
|
|
2422
2493
|
context: () => this.context(),
|
|
2423
2494
|
setLoading: (loading) => {
|
|
2424
|
-
this.isDialogLoading.set(loading);
|
|
2495
|
+
(opts.setLoading ?? ((v) => this.isDialogLoading.set(v)))(loading);
|
|
2425
2496
|
},
|
|
2426
2497
|
}));
|
|
2498
|
+
// Footer predicates (e.g. wizard step) must refresh when the widget advances outside executeAction (e.g. dialogRef.invokeWidget after entity-form continue).
|
|
2499
|
+
await this.aggregateAndEvaluateActions();
|
|
2427
2500
|
}
|
|
2428
2501
|
}
|
|
2429
|
-
catch {
|
|
2502
|
+
catch {
|
|
2503
|
+
//
|
|
2504
|
+
}
|
|
2430
2505
|
}
|
|
2431
2506
|
async close(result) {
|
|
2432
2507
|
if (result) {
|
|
@@ -2476,6 +2551,7 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
|
|
|
2476
2551
|
zone: 'footer',
|
|
2477
2552
|
placement,
|
|
2478
2553
|
scope: a.scope,
|
|
2554
|
+
predicateApiWidgetName: a.predicateApiWidgetName,
|
|
2479
2555
|
});
|
|
2480
2556
|
const prefix = (footer?.prefix || []).map((a) => mapOne(a, 'prefix'));
|
|
2481
2557
|
const suffix = (footer?.suffix || []).map((a) => mapOne(a, 'suffix'));
|
|
@@ -2485,16 +2561,18 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
|
|
|
2485
2561
|
const out = [];
|
|
2486
2562
|
for (const a of actions) {
|
|
2487
2563
|
const parsed = typeof a.command === 'string' ? this.parseWidgetCommand(a.command) : {};
|
|
2488
|
-
const
|
|
2564
|
+
const widgetNameForApi = parsed.widgetName ?? a.predicateApiWidgetName;
|
|
2565
|
+
const api = widgetNameForApi ? await this.resolveApi(widgetNameForApi) : undefined;
|
|
2489
2566
|
const scope = {
|
|
2490
2567
|
api,
|
|
2491
|
-
widget: { name:
|
|
2568
|
+
widget: { name: widgetNameForApi },
|
|
2492
2569
|
dialog: { context: this.context() },
|
|
2493
2570
|
context: this.context(),
|
|
2494
2571
|
};
|
|
2495
2572
|
const disabled = await this.evalBool(a.disabled, scope);
|
|
2496
2573
|
const hidden = await this.evalBool(a.hidden, scope);
|
|
2497
|
-
|
|
2574
|
+
const resolvedTitle = (await this.evalActionTitle(a.title, scope)) ?? a.title;
|
|
2575
|
+
out.push({ ...a, disabled, hidden, title: resolvedTitle });
|
|
2498
2576
|
}
|
|
2499
2577
|
return out;
|
|
2500
2578
|
}
|
|
@@ -2512,6 +2590,25 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
|
|
|
2512
2590
|
}
|
|
2513
2591
|
return value;
|
|
2514
2592
|
}
|
|
2593
|
+
/** Resolves footer action title when it contains {{ ... }} (e.g. wizard labels from dialog context). */
|
|
2594
|
+
async evalActionTitle(value, scope) {
|
|
2595
|
+
if (value == null || typeof value !== 'string' || !value.includes('{{')) {
|
|
2596
|
+
return value;
|
|
2597
|
+
}
|
|
2598
|
+
try {
|
|
2599
|
+
const result = await this.expressionEvaluator.evaluate(value, scope);
|
|
2600
|
+
if (typeof result === 'string' && result.length > 0) {
|
|
2601
|
+
return result;
|
|
2602
|
+
}
|
|
2603
|
+
if (result != null && result !== false) {
|
|
2604
|
+
return String(result);
|
|
2605
|
+
}
|
|
2606
|
+
}
|
|
2607
|
+
catch {
|
|
2608
|
+
//
|
|
2609
|
+
}
|
|
2610
|
+
return value;
|
|
2611
|
+
}
|
|
2515
2612
|
async resolveApi(widgetName) {
|
|
2516
2613
|
try {
|
|
2517
2614
|
await this.widgetCoreService?.waitForWidget(widgetName, 2000);
|
|
@@ -2526,6 +2623,9 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
|
|
|
2526
2623
|
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
2624
|
<axp-component-slot name="dialog-header" [context]="context()"></axp-component-slot>
|
|
2528
2625
|
<div class="ax-p-4">
|
|
2626
|
+
@if (config.message) {
|
|
2627
|
+
<p class="ax-mb-4 ax-leading-relaxed">{{ config.message | translate | async }}</p>
|
|
2628
|
+
}
|
|
2529
2629
|
<axp-layout-renderer
|
|
2530
2630
|
[layout]="config.definition"
|
|
2531
2631
|
[context]="context()"
|
|
@@ -2599,6 +2699,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
2599
2699
|
template: `
|
|
2600
2700
|
<axp-component-slot name="dialog-header" [context]="context()"></axp-component-slot>
|
|
2601
2701
|
<div class="ax-p-4">
|
|
2702
|
+
@if (config.message) {
|
|
2703
|
+
<p class="ax-mb-4 ax-leading-relaxed">{{ config.message | translate | async }}</p>
|
|
2704
|
+
}
|
|
2602
2705
|
<axp-layout-renderer
|
|
2603
2706
|
[layout]="config.definition"
|
|
2604
2707
|
[context]="context()"
|