@acorex-platform/framework-client 0.0.15 → 0.0.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/acorex-platform-framework-client-auth.mjs +872 -314
- package/fesm2022/acorex-platform-framework-client-auth.mjs.map +1 -1
- package/fesm2022/{acorex-platform-framework-client-common-common-settings.provider-Euotv9l0.mjs → acorex-platform-framework-client-common-common-settings.provider-CLm2BVk-.mjs} +88 -5
- package/fesm2022/acorex-platform-framework-client-common-common-settings.provider-CLm2BVk-.mjs.map +1 -0
- package/fesm2022/acorex-platform-framework-client-common.mjs +2685 -898
- package/fesm2022/acorex-platform-framework-client-common.mjs.map +1 -1
- package/fesm2022/acorex-platform-framework-client-core.mjs +691 -823
- package/fesm2022/acorex-platform-framework-client-core.mjs.map +1 -1
- package/fesm2022/acorex-platform-framework-client-domain.mjs +16 -16
- package/fesm2022/acorex-platform-framework-client-layout-builder.mjs +181 -84
- package/fesm2022/acorex-platform-framework-client-layout-builder.mjs.map +1 -1
- package/fesm2022/{acorex-platform-framework-client-layout-components-binding-expression-editor-popup.component-CjnQ9hAJ.mjs → acorex-platform-framework-client-layout-components-binding-expression-editor-popup.component-oE8CeLE8.mjs} +8 -6
- package/fesm2022/{acorex-platform-framework-client-layout-components-binding-expression-editor-popup.component-CjnQ9hAJ.mjs.map → acorex-platform-framework-client-layout-components-binding-expression-editor-popup.component-oE8CeLE8.mjs.map} +1 -1
- package/fesm2022/{acorex-platform-framework-client-layout-components-file-provider-picker.popup.component-fFen8w8M.mjs → acorex-platform-framework-client-layout-components-file-provider-picker.popup.component-BtLEUWAA.mjs} +4 -4
- package/fesm2022/{acorex-platform-framework-client-layout-components-file-provider-picker.popup.component-fFen8w8M.mjs.map → acorex-platform-framework-client-layout-components-file-provider-picker.popup.component-BtLEUWAA.mjs.map} +1 -1
- package/fesm2022/acorex-platform-framework-client-layout-components.mjs +3300 -1236
- package/fesm2022/acorex-platform-framework-client-layout-components.mjs.map +1 -1
- package/fesm2022/acorex-platform-framework-client-layout-designer.mjs +277 -185
- package/fesm2022/acorex-platform-framework-client-layout-designer.mjs.map +1 -1
- package/fesm2022/acorex-platform-framework-client-layout-entity-acorex-platform-framework-client-layout-entity-BXOMs6oD.mjs +29184 -0
- package/fesm2022/acorex-platform-framework-client-layout-entity-acorex-platform-framework-client-layout-entity-BXOMs6oD.mjs.map +1 -0
- package/fesm2022/{acorex-platform-framework-client-layout-entity-attachments-page.component-BzUM-JMC.mjs → acorex-platform-framework-client-layout-entity-attachments-page.component-DCK-qb-F.mjs} +34 -20
- package/fesm2022/acorex-platform-framework-client-layout-entity-attachments-page.component-DCK-qb-F.mjs.map +1 -0
- package/fesm2022/acorex-platform-framework-client-layout-entity-bulk-entity.command-Cs3agnpF.mjs +162 -0
- package/fesm2022/acorex-platform-framework-client-layout-entity-bulk-entity.command-Cs3agnpF.mjs.map +1 -0
- package/fesm2022/{acorex-platform-framework-client-layout-entity-file-list-popup.component-Ci_CTFtq.mjs → acorex-platform-framework-client-layout-entity-file-list-popup.component-p0hxDb0W.mjs} +31 -19
- package/fesm2022/acorex-platform-framework-client-layout-entity-file-list-popup.component-p0hxDb0W.mjs.map +1 -0
- package/fesm2022/{acorex-platform-framework-client-layout-entity-gallery-page.component-DmiB__JR.mjs → acorex-platform-framework-client-layout-entity-gallery-page.component-DYV9YPyw.mjs} +30 -18
- package/fesm2022/acorex-platform-framework-client-layout-entity-gallery-page.component-DYV9YPyw.mjs.map +1 -0
- package/fesm2022/acorex-platform-framework-client-layout-entity.mjs +2 -26780
- package/fesm2022/acorex-platform-framework-client-layout-entity.mjs.map +1 -1
- package/fesm2022/acorex-platform-framework-client-layout-views.mjs +421 -151
- package/fesm2022/acorex-platform-framework-client-layout-views.mjs.map +1 -1
- package/fesm2022/acorex-platform-framework-client-layout-widget-core.mjs +673 -287
- package/fesm2022/acorex-platform-framework-client-layout-widget-core.mjs.map +1 -1
- package/fesm2022/{acorex-platform-framework-client-layout-widgets-button-widget-designer.component-CIwpAXbL.mjs → acorex-platform-framework-client-layout-widgets-button-widget-designer.component-BiWerYcu.mjs} +16 -10
- package/fesm2022/{acorex-platform-framework-client-layout-widgets-button-widget-designer.component-CIwpAXbL.mjs.map → acorex-platform-framework-client-layout-widgets-button-widget-designer.component-BiWerYcu.mjs.map} +1 -1
- package/fesm2022/{acorex-platform-framework-client-layout-widgets-image-preview.popup-CazpERbX.mjs → acorex-platform-framework-client-layout-widgets-image-preview.popup-BOrrMm3U.mjs} +9 -8
- package/fesm2022/acorex-platform-framework-client-layout-widgets-image-preview.popup-BOrrMm3U.mjs.map +1 -0
- package/fesm2022/{acorex-platform-framework-client-layout-widgets-page-widget-designer.component-DKkJi40s.mjs → acorex-platform-framework-client-layout-widgets-page-widget-designer.component-WzIiwnGC.mjs} +20 -12
- package/fesm2022/{acorex-platform-framework-client-layout-widgets-page-widget-designer.component-DKkJi40s.mjs.map → acorex-platform-framework-client-layout-widgets-page-widget-designer.component-WzIiwnGC.mjs.map} +1 -1
- package/fesm2022/{acorex-platform-framework-client-layout-widgets-repeater-widget-column.component-DtYZfA79.mjs → acorex-platform-framework-client-layout-widgets-repeater-widget-column.component-3CO4xJB3.mjs} +32 -18
- package/fesm2022/{acorex-platform-framework-client-layout-widgets-repeater-widget-column.component-DtYZfA79.mjs.map → acorex-platform-framework-client-layout-widgets-repeater-widget-column.component-3CO4xJB3.mjs.map} +1 -1
- package/fesm2022/{acorex-platform-framework-client-layout-widgets-tabular-data-edit-popup.component-nMUtxAyy.mjs → acorex-platform-framework-client-layout-widgets-tabular-data-edit-popup.component-CRST84ou.mjs} +8 -7
- package/fesm2022/{acorex-platform-framework-client-layout-widgets-tabular-data-edit-popup.component-nMUtxAyy.mjs.map → acorex-platform-framework-client-layout-widgets-tabular-data-edit-popup.component-CRST84ou.mjs.map} +1 -1
- package/fesm2022/{acorex-platform-framework-client-layout-widgets-tabular-data-view-popup.component-DvUSZ4hJ.mjs → acorex-platform-framework-client-layout-widgets-tabular-data-view-popup.component-FjtSRxIX.mjs} +4 -4
- package/fesm2022/{acorex-platform-framework-client-layout-widgets-tabular-data-view-popup.component-DvUSZ4hJ.mjs.map → acorex-platform-framework-client-layout-widgets-tabular-data-view-popup.component-FjtSRxIX.mjs.map} +1 -1
- package/fesm2022/{acorex-platform-framework-client-layout-widgets-text-block-widget-designer.component-BihIfkZW.mjs → acorex-platform-framework-client-layout-widgets-text-block-widget-designer.component-D6HFPmGC.mjs} +10 -8
- package/fesm2022/{acorex-platform-framework-client-layout-widgets-text-block-widget-designer.component-BihIfkZW.mjs.map → acorex-platform-framework-client-layout-widgets-text-block-widget-designer.component-D6HFPmGC.mjs.map} +1 -1
- package/fesm2022/acorex-platform-framework-client-layout-widgets.mjs +4907 -2554
- package/fesm2022/acorex-platform-framework-client-layout-widgets.mjs.map +1 -1
- package/fesm2022/acorex-platform-framework-client-native.mjs +7 -7
- package/fesm2022/acorex-platform-framework-client-realtime-set-presence-availability.command-CetlUjnM.mjs +29 -0
- package/fesm2022/acorex-platform-framework-client-realtime-set-presence-availability.command-CetlUjnM.mjs.map +1 -0
- package/fesm2022/acorex-platform-framework-client-realtime.mjs +463 -26
- package/fesm2022/acorex-platform-framework-client-realtime.mjs.map +1 -1
- package/fesm2022/acorex-platform-framework-client-runtime.mjs +300 -137
- package/fesm2022/acorex-platform-framework-client-runtime.mjs.map +1 -1
- package/fesm2022/{acorex-platform-framework-client-themes-default-entity-master-create-view.component-QIFX11dh.mjs → acorex-platform-framework-client-themes-default-entity-master-create-view.component-yeftgJ_K.mjs} +10 -7
- package/fesm2022/{acorex-platform-framework-client-themes-default-entity-master-create-view.component-QIFX11dh.mjs.map → acorex-platform-framework-client-themes-default-entity-master-create-view.component-yeftgJ_K.mjs.map} +1 -1
- package/fesm2022/{acorex-platform-framework-client-themes-default-entity-master-modify-view.component-BBdellyL.mjs → acorex-platform-framework-client-themes-default-entity-master-modify-view.component-DWE3OWGm.mjs} +10 -7
- package/fesm2022/{acorex-platform-framework-client-themes-default-entity-master-modify-view.component-BBdellyL.mjs.map → acorex-platform-framework-client-themes-default-entity-master-modify-view.component-DWE3OWGm.mjs.map} +1 -1
- package/fesm2022/{acorex-platform-framework-client-themes-default-entity-master-single-view.component-CIf1VWNW.mjs → acorex-platform-framework-client-themes-default-entity-master-single-view.component-C2Abf7Lb.mjs} +21 -19
- package/fesm2022/acorex-platform-framework-client-themes-default-entity-master-single-view.component-C2Abf7Lb.mjs.map +1 -0
- package/fesm2022/{acorex-platform-framework-client-themes-default-error-401.component-C_czT_JC.mjs → acorex-platform-framework-client-themes-default-error-401.component-BrTotLx1.mjs} +5 -5
- package/fesm2022/{acorex-platform-framework-client-themes-default-error-401.component-C_czT_JC.mjs.map → acorex-platform-framework-client-themes-default-error-401.component-BrTotLx1.mjs.map} +1 -1
- package/fesm2022/{acorex-platform-framework-client-themes-default-error-404.component-C2Wu0YtF.mjs → acorex-platform-framework-client-themes-default-error-404.component-DsC7_s59.mjs} +5 -5
- package/fesm2022/{acorex-platform-framework-client-themes-default-error-404.component-C2Wu0YtF.mjs.map → acorex-platform-framework-client-themes-default-error-404.component-DsC7_s59.mjs.map} +1 -1
- package/fesm2022/{acorex-platform-framework-client-themes-default-error-offline.component-DRz-kVsT.mjs → acorex-platform-framework-client-themes-default-error-offline.component-CngiQycG.mjs} +6 -6
- package/fesm2022/acorex-platform-framework-client-themes-default-error-offline.component-CngiQycG.mjs.map +1 -0
- package/fesm2022/acorex-platform-framework-client-themes-default.mjs +448 -277
- package/fesm2022/acorex-platform-framework-client-themes-default.mjs.map +1 -1
- package/fesm2022/{acorex-platform-framework-client-themes-shared-icon-chooser-column.component-Ci_oH7NE.mjs → acorex-platform-framework-client-themes-shared-icon-chooser-column.component-CbZALjB5.mjs} +8 -6
- package/fesm2022/{acorex-platform-framework-client-themes-shared-icon-chooser-column.component-Ci_oH7NE.mjs.map → acorex-platform-framework-client-themes-shared-icon-chooser-column.component-CbZALjB5.mjs.map} +1 -1
- package/fesm2022/{acorex-platform-framework-client-themes-shared-icon-chooser-view.component-Lb1G2Xz7.mjs → acorex-platform-framework-client-themes-shared-icon-chooser-view.component-BRrNT6x2.mjs} +8 -6
- package/fesm2022/{acorex-platform-framework-client-themes-shared-icon-chooser-view.component-Lb1G2Xz7.mjs.map → acorex-platform-framework-client-themes-shared-icon-chooser-view.component-BRrNT6x2.mjs.map} +1 -1
- package/fesm2022/{acorex-platform-framework-client-themes-shared-theme-color-chooser-column.component-D4ubvFYf.mjs → acorex-platform-framework-client-themes-shared-theme-color-chooser-column.component-BIsQTr6B.mjs} +4 -4
- package/fesm2022/{acorex-platform-framework-client-themes-shared-theme-color-chooser-column.component-D4ubvFYf.mjs.map → acorex-platform-framework-client-themes-shared-theme-color-chooser-column.component-BIsQTr6B.mjs.map} +1 -1
- package/fesm2022/{acorex-platform-framework-client-themes-shared-theme-color-chooser-view.component-Br8j_BF_.mjs → acorex-platform-framework-client-themes-shared-theme-color-chooser-view.component-ZclmSbt9.mjs} +16 -10
- package/fesm2022/{acorex-platform-framework-client-themes-shared-theme-color-chooser-view.component-Br8j_BF_.mjs.map → acorex-platform-framework-client-themes-shared-theme-color-chooser-view.component-ZclmSbt9.mjs.map} +1 -1
- package/fesm2022/acorex-platform-framework-client-themes-shared.mjs +538 -133
- package/fesm2022/acorex-platform-framework-client-themes-shared.mjs.map +1 -1
- package/fesm2022/acorex-platform-framework-client-workflow.mjs +26 -66
- package/fesm2022/acorex-platform-framework-client-workflow.mjs.map +1 -1
- package/package.json +10 -10
- package/realtime/README.md +16 -0
- package/runtime/README.md +14 -0
- package/types/acorex-platform-framework-client-auth.d.ts +291 -52
- package/types/acorex-platform-framework-client-common.d.ts +615 -202
- package/types/acorex-platform-framework-client-core.d.ts +215 -225
- package/types/acorex-platform-framework-client-layout-builder.d.ts +24 -8
- package/types/acorex-platform-framework-client-layout-components.d.ts +407 -94
- package/types/acorex-platform-framework-client-layout-entity.d.ts +734 -411
- package/types/acorex-platform-framework-client-layout-views.d.ts +40 -15
- package/types/acorex-platform-framework-client-layout-widget-core.d.ts +66 -17
- package/types/acorex-platform-framework-client-layout-widgets.d.ts +295 -68
- package/types/acorex-platform-framework-client-realtime.d.ts +183 -6
- package/types/acorex-platform-framework-client-runtime.d.ts +134 -28
- package/types/acorex-platform-framework-client-themes-default.d.ts +9 -1
- package/types/acorex-platform-framework-client-themes-shared.d.ts +8 -2
- package/types/acorex-platform-framework-client-workflow.d.ts +12 -37
- package/fesm2022/acorex-platform-framework-client-common-common-settings.provider-Euotv9l0.mjs.map +0 -1
- package/fesm2022/acorex-platform-framework-client-layout-entity-attachments-page.component-BzUM-JMC.mjs.map +0 -1
- package/fesm2022/acorex-platform-framework-client-layout-entity-file-list-popup.component-Ci_CTFtq.mjs.map +0 -1
- package/fesm2022/acorex-platform-framework-client-layout-entity-gallery-page.component-DmiB__JR.mjs.map +0 -1
- package/fesm2022/acorex-platform-framework-client-layout-widgets-image-preview.popup-CazpERbX.mjs.map +0 -1
- package/fesm2022/acorex-platform-framework-client-themes-default-entity-master-single-view.component-CIf1VWNW.mjs.map +0 -1
- package/fesm2022/acorex-platform-framework-client-themes-default-error-offline.component-DRz-kVsT.mjs.map +0 -1
|
@@ -23,6 +23,7 @@ import { AXDecoratorModule } from '@acorex/components/decorators';
|
|
|
23
23
|
import * as i3 from '@acorex/components/loading';
|
|
24
24
|
import { AXLoadingModule } from '@acorex/components/loading';
|
|
25
25
|
import { AXBasePageComponent } from '@acorex/components/page';
|
|
26
|
+
import { AXToastService } from '@acorex/components/toast';
|
|
26
27
|
import * as i6 from '@acorex/core/translation';
|
|
27
28
|
import { AXTranslationService, AXTranslationModule } from '@acorex/core/translation';
|
|
28
29
|
import { AXPUnsavedChangesConfirmService } from '@acorex-platform/framework-client/common';
|
|
@@ -215,10 +216,12 @@ class AXPLayoutConversionService {
|
|
|
215
216
|
type: 'form-field',
|
|
216
217
|
name: field.path,
|
|
217
218
|
mode: fieldMode,
|
|
219
|
+
visible: field.visible,
|
|
218
220
|
options: {
|
|
219
221
|
label: field.title,
|
|
220
222
|
badge: field.badge,
|
|
221
223
|
showLabel: true,
|
|
224
|
+
...(field.visible !== undefined ? { visible: field.visible } : {}),
|
|
222
225
|
...hintOpts,
|
|
223
226
|
},
|
|
224
227
|
children: [editorWidget], // The editor widget becomes a child of form-field
|
|
@@ -263,6 +266,7 @@ class AXPLayoutConversionService {
|
|
|
263
266
|
title: formFieldNode.options?.['label'],
|
|
264
267
|
badge: formFieldNode.options?.['badge'],
|
|
265
268
|
description: formFieldNode.options?.['hint'],
|
|
269
|
+
visible: (formFieldNode.visible ?? formFieldNode.options?.['visible']),
|
|
266
270
|
widget: editorWidget,
|
|
267
271
|
mode: formFieldNode.mode,
|
|
268
272
|
};
|
|
@@ -283,7 +287,8 @@ class AXPLayoutConversionService {
|
|
|
283
287
|
// Field mode must be part of the key; otherwise metadata forms that only differ by
|
|
284
288
|
// view/edit (same paths and widget types) incorrectly reuse the first cached tree.
|
|
285
289
|
const fieldModePart = param.mode ?? '_';
|
|
286
|
-
|
|
290
|
+
const visiblePart = param.visible === undefined ? '_' : String(param.visible);
|
|
291
|
+
keyParts.push(`p${groupIndex}.${paramIndex}:${param.path}:${param.widget.type}:${fieldModePart}:${visiblePart}`);
|
|
287
292
|
keyParts.push(`pL${groupIndex}.${paramIndex}:${JSON.stringify(param.title ?? null)}:${JSON.stringify(param.description ?? null)}:${JSON.stringify(param.badge ?? null)}`);
|
|
288
293
|
});
|
|
289
294
|
});
|
|
@@ -345,10 +350,10 @@ class AXPLayoutConversionService {
|
|
|
345
350
|
}
|
|
346
351
|
return Math.abs(hash).toString(36); // Convert to base36 for shorter string
|
|
347
352
|
}
|
|
348
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
349
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
353
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPLayoutConversionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
354
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPLayoutConversionService, providedIn: 'root' }); }
|
|
350
355
|
}
|
|
351
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
356
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPLayoutConversionService, decorators: [{
|
|
352
357
|
type: Injectable,
|
|
353
358
|
args: [{
|
|
354
359
|
providedIn: 'root',
|
|
@@ -481,10 +486,10 @@ class AXPLayoutBuilderService {
|
|
|
481
486
|
create() {
|
|
482
487
|
return new LayoutBuilder(this.popupService, this.hookService);
|
|
483
488
|
}
|
|
484
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
485
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
489
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPLayoutBuilderService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
490
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPLayoutBuilderService, providedIn: 'root' }); }
|
|
486
491
|
}
|
|
487
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
492
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPLayoutBuilderService, decorators: [{
|
|
488
493
|
type: Injectable,
|
|
489
494
|
args: [{
|
|
490
495
|
providedIn: 'root',
|
|
@@ -816,6 +821,9 @@ class LayoutContainerMixin extends BaseContainerMixin {
|
|
|
816
821
|
opts.rowStart = placement.rowStart;
|
|
817
822
|
if (placement.rowEnd != null)
|
|
818
823
|
opts.rowEnd = placement.rowEnd;
|
|
824
|
+
const layoutOrder = value.order ?? placement.order;
|
|
825
|
+
if (layoutOrder != null)
|
|
826
|
+
opts.order = layoutOrder;
|
|
819
827
|
}
|
|
820
828
|
}
|
|
821
829
|
}
|
|
@@ -1132,6 +1140,9 @@ function toGridItemOptions(layoutOptions) {
|
|
|
1132
1140
|
opts['rowStart'] = placement['rowStart'];
|
|
1133
1141
|
if (placement['rowEnd'] != null)
|
|
1134
1142
|
opts['rowEnd'] = placement['rowEnd'];
|
|
1143
|
+
const layoutOrder = layoutOptions.order ?? placement['order'];
|
|
1144
|
+
if (layoutOrder != null)
|
|
1145
|
+
opts['order'] = layoutOrder;
|
|
1135
1146
|
if (Object.keys(opts).length === 0)
|
|
1136
1147
|
opts['colSpan'] = 12;
|
|
1137
1148
|
return opts;
|
|
@@ -2130,27 +2141,33 @@ class AXPLayoutRendererComponent {
|
|
|
2130
2141
|
/**
|
|
2131
2142
|
* Form definition containing groups and fields OR widget tree
|
|
2132
2143
|
*/
|
|
2133
|
-
this.layout = input.required(
|
|
2144
|
+
this.layout = input.required(/* @ts-ignore */
|
|
2145
|
+
...(ngDevMode ? [{ debugName: "layout" }] : /* istanbul ignore next */ []));
|
|
2134
2146
|
/**
|
|
2135
2147
|
* Form context/model data
|
|
2136
2148
|
*/
|
|
2137
|
-
this.context = model({},
|
|
2149
|
+
this.context = model({}, /* @ts-ignore */
|
|
2150
|
+
...(ngDevMode ? [{ debugName: "context" }] : /* istanbul ignore next */ []));
|
|
2138
2151
|
/**
|
|
2139
2152
|
* Form appearance and density styling (normal, compact, spacious)
|
|
2140
2153
|
*/
|
|
2141
|
-
this.look = input('fieldset',
|
|
2154
|
+
this.look = input('fieldset', /* @ts-ignore */
|
|
2155
|
+
...(ngDevMode ? [{ debugName: "look" }] : /* istanbul ignore next */ []));
|
|
2142
2156
|
/**
|
|
2143
2157
|
* Default form mode. Can be overridden by section/group and field.
|
|
2144
2158
|
*/
|
|
2145
|
-
this.mode = input('edit',
|
|
2159
|
+
this.mode = input('edit', /* @ts-ignore */
|
|
2160
|
+
...(ngDevMode ? [{ debugName: "mode" }] : /* istanbul ignore next */ []));
|
|
2146
2161
|
//#endregion
|
|
2147
2162
|
//#region ---- Widget Tree Conversion ----
|
|
2148
|
-
this.widgetTree = signal(null,
|
|
2163
|
+
this.widgetTree = signal(null, /* @ts-ignore */
|
|
2164
|
+
...(ngDevMode ? [{ debugName: "widgetTree" }] : /* istanbul ignore next */ []));
|
|
2149
2165
|
/**
|
|
2150
2166
|
* Prefer explicit {@link AXPWidgetNode.mode} on the root node (e.g. dialog flex `mode('view')`)
|
|
2151
2167
|
* so nested widgets resolve view vs edit correctly; fall back to the layout `mode` input.
|
|
2152
2168
|
*/
|
|
2153
|
-
this.effectiveRenderMode = computed(() => this.widgetTree()?.mode ?? this.mode(),
|
|
2169
|
+
this.effectiveRenderMode = computed(() => this.widgetTree()?.mode ?? this.mode(), /* @ts-ignore */
|
|
2170
|
+
...(ngDevMode ? [{ debugName: "effectiveRenderMode" }] : /* istanbul ignore next */ []));
|
|
2154
2171
|
/**
|
|
2155
2172
|
* Convert layout data to widget tree when inputs change
|
|
2156
2173
|
*/
|
|
@@ -2175,7 +2192,8 @@ class AXPLayoutRendererComponent {
|
|
|
2175
2192
|
if (!isEqual(prev, tree)) {
|
|
2176
2193
|
this.widgetTree.set(tree);
|
|
2177
2194
|
}
|
|
2178
|
-
},
|
|
2195
|
+
}, /* @ts-ignore */
|
|
2196
|
+
...(ngDevMode ? [{ debugName: "conversionEffect" }] : /* istanbul ignore next */ []));
|
|
2179
2197
|
//#endregion
|
|
2180
2198
|
//#region ---- Outputs ----
|
|
2181
2199
|
/**
|
|
@@ -2188,12 +2206,15 @@ class AXPLayoutRendererComponent {
|
|
|
2188
2206
|
this.validityChange = output();
|
|
2189
2207
|
//#endregion
|
|
2190
2208
|
//#region ---- Properties ----
|
|
2191
|
-
this.form = viewChild(AXFormComponent,
|
|
2192
|
-
|
|
2209
|
+
this.form = viewChild(AXFormComponent, /* @ts-ignore */
|
|
2210
|
+
...(ngDevMode ? [{ debugName: "form" }] : /* istanbul ignore next */ []));
|
|
2211
|
+
this.container = viewChild(AXPWidgetContainerComponent, /* @ts-ignore */
|
|
2212
|
+
...(ngDevMode ? [{ debugName: "container" }] : /* istanbul ignore next */ []));
|
|
2193
2213
|
/**
|
|
2194
2214
|
* Internal context signal for reactivity
|
|
2195
2215
|
*/
|
|
2196
|
-
this.internalContext = signal({},
|
|
2216
|
+
this.internalContext = signal({}, /* @ts-ignore */
|
|
2217
|
+
...(ngDevMode ? [{ debugName: "internalContext" }] : /* istanbul ignore next */ []));
|
|
2197
2218
|
/**
|
|
2198
2219
|
* Initial context for reset functionality
|
|
2199
2220
|
*/
|
|
@@ -2206,7 +2227,8 @@ class AXPLayoutRendererComponent {
|
|
|
2206
2227
|
this.#contextSyncEffect = effect(() => {
|
|
2207
2228
|
const ctx = this.context() ?? {};
|
|
2208
2229
|
this.contextUpdateSubject.next(ctx);
|
|
2209
|
-
},
|
|
2230
|
+
}, /* @ts-ignore */
|
|
2231
|
+
...(ngDevMode ? [{ debugName: "#contextSyncEffect" }] : /* istanbul ignore next */ []));
|
|
2210
2232
|
/**
|
|
2211
2233
|
* Effect to handle widget tree status changes
|
|
2212
2234
|
*/
|
|
@@ -2215,7 +2237,8 @@ class AXPLayoutRendererComponent {
|
|
|
2215
2237
|
if (widgetTree) {
|
|
2216
2238
|
this.container()?.builderService.setStatus(AXPPageStatus.Rendered);
|
|
2217
2239
|
}
|
|
2218
|
-
},
|
|
2240
|
+
}, /* @ts-ignore */
|
|
2241
|
+
...(ngDevMode ? [{ debugName: "#widgetStatusEffect" }] : /* istanbul ignore next */ []));
|
|
2219
2242
|
}
|
|
2220
2243
|
//#endregion
|
|
2221
2244
|
//#region ---- Lifecycle Methods ----
|
|
@@ -2355,8 +2378,8 @@ class AXPLayoutRendererComponent {
|
|
|
2355
2378
|
isWidgetNode(data) {
|
|
2356
2379
|
return data && typeof data === 'object' && 'type' in data && typeof data.type === 'string';
|
|
2357
2380
|
}
|
|
2358
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2359
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
2381
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPLayoutRendererComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2382
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", 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: `
|
|
2360
2383
|
<ax-form>
|
|
2361
2384
|
<axp-widgets-container [context]="internalContext()" (onContextChanged)="handleContextChanged($event)">
|
|
2362
2385
|
@if (widgetTree()) {
|
|
@@ -2374,7 +2397,7 @@ class AXPLayoutRendererComponent {
|
|
|
2374
2397
|
</ax-form>
|
|
2375
2398
|
`, 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"] }, { kind: "component", type: i2.AXValidationSummaryComponent, selector: "ax-validation-summary", inputs: ["title", "displayMode", "timeOut", "autoHide"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2376
2399
|
}
|
|
2377
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2400
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPLayoutRendererComponent, decorators: [{
|
|
2378
2401
|
type: Component,
|
|
2379
2402
|
args: [{ selector: 'axp-layout-renderer', standalone: true, imports: [AXPWidgetCoreModule, AXFormModule], changeDetection: ChangeDetectionStrategy.OnPush, template: `
|
|
2380
2403
|
<ax-form>
|
|
@@ -2462,18 +2485,18 @@ class AXPSettingsDefinitionDialogOpenerService {
|
|
|
2462
2485
|
return false;
|
|
2463
2486
|
}
|
|
2464
2487
|
}
|
|
2465
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2466
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
2488
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPSettingsDefinitionDialogOpenerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
2489
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPSettingsDefinitionDialogOpenerService, providedIn: 'root' }); }
|
|
2467
2490
|
}
|
|
2468
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2491
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPSettingsDefinitionDialogOpenerService, decorators: [{
|
|
2469
2492
|
type: Injectable,
|
|
2470
2493
|
args: [{ providedIn: 'root' }]
|
|
2471
2494
|
}] });
|
|
2472
2495
|
|
|
2473
2496
|
class LayoutBuilderModule {
|
|
2474
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
2475
|
-
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "
|
|
2476
|
-
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "
|
|
2497
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: LayoutBuilderModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
2498
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.0.8", ngImport: i0, type: LayoutBuilderModule, imports: [CommonModule, AXPLayoutRendererComponent], exports: [AXPLayoutRendererComponent] }); }
|
|
2499
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: LayoutBuilderModule, providers: [
|
|
2477
2500
|
AXPLayoutBuilderService,
|
|
2478
2501
|
{
|
|
2479
2502
|
provide: AXP_SETTINGS_DEFINITION_DIALOG_OPENER,
|
|
@@ -2487,7 +2510,7 @@ class LayoutBuilderModule {
|
|
|
2487
2510
|
]),
|
|
2488
2511
|
], imports: [CommonModule, AXPLayoutRendererComponent] }); }
|
|
2489
2512
|
}
|
|
2490
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
2513
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: LayoutBuilderModule, decorators: [{
|
|
2491
2514
|
type: NgModule,
|
|
2492
2515
|
args: [{
|
|
2493
2516
|
imports: [CommonModule, AXPLayoutRendererComponent],
|
|
@@ -2622,6 +2645,7 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
|
|
|
2622
2645
|
this.hookService = inject(AXPHookService, { optional: true });
|
|
2623
2646
|
this.unsavedChangesConfirm = inject(AXPUnsavedChangesConfirmService);
|
|
2624
2647
|
this.overlayService = inject(AXOverlayService);
|
|
2648
|
+
this.toastService = inject(AXToastService);
|
|
2625
2649
|
this.translationService = inject(AXTranslationService);
|
|
2626
2650
|
this.document = inject(DOCUMENT);
|
|
2627
2651
|
this.host = inject((ElementRef));
|
|
@@ -2633,13 +2657,17 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
|
|
|
2633
2657
|
/** Blocks re-entrant {@link onClosing} while the first close gate is still resolving. */
|
|
2634
2658
|
this.closeGateInProgress = false;
|
|
2635
2659
|
this.destroyRef = inject(DestroyRef);
|
|
2636
|
-
this.context = signal({},
|
|
2660
|
+
this.context = signal({}, /* @ts-ignore */
|
|
2661
|
+
...(ngDevMode ? [{ debugName: "context" }] : /* istanbul ignore next */ []));
|
|
2637
2662
|
// This will be set by the popup service automatically - same as dynamic-dialog
|
|
2638
2663
|
this.callBack = () => { };
|
|
2639
|
-
this.isDialogLoading = signal(false,
|
|
2664
|
+
this.isDialogLoading = signal(false, /* @ts-ignore */
|
|
2665
|
+
...(ngDevMode ? [{ debugName: "isDialogLoading" }] : /* istanbul ignore next */ []));
|
|
2640
2666
|
// Aggregated actions for footer rendering
|
|
2641
|
-
this.footerPrefix = signal([],
|
|
2642
|
-
|
|
2667
|
+
this.footerPrefix = signal([], /* @ts-ignore */
|
|
2668
|
+
...(ngDevMode ? [{ debugName: "footerPrefix" }] : /* istanbul ignore next */ []));
|
|
2669
|
+
this.footerSuffix = signal([], /* @ts-ignore */
|
|
2670
|
+
...(ngDevMode ? [{ debugName: "footerSuffix" }] : /* istanbul ignore next */ []));
|
|
2643
2671
|
/**
|
|
2644
2672
|
* Correlate layout context snapshots for distributed hooks (`layout-builder.dialog.context-changed`).
|
|
2645
2673
|
*/
|
|
@@ -2655,11 +2683,13 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
|
|
|
2655
2683
|
this.footerSuffix();
|
|
2656
2684
|
this.isDialogLoading();
|
|
2657
2685
|
untracked(() => this.refreshDialogKeyboardShortcuts());
|
|
2658
|
-
},
|
|
2686
|
+
}, /* @ts-ignore */
|
|
2687
|
+
...(ngDevMode ? [{ debugName: "#dialogShortcutsEffect" }] : /* istanbul ignore next */ []));
|
|
2659
2688
|
//#endregion
|
|
2660
2689
|
//#region ---- View Accessors ----
|
|
2661
2690
|
// Access the internal layout renderer to reach the widgets container injector
|
|
2662
|
-
this.layoutRenderer = viewChild(AXPLayoutRendererComponent,
|
|
2691
|
+
this.layoutRenderer = viewChild(AXPLayoutRendererComponent, /* @ts-ignore */
|
|
2692
|
+
...(ngDevMode ? [{ debugName: "layoutRenderer" }] : /* istanbul ignore next */ []));
|
|
2663
2693
|
this.#widgetActionsEffect = effect(() => {
|
|
2664
2694
|
this.aggregateAndEvaluateActions();
|
|
2665
2695
|
if (!this.widgetCoreService) {
|
|
@@ -2675,7 +2705,10 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
|
|
|
2675
2705
|
this.debounceTimer = setTimeout(() => {
|
|
2676
2706
|
this.aggregateAndEvaluateActions();
|
|
2677
2707
|
}, DIALOG_WIDGET_COUNT_STABLE_DELAY_MS);
|
|
2678
|
-
},
|
|
2708
|
+
}, /* @ts-ignore */
|
|
2709
|
+
...(ngDevMode ? [{ debugName: "#widgetActionsEffect" }] : /* istanbul ignore next */ []));
|
|
2710
|
+
// --- Actions aggregation & evaluation ---
|
|
2711
|
+
this.footerActionsEvalSeq = 0;
|
|
2679
2712
|
}
|
|
2680
2713
|
/**
|
|
2681
2714
|
* Registers footer shortcuts on the platform registry at modal priority so they win over page
|
|
@@ -2845,9 +2878,7 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
|
|
|
2845
2878
|
},
|
|
2846
2879
|
metadata: meta,
|
|
2847
2880
|
patchContext: (partial) => {
|
|
2848
|
-
|
|
2849
|
-
this.context.set(merged);
|
|
2850
|
-
this.layoutRenderer()?.updateContext(merged);
|
|
2881
|
+
this.applyDialogContextPatch(partial);
|
|
2851
2882
|
},
|
|
2852
2883
|
setLoading: (loading) => this.isDialogLoading.set(loading),
|
|
2853
2884
|
};
|
|
@@ -2926,8 +2957,9 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
|
|
|
2926
2957
|
this.resolveDialog(result);
|
|
2927
2958
|
await this.closeWithOptionalSkipValidate(result);
|
|
2928
2959
|
}
|
|
2929
|
-
catch {
|
|
2930
|
-
//
|
|
2960
|
+
catch (error) {
|
|
2961
|
+
// Keep dialog open for retry, but surface validation / handler errors.
|
|
2962
|
+
await this.showOnActionError(error);
|
|
2931
2963
|
}
|
|
2932
2964
|
finally {
|
|
2933
2965
|
this.isDialogLoading.set(false);
|
|
@@ -2972,6 +3004,21 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
|
|
|
2972
3004
|
message: confirmOptions.message,
|
|
2973
3005
|
});
|
|
2974
3006
|
}
|
|
3007
|
+
/** Surfaces `onAction` throw messages (validation) without closing the dialog. */
|
|
3008
|
+
async showOnActionError(error) {
|
|
3009
|
+
const raw = error instanceof Error && error.message.trim()
|
|
3010
|
+
? error.message.trim()
|
|
3011
|
+
: '@general:messages.generic.error.title';
|
|
3012
|
+
const content = raw.startsWith('@')
|
|
3013
|
+
? await this.translationService.translateAsync(raw)
|
|
3014
|
+
: raw;
|
|
3015
|
+
const title = await this.translationService.translateAsync('@general:messages.generic.error.title');
|
|
3016
|
+
this.toastService.show({
|
|
3017
|
+
color: 'danger',
|
|
3018
|
+
title,
|
|
3019
|
+
content,
|
|
3020
|
+
});
|
|
3021
|
+
}
|
|
2975
3022
|
/** Whether the layout form should be validated before running this footer command. */
|
|
2976
3023
|
shouldValidateBeforeAction(cmd) {
|
|
2977
3024
|
if (!cmd || cmd === 'cancel' || cmd === 'entity-form-done' || cmd === 'entity-form-next-step') {
|
|
@@ -3012,17 +3059,49 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
|
|
|
3012
3059
|
close: (res) => {
|
|
3013
3060
|
void this.closeWithOptionalSkipValidate(res);
|
|
3014
3061
|
},
|
|
3015
|
-
context: () =>
|
|
3062
|
+
context: () => {
|
|
3063
|
+
const store = this.getWidgetContainer()?.contextService;
|
|
3064
|
+
return (store?.data() ?? this.context());
|
|
3065
|
+
},
|
|
3016
3066
|
action: () => actionCmd,
|
|
3017
3067
|
setLoading: (loading) => this.isDialogLoading.set(loading),
|
|
3018
3068
|
patchContext: (partial) => {
|
|
3019
|
-
|
|
3020
|
-
this.context.set(merged);
|
|
3021
|
-
this.layoutRenderer()?.updateContext(merged);
|
|
3069
|
+
this.applyDialogContextPatch(partial);
|
|
3022
3070
|
},
|
|
3023
3071
|
invokeWidget: (widgetName, method, opts) => this.invokeWidget(widgetName, method, opts ?? {}),
|
|
3024
3072
|
};
|
|
3025
3073
|
}
|
|
3074
|
+
/**
|
|
3075
|
+
* Merges into the live widget-container store (not a possibly-stale dialog signal),
|
|
3076
|
+
* and forces persisted root `id` onto the store for create-wizard related steps.
|
|
3077
|
+
*/
|
|
3078
|
+
applyDialogContextPatch(partial) {
|
|
3079
|
+
const store = this.getWidgetContainer()?.contextService;
|
|
3080
|
+
const live = (store?.data() ?? this.context() ?? {});
|
|
3081
|
+
const merged = merge({}, live, partial);
|
|
3082
|
+
if (store) {
|
|
3083
|
+
const nextId = merged['id'] ?? merged['_id'];
|
|
3084
|
+
const currentId = store.data()['id'] ?? store.data()['_id'];
|
|
3085
|
+
const hasNext = (typeof nextId === 'string' && nextId.length > 0) ||
|
|
3086
|
+
(typeof nextId === 'number' && !Number.isNaN(nextId));
|
|
3087
|
+
const hasCurrent = (typeof currentId === 'string' && currentId.length > 0) ||
|
|
3088
|
+
(typeof currentId === 'number' && !Number.isNaN(currentId));
|
|
3089
|
+
if (hasNext && !hasCurrent) {
|
|
3090
|
+
const identity = { id: nextId };
|
|
3091
|
+
if (merged['_id'] !== undefined) {
|
|
3092
|
+
identity['_id'] = merged['_id'];
|
|
3093
|
+
}
|
|
3094
|
+
store.patch(identity, { updateSaved: true });
|
|
3095
|
+
}
|
|
3096
|
+
else {
|
|
3097
|
+
store.patch(partial, { updateSaved: false });
|
|
3098
|
+
}
|
|
3099
|
+
}
|
|
3100
|
+
this.context.set(merged);
|
|
3101
|
+
// Prefer identity-only sync via [context] binding + syncExternalContext identity path.
|
|
3102
|
+
// Passing the full merged object after updateSaved can clearWidgets and reset the wizard.
|
|
3103
|
+
this.layoutRenderer()?.updateContext(merged);
|
|
3104
|
+
}
|
|
3026
3105
|
async closeWithOptionalSkipValidate(result) {
|
|
3027
3106
|
if (result && typeof result === 'object' && result.skipValidate) {
|
|
3028
3107
|
this.result.emit(result);
|
|
@@ -3034,6 +3113,16 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
|
|
|
3034
3113
|
await this.close(result, { skipDirtyConfirm: true });
|
|
3035
3114
|
}
|
|
3036
3115
|
/** Resolves footer/widget action command to a string (e.g. `cancel`, `submit`, `widget:...`). */
|
|
3116
|
+
resolveDialogActionTestId(action) {
|
|
3117
|
+
const command = this.resolveActionCommandName(action.command);
|
|
3118
|
+
if (command === 'submit') {
|
|
3119
|
+
return 'entity-dialog-submit';
|
|
3120
|
+
}
|
|
3121
|
+
if (command === 'cancel') {
|
|
3122
|
+
return 'entity-dialog-cancel';
|
|
3123
|
+
}
|
|
3124
|
+
return command ? `entity-dialog-action-${command}` : 'entity-dialog-action';
|
|
3125
|
+
}
|
|
3037
3126
|
resolveActionCommandName(command) {
|
|
3038
3127
|
if (typeof command === 'string') {
|
|
3039
3128
|
return command;
|
|
@@ -3094,12 +3183,16 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
|
|
|
3094
3183
|
}
|
|
3095
3184
|
super.close(result);
|
|
3096
3185
|
}
|
|
3097
|
-
// --- Actions aggregation & evaluation ---
|
|
3098
3186
|
async aggregateAndEvaluateActions() {
|
|
3187
|
+
const seq = ++this.footerActionsEvalSeq;
|
|
3099
3188
|
const widgetActions = await this.collectWidgetActions();
|
|
3100
3189
|
const dialogActions = this.collectDialogActionsFromConfig();
|
|
3101
3190
|
const all = [...widgetActions, ...dialogActions];
|
|
3102
3191
|
const evaluated = await this.evaluatePredicates(all);
|
|
3192
|
+
// Drop stale runs (e.g. nested Assign create triggers overlapping context refreshes).
|
|
3193
|
+
if (seq !== this.footerActionsEvalSeq) {
|
|
3194
|
+
return;
|
|
3195
|
+
}
|
|
3103
3196
|
const visible = evaluated.filter((a) => a.hidden !== true);
|
|
3104
3197
|
const prefix = visible.filter((a) => (a.zone ?? 'footer') === 'footer' && (a.placement ?? 'suffix') === 'prefix');
|
|
3105
3198
|
const suffix = visible.filter((a) => (a.zone ?? 'footer') === 'footer' && (a.placement ?? 'suffix') === 'suffix');
|
|
@@ -3157,23 +3250,32 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
|
|
|
3157
3250
|
dialog: { context: this.context() },
|
|
3158
3251
|
context: this.context(),
|
|
3159
3252
|
};
|
|
3160
|
-
const
|
|
3161
|
-
const
|
|
3253
|
+
const hiddenNeedsApi = typeof a.hidden === 'string' && /\bapi\b/.test(a.hidden);
|
|
3254
|
+
const disabledNeedsApi = typeof a.disabled === 'string' && /\bapi\b/.test(a.disabled);
|
|
3255
|
+
// Fail closed: missing wizard api must not reveal step-scoped footer actions (Done / Continue).
|
|
3256
|
+
const disabled = disabledNeedsApi && !api ? true : await this.evalBool(a.disabled, scope, false);
|
|
3257
|
+
const hidden = hiddenNeedsApi && !api ? true : await this.evalBool(a.hidden, scope, true);
|
|
3162
3258
|
const resolvedTitle = (await this.evalActionTitle(a.title, scope)) ?? a.title;
|
|
3163
3259
|
out.push({ ...a, disabled, hidden, title: resolvedTitle });
|
|
3164
3260
|
}
|
|
3165
3261
|
return out;
|
|
3166
3262
|
}
|
|
3167
|
-
|
|
3263
|
+
/**
|
|
3264
|
+
* @param failClosed When evaluation throws / returns an error sentinel, use this value.
|
|
3265
|
+
* Footer `hidden` should fail closed (`true`) so step actions do not leak.
|
|
3266
|
+
*/
|
|
3267
|
+
async evalBool(value, scope, failClosed) {
|
|
3168
3268
|
if (typeof value === 'boolean')
|
|
3169
3269
|
return value;
|
|
3170
3270
|
if (typeof value === 'string') {
|
|
3171
3271
|
try {
|
|
3172
3272
|
const result = await this.expressionEvaluator.evaluate(value, scope);
|
|
3273
|
+
// Expression evaluator swallows errors and returns false — treat that as failClosed
|
|
3274
|
+
// only when the expression references api and api is missing (handled by caller).
|
|
3173
3275
|
return !!result;
|
|
3174
3276
|
}
|
|
3175
3277
|
catch {
|
|
3176
|
-
return
|
|
3278
|
+
return failClosed;
|
|
3177
3279
|
}
|
|
3178
3280
|
}
|
|
3179
3281
|
return value;
|
|
@@ -3207,10 +3309,10 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
|
|
|
3207
3309
|
return undefined;
|
|
3208
3310
|
}
|
|
3209
3311
|
}
|
|
3210
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
3211
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
3312
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPDialogRendererComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
3313
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", 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: `
|
|
3212
3314
|
<axp-component-slot name="dialog-header" [context]="context()"></axp-component-slot>
|
|
3213
|
-
<div class="p-4">
|
|
3315
|
+
<div class="p-4" data-testid="entity-dialog">
|
|
3214
3316
|
<!-- @if (config.message) {
|
|
3215
3317
|
<p class="mb-4 leading-relaxed">{{ config.message | translate | async }}</p>
|
|
3216
3318
|
} -->
|
|
@@ -3231,6 +3333,7 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
|
|
|
3231
3333
|
<axp-component-slot name="dialog-footer-prefix" [context]="context()"></axp-component-slot>
|
|
3232
3334
|
@for (action of footerPrefixActions(); track $index) {
|
|
3233
3335
|
<ax-button
|
|
3336
|
+
[attr.data-testid]="resolveDialogActionTestId(action)"
|
|
3234
3337
|
[disabled]="action.disabled || isFormLoading()"
|
|
3235
3338
|
[text]="(action.title | translate | async)!"
|
|
3236
3339
|
[look]="'outline'"
|
|
@@ -3251,6 +3354,7 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
|
|
|
3251
3354
|
<ax-suffix>
|
|
3252
3355
|
@for (action of footerSuffixActions(); track $index) {
|
|
3253
3356
|
<ax-button
|
|
3357
|
+
[attr.data-testid]="resolveDialogActionTestId(action)"
|
|
3254
3358
|
[disabled]="action.disabled || isSubmitting()"
|
|
3255
3359
|
[text]="(action.title | translate | async)!"
|
|
3256
3360
|
[look]="'solid'"
|
|
@@ -3273,7 +3377,7 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
|
|
|
3273
3377
|
}
|
|
3274
3378
|
`, 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 }); }
|
|
3275
3379
|
}
|
|
3276
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
3380
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPDialogRendererComponent, decorators: [{
|
|
3277
3381
|
type: Component,
|
|
3278
3382
|
args: [{
|
|
3279
3383
|
selector: 'axp-dialog-renderer',
|
|
@@ -3291,7 +3395,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
3291
3395
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
3292
3396
|
template: `
|
|
3293
3397
|
<axp-component-slot name="dialog-header" [context]="context()"></axp-component-slot>
|
|
3294
|
-
<div class="p-4">
|
|
3398
|
+
<div class="p-4" data-testid="entity-dialog">
|
|
3295
3399
|
<!-- @if (config.message) {
|
|
3296
3400
|
<p class="mb-4 leading-relaxed">{{ config.message | translate | async }}</p>
|
|
3297
3401
|
} -->
|
|
@@ -3312,6 +3416,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
3312
3416
|
<axp-component-slot name="dialog-footer-prefix" [context]="context()"></axp-component-slot>
|
|
3313
3417
|
@for (action of footerPrefixActions(); track $index) {
|
|
3314
3418
|
<ax-button
|
|
3419
|
+
[attr.data-testid]="resolveDialogActionTestId(action)"
|
|
3315
3420
|
[disabled]="action.disabled || isFormLoading()"
|
|
3316
3421
|
[text]="(action.title | translate | async)!"
|
|
3317
3422
|
[look]="'outline'"
|
|
@@ -3332,6 +3437,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
3332
3437
|
<ax-suffix>
|
|
3333
3438
|
@for (action of footerSuffixActions(); track $index) {
|
|
3334
3439
|
<ax-button
|
|
3440
|
+
[attr.data-testid]="resolveDialogActionTestId(action)"
|
|
3335
3441
|
[disabled]="action.disabled || isSubmitting()"
|
|
3336
3442
|
[text]="(action.title | translate | async)!"
|
|
3337
3443
|
[look]="'solid'"
|
|
@@ -3424,12 +3530,13 @@ class AXPPreviewWidgetFieldCommand {
|
|
|
3424
3530
|
const merged = this.mergeInvocation(input);
|
|
3425
3531
|
const currentWidget = this.normalizeWidget(merged['widget'] ?? merged['interface']);
|
|
3426
3532
|
if (!currentWidget?.type) {
|
|
3427
|
-
return
|
|
3428
|
-
success:
|
|
3429
|
-
|
|
3430
|
-
|
|
3431
|
-
|
|
3432
|
-
|
|
3533
|
+
return false
|
|
3534
|
+
? { success: true, kind: 'object', data: undefined, message: {
|
|
3535
|
+
text: (await this.translationService.translateAsync('@general:messages.invalid-data')) || 'Invalid data',
|
|
3536
|
+
} }
|
|
3537
|
+
: { success: false, message: {
|
|
3538
|
+
text: (await this.translationService.translateAsync('@general:messages.invalid-data')) || 'Invalid data',
|
|
3539
|
+
} };
|
|
3433
3540
|
}
|
|
3434
3541
|
const fieldName = String(merged['fieldName'] ?? merged['name'] ?? 'Field');
|
|
3435
3542
|
const rawTitle = (merged['fieldTitle'] ?? merged['title']);
|
|
@@ -3440,7 +3547,7 @@ class AXPPreviewWidgetFieldCommand {
|
|
|
3440
3547
|
name: fieldName,
|
|
3441
3548
|
...extendedNodePropsForPreview(currentWidget),
|
|
3442
3549
|
};
|
|
3443
|
-
|
|
3550
|
+
await this.formBuilderService
|
|
3444
3551
|
.create()
|
|
3445
3552
|
.dialog((dialog) => {
|
|
3446
3553
|
dialog
|
|
@@ -3456,24 +3563,24 @@ class AXPPreviewWidgetFieldCommand {
|
|
|
3456
3563
|
.setActions((actions) => actions.cancel('@general:actions.close.title'));
|
|
3457
3564
|
})
|
|
3458
3565
|
.show();
|
|
3459
|
-
|
|
3566
|
+
// Preview is read-only; never refresh the hosting entity list on close.
|
|
3460
3567
|
return {
|
|
3461
|
-
success:
|
|
3568
|
+
success: true,
|
|
3569
|
+
kind: 'object',
|
|
3570
|
+
data: undefined,
|
|
3571
|
+
metadata: { refresh: false },
|
|
3462
3572
|
message: { text: '' },
|
|
3463
3573
|
};
|
|
3464
3574
|
}
|
|
3465
3575
|
catch (error) {
|
|
3466
3576
|
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
3467
|
-
return {
|
|
3468
|
-
success: false,
|
|
3469
|
-
message: { text: message },
|
|
3470
|
-
};
|
|
3577
|
+
return { success: false, message: { text: message } };
|
|
3471
3578
|
}
|
|
3472
3579
|
}
|
|
3473
3580
|
mergeInvocation(input) {
|
|
3474
|
-
const contextOptions = input.
|
|
3475
|
-
const ctxData = input.
|
|
3476
|
-
const
|
|
3581
|
+
const contextOptions = input.options;
|
|
3582
|
+
const ctxData = input.data;
|
|
3583
|
+
const rest = input;
|
|
3477
3584
|
return {
|
|
3478
3585
|
...(ctxData ?? {}),
|
|
3479
3586
|
...(contextOptions ?? {}),
|
|
@@ -3507,16 +3614,6 @@ class AXPPreviewWidgetFieldCommand {
|
|
|
3507
3614
|
}
|
|
3508
3615
|
return this.translationService.resolve(source);
|
|
3509
3616
|
}
|
|
3510
|
-
isCancelDialogOutcome(outcome) {
|
|
3511
|
-
if (outcome == null) {
|
|
3512
|
-
return false;
|
|
3513
|
-
}
|
|
3514
|
-
const ref = outcome;
|
|
3515
|
-
if (typeof ref.action !== 'function') {
|
|
3516
|
-
return false;
|
|
3517
|
-
}
|
|
3518
|
-
return ref.action() === 'cancel';
|
|
3519
|
-
}
|
|
3520
3617
|
async resolveWidgetDisplayTitle(widgetType) {
|
|
3521
3618
|
const crud = this.crudService;
|
|
3522
3619
|
if (crud) {
|
|
@@ -3531,10 +3628,10 @@ class AXPPreviewWidgetFieldCommand {
|
|
|
3531
3628
|
const resolved = this.translationService.resolve(config.title);
|
|
3532
3629
|
return resolved || undefined;
|
|
3533
3630
|
}
|
|
3534
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
3535
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
3631
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPPreviewWidgetFieldCommand, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
3632
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPPreviewWidgetFieldCommand }); }
|
|
3536
3633
|
}
|
|
3537
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
3634
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPPreviewWidgetFieldCommand, decorators: [{
|
|
3538
3635
|
type: Injectable
|
|
3539
3636
|
}] });
|
|
3540
3637
|
|