@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.
Files changed (108) hide show
  1. package/fesm2022/acorex-platform-framework-client-auth.mjs +872 -314
  2. package/fesm2022/acorex-platform-framework-client-auth.mjs.map +1 -1
  3. package/fesm2022/{acorex-platform-framework-client-common-common-settings.provider-Euotv9l0.mjs → acorex-platform-framework-client-common-common-settings.provider-CLm2BVk-.mjs} +88 -5
  4. package/fesm2022/acorex-platform-framework-client-common-common-settings.provider-CLm2BVk-.mjs.map +1 -0
  5. package/fesm2022/acorex-platform-framework-client-common.mjs +2685 -898
  6. package/fesm2022/acorex-platform-framework-client-common.mjs.map +1 -1
  7. package/fesm2022/acorex-platform-framework-client-core.mjs +691 -823
  8. package/fesm2022/acorex-platform-framework-client-core.mjs.map +1 -1
  9. package/fesm2022/acorex-platform-framework-client-domain.mjs +16 -16
  10. package/fesm2022/acorex-platform-framework-client-layout-builder.mjs +181 -84
  11. package/fesm2022/acorex-platform-framework-client-layout-builder.mjs.map +1 -1
  12. 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
  13. 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
  14. 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
  15. 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
  16. package/fesm2022/acorex-platform-framework-client-layout-components.mjs +3300 -1236
  17. package/fesm2022/acorex-platform-framework-client-layout-components.mjs.map +1 -1
  18. package/fesm2022/acorex-platform-framework-client-layout-designer.mjs +277 -185
  19. package/fesm2022/acorex-platform-framework-client-layout-designer.mjs.map +1 -1
  20. package/fesm2022/acorex-platform-framework-client-layout-entity-acorex-platform-framework-client-layout-entity-BXOMs6oD.mjs +29184 -0
  21. package/fesm2022/acorex-platform-framework-client-layout-entity-acorex-platform-framework-client-layout-entity-BXOMs6oD.mjs.map +1 -0
  22. 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
  23. package/fesm2022/acorex-platform-framework-client-layout-entity-attachments-page.component-DCK-qb-F.mjs.map +1 -0
  24. package/fesm2022/acorex-platform-framework-client-layout-entity-bulk-entity.command-Cs3agnpF.mjs +162 -0
  25. package/fesm2022/acorex-platform-framework-client-layout-entity-bulk-entity.command-Cs3agnpF.mjs.map +1 -0
  26. 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
  27. package/fesm2022/acorex-platform-framework-client-layout-entity-file-list-popup.component-p0hxDb0W.mjs.map +1 -0
  28. 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
  29. package/fesm2022/acorex-platform-framework-client-layout-entity-gallery-page.component-DYV9YPyw.mjs.map +1 -0
  30. package/fesm2022/acorex-platform-framework-client-layout-entity.mjs +2 -26780
  31. package/fesm2022/acorex-platform-framework-client-layout-entity.mjs.map +1 -1
  32. package/fesm2022/acorex-platform-framework-client-layout-views.mjs +421 -151
  33. package/fesm2022/acorex-platform-framework-client-layout-views.mjs.map +1 -1
  34. package/fesm2022/acorex-platform-framework-client-layout-widget-core.mjs +673 -287
  35. package/fesm2022/acorex-platform-framework-client-layout-widget-core.mjs.map +1 -1
  36. 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
  37. 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
  38. 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
  39. package/fesm2022/acorex-platform-framework-client-layout-widgets-image-preview.popup-BOrrMm3U.mjs.map +1 -0
  40. 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
  41. 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
  42. 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
  43. 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
  44. 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
  45. 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
  46. 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
  47. 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
  48. 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
  49. 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
  50. package/fesm2022/acorex-platform-framework-client-layout-widgets.mjs +4907 -2554
  51. package/fesm2022/acorex-platform-framework-client-layout-widgets.mjs.map +1 -1
  52. package/fesm2022/acorex-platform-framework-client-native.mjs +7 -7
  53. package/fesm2022/acorex-platform-framework-client-realtime-set-presence-availability.command-CetlUjnM.mjs +29 -0
  54. package/fesm2022/acorex-platform-framework-client-realtime-set-presence-availability.command-CetlUjnM.mjs.map +1 -0
  55. package/fesm2022/acorex-platform-framework-client-realtime.mjs +463 -26
  56. package/fesm2022/acorex-platform-framework-client-realtime.mjs.map +1 -1
  57. package/fesm2022/acorex-platform-framework-client-runtime.mjs +300 -137
  58. package/fesm2022/acorex-platform-framework-client-runtime.mjs.map +1 -1
  59. 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
  60. 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
  61. 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
  62. 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
  63. 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
  64. package/fesm2022/acorex-platform-framework-client-themes-default-entity-master-single-view.component-C2Abf7Lb.mjs.map +1 -0
  65. 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
  66. 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
  67. 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
  68. 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
  69. 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
  70. package/fesm2022/acorex-platform-framework-client-themes-default-error-offline.component-CngiQycG.mjs.map +1 -0
  71. package/fesm2022/acorex-platform-framework-client-themes-default.mjs +448 -277
  72. package/fesm2022/acorex-platform-framework-client-themes-default.mjs.map +1 -1
  73. 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
  74. 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
  75. 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
  76. 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
  77. 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
  78. 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
  79. 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
  80. 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
  81. package/fesm2022/acorex-platform-framework-client-themes-shared.mjs +538 -133
  82. package/fesm2022/acorex-platform-framework-client-themes-shared.mjs.map +1 -1
  83. package/fesm2022/acorex-platform-framework-client-workflow.mjs +26 -66
  84. package/fesm2022/acorex-platform-framework-client-workflow.mjs.map +1 -1
  85. package/package.json +10 -10
  86. package/realtime/README.md +16 -0
  87. package/runtime/README.md +14 -0
  88. package/types/acorex-platform-framework-client-auth.d.ts +291 -52
  89. package/types/acorex-platform-framework-client-common.d.ts +615 -202
  90. package/types/acorex-platform-framework-client-core.d.ts +215 -225
  91. package/types/acorex-platform-framework-client-layout-builder.d.ts +24 -8
  92. package/types/acorex-platform-framework-client-layout-components.d.ts +407 -94
  93. package/types/acorex-platform-framework-client-layout-entity.d.ts +734 -411
  94. package/types/acorex-platform-framework-client-layout-views.d.ts +40 -15
  95. package/types/acorex-platform-framework-client-layout-widget-core.d.ts +66 -17
  96. package/types/acorex-platform-framework-client-layout-widgets.d.ts +295 -68
  97. package/types/acorex-platform-framework-client-realtime.d.ts +183 -6
  98. package/types/acorex-platform-framework-client-runtime.d.ts +134 -28
  99. package/types/acorex-platform-framework-client-themes-default.d.ts +9 -1
  100. package/types/acorex-platform-framework-client-themes-shared.d.ts +8 -2
  101. package/types/acorex-platform-framework-client-workflow.d.ts +12 -37
  102. package/fesm2022/acorex-platform-framework-client-common-common-settings.provider-Euotv9l0.mjs.map +0 -1
  103. package/fesm2022/acorex-platform-framework-client-layout-entity-attachments-page.component-BzUM-JMC.mjs.map +0 -1
  104. package/fesm2022/acorex-platform-framework-client-layout-entity-file-list-popup.component-Ci_CTFtq.mjs.map +0 -1
  105. package/fesm2022/acorex-platform-framework-client-layout-entity-gallery-page.component-DmiB__JR.mjs.map +0 -1
  106. package/fesm2022/acorex-platform-framework-client-layout-widgets-image-preview.popup-CazpERbX.mjs.map +0 -1
  107. package/fesm2022/acorex-platform-framework-client-themes-default-entity-master-single-view.component-CIf1VWNW.mjs.map +0 -1
  108. 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
- keyParts.push(`p${groupIndex}.${paramIndex}:${param.path}:${param.widget.type}:${fieldModePart}`);
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: "21.2.9", ngImport: i0, type: AXPLayoutConversionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
349
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPLayoutConversionService, providedIn: 'root' }); }
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: "21.2.9", ngImport: i0, type: AXPLayoutConversionService, decorators: [{
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: "21.2.9", ngImport: i0, type: AXPLayoutBuilderService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
485
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPLayoutBuilderService, providedIn: 'root' }); }
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: "21.2.9", ngImport: i0, type: AXPLayoutBuilderService, decorators: [{
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(...(ngDevMode ? [{ debugName: "layout" }] : /* istanbul ignore next */ []));
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({}, ...(ngDevMode ? [{ debugName: "context" }] : /* istanbul ignore next */ []));
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', ...(ngDevMode ? [{ debugName: "look" }] : /* istanbul ignore next */ []));
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', ...(ngDevMode ? [{ debugName: "mode" }] : /* istanbul ignore next */ []));
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, ...(ngDevMode ? [{ debugName: "widgetTree" }] : /* istanbul ignore next */ []));
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(), ...(ngDevMode ? [{ debugName: "effectiveRenderMode" }] : /* istanbul ignore next */ []));
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
- }, ...(ngDevMode ? [{ debugName: "conversionEffect" }] : /* istanbul ignore next */ []));
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, ...(ngDevMode ? [{ debugName: "form" }] : /* istanbul ignore next */ []));
2192
- this.container = viewChild(AXPWidgetContainerComponent, ...(ngDevMode ? [{ debugName: "container" }] : /* istanbul ignore next */ []));
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({}, ...(ngDevMode ? [{ debugName: "internalContext" }] : /* istanbul ignore next */ []));
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
- }, ...(ngDevMode ? [{ debugName: "#contextSyncEffect" }] : /* istanbul ignore next */ []));
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
- }, ...(ngDevMode ? [{ debugName: "#widgetStatusEffect" }] : /* istanbul ignore next */ []));
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: "21.2.9", ngImport: i0, type: AXPLayoutRendererComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2359
- 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: `
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: "21.2.9", ngImport: i0, type: AXPLayoutRendererComponent, decorators: [{
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: "21.2.9", ngImport: i0, type: AXPSettingsDefinitionDialogOpenerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2466
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPSettingsDefinitionDialogOpenerService, providedIn: 'root' }); }
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: "21.2.9", ngImport: i0, type: AXPSettingsDefinitionDialogOpenerService, decorators: [{
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: "21.2.9", ngImport: i0, type: LayoutBuilderModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
2475
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.9", ngImport: i0, type: LayoutBuilderModule, imports: [CommonModule, AXPLayoutRendererComponent], exports: [AXPLayoutRendererComponent] }); }
2476
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: LayoutBuilderModule, providers: [
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: "21.2.9", ngImport: i0, type: LayoutBuilderModule, decorators: [{
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({}, ...(ngDevMode ? [{ debugName: "context" }] : /* istanbul ignore next */ []));
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, ...(ngDevMode ? [{ debugName: "isDialogLoading" }] : /* istanbul ignore next */ []));
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([], ...(ngDevMode ? [{ debugName: "footerPrefix" }] : /* istanbul ignore next */ []));
2642
- this.footerSuffix = signal([], ...(ngDevMode ? [{ debugName: "footerSuffix" }] : /* istanbul ignore next */ []));
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
- }, ...(ngDevMode ? [{ debugName: "#dialogShortcutsEffect" }] : /* istanbul ignore next */ []));
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, ...(ngDevMode ? [{ debugName: "layoutRenderer" }] : /* istanbul ignore next */ []));
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
- }, ...(ngDevMode ? [{ debugName: "#widgetActionsEffect" }] : /* istanbul ignore next */ []));
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
- const merged = merge({}, this.context(), partial);
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
- // Handler threw: stay open for retry, actions remain clickable
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: () => this.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
- const merged = merge({}, this.context(), partial);
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 disabled = await this.evalBool(a.disabled, scope);
3161
- const hidden = await this.evalBool(a.hidden, scope);
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
- async evalBool(value, scope) {
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 false;
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: "21.2.9", ngImport: i0, type: AXPDialogRendererComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
3211
- 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: `
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: "21.2.9", ngImport: i0, type: AXPDialogRendererComponent, decorators: [{
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: false,
3429
- message: {
3430
- text: (await this.translationService.translateAsync('@general:messages.invalid-data')) || 'Invalid data',
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
- const dialogOutcome = await this.formBuilderService
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
- const cancelled = this.isCancelDialogOutcome(dialogOutcome);
3566
+ // Preview is read-only; never refresh the hosting entity list on close.
3460
3567
  return {
3461
- success: !cancelled,
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.__context__?.options;
3475
- const ctxData = input.__context__?.data;
3476
- const { __context__: _ctx, ...rest } = input;
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: "21.2.9", ngImport: i0, type: AXPPreviewWidgetFieldCommand, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
3535
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPPreviewWidgetFieldCommand }); }
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: "21.2.9", ngImport: i0, type: AXPPreviewWidgetFieldCommand, decorators: [{
3634
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXPPreviewWidgetFieldCommand, decorators: [{
3538
3635
  type: Injectable
3539
3636
  }] });
3540
3637