@acorex/platform 21.0.0-next.24 → 21.0.0-next.33

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 (118) hide show
  1. package/fesm2022/acorex-platform-auth.mjs +121 -27
  2. package/fesm2022/acorex-platform-auth.mjs.map +1 -1
  3. package/fesm2022/{acorex-platform-common-common-settings.provider-gyb6ohAE.mjs → acorex-platform-common-common-settings.provider-G9XcXXOG.mjs} +46 -4
  4. package/fesm2022/acorex-platform-common-common-settings.provider-G9XcXXOG.mjs.map +1 -0
  5. package/fesm2022/acorex-platform-common.mjs +677 -267
  6. package/fesm2022/acorex-platform-common.mjs.map +1 -1
  7. package/fesm2022/acorex-platform-core.mjs +393 -111
  8. package/fesm2022/acorex-platform-core.mjs.map +1 -1
  9. package/fesm2022/acorex-platform-domain.mjs +554 -826
  10. package/fesm2022/acorex-platform-domain.mjs.map +1 -1
  11. package/fesm2022/acorex-platform-layout-builder.mjs +345 -59
  12. package/fesm2022/acorex-platform-layout-builder.mjs.map +1 -1
  13. package/fesm2022/{acorex-platform-layout-components-binding-expression-editor-popup.component-Cb6Lk4Ch.mjs → acorex-platform-layout-components-binding-expression-editor-popup.component-CXEdvDTf.mjs} +9 -9
  14. package/fesm2022/acorex-platform-layout-components-binding-expression-editor-popup.component-CXEdvDTf.mjs.map +1 -0
  15. package/fesm2022/acorex-platform-layout-components.mjs +3373 -872
  16. package/fesm2022/acorex-platform-layout-components.mjs.map +1 -1
  17. package/fesm2022/acorex-platform-layout-designer.mjs +169 -154
  18. package/fesm2022/acorex-platform-layout-designer.mjs.map +1 -1
  19. package/fesm2022/acorex-platform-layout-entity.mjs +14645 -11533
  20. package/fesm2022/acorex-platform-layout-entity.mjs.map +1 -1
  21. package/fesm2022/acorex-platform-layout-views.mjs +244 -170
  22. package/fesm2022/acorex-platform-layout-views.mjs.map +1 -1
  23. package/fesm2022/acorex-platform-layout-widget-core.mjs +367 -408
  24. package/fesm2022/acorex-platform-layout-widget-core.mjs.map +1 -1
  25. package/fesm2022/{acorex-platform-layout-widgets-button-widget-designer.component-Dnbx_uY7.mjs → acorex-platform-layout-widgets-button-widget-designer.component-Dy7jF-oD.mjs} +10 -10
  26. package/fesm2022/acorex-platform-layout-widgets-button-widget-designer.component-Dy7jF-oD.mjs.map +1 -0
  27. package/fesm2022/{acorex-platform-layout-widgets-file-list-popup.component-B0omAUil.mjs → acorex-platform-layout-widgets-file-list-popup.component-9uCkMxcc.mjs} +30 -22
  28. package/fesm2022/acorex-platform-layout-widgets-file-list-popup.component-9uCkMxcc.mjs.map +1 -0
  29. package/fesm2022/{acorex-platform-layout-widgets-image-preview.popup-D-HFZHNZ.mjs → acorex-platform-layout-widgets-image-preview.popup-C_EPAvCU.mjs} +6 -7
  30. package/fesm2022/acorex-platform-layout-widgets-image-preview.popup-C_EPAvCU.mjs.map +1 -0
  31. package/fesm2022/{acorex-platform-layout-widgets-page-widget-designer.component-q30grR3z.mjs → acorex-platform-layout-widgets-page-widget-designer.component-D10yO28c.mjs} +12 -12
  32. package/fesm2022/acorex-platform-layout-widgets-page-widget-designer.component-D10yO28c.mjs.map +1 -0
  33. package/fesm2022/acorex-platform-layout-widgets-repeater-widget-column.component-BGQqY5Mw.mjs +111 -0
  34. package/fesm2022/acorex-platform-layout-widgets-repeater-widget-column.component-BGQqY5Mw.mjs.map +1 -0
  35. package/fesm2022/{acorex-platform-layout-widgets-tabular-data-edit-popup.component-BJh1QJqp.mjs → acorex-platform-layout-widgets-tabular-data-edit-popup.component-DmzNTYiS.mjs} +7 -7
  36. package/fesm2022/acorex-platform-layout-widgets-tabular-data-edit-popup.component-DmzNTYiS.mjs.map +1 -0
  37. package/fesm2022/{acorex-platform-layout-widgets-tabular-data-view-popup.component--rzP7scF.mjs → acorex-platform-layout-widgets-tabular-data-view-popup.component-BNG_588B.mjs} +5 -5
  38. package/fesm2022/acorex-platform-layout-widgets-tabular-data-view-popup.component-BNG_588B.mjs.map +1 -0
  39. package/fesm2022/{acorex-platform-layout-widgets-text-block-widget-designer.component-DHlgsHa7.mjs → acorex-platform-layout-widgets-text-block-widget-designer.component-Vo4fWHtX.mjs} +6 -6
  40. package/fesm2022/acorex-platform-layout-widgets-text-block-widget-designer.component-Vo4fWHtX.mjs.map +1 -0
  41. package/fesm2022/acorex-platform-layout-widgets.mjs +5924 -4049
  42. package/fesm2022/acorex-platform-layout-widgets.mjs.map +1 -1
  43. package/fesm2022/acorex-platform-native.mjs +8 -7
  44. package/fesm2022/acorex-platform-native.mjs.map +1 -1
  45. package/fesm2022/acorex-platform-runtime.mjs +220 -169
  46. package/fesm2022/acorex-platform-runtime.mjs.map +1 -1
  47. package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-Cvvr4HnL.mjs +160 -0
  48. package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-Cvvr4HnL.mjs.map +1 -0
  49. package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-TYoLN1Jq.mjs +120 -0
  50. package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-TYoLN1Jq.mjs.map +1 -0
  51. package/fesm2022/{acorex-platform-themes-default-entity-master-single-view.component-di5w_3K2.mjs → acorex-platform-themes-default-entity-master-single-view.component-C2z5Lq9y.mjs} +15 -22
  52. package/fesm2022/acorex-platform-themes-default-entity-master-single-view.component-C2z5Lq9y.mjs.map +1 -0
  53. package/fesm2022/{acorex-platform-themes-default-error-401.component-D9NZ-6L_.mjs → acorex-platform-themes-default-error-401.component-C7EYJzSr.mjs} +4 -4
  54. package/fesm2022/acorex-platform-themes-default-error-401.component-C7EYJzSr.mjs.map +1 -0
  55. package/fesm2022/{acorex-platform-themes-default-error-404.component-CgB_tlPU.mjs → acorex-platform-themes-default-error-404.component-7MVLMwIa.mjs} +4 -4
  56. package/fesm2022/acorex-platform-themes-default-error-404.component-7MVLMwIa.mjs.map +1 -0
  57. package/fesm2022/acorex-platform-themes-default-error-offline.component-DR6G8gPC.mjs +19 -0
  58. package/fesm2022/acorex-platform-themes-default-error-offline.component-DR6G8gPC.mjs.map +1 -0
  59. package/fesm2022/acorex-platform-themes-default.mjs +1667 -61
  60. package/fesm2022/acorex-platform-themes-default.mjs.map +1 -1
  61. package/fesm2022/{acorex-platform-themes-shared-icon-chooser-column.component-Cmju9l91.mjs → acorex-platform-themes-shared-icon-chooser-column.component-CqkWJYdv.mjs} +6 -6
  62. package/fesm2022/acorex-platform-themes-shared-icon-chooser-column.component-CqkWJYdv.mjs.map +1 -0
  63. package/fesm2022/{acorex-platform-themes-shared-icon-chooser-view.component-Cp5Th57U.mjs → acorex-platform-themes-shared-icon-chooser-view.component-BOTuLdWN.mjs} +6 -6
  64. package/fesm2022/acorex-platform-themes-shared-icon-chooser-view.component-BOTuLdWN.mjs.map +1 -0
  65. package/fesm2022/acorex-platform-themes-shared-settings.provider-DSs1o1M6.mjs.map +1 -1
  66. package/fesm2022/{acorex-platform-themes-shared-theme-color-chooser-column.component-BQxoUmYL.mjs → acorex-platform-themes-shared-theme-color-chooser-column.component-CHfrTtol.mjs} +4 -4
  67. package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-column.component-CHfrTtol.mjs.map +1 -0
  68. package/fesm2022/{acorex-platform-themes-shared-theme-color-chooser-view.component-CTGy2kjJ.mjs → acorex-platform-themes-shared-theme-color-chooser-view.component-BSmvnUVq.mjs} +9 -9
  69. package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-view.component-BSmvnUVq.mjs.map +1 -0
  70. package/fesm2022/acorex-platform-themes-shared.mjs +231 -227
  71. package/fesm2022/acorex-platform-themes-shared.mjs.map +1 -1
  72. package/fesm2022/acorex-platform-workflow.mjs +208 -91
  73. package/fesm2022/acorex-platform-workflow.mjs.map +1 -1
  74. package/fesm2022/acorex-platform.mjs.map +1 -1
  75. package/package.json +34 -34
  76. package/{auth/index.d.ts → types/acorex-platform-auth.d.ts} +14 -2
  77. package/{common/index.d.ts → types/acorex-platform-common.d.ts} +189 -16
  78. package/{core/index.d.ts → types/acorex-platform-core.d.ts} +178 -15
  79. package/{domain/index.d.ts → types/acorex-platform-domain.d.ts} +719 -413
  80. package/{layout/builder/index.d.ts → types/acorex-platform-layout-builder.d.ts} +91 -42
  81. package/{layout/components/index.d.ts → types/acorex-platform-layout-components.d.ts} +893 -138
  82. package/{layout/designer/index.d.ts → types/acorex-platform-layout-designer.d.ts} +9 -3
  83. package/{layout/entity/index.d.ts → types/acorex-platform-layout-entity.d.ts} +515 -26
  84. package/{layout/views/index.d.ts → types/acorex-platform-layout-views.d.ts} +44 -9
  85. package/{layout/widget-core/index.d.ts → types/acorex-platform-layout-widget-core.d.ts} +146 -95
  86. package/{layout/widgets/index.d.ts → types/acorex-platform-layout-widgets.d.ts} +506 -98
  87. package/{native/index.d.ts → types/acorex-platform-native.d.ts} +0 -7
  88. package/{runtime/index.d.ts → types/acorex-platform-runtime.d.ts} +237 -74
  89. package/{themes/default/index.d.ts → types/acorex-platform-themes-default.d.ts} +104 -4
  90. package/{workflow/index.d.ts → types/acorex-platform-workflow.d.ts} +33 -30
  91. package/fesm2022/acorex-platform-common-common-settings.provider-gyb6ohAE.mjs.map +0 -1
  92. package/fesm2022/acorex-platform-layout-components-binding-expression-editor-popup.component-Cb6Lk4Ch.mjs.map +0 -1
  93. package/fesm2022/acorex-platform-layout-widgets-button-widget-designer.component-Dnbx_uY7.mjs.map +0 -1
  94. package/fesm2022/acorex-platform-layout-widgets-file-list-popup.component-B0omAUil.mjs.map +0 -1
  95. package/fesm2022/acorex-platform-layout-widgets-image-preview.popup-D-HFZHNZ.mjs.map +0 -1
  96. package/fesm2022/acorex-platform-layout-widgets-page-widget-designer.component-q30grR3z.mjs.map +0 -1
  97. package/fesm2022/acorex-platform-layout-widgets-repeater-widget-column.component-fcCirNxz.mjs +0 -111
  98. package/fesm2022/acorex-platform-layout-widgets-repeater-widget-column.component-fcCirNxz.mjs.map +0 -1
  99. package/fesm2022/acorex-platform-layout-widgets-tabular-data-edit-popup.component-BJh1QJqp.mjs.map +0 -1
  100. package/fesm2022/acorex-platform-layout-widgets-tabular-data-view-popup.component--rzP7scF.mjs.map +0 -1
  101. package/fesm2022/acorex-platform-layout-widgets-text-block-widget-designer.component-DHlgsHa7.mjs.map +0 -1
  102. package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-D_ex0nL2.mjs +0 -160
  103. package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-D_ex0nL2.mjs.map +0 -1
  104. package/fesm2022/acorex-platform-themes-default-entity-master-list-view.component-BhDLyC5P.mjs +0 -1611
  105. package/fesm2022/acorex-platform-themes-default-entity-master-list-view.component-BhDLyC5P.mjs.map +0 -1
  106. package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-CgLUnYRq.mjs +0 -99
  107. package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-CgLUnYRq.mjs.map +0 -1
  108. package/fesm2022/acorex-platform-themes-default-entity-master-single-view.component-di5w_3K2.mjs.map +0 -1
  109. package/fesm2022/acorex-platform-themes-default-error-401.component-D9NZ-6L_.mjs.map +0 -1
  110. package/fesm2022/acorex-platform-themes-default-error-404.component-CgB_tlPU.mjs.map +0 -1
  111. package/fesm2022/acorex-platform-themes-default-error-offline.component-DlUrqVmj.mjs +0 -19
  112. package/fesm2022/acorex-platform-themes-default-error-offline.component-DlUrqVmj.mjs.map +0 -1
  113. package/fesm2022/acorex-platform-themes-shared-icon-chooser-column.component-Cmju9l91.mjs.map +0 -1
  114. package/fesm2022/acorex-platform-themes-shared-icon-chooser-view.component-Cp5Th57U.mjs.map +0 -1
  115. package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-column.component-BQxoUmYL.mjs.map +0 -1
  116. package/fesm2022/acorex-platform-themes-shared-theme-color-chooser-view.component-CTGy2kjJ.mjs.map +0 -1
  117. /package/{themes/shared/index.d.ts → types/acorex-platform-themes-shared.d.ts} +0 -0
  118. /package/{index.d.ts → types/acorex-platform.d.ts} +0 -0
@@ -2,9 +2,10 @@ import * as i5 from '@angular/common';
2
2
  import { CommonModule } from '@angular/common';
3
3
  import * as i0 from '@angular/core';
4
4
  import { Injectable, inject, input, model, signal, effect, output, viewChild, ChangeDetectionStrategy, Component, NgModule, EventEmitter, Output } from '@angular/core';
5
+ import { provideCommandSetups } from '@acorex/platform/runtime';
5
6
  import { AXPopupService } from '@acorex/components/popup';
6
7
  import * as i1 from '@acorex/platform/layout/widget-core';
7
- import { AXPWidgetSerializationHelper, AXPWidgetContainerComponent, AXPPageStatus, AXPWidgetCoreModule } from '@acorex/platform/layout/widget-core';
8
+ import { AXPWidgetSerializationHelper, AXPWidgetContainerComponent, AXPPageStatus, AXPWidgetCoreModule, AXPWidgetRegistryService } from '@acorex/platform/layout/widget-core';
8
9
  import { cloneDeep, isNil, set, isEqual } from 'lodash-es';
9
10
  import * as i2 from '@acorex/components/form';
10
11
  import { AXFormComponent, AXFormModule } from '@acorex/components/form';
@@ -17,9 +18,10 @@ import * as i3 from '@acorex/components/loading';
17
18
  import { AXLoadingModule } from '@acorex/components/loading';
18
19
  import { AXBasePageComponent } from '@acorex/components/page';
19
20
  import * as i6 from '@acorex/core/translation';
20
- import { AXTranslationModule } from '@acorex/core/translation';
21
+ import { AXTranslationModule, AXTranslationService } from '@acorex/core/translation';
21
22
  import * as i4 from '@acorex/platform/core';
22
- import { AXPExpressionEvaluatorService, AXPComponentSlotModule } from '@acorex/platform/core';
23
+ import { AXPExpressionEvaluatorService, AXPComponentSlotModule, AXPContextStore, AXPMultiLanguageStringResolverService } from '@acorex/platform/core';
24
+ import { AXP_ENTITY_DEFINITION_CRUD_SERVICE } from '@acorex/platform/domain';
23
25
 
24
26
  class AXPLayoutConversionService {
25
27
  constructor() {
@@ -223,9 +225,16 @@ class AXPLayoutConversionService {
223
225
  const keyParts = [];
224
226
  keyParts.push(`groups:${formDefinition.groups.length}`);
225
227
  formDefinition.groups.forEach((group, groupIndex) => {
226
- keyParts.push(`g${groupIndex}:${group.name}:${group.parameters.length}`);
228
+ // Include group.mode so view vs edit (or mixed) layouts do not share a cached widget tree.
229
+ const groupModePart = group.mode ?? '_';
230
+ keyParts.push(`g${groupIndex}:${group.name}:${group.parameters.length}:${groupModePart}`);
231
+ keyParts.push(`gL${groupIndex}:${JSON.stringify(group.title ?? null)}:${JSON.stringify(group.description ?? null)}`);
227
232
  group.parameters.forEach((param, paramIndex) => {
228
- keyParts.push(`p${groupIndex}.${paramIndex}:${param.path}:${param.widget.type}`);
233
+ // Field mode must be part of the key; otherwise metadata forms that only differ by
234
+ // view/edit (same paths and widget types) incorrectly reuse the first cached tree.
235
+ const fieldModePart = param.mode ?? '_';
236
+ keyParts.push(`p${groupIndex}.${paramIndex}:${param.path}:${param.widget.type}:${fieldModePart}`);
237
+ keyParts.push(`pL${groupIndex}.${paramIndex}:${JSON.stringify(param.title ?? null)}:${JSON.stringify(param.description ?? null)}:${JSON.stringify(param.badge ?? null)}`);
229
238
  });
230
239
  });
231
240
  if (formDefinition.mode) {
@@ -286,10 +295,10 @@ class AXPLayoutConversionService {
286
295
  }
287
296
  return Math.abs(hash).toString(36); // Convert to base36 for shorter string
288
297
  }
289
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPLayoutConversionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
290
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPLayoutConversionService, providedIn: 'root' }); }
298
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPLayoutConversionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
299
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPLayoutConversionService, providedIn: 'root' }); }
291
300
  }
292
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPLayoutConversionService, decorators: [{
301
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPLayoutConversionService, decorators: [{
293
302
  type: Injectable,
294
303
  args: [{
295
304
  providedIn: 'root',
@@ -406,10 +415,10 @@ class AXPLayoutBuilderService {
406
415
  create() {
407
416
  return new LayoutBuilder(this.popupService);
408
417
  }
409
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPLayoutBuilderService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
410
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPLayoutBuilderService, providedIn: 'root' }); }
418
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPLayoutBuilderService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
419
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPLayoutBuilderService, providedIn: 'root' }); }
411
420
  }
412
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPLayoutBuilderService, decorators: [{
421
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPLayoutBuilderService, decorators: [{
413
422
  type: Injectable,
414
423
  args: [{
415
424
  providedIn: 'root',
@@ -591,6 +600,7 @@ class BaseContainerBuilder {
591
600
  'number-editor',
592
601
  'select-editor',
593
602
  'lookup-editor',
603
+ 'entity-definition-provider-editor',
594
604
  'selection-list-editor',
595
605
  'date-time-editor',
596
606
  'toggle-editor',
@@ -693,24 +703,30 @@ class BaseContainerMixin extends BaseContainerBuilder {
693
703
  class LayoutContainerMixin extends BaseContainerMixin {
694
704
  layout(value) {
695
705
  // Map layout intent to grid item sizing so containers like `form-field`
696
- // can span multiple columns inside grid/fieldset layouts.
706
+ // can span multiple columns/rows inside grid/fieldset layouts.
697
707
  if (!this.containerState.options)
698
708
  this.containerState.options = {};
699
709
  if (typeof value === 'number') {
700
- // Direct numeric shorthand → colSpan
701
710
  this.containerState.options.colSpan = value;
702
711
  }
703
712
  else if (value) {
704
- // Try to extract a reasonable colSpan from breakpoint positions
705
713
  const positions = value.positions;
706
714
  if (positions) {
707
- const colSpan = positions?.lg?.colSpan ??
708
- positions?.xl?.colSpan ??
709
- positions?.xxl?.colSpan ??
710
- positions?.md?.colSpan ??
711
- positions?.sm?.colSpan;
712
- if (colSpan != null) {
713
- this.containerState.options.colSpan = colSpan;
715
+ const placement = positions?.lg ?? positions?.xl ?? positions?.xxl ?? positions?.md ?? positions?.sm;
716
+ if (placement) {
717
+ const opts = this.containerState.options;
718
+ if (placement.colSpan != null)
719
+ opts.colSpan = placement.colSpan;
720
+ if (placement.colStart != null)
721
+ opts.colStart = placement.colStart;
722
+ if (placement.colEnd != null)
723
+ opts.colEnd = placement.colEnd;
724
+ if (placement.rowSpan != null)
725
+ opts.rowSpan = placement.rowSpan;
726
+ if (placement.rowStart != null)
727
+ opts.rowStart = placement.rowStart;
728
+ if (placement.rowEnd != null)
729
+ opts.rowEnd = placement.rowEnd;
714
730
  }
715
731
  }
716
732
  }
@@ -929,6 +945,7 @@ class WidgetContainerMixin extends ChildContainerMixin {
929
945
  'number-editor',
930
946
  'select-editor',
931
947
  'lookup-editor',
948
+ 'entity-definition-provider-editor',
932
949
  'selection-list-editor',
933
950
  'date-time-editor',
934
951
  'toggle-editor',
@@ -984,6 +1001,34 @@ class FlexContainerBuilder extends WidgetContainerMixin {
984
1001
  * Grid Container Builder - Liskov Substitution Principle
985
1002
  * Extends WidgetContainerMixin to inherit all common functionality
986
1003
  */
1004
+ /**
1005
+ * Extracts flat grid-item options from AXPGridLayoutOptions for grid-item-layout widget.
1006
+ * Uses first available breakpoint (lg, xl, md, sm).
1007
+ */
1008
+ function toGridItemOptions(layoutOptions) {
1009
+ if (!layoutOptions?.positions)
1010
+ return { colSpan: 12 };
1011
+ const positions = layoutOptions.positions;
1012
+ const placement = positions['lg'] ?? positions['xl'] ?? positions['xxl'] ?? positions['md'] ?? positions['sm'];
1013
+ if (!placement)
1014
+ return { colSpan: 12 };
1015
+ const opts = {};
1016
+ if (placement['colSpan'] != null)
1017
+ opts['colSpan'] = placement['colSpan'];
1018
+ if (placement['colStart'] != null)
1019
+ opts['colStart'] = placement['colStart'];
1020
+ if (placement['colEnd'] != null)
1021
+ opts['colEnd'] = placement['colEnd'];
1022
+ if (placement['rowSpan'] != null)
1023
+ opts['rowSpan'] = placement['rowSpan'];
1024
+ if (placement['rowStart'] != null)
1025
+ opts['rowStart'] = placement['rowStart'];
1026
+ if (placement['rowEnd'] != null)
1027
+ opts['rowEnd'] = placement['rowEnd'];
1028
+ if (Object.keys(opts).length === 0)
1029
+ opts['colSpan'] = 12;
1030
+ return opts;
1031
+ }
987
1032
  class GridContainerBuilder extends WidgetContainerMixin {
988
1033
  constructor() {
989
1034
  super('grid-layout');
@@ -992,6 +1037,21 @@ class GridContainerBuilder extends WidgetContainerMixin {
992
1037
  this.containerState.options = { ...this.containerState.options, ...options };
993
1038
  return this;
994
1039
  }
1040
+ item(layoutOptions, delegate) {
1041
+ const fieldset = new FieldsetContainerBuilder();
1042
+ fieldset.withInheritanceContext(this.inheritanceContext);
1043
+ delegate(fieldset);
1044
+ const fieldsetNode = fieldset.build();
1045
+ const gridItemOptions = toGridItemOptions(layoutOptions);
1046
+ const gridItemNode = {
1047
+ type: 'grid-item-layout',
1048
+ options: gridItemOptions,
1049
+ children: [fieldsetNode],
1050
+ };
1051
+ this.ensureChildren();
1052
+ this.containerState.children.push(gridItemNode);
1053
+ return this;
1054
+ }
995
1055
  // Individual fluent methods for Grid
996
1056
  setColumns(columns) {
997
1057
  return this.setOptions({ grid: { default: { columns } } });
@@ -1761,10 +1821,19 @@ class ActionBuilder {
1761
1821
  return this;
1762
1822
  }
1763
1823
  custom(action) {
1764
- if (!this.dialogBuilder['dialogState'].actions.footer.suffix) {
1765
- this.dialogBuilder['dialogState'].actions.footer.suffix = [];
1824
+ const position = action.position ?? 'suffix';
1825
+ if (position === 'prefix') {
1826
+ if (!this.dialogBuilder['dialogState'].actions.footer.prefix) {
1827
+ this.dialogBuilder['dialogState'].actions.footer.prefix = [];
1828
+ }
1829
+ this.dialogBuilder['dialogState'].actions.footer.prefix.push(action);
1830
+ }
1831
+ else {
1832
+ if (!this.dialogBuilder['dialogState'].actions.footer.suffix) {
1833
+ this.dialogBuilder['dialogState'].actions.footer.suffix = [];
1834
+ }
1835
+ this.dialogBuilder['dialogState'].actions.footer.suffix.push(action);
1766
1836
  }
1767
- this.dialogBuilder['dialogState'].actions.footer.suffix.push(action);
1768
1837
  return this;
1769
1838
  }
1770
1839
  }
@@ -1913,22 +1982,22 @@ class AXPLayoutRendererComponent {
1913
1982
  /**
1914
1983
  * Form definition containing groups and fields OR widget tree
1915
1984
  */
1916
- this.layout = input.required(...(ngDevMode ? [{ debugName: "layout" }] : []));
1985
+ this.layout = input.required(...(ngDevMode ? [{ debugName: "layout" }] : /* istanbul ignore next */ []));
1917
1986
  /**
1918
1987
  * Form context/model data
1919
1988
  */
1920
- this.context = model({}, ...(ngDevMode ? [{ debugName: "context" }] : []));
1989
+ this.context = model({}, ...(ngDevMode ? [{ debugName: "context" }] : /* istanbul ignore next */ []));
1921
1990
  /**
1922
1991
  * Form appearance and density styling (normal, compact, spacious)
1923
1992
  */
1924
- this.look = input('fieldset', ...(ngDevMode ? [{ debugName: "look" }] : []));
1993
+ this.look = input('fieldset', ...(ngDevMode ? [{ debugName: "look" }] : /* istanbul ignore next */ []));
1925
1994
  /**
1926
1995
  * Default form mode. Can be overridden by section/group and field.
1927
1996
  */
1928
- this.mode = input('edit', ...(ngDevMode ? [{ debugName: "mode" }] : []));
1997
+ this.mode = input('edit', ...(ngDevMode ? [{ debugName: "mode" }] : /* istanbul ignore next */ []));
1929
1998
  //#endregion
1930
1999
  //#region ---- Widget Tree Conversion ----
1931
- this.widgetTree = signal(null, ...(ngDevMode ? [{ debugName: "widgetTree" }] : []));
2000
+ this.widgetTree = signal(null, ...(ngDevMode ? [{ debugName: "widgetTree" }] : /* istanbul ignore next */ []));
1932
2001
  /**
1933
2002
  * Convert layout data to widget tree when inputs change
1934
2003
  */
@@ -1953,7 +2022,7 @@ class AXPLayoutRendererComponent {
1953
2022
  if (!isEqual(prev, tree)) {
1954
2023
  this.widgetTree.set(tree);
1955
2024
  }
1956
- }, ...(ngDevMode ? [{ debugName: "conversionEffect" }] : []));
2025
+ }, ...(ngDevMode ? [{ debugName: "conversionEffect" }] : /* istanbul ignore next */ []));
1957
2026
  //#endregion
1958
2027
  //#region ---- Outputs ----
1959
2028
  /**
@@ -1966,12 +2035,12 @@ class AXPLayoutRendererComponent {
1966
2035
  this.validityChange = output();
1967
2036
  //#endregion
1968
2037
  //#region ---- Properties ----
1969
- this.form = viewChild(AXFormComponent, ...(ngDevMode ? [{ debugName: "form" }] : []));
1970
- this.container = viewChild(AXPWidgetContainerComponent, ...(ngDevMode ? [{ debugName: "container" }] : []));
2038
+ this.form = viewChild(AXFormComponent, ...(ngDevMode ? [{ debugName: "form" }] : /* istanbul ignore next */ []));
2039
+ this.container = viewChild(AXPWidgetContainerComponent, ...(ngDevMode ? [{ debugName: "container" }] : /* istanbul ignore next */ []));
1971
2040
  /**
1972
2041
  * Internal context signal for reactivity
1973
2042
  */
1974
- this.internalContext = signal({}, ...(ngDevMode ? [{ debugName: "internalContext" }] : []));
2043
+ this.internalContext = signal({}, ...(ngDevMode ? [{ debugName: "internalContext" }] : /* istanbul ignore next */ []));
1975
2044
  /**
1976
2045
  * Initial context for reset functionality
1977
2046
  */
@@ -1984,7 +2053,7 @@ class AXPLayoutRendererComponent {
1984
2053
  this.#contextSyncEffect = effect(() => {
1985
2054
  const ctx = this.context() ?? {};
1986
2055
  this.contextUpdateSubject.next(ctx);
1987
- }, ...(ngDevMode ? [{ debugName: "#contextSyncEffect" }] : []));
2056
+ }, ...(ngDevMode ? [{ debugName: "#contextSyncEffect" }] : /* istanbul ignore next */ []));
1988
2057
  /**
1989
2058
  * Effect to handle widget tree status changes
1990
2059
  */
@@ -1993,7 +2062,7 @@ class AXPLayoutRendererComponent {
1993
2062
  if (widgetTree) {
1994
2063
  this.container()?.builderService.setStatus(AXPPageStatus.Rendered);
1995
2064
  }
1996
- }, ...(ngDevMode ? [{ debugName: "#widgetStatusEffect" }] : []));
2065
+ }, ...(ngDevMode ? [{ debugName: "#widgetStatusEffect" }] : /* istanbul ignore next */ []));
1997
2066
  }
1998
2067
  //#endregion
1999
2068
  //#region ---- Lifecycle Methods ----
@@ -2133,8 +2202,8 @@ class AXPLayoutRendererComponent {
2133
2202
  isWidgetNode(data) {
2134
2203
  return data && typeof data === 'object' && 'type' in data && typeof data.type === 'string';
2135
2204
  }
2136
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPLayoutRendererComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2137
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", 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: `
2205
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPLayoutRendererComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2206
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPLayoutRendererComponent, isStandalone: true, selector: "axp-layout-renderer", inputs: { layout: { classPropertyName: "layout", publicName: "layout", isSignal: true, isRequired: true, transformFunction: null }, context: { classPropertyName: "context", publicName: "context", isSignal: true, isRequired: false, transformFunction: null }, look: { classPropertyName: "look", publicName: "look", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { context: "contextChange", contextInitiated: "contextInitiated", validityChange: "validityChange" }, viewQueries: [{ propertyName: "form", first: true, predicate: AXFormComponent, descendants: true, isSignal: true }, { propertyName: "container", first: true, predicate: AXPWidgetContainerComponent, descendants: true, isSignal: true }], ngImport: i0, template: `
2138
2207
  <ax-form>
2139
2208
  <axp-widgets-container [context]="internalContext()" (onContextChanged)="handleContextChanged($event)">
2140
2209
  @if (widgetTree()) {
@@ -2142,11 +2211,11 @@ class AXPLayoutRendererComponent {
2142
2211
  }
2143
2212
  </axp-widgets-container>
2144
2213
  </ax-form>
2145
- `, isInline: true, styles: [":host{display:block;width:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXPWidgetCoreModule }, { kind: "component", type: i1.AXPWidgetContainerComponent, selector: "axp-widgets-container", inputs: ["context", "functions"], outputs: ["onContextChanged"] }, { kind: "directive", type: i1.AXPWidgetRendererDirective, selector: "[axp-widget-renderer]", inputs: ["parentNode", "index", "mode", "node"], outputs: ["onOptionsChanged", "onValueChanged", "onLoad"], exportAs: ["widgetRenderer"] }, { kind: "ngmodule", type: AXFormModule }, { kind: "component", type: i2.AXFormComponent, selector: "ax-form", inputs: ["disabled", "readonly", "labelMode", "look", "messageStyle", "updateOn", "inUserInteractionActive"], outputs: ["onValidate", "updateOnChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2214
+ `, isInline: true, styles: [":host{display:block;width:100%}\n"], dependencies: [{ kind: "ngmodule", type: AXPWidgetCoreModule }, { kind: "component", type: i1.AXPWidgetContainerComponent, selector: "axp-widgets-container", inputs: ["context", "functions"], outputs: ["onContextChanged"] }, { kind: "directive", type: i1.AXPWidgetRendererDirective, selector: "[axp-widget-renderer]", inputs: ["parentNode", "index", "mode", "node"], outputs: ["onOptionsChanged", "onValueChanged", "onLoad"], exportAs: ["widgetRenderer"] }, { kind: "ngmodule", type: AXFormModule }, { kind: "component", type: i2.AXFormComponent, selector: "ax-form", inputs: ["disabled", "readonly", "labelMode", "look", "messageStyle", "updateOn", "inUserInteractionActive"], outputs: ["onValidate", "updateOnChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2146
2215
  }
2147
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPLayoutRendererComponent, decorators: [{
2216
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPLayoutRendererComponent, decorators: [{
2148
2217
  type: Component,
2149
- args: [{ selector: 'axp-layout-renderer', standalone: true, imports: [CommonModule, AXPWidgetCoreModule, AXFormModule], changeDetection: ChangeDetectionStrategy.OnPush, template: `
2218
+ args: [{ selector: 'axp-layout-renderer', standalone: true, imports: [AXPWidgetCoreModule, AXFormModule], changeDetection: ChangeDetectionStrategy.OnPush, template: `
2150
2219
  <ax-form>
2151
2220
  <axp-widgets-container [context]="internalContext()" (onContextChanged)="handleContextChanged($event)">
2152
2221
  @if (widgetTree()) {
@@ -2157,16 +2226,35 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
2157
2226
  `, styles: [":host{display:block;width:100%}\n"] }]
2158
2227
  }], propDecorators: { layout: [{ type: i0.Input, args: [{ isSignal: true, alias: "layout", required: true }] }], context: [{ type: i0.Input, args: [{ isSignal: true, alias: "context", required: false }] }, { type: i0.Output, args: ["contextChange"] }], look: [{ type: i0.Input, args: [{ isSignal: true, alias: "look", required: false }] }], mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], contextInitiated: [{ type: i0.Output, args: ["contextInitiated"] }], validityChange: [{ type: i0.Output, args: ["validityChange"] }], form: [{ type: i0.ViewChild, args: [i0.forwardRef(() => AXFormComponent), { isSignal: true }] }], container: [{ type: i0.ViewChild, args: [i0.forwardRef(() => AXPWidgetContainerComponent), { isSignal: true }] }] } });
2159
2228
 
2229
+ /** Registration key for {@link AXPPreviewWidgetFieldCommand}; lives alone so `LayoutBuilderModule` can reference it without static-importing the command implementation. */
2230
+ const AXP_PREVIEW_WIDGET_FIELD_COMMAND_KEY = 'Widget:Preview';
2231
+
2160
2232
  class LayoutBuilderModule {
2161
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: LayoutBuilderModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
2162
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.16", ngImport: i0, type: LayoutBuilderModule, imports: [CommonModule, AXPLayoutRendererComponent], exports: [AXPLayoutRendererComponent] }); }
2163
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: LayoutBuilderModule, providers: [AXPLayoutBuilderService], imports: [CommonModule, AXPLayoutRendererComponent] }); }
2233
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: LayoutBuilderModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
2234
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.9", ngImport: i0, type: LayoutBuilderModule, imports: [CommonModule, AXPLayoutRendererComponent], exports: [AXPLayoutRendererComponent] }); }
2235
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: LayoutBuilderModule, providers: [
2236
+ AXPLayoutBuilderService,
2237
+ provideCommandSetups([
2238
+ {
2239
+ key: AXP_PREVIEW_WIDGET_FIELD_COMMAND_KEY,
2240
+ command: () => Promise.resolve().then(function () { return previewWidgetField_command; }).then((c) => c.AXPPreviewWidgetFieldCommand),
2241
+ },
2242
+ ]),
2243
+ ], imports: [CommonModule, AXPLayoutRendererComponent] }); }
2164
2244
  }
2165
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: LayoutBuilderModule, decorators: [{
2245
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: LayoutBuilderModule, decorators: [{
2166
2246
  type: NgModule,
2167
2247
  args: [{
2168
2248
  imports: [CommonModule, AXPLayoutRendererComponent],
2169
- providers: [AXPLayoutBuilderService],
2249
+ providers: [
2250
+ AXPLayoutBuilderService,
2251
+ provideCommandSetups([
2252
+ {
2253
+ key: AXP_PREVIEW_WIDGET_FIELD_COMMAND_KEY,
2254
+ command: () => Promise.resolve().then(function () { return previewWidgetField_command; }).then((c) => c.AXPPreviewWidgetFieldCommand),
2255
+ },
2256
+ ]),
2257
+ ],
2170
2258
  exports: [AXPLayoutRendererComponent],
2171
2259
  }]
2172
2260
  }] });
@@ -2178,17 +2266,17 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
2178
2266
  super(...arguments);
2179
2267
  this.result = new EventEmitter();
2180
2268
  this.expressionEvaluator = inject(AXPExpressionEvaluatorService);
2181
- this.context = signal({}, ...(ngDevMode ? [{ debugName: "context" }] : []));
2269
+ this.context = signal({}, ...(ngDevMode ? [{ debugName: "context" }] : /* istanbul ignore next */ []));
2182
2270
  // This will be set by the popup service automatically - same as dynamic-dialog
2183
2271
  this.callBack = () => { };
2184
- this.isDialogLoading = signal(false, ...(ngDevMode ? [{ debugName: "isDialogLoading" }] : []));
2272
+ this.isDialogLoading = signal(false, ...(ngDevMode ? [{ debugName: "isDialogLoading" }] : /* istanbul ignore next */ []));
2185
2273
  // Aggregated actions for footer rendering
2186
- this.footerPrefix = signal([], ...(ngDevMode ? [{ debugName: "footerPrefix" }] : []));
2187
- this.footerSuffix = signal([], ...(ngDevMode ? [{ debugName: "footerSuffix" }] : []));
2274
+ this.footerPrefix = signal([], ...(ngDevMode ? [{ debugName: "footerPrefix" }] : /* istanbul ignore next */ []));
2275
+ this.footerSuffix = signal([], ...(ngDevMode ? [{ debugName: "footerSuffix" }] : /* istanbul ignore next */ []));
2188
2276
  //#endregion
2189
2277
  //#region ---- View Accessors ----
2190
2278
  // Access the internal layout renderer to reach the widgets container injector
2191
- this.layoutRenderer = viewChild(AXPLayoutRendererComponent, ...(ngDevMode ? [{ debugName: "layoutRenderer" }] : []));
2279
+ this.layoutRenderer = viewChild(AXPLayoutRendererComponent, ...(ngDevMode ? [{ debugName: "layoutRenderer" }] : /* istanbul ignore next */ []));
2192
2280
  this.#eff = effect(() => {
2193
2281
  let count = 0;
2194
2282
  this.aggregateAndEvaluateActions();
@@ -2209,7 +2297,7 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
2209
2297
  this.aggregateAndEvaluateActions();
2210
2298
  }, 200);
2211
2299
  }
2212
- }, ...(ngDevMode ? [{ debugName: "#eff" }] : []));
2300
+ }, ...(ngDevMode ? [{ debugName: "#eff" }] : /* istanbul ignore next */ []));
2213
2301
  }
2214
2302
  //#endregion
2215
2303
  //#region ---- Lifecycle ----
@@ -2239,14 +2327,14 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
2239
2327
  return this.isDialogLoading();
2240
2328
  }
2241
2329
  async executeAction(action) {
2242
- const cmd = action.command;
2330
+ const cmd = this.resolveActionCommandName(action.command);
2243
2331
  if (cmd !== 'cancel') {
2244
2332
  const isValid = await this.layoutRenderer()?.validate();
2245
2333
  if (!isValid?.result) {
2246
2334
  return;
2247
2335
  }
2248
2336
  }
2249
- if (typeof cmd === 'string' && cmd.startsWith('widget:')) {
2337
+ if (cmd?.startsWith('widget:')) {
2250
2338
  const parsed = this.parseWidgetCommand(cmd);
2251
2339
  if (parsed.widgetName && parsed.action) {
2252
2340
  await this.executeWidgetApi(parsed.widgetName, parsed.action);
@@ -2260,7 +2348,7 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
2260
2348
  const dialogRef = {
2261
2349
  close: (res) => this.close(res),
2262
2350
  context: () => this.context(),
2263
- action: () => cmd ?? undefined,
2351
+ action: () => action.command ?? undefined,
2264
2352
  setLoading: (loading) => this.isDialogLoading.set(loading),
2265
2353
  };
2266
2354
  try {
@@ -2294,6 +2382,20 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
2294
2382
  this.isDialogLoading.set(loading);
2295
2383
  },
2296
2384
  });
2385
+ // Without `onAction`, only the configured cancel action dismisses the dialog (not submit/custom).
2386
+ if (cmd === 'cancel') {
2387
+ await this.close(result);
2388
+ }
2389
+ }
2390
+ /** Resolves footer/widget action command to a string (e.g. `cancel`, `submit`, `widget:...`). */
2391
+ resolveActionCommandName(command) {
2392
+ if (typeof command === 'string') {
2393
+ return command;
2394
+ }
2395
+ if (command && typeof command === 'object' && 'name' in command) {
2396
+ return command.name;
2397
+ }
2398
+ return undefined;
2297
2399
  }
2298
2400
  parseWidgetCommand(cmd) {
2299
2401
  // Expected 'widget:<widgetName>.<action>'
@@ -2420,8 +2522,8 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
2420
2522
  return undefined;
2421
2523
  }
2422
2524
  }
2423
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPDialogRendererComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
2424
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: AXPDialogRendererComponent, isStandalone: true, selector: "axp-dialog-renderer", outputs: { result: "result" }, viewQueries: [{ propertyName: "layoutRenderer", first: true, predicate: AXPLayoutRendererComponent, descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: `
2525
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPDialogRendererComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
2526
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPDialogRendererComponent, isStandalone: true, selector: "axp-dialog-renderer", outputs: { result: "result" }, providers: [AXPContextStore], viewQueries: [{ propertyName: "layoutRenderer", first: true, predicate: AXPLayoutRendererComponent, descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: `
2425
2527
  <axp-component-slot name="dialog-header" [context]="context()"></axp-component-slot>
2426
2528
  <div class="ax-p-4">
2427
2529
  <axp-layout-renderer
@@ -2476,9 +2578,9 @@ class AXPDialogRendererComponent extends AXBasePageComponent {
2476
2578
  </ax-suffix>
2477
2579
  </ax-footer>
2478
2580
  }
2479
- `, 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" }] }); }
2581
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: AXPLayoutRendererComponent, selector: "axp-layout-renderer", inputs: ["layout", "context", "look", "mode"], outputs: ["contextChange", "contextInitiated", "validityChange"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1$1.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i2$1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXLoadingModule }, { kind: "component", type: i3.AXLoadingComponent, selector: "ax-loading", inputs: ["visible", "type", "context"], outputs: ["visibleChange"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: AXPComponentSlotModule }, { kind: "directive", type: i4.AXPComponentSlotDirective, selector: "axp-component-slot", inputs: ["name", "host", "context"], exportAs: ["slot"] }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }, { kind: "pipe", type: i6.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2480
2582
  }
2481
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: AXPDialogRendererComponent, decorators: [{
2583
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPDialogRendererComponent, decorators: [{
2482
2584
  type: Component,
2483
2585
  args: [{
2484
2586
  selector: 'axp-dialog-renderer',
@@ -2492,6 +2594,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
2492
2594
  AXTranslationModule,
2493
2595
  AXPComponentSlotModule,
2494
2596
  ],
2597
+ providers: [AXPContextStore],
2598
+ changeDetection: ChangeDetectionStrategy.OnPush,
2495
2599
  template: `
2496
2600
  <axp-component-slot name="dialog-header" [context]="context()"></axp-component-slot>
2497
2601
  <div class="ax-p-4">
@@ -2558,9 +2662,191 @@ var dialogRenderer_component = /*#__PURE__*/Object.freeze({
2558
2662
  AXPDialogRendererComponent: AXPDialogRendererComponent
2559
2663
  });
2560
2664
 
2665
+ //#region ---- Imports ----
2666
+ /**
2667
+ * `customWidget` only forwards keys from its options bag into the built node via `addSingleWidget`.
2668
+ * Designer / configurator persist `defaultValue` (and other extended fields) on the widget node root;
2669
+ * spreading `options` alone drops them, so preview never applied defaults.
2670
+ */
2671
+ /**
2672
+ * Widget options are sometimes persisted with an extra nesting (`options.options`) when context
2673
+ * was merged incorrectly. Flatten so list/data-source resolution sees `dataSource` at the top level.
2674
+ */
2675
+ function optionsBagForPreview(node) {
2676
+ const raw = (node.options ?? {});
2677
+ const inner = raw['options'];
2678
+ if (inner !== undefined && typeof inner === 'object' && !Array.isArray(inner)) {
2679
+ const { options: _nested, ...rest } = raw;
2680
+ return { ...rest, ...inner };
2681
+ }
2682
+ return { ...raw };
2683
+ }
2684
+ function extendedNodePropsForPreview(node) {
2685
+ const out = {};
2686
+ if (node.defaultValue !== undefined) {
2687
+ out['defaultValue'] = node.defaultValue;
2688
+ }
2689
+ if (node.triggers !== undefined) {
2690
+ out['triggers'] = node.triggers;
2691
+ }
2692
+ if (node.meta !== undefined) {
2693
+ out['meta'] = node.meta;
2694
+ }
2695
+ if (node.valueTransforms !== undefined) {
2696
+ out['valueTransforms'] = node.valueTransforms;
2697
+ }
2698
+ if (node.visible !== undefined) {
2699
+ out['visible'] = node.visible;
2700
+ }
2701
+ if (node.mode !== undefined) {
2702
+ out['mode'] = node.mode;
2703
+ }
2704
+ if (node.children !== undefined) {
2705
+ out['children'] = node.children;
2706
+ }
2707
+ return out;
2708
+ }
2709
+ //#endregion
2710
+ //#region ---- Command ----
2711
+ /**
2712
+ * Opens a dialog that previews a widget configuration (same behavior as the preview button on
2713
+ * `axp-widget-field-configurator`). Invoked from that component and from entity list actions.
2714
+ */
2715
+ class AXPPreviewWidgetFieldCommand {
2716
+ constructor() {
2717
+ this.formBuilderService = inject(AXPLayoutBuilderService);
2718
+ this.widgetRegistry = inject(AXPWidgetRegistryService);
2719
+ this.translationService = inject(AXTranslationService);
2720
+ this.mlResolver = inject(AXPMultiLanguageStringResolverService);
2721
+ this.crudService = inject(AXP_ENTITY_DEFINITION_CRUD_SERVICE, { optional: true });
2722
+ }
2723
+ async execute(input) {
2724
+ try {
2725
+ const merged = this.mergeInvocation(input);
2726
+ const currentWidget = this.normalizeWidget(merged['widget'] ?? merged['interface']);
2727
+ if (!currentWidget?.type) {
2728
+ return {
2729
+ success: false,
2730
+ message: { text: (await this.translationService.translateAsync('@general:messages.invalid-data')) || 'Invalid data' },
2731
+ };
2732
+ }
2733
+ const fieldName = String(merged['fieldName'] ?? merged['name'] ?? 'Field');
2734
+ const rawTitle = (merged['fieldTitle'] ?? merged['title']);
2735
+ const fieldTitleLabel = this.resolveFieldTitleLabel(rawTitle, fieldName);
2736
+ const dialogTitle = (await this.resolveWidgetDisplayTitle(currentWidget.type)) ||
2737
+ currentWidget.type ||
2738
+ fieldTitleLabel;
2739
+ const previewWidgetOptions = {
2740
+ ...optionsBagForPreview(currentWidget),
2741
+ name: fieldName,
2742
+ ...extendedNodePropsForPreview(currentWidget),
2743
+ };
2744
+ const dialogOutcome = await this.formBuilderService
2745
+ .create()
2746
+ .dialog((dialog) => {
2747
+ dialog
2748
+ .setTitle(dialogTitle)
2749
+ .setSize('md')
2750
+ .setCloseButton(true)
2751
+ .setContext({})
2752
+ .content((layoutBuilder) => {
2753
+ layoutBuilder.formField(fieldTitleLabel, (formField) => {
2754
+ formField.customWidget(currentWidget.type, previewWidgetOptions);
2755
+ });
2756
+ })
2757
+ .setActions((actions) => actions.cancel('@general:actions.close.title'));
2758
+ })
2759
+ .show();
2760
+ const cancelled = this.isCancelDialogOutcome(dialogOutcome);
2761
+ return {
2762
+ success: !cancelled,
2763
+ message: { text: '' },
2764
+ };
2765
+ }
2766
+ catch (error) {
2767
+ const message = error instanceof Error ? error.message : 'Unknown error';
2768
+ return {
2769
+ success: false,
2770
+ message: { text: message },
2771
+ };
2772
+ }
2773
+ }
2774
+ mergeInvocation(input) {
2775
+ const contextOptions = input.__context__?.options;
2776
+ const ctxData = input.__context__?.data;
2777
+ const { __context__: _ctx, ...rest } = input;
2778
+ return {
2779
+ ...(ctxData ?? {}),
2780
+ ...(contextOptions ?? {}),
2781
+ ...rest,
2782
+ };
2783
+ }
2784
+ normalizeWidget(raw) {
2785
+ if (raw == null)
2786
+ return null;
2787
+ if (typeof raw === 'string') {
2788
+ const t = raw.trim();
2789
+ return t ? { type: t, options: {} } : null;
2790
+ }
2791
+ if (typeof raw === 'object' && !Array.isArray(raw) && 'type' in raw) {
2792
+ const w = raw;
2793
+ return w.type ? cloneDeep(w) : null;
2794
+ }
2795
+ return null;
2796
+ }
2797
+ resolveFieldTitleLabel(raw, fallback) {
2798
+ let source = fallback;
2799
+ if (raw !== undefined && raw !== null) {
2800
+ if (typeof raw === 'string') {
2801
+ if (raw.trim() !== '') {
2802
+ source = raw;
2803
+ }
2804
+ }
2805
+ else if (typeof raw === 'object' && !Array.isArray(raw) && Object.keys(raw).length > 0) {
2806
+ source = raw;
2807
+ }
2808
+ }
2809
+ return this.mlResolver.resolve(source);
2810
+ }
2811
+ isCancelDialogOutcome(outcome) {
2812
+ if (outcome == null) {
2813
+ return false;
2814
+ }
2815
+ const ref = outcome;
2816
+ if (typeof ref.action !== 'function') {
2817
+ return false;
2818
+ }
2819
+ return ref.action() === 'cancel';
2820
+ }
2821
+ async resolveWidgetDisplayTitle(widgetType) {
2822
+ const crud = this.crudService;
2823
+ if (crud) {
2824
+ const interfaces = await crud.listInterfaces();
2825
+ const iface = interfaces.find((d) => d.name === widgetType);
2826
+ return iface?.title ?? iface?.name;
2827
+ }
2828
+ const config = this.widgetRegistry.getOptional(widgetType);
2829
+ if (!config) {
2830
+ return undefined;
2831
+ }
2832
+ const resolved = this.mlResolver.resolve(config.title);
2833
+ return resolved || undefined;
2834
+ }
2835
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPPreviewWidgetFieldCommand, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2836
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPPreviewWidgetFieldCommand }); }
2837
+ }
2838
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPPreviewWidgetFieldCommand, decorators: [{
2839
+ type: Injectable
2840
+ }] });
2841
+
2842
+ var previewWidgetField_command = /*#__PURE__*/Object.freeze({
2843
+ __proto__: null,
2844
+ AXPPreviewWidgetFieldCommand: AXPPreviewWidgetFieldCommand
2845
+ });
2846
+
2561
2847
  /**
2562
2848
  * Generated bundle index. Do not edit.
2563
2849
  */
2564
2850
 
2565
- export { AXPDialogRendererComponent, AXPLayoutBuilderService, AXPLayoutConversionService, AXPLayoutRendererComponent, LayoutBuilderModule };
2851
+ export { AXPDialogRendererComponent, AXPLayoutBuilderService, AXPLayoutConversionService, AXPLayoutRendererComponent, AXPPreviewWidgetFieldCommand, AXP_PREVIEW_WIDGET_FIELD_COMMAND_KEY, LayoutBuilderModule };
2566
2852
  //# sourceMappingURL=acorex-platform-layout-builder.mjs.map