@acorex/platform 21.0.0-beta.2 → 21.0.0-beta.4
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-common-settings.provider-G9XcXXOG.mjs → acorex-platform-common-common-settings.provider-lWz_f-Ia.mjs} +22 -24
- package/fesm2022/acorex-platform-common-common-settings.provider-lWz_f-Ia.mjs.map +1 -0
- package/fesm2022/acorex-platform-common.mjs +115 -23
- package/fesm2022/acorex-platform-common.mjs.map +1 -1
- package/fesm2022/acorex-platform-core.mjs +89 -1
- package/fesm2022/acorex-platform-core.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-builder.mjs +104 -13
- package/fesm2022/acorex-platform-layout-builder.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-components.mjs +220 -2
- package/fesm2022/acorex-platform-layout-components.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-designer.mjs +37 -2
- package/fesm2022/acorex-platform-layout-designer.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-entity.mjs +149 -2
- package/fesm2022/acorex-platform-layout-entity.mjs.map +1 -1
- package/fesm2022/acorex-platform-layout-widgets.mjs +62 -17
- package/fesm2022/acorex-platform-layout-widgets.mjs.map +1 -1
- package/fesm2022/acorex-platform-runtime.mjs +65 -2
- package/fesm2022/acorex-platform-runtime.mjs.map +1 -1
- package/fesm2022/{acorex-platform-themes-shared-settings.provider-D13QB3Hr.mjs → acorex-platform-themes-shared-settings.provider-DK6R87Lf.mjs} +23 -24
- package/fesm2022/acorex-platform-themes-shared-settings.provider-DK6R87Lf.mjs.map +1 -0
- package/fesm2022/acorex-platform-themes-shared.mjs +2 -2
- package/package.json +2 -4
- package/types/acorex-platform-common.d.ts +38 -4
- package/types/acorex-platform-core.d.ts +20 -2
- package/types/acorex-platform-layout-builder.d.ts +26 -3
- package/types/acorex-platform-layout-components.d.ts +52 -1
- package/types/acorex-platform-layout-entity.d.ts +19 -2
- package/types/acorex-platform-layout-widgets.d.ts +19 -5
- package/types/acorex-platform-runtime.d.ts +6 -0
- package/fesm2022/acorex-platform-common-common-settings.provider-G9XcXXOG.mjs.map +0 -1
- package/fesm2022/acorex-platform-themes-shared-settings.provider-D13QB3Hr.mjs.map +0 -1
|
@@ -2,7 +2,7 @@ import * as i5 from '@angular/common';
|
|
|
2
2
|
import { CommonModule } from '@angular/common';
|
|
3
3
|
import * as i0 from '@angular/core';
|
|
4
4
|
import { Injectable, inject, input, model, signal, computed, effect, output, viewChild, ChangeDetectionStrategy, Component, NgModule, EventEmitter, Output } from '@angular/core';
|
|
5
|
-
import { provideCommandSetups } from '@acorex/platform/runtime';
|
|
5
|
+
import { provideCommandSetups, AXPCommandService } from '@acorex/platform/runtime';
|
|
6
6
|
import { AXPopupService } from '@acorex/components/popup';
|
|
7
7
|
import * as i4 from '@acorex/platform/core';
|
|
8
8
|
import { AXPHookService, AXPExpressionEvaluatorService, AXPComponentSlotModule, AXPContextStore } from '@acorex/platform/core';
|
|
@@ -40,6 +40,15 @@ const AXP_LAYOUT_BUILDER_DIALOG_BEFORE_OPEN_HOOK_KEY = 'layout-builder.dialog.be
|
|
|
40
40
|
*/
|
|
41
41
|
const AXP_LAYOUT_BUILDER_DIALOG_CONFIG_HOOK_KEY = 'layout-builder.dialog.config';
|
|
42
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
|
|
43
52
|
|
|
44
53
|
class AXPLayoutConversionService {
|
|
45
54
|
constructor() {
|
|
@@ -1670,7 +1679,8 @@ class DialogContainerBuilder {
|
|
|
1670
1679
|
// Create dialog configuration
|
|
1671
1680
|
const dialogConfig = {
|
|
1672
1681
|
title: this.dialogState.dialogOptions?.title || '',
|
|
1673
|
-
|
|
1682
|
+
//TODO: why we need message?
|
|
1683
|
+
//message: this.dialogState.dialogOptions?.message,
|
|
1674
1684
|
context: initialContext,
|
|
1675
1685
|
definition: dialogNode,
|
|
1676
1686
|
metadata: this.dialogState.dialogOptions.metadata,
|
|
@@ -1684,7 +1694,7 @@ class DialogContainerBuilder {
|
|
|
1684
1694
|
// The Promise resolves when user clicks an action button
|
|
1685
1695
|
return new Promise(async (resolve) => {
|
|
1686
1696
|
let flag = false;
|
|
1687
|
-
this.popupService.open(AXPDialogRendererComponent, {
|
|
1697
|
+
await this.popupService.open(AXPDialogRendererComponent, {
|
|
1688
1698
|
title: dialogConfig.title,
|
|
1689
1699
|
size: this.dialogState.dialogOptions?.size || 'md',
|
|
1690
1700
|
closeButton: this.dialogState.dialogOptions?.closeButton || false,
|
|
@@ -2360,6 +2370,8 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
|
|
|
2360
2370
|
super(...arguments);
|
|
2361
2371
|
this.result = new EventEmitter();
|
|
2362
2372
|
this.expressionEvaluator = inject(AXPExpressionEvaluatorService);
|
|
2373
|
+
this.commandService = inject(AXPCommandService);
|
|
2374
|
+
this.hookService = inject(AXPHookService, { optional: true });
|
|
2363
2375
|
this.context = signal({}, ...(ngDevMode ? [{ debugName: "context" }] : /* istanbul ignore next */ []));
|
|
2364
2376
|
// This will be set by the popup service automatically - same as dynamic-dialog
|
|
2365
2377
|
this.callBack = () => { };
|
|
@@ -2367,6 +2379,12 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
|
|
|
2367
2379
|
// Aggregated actions for footer rendering
|
|
2368
2380
|
this.footerPrefix = signal([], ...(ngDevMode ? [{ debugName: "footerPrefix" }] : /* istanbul ignore next */ []));
|
|
2369
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)}`;
|
|
2370
2388
|
//#endregion
|
|
2371
2389
|
//#region ---- View Accessors ----
|
|
2372
2390
|
// Access the internal layout renderer to reach the widgets container injector
|
|
@@ -2397,16 +2415,42 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
|
|
|
2397
2415
|
//#region ---- Lifecycle ----
|
|
2398
2416
|
ngOnInit() {
|
|
2399
2417
|
this.context.set(this.config?.context || {});
|
|
2418
|
+
void this.invokeLayoutContextChangedHooks();
|
|
2400
2419
|
}
|
|
2401
2420
|
#eff;
|
|
2402
2421
|
//#endregion
|
|
2403
2422
|
handleContextChanged(event) {
|
|
2404
2423
|
this.context.set(event);
|
|
2405
2424
|
this.aggregateAndEvaluateActions();
|
|
2425
|
+
void this.invokeLayoutContextChangedHooks();
|
|
2406
2426
|
}
|
|
2407
2427
|
handleContextInitiated(event) {
|
|
2408
2428
|
this.context.set(event);
|
|
2409
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
|
+
}
|
|
2410
2454
|
}
|
|
2411
2455
|
footerPrefixActions() {
|
|
2412
2456
|
return this.footerPrefix();
|
|
@@ -2428,6 +2472,7 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
|
|
|
2428
2472
|
return;
|
|
2429
2473
|
}
|
|
2430
2474
|
}
|
|
2475
|
+
//TODO: matin, why we need this? maybe we can remove it?
|
|
2431
2476
|
if (cmd?.startsWith('widget:')) {
|
|
2432
2477
|
const parsed = this.parseWidgetCommand(cmd);
|
|
2433
2478
|
if (parsed.widgetName && parsed.action) {
|
|
@@ -2436,6 +2481,25 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
|
|
|
2436
2481
|
return;
|
|
2437
2482
|
}
|
|
2438
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
|
+
}
|
|
2439
2503
|
const context = this.context();
|
|
2440
2504
|
const onAction = this.config?.onAction;
|
|
2441
2505
|
if (onAction) {
|
|
@@ -2443,7 +2507,7 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
|
|
|
2443
2507
|
try {
|
|
2444
2508
|
this.isDialogLoading.set(true);
|
|
2445
2509
|
const result = await Promise.resolve(onAction(dialogRef));
|
|
2446
|
-
if (result
|
|
2510
|
+
if (this.shouldKeepDialogOpenAfterCommandResult(result)) {
|
|
2447
2511
|
return;
|
|
2448
2512
|
}
|
|
2449
2513
|
this.callBack(result);
|
|
@@ -2481,8 +2545,25 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
|
|
|
2481
2545
|
if (cmd.startsWith('widget:')) {
|
|
2482
2546
|
return false;
|
|
2483
2547
|
}
|
|
2548
|
+
if (this.commandService.exists(cmd)) {
|
|
2549
|
+
return false;
|
|
2550
|
+
}
|
|
2484
2551
|
return true;
|
|
2485
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
|
+
}
|
|
2486
2567
|
createDialogRef(actionCmd) {
|
|
2487
2568
|
return {
|
|
2488
2569
|
close: (res) => {
|
|
@@ -2672,9 +2753,9 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
|
|
|
2672
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: `
|
|
2673
2754
|
<axp-component-slot name="dialog-header" [context]="context()"></axp-component-slot>
|
|
2674
2755
|
<div class="p-4">
|
|
2675
|
-
@if (config.message) {
|
|
2756
|
+
<!-- @if (config.message) {
|
|
2676
2757
|
<p class="mb-4 leading-relaxed">{{ config.message | translate | async }}</p>
|
|
2677
|
-
}
|
|
2758
|
+
} -->
|
|
2678
2759
|
<axp-layout-renderer
|
|
2679
2760
|
[layout]="config.definition"
|
|
2680
2761
|
[context]="context()"
|
|
@@ -2698,8 +2779,13 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
|
|
|
2698
2779
|
[color]="action.color"
|
|
2699
2780
|
(onClick)="executeAction(action)"
|
|
2700
2781
|
>
|
|
2782
|
+
@if (isFormLoading()) {
|
|
2783
|
+
<ax-loading></ax-loading>
|
|
2784
|
+
}
|
|
2701
2785
|
<ax-prefix>
|
|
2702
|
-
|
|
2786
|
+
@if (action.icon) {
|
|
2787
|
+
<ax-icon [icon]="action.icon"></ax-icon>
|
|
2788
|
+
}
|
|
2703
2789
|
</ax-prefix>
|
|
2704
2790
|
</ax-button>
|
|
2705
2791
|
}
|
|
@@ -2718,7 +2804,7 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
|
|
|
2718
2804
|
}
|
|
2719
2805
|
@if (action.icon) {
|
|
2720
2806
|
<ax-prefix>
|
|
2721
|
-
<ax-icon icon="
|
|
2807
|
+
<ax-icon [icon]="action.icon"></ax-icon>
|
|
2722
2808
|
</ax-prefix>
|
|
2723
2809
|
}
|
|
2724
2810
|
</ax-button>
|
|
@@ -2748,9 +2834,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
2748
2834
|
template: `
|
|
2749
2835
|
<axp-component-slot name="dialog-header" [context]="context()"></axp-component-slot>
|
|
2750
2836
|
<div class="p-4">
|
|
2751
|
-
@if (config.message) {
|
|
2837
|
+
<!-- @if (config.message) {
|
|
2752
2838
|
<p class="mb-4 leading-relaxed">{{ config.message | translate | async }}</p>
|
|
2753
|
-
}
|
|
2839
|
+
} -->
|
|
2754
2840
|
<axp-layout-renderer
|
|
2755
2841
|
[layout]="config.definition"
|
|
2756
2842
|
[context]="context()"
|
|
@@ -2774,8 +2860,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
2774
2860
|
[color]="action.color"
|
|
2775
2861
|
(onClick)="executeAction(action)"
|
|
2776
2862
|
>
|
|
2863
|
+
@if (isFormLoading()) {
|
|
2864
|
+
<ax-loading></ax-loading>
|
|
2865
|
+
}
|
|
2777
2866
|
<ax-prefix>
|
|
2778
|
-
|
|
2867
|
+
@if (action.icon) {
|
|
2868
|
+
<ax-icon [icon]="action.icon"></ax-icon>
|
|
2869
|
+
}
|
|
2779
2870
|
</ax-prefix>
|
|
2780
2871
|
</ax-button>
|
|
2781
2872
|
}
|
|
@@ -2794,7 +2885,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
2794
2885
|
}
|
|
2795
2886
|
@if (action.icon) {
|
|
2796
2887
|
<ax-prefix>
|
|
2797
|
-
<ax-icon icon="
|
|
2888
|
+
<ax-icon [icon]="action.icon"></ax-icon>
|
|
2798
2889
|
</ax-prefix>
|
|
2799
2890
|
}
|
|
2800
2891
|
</ax-button>
|
|
@@ -2999,5 +3090,5 @@ var previewWidgetField_command = /*#__PURE__*/Object.freeze({
|
|
|
2999
3090
|
* Generated bundle index. Do not edit.
|
|
3000
3091
|
*/
|
|
3001
3092
|
|
|
3002
|
-
export { AXPDialogRendererComponent, AXPLayoutBuilderService, AXPLayoutConversionService, AXPLayoutRendererComponent, AXPPreviewWidgetFieldCommand, AXP_LAYOUT_BUILDER_DIALOG_BEFORE_OPEN_HOOK_KEY, AXP_LAYOUT_BUILDER_DIALOG_CONFIG_HOOK_KEY, AXP_PREVIEW_WIDGET_FIELD_COMMAND_KEY, 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 };
|
|
3003
3094
|
//# sourceMappingURL=acorex-platform-layout-builder.mjs.map
|